Skip to content

Commit ded0fa4

Browse files
author
OriginRing
committed
feat(module:check-list): add check-list component
1 parent 5898da7 commit ded0fa4

22 files changed

+913
-0
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ components/color-picker/** @OriginRing
7474
components/hash-code/** @OriginRing
7575
components/flex/** @ParsaArvanehPA
7676
components/float-button/** @OriginRing
77+
components/check-list/** @OriginRing
7778

7879
# The `components/core/*` owners
7980
components/core/config/** @simplejason
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
import { ChangeDetectionStrategy, Component, Input, TemplateRef, ViewEncapsulation } from '@angular/core';
7+
8+
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
9+
import { NzCheckListI18nInterface } from 'ng-zorro-antd/i18n';
10+
import { NzIconModule } from 'ng-zorro-antd/icon';
11+
12+
@Component({
13+
selector: 'nz-check-list-button',
14+
changeDetection: ChangeDetectionStrategy.OnPush,
15+
encapsulation: ViewEncapsulation.None,
16+
imports: [NzIconModule, NzOutletModule],
17+
template: `
18+
@if (!!triggerRender) {
19+
<ng-container *nzStringTemplateOutlet="triggerRender">{{ triggerRender }}</ng-container>
20+
} @else {
21+
<span nz-icon nzType="check-circle" nzTheme="outline" class="ant-checklist-icon"></span>
22+
<div class="ant-checklist-description">{{ locale.checkList }}</div>
23+
}
24+
`,
25+
host: {
26+
class: 'ant-btn ant-btn-primary ant-checklist-button'
27+
}
28+
})
29+
export class NzCheckListButtonComponent {
30+
@Input() triggerRender: TemplateRef<void> | string | null = '';
31+
@Input() locale!: NzCheckListI18nInterface;
32+
33+
constructor() {}
34+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
import { DecimalPipe } from '@angular/common';
7+
import {
8+
ChangeDetectionStrategy,
9+
ChangeDetectorRef,
10+
Component,
11+
EventEmitter,
12+
Input,
13+
Output,
14+
TemplateRef,
15+
ViewEncapsulation
16+
} from '@angular/core';
17+
import { FormsModule } from '@angular/forms';
18+
19+
import { NzButtonModule } from 'ng-zorro-antd/button';
20+
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
21+
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
22+
import { NzCheckListI18nInterface } from 'ng-zorro-antd/i18n';
23+
import { NzIconModule } from 'ng-zorro-antd/icon';
24+
import { NzProgressModule } from 'ng-zorro-antd/progress';
25+
26+
import { NzItemProps } from './typings';
27+
28+
@Component({
29+
selector: 'nz-check-list-content',
30+
changeDetection: ChangeDetectionStrategy.OnPush,
31+
encapsulation: ViewEncapsulation.None,
32+
imports: [NzIconModule, NzProgressModule, NzOutletModule, NzButtonModule, NzCheckboxModule, FormsModule, DecimalPipe],
33+
template: `
34+
@if (isVisible) {
35+
@if (getPercent() === 100) {
36+
<div class="ant-checklist-header-finish">
37+
<span nz-icon nzType="check-circle" nzTheme="outline" class="ant-checklist-header-finish-icon"></span>
38+
<h3 class="ant-checklist-header-finish-title">{{ locale.checkListFinish }}</h3>
39+
<button nz-button nzType="primary" style="margin: 24px" (click)="closePopover.emit(false)">{{
40+
locale.checkListClose
41+
}}</button>
42+
</div>
43+
} @else {
44+
<div class="ant-checklist-header">
45+
<div class="ant-checklist-header-title">
46+
@if (!!title) {
47+
<ng-container *nzStringTemplateOutlet="title">{{ title }}</ng-container>
48+
} @else {
49+
{{ locale.checkList }}
50+
}
51+
</div>
52+
<div class="ant-checklist-header-extra">
53+
<span nz-icon nzType="down" nzTheme="outline" (click)="closePopover.emit(false)"></span>
54+
</div>
55+
</div>
56+
@if (progress) {
57+
<div class="ant-checklist-progressBar">
58+
<div class="ant-checklist-progressBar-progress">
59+
<nz-progress [nzPercent]="getPercent() | number: '1.0-0'"></nz-progress>
60+
</div>
61+
</div>
62+
}
63+
}
64+
<div class="ant-checklist-steps-content">
65+
@for (item of items; track item.key || item.description; let i = $index) {
66+
<div
67+
class="ant-checklist-steps"
68+
[class.ant-checklist-highlight]="index === i + 1"
69+
[class.ant-checklist-checked]="index > i + 1"
70+
>
71+
<div class="ant-checklist-steps-item">
72+
<div class="ant-checklist-steps-item-circle">
73+
@if (index > i + 1) {
74+
<span nz-icon nzType="check" nzTheme="outline" class="ant-checklist-steps-checkoutlined"></span>
75+
} @else {
76+
<div class="ant-checklist-steps-number">{{ i + 1 }}</div>
77+
}
78+
</div>
79+
<div class="ant-checklist-steps-item-description">{{ item.description }}</div>
80+
</div>
81+
@if (index === i + 1 && !!item.onClick) {
82+
<span
83+
nz-icon
84+
nzType="arrow-right"
85+
nzTheme="outline"
86+
class="ant-checklist-steps-item-arrows"
87+
(click)="item.onClick()"
88+
></span>
89+
}
90+
</div>
91+
}
92+
</div>
93+
<div class="ant-checklist-footer" (click)="cancel(false)">
94+
@if (!!footer) {
95+
<ng-container *nzStringTemplateOutlet="footer">{{ footer }}</ng-container>
96+
} @else {
97+
{{ locale.checkListFooter }}
98+
}
99+
</div>
100+
} @else {
101+
<div class="ant-checklist-close-check">
102+
<div class="ant-checklist-close-check-title">{{ locale.checkListCheck }}</div>
103+
<div class="ant-checklist-close-check-action">
104+
<button nz-button nzType="primary" (click)="clearModel()">{{ locale.ok }}</button>
105+
<button nz-button (click)="cancel(true)">{{ locale.cancel }}</button>
106+
</div>
107+
<div class="ant-checklist-close-check-other">
108+
<label nz-checkbox [(ngModel)]="checked">{{ locale.checkListCheckOther }}</label>
109+
</div>
110+
</div>
111+
}
112+
`,
113+
host: {
114+
class: 'ant-checklist-content'
115+
}
116+
})
117+
export class NzCheckListContentComponent {
118+
@Input() locale!: NzCheckListI18nInterface;
119+
@Input() items: NzItemProps[] = [];
120+
@Input() index: number = 0;
121+
@Input() title: TemplateRef<void> | string | null = null;
122+
@Input() progress: boolean = true;
123+
@Input() footer: TemplateRef<void> | string | null = null;
124+
@Output() readonly closePopover = new EventEmitter<boolean>();
125+
@Output() readonly hideCallback = new EventEmitter<boolean>();
126+
127+
checked: boolean = false;
128+
isVisible: boolean = true;
129+
130+
getPercent(): number {
131+
if (this.index <= 1) {
132+
return 0;
133+
} else if (this.index > this.items.length) {
134+
return 100;
135+
} else {
136+
return ((this.index - 1) / this.items.length) * 100;
137+
}
138+
}
139+
140+
constructor(private cdr: ChangeDetectorRef) {}
141+
142+
clearModel(): void {
143+
this.hideCallback.emit(this.checked);
144+
}
145+
146+
cancel(visible: boolean): void {
147+
this.isVisible = visible;
148+
this.cdr.markForCheck();
149+
}
150+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
import {
7+
ChangeDetectionStrategy,
8+
ChangeDetectorRef,
9+
Component,
10+
EventEmitter,
11+
inject,
12+
Input,
13+
OnInit,
14+
Output,
15+
TemplateRef,
16+
ViewEncapsulation
17+
} from '@angular/core';
18+
import { takeUntil } from 'rxjs/operators';
19+
20+
import { NzItemProps } from 'ng-zorro-antd/check-list/typings';
21+
import { NzDestroyService } from 'ng-zorro-antd/core/services';
22+
import { NzCheckListI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n';
23+
import { NzPopoverModule } from 'ng-zorro-antd/popover';
24+
25+
import { NzCheckListButtonComponent } from './check-list-button.component';
26+
import { NzCheckListContentComponent } from './check-list-content.component';
27+
28+
@Component({
29+
selector: 'nz-check-list',
30+
changeDetection: ChangeDetectionStrategy.OnPush,
31+
encapsulation: ViewEncapsulation.None,
32+
imports: [NzCheckListButtonComponent, NzPopoverModule, NzCheckListContentComponent],
33+
providers: [NzDestroyService],
34+
template: `
35+
<nz-check-list-button
36+
[locale]="locale"
37+
[triggerRender]="nzTriggerRender"
38+
nz-popover
39+
[nzPopoverContent]="checklistTemplate"
40+
nzPopoverTrigger="click"
41+
nzPopoverPlacement="topRight"
42+
[nzPopoverOverlayClickable]="false"
43+
[nzPopoverVisible]="nzVisible"
44+
(nzPopoverVisibleChange)="popoverVisibleChange($event)"
45+
></nz-check-list-button>
46+
<ng-template #checklistTemplate>
47+
<nz-check-list-content
48+
[locale]="locale"
49+
[items]="nzItems"
50+
[index]="nzIndex"
51+
[title]="nzTitle"
52+
[progress]="nzProgress"
53+
[footer]="nzFooter"
54+
(closePopover)="closePopover($event)"
55+
(hideCallback)="hideCallback($event)"
56+
></nz-check-list-content>
57+
</ng-template>
58+
`,
59+
host: {
60+
class: 'ant-checklist',
61+
'[class.ant-checklist-hide]': `!nzShow`
62+
}
63+
})
64+
export class NzCheckListComponent implements OnInit {
65+
@Input() nzShow: boolean = true;
66+
@Input() nzItems: NzItemProps[] = [];
67+
@Input() nzVisible: boolean = false;
68+
@Input() nzIndex: number = 1;
69+
@Input() nzProgress: boolean = true;
70+
@Input() nzTriggerRender: TemplateRef<void> | string | null = null;
71+
@Input() nzTitle: TemplateRef<void> | string | null = null;
72+
@Input() nzFooter: TemplateRef<void> | string | null = null;
73+
@Output() readonly nzHideCallback = new EventEmitter<boolean>();
74+
75+
private destroy$ = inject(NzDestroyService);
76+
locale!: NzCheckListI18nInterface;
77+
78+
constructor(
79+
private cdr: ChangeDetectorRef,
80+
private i18n: NzI18nService
81+
) {}
82+
83+
ngOnInit(): void {
84+
this.i18n.localeChange.pipe(takeUntil(this.destroy$)).subscribe(() => {
85+
this.locale = this.i18n.getLocaleData('CheckList');
86+
this.cdr.markForCheck();
87+
});
88+
}
89+
90+
hideCallback(check: boolean): void {
91+
this.nzVisible = false;
92+
this.nzHideCallback.emit(check);
93+
}
94+
95+
closePopover(visible: boolean): void {
96+
this.nzVisible = visible;
97+
this.cdr.markForCheck();
98+
}
99+
100+
popoverVisibleChange(visible: boolean): void {
101+
this.nzVisible = visible;
102+
this.cdr.markForCheck();
103+
}
104+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
import { NgModule } from '@angular/core';
7+
8+
import { NzCheckListComponent } from './check-list.component';
9+
10+
@NgModule({
11+
imports: [NzCheckListComponent],
12+
exports: [NzCheckListComponent]
13+
})
14+
export class NzCheckListModule {}

components/check-list/demo/basic.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
order: 0
3+
title:
4+
zh-CN: 任务清单
5+
en-US: CheckList
6+
---
7+
8+
## zh-CN
9+
10+
最简单的用法。
11+
12+
## en-US
13+
14+
The simplest usage.
15+

components/check-list/demo/basic.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { Component } from '@angular/core';
2+
3+
import { NzButtonModule } from 'ng-zorro-antd/button';
4+
import { NzCheckListModule, NzItemProps } from 'ng-zorro-antd/check-list';
5+
import { NzWaveDirective } from 'ng-zorro-antd/core/wave';
6+
import { NzModalModule } from 'ng-zorro-antd/modal';
7+
8+
@Component({
9+
selector: 'nz-demo-check-list-basic',
10+
imports: [NzCheckListModule, NzButtonModule, NzWaveDirective, NzModalModule],
11+
template: `
12+
<nz-check-list [nzItems]="nzItems" [nzIndex]="index" (nzHideCallback)="hideCancel($event)"></nz-check-list>
13+
<nz-modal [(nzVisible)]="isVisible" nzTitle="The first Modal" (nzOnCancel)="handleCancel()" (nzOnOk)="handleOk()">
14+
<ng-container *nzModalContent>
15+
<p>Content one</p>
16+
<p>Content two</p>
17+
<p>Content three</p>
18+
</ng-container>
19+
<ng-container *nzModalFooter>
20+
<button nz-button nzType="default" (click)="handleCancel()">Cancel</button>
21+
<button nz-button nzType="primary" (click)="handleOk()">Finish</button>
22+
</ng-container>
23+
</nz-modal>
24+
`
25+
})
26+
export class NzDemoCheckListBasicComponent {
27+
index: number = 1;
28+
isVisible: boolean = false;
29+
nzItems: NzItemProps[] = [
30+
{
31+
description: '第一步',
32+
onClick: () => {
33+
console.log(1);
34+
this.index++;
35+
}
36+
},
37+
{
38+
description: '第二步',
39+
onClick: () => {
40+
this.isVisible = true;
41+
this.index++;
42+
}
43+
},
44+
{
45+
description: '第三步',
46+
onClick: () => {
47+
this.index++;
48+
}
49+
},
50+
{
51+
description: '第四步',
52+
onClick: () => {
53+
this.index++;
54+
}
55+
}
56+
];
57+
58+
handleOk(): void {
59+
this.isVisible = false;
60+
}
61+
62+
handleCancel(): void {
63+
this.isVisible = false;
64+
}
65+
66+
hideCancel(check: boolean): void {
67+
console.log(check);
68+
}
69+
}

0 commit comments

Comments
 (0)