Skip to content

Commit

Permalink
feat(module:check-list): add check-list component
Browse files Browse the repository at this point in the history
  • Loading branch information
OriginRing committed Jan 16, 2025
1 parent 5898da7 commit ded0fa4
Show file tree
Hide file tree
Showing 22 changed files with 913 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ components/color-picker/** @OriginRing
components/hash-code/** @OriginRing
components/flex/** @ParsaArvanehPA
components/float-button/** @OriginRing
components/check-list/** @OriginRing

# The `components/core/*` owners
components/core/config/** @simplejason
Expand Down
34 changes: 34 additions & 0 deletions components/check-list/check-list-button.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { ChangeDetectionStrategy, Component, Input, TemplateRef, ViewEncapsulation } from '@angular/core';

import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
import { NzCheckListI18nInterface } from 'ng-zorro-antd/i18n';
import { NzIconModule } from 'ng-zorro-antd/icon';

@Component({
selector: 'nz-check-list-button',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
imports: [NzIconModule, NzOutletModule],
template: `
@if (!!triggerRender) {
<ng-container *nzStringTemplateOutlet="triggerRender">{{ triggerRender }}</ng-container>
} @else {
<span nz-icon nzType="check-circle" nzTheme="outline" class="ant-checklist-icon"></span>
<div class="ant-checklist-description">{{ locale.checkList }}</div>
}
`,
host: {
class: 'ant-btn ant-btn-primary ant-checklist-button'
}
})
export class NzCheckListButtonComponent {
@Input() triggerRender: TemplateRef<void> | string | null = '';
@Input() locale!: NzCheckListI18nInterface;

constructor() {}
}
150 changes: 150 additions & 0 deletions components/check-list/check-list-content.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { DecimalPipe } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
Input,
Output,
TemplateRef,
ViewEncapsulation
} from '@angular/core';
import { FormsModule } from '@angular/forms';

import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
import { NzCheckListI18nInterface } from 'ng-zorro-antd/i18n';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzProgressModule } from 'ng-zorro-antd/progress';

import { NzItemProps } from './typings';

@Component({
selector: 'nz-check-list-content',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
imports: [NzIconModule, NzProgressModule, NzOutletModule, NzButtonModule, NzCheckboxModule, FormsModule, DecimalPipe],
template: `
@if (isVisible) {
@if (getPercent() === 100) {
<div class="ant-checklist-header-finish">
<span nz-icon nzType="check-circle" nzTheme="outline" class="ant-checklist-header-finish-icon"></span>
<h3 class="ant-checklist-header-finish-title">{{ locale.checkListFinish }}</h3>
<button nz-button nzType="primary" style="margin: 24px" (click)="closePopover.emit(false)">{{
locale.checkListClose
}}</button>
</div>
} @else {
<div class="ant-checklist-header">
<div class="ant-checklist-header-title">
@if (!!title) {
<ng-container *nzStringTemplateOutlet="title">{{ title }}</ng-container>
} @else {
{{ locale.checkList }}
}
</div>
<div class="ant-checklist-header-extra">
<span nz-icon nzType="down" nzTheme="outline" (click)="closePopover.emit(false)"></span>
</div>
</div>
@if (progress) {
<div class="ant-checklist-progressBar">
<div class="ant-checklist-progressBar-progress">
<nz-progress [nzPercent]="getPercent() | number: '1.0-0'"></nz-progress>
</div>
</div>
}
}
<div class="ant-checklist-steps-content">
@for (item of items; track item.key || item.description; let i = $index) {
<div
class="ant-checklist-steps"
[class.ant-checklist-highlight]="index === i + 1"
[class.ant-checklist-checked]="index > i + 1"
>
<div class="ant-checklist-steps-item">
<div class="ant-checklist-steps-item-circle">
@if (index > i + 1) {
<span nz-icon nzType="check" nzTheme="outline" class="ant-checklist-steps-checkoutlined"></span>
} @else {
<div class="ant-checklist-steps-number">{{ i + 1 }}</div>
}
</div>
<div class="ant-checklist-steps-item-description">{{ item.description }}</div>
</div>
@if (index === i + 1 && !!item.onClick) {
<span
nz-icon
nzType="arrow-right"
nzTheme="outline"
class="ant-checklist-steps-item-arrows"
(click)="item.onClick()"
></span>
}
</div>
}
</div>
<div class="ant-checklist-footer" (click)="cancel(false)">
@if (!!footer) {
<ng-container *nzStringTemplateOutlet="footer">{{ footer }}</ng-container>
} @else {
{{ locale.checkListFooter }}
}
</div>
} @else {
<div class="ant-checklist-close-check">
<div class="ant-checklist-close-check-title">{{ locale.checkListCheck }}</div>
<div class="ant-checklist-close-check-action">
<button nz-button nzType="primary" (click)="clearModel()">{{ locale.ok }}</button>
<button nz-button (click)="cancel(true)">{{ locale.cancel }}</button>
</div>
<div class="ant-checklist-close-check-other">
<label nz-checkbox [(ngModel)]="checked">{{ locale.checkListCheckOther }}</label>
</div>
</div>
}
`,
host: {
class: 'ant-checklist-content'
}
})
export class NzCheckListContentComponent {
@Input() locale!: NzCheckListI18nInterface;
@Input() items: NzItemProps[] = [];
@Input() index: number = 0;
@Input() title: TemplateRef<void> | string | null = null;
@Input() progress: boolean = true;
@Input() footer: TemplateRef<void> | string | null = null;
@Output() readonly closePopover = new EventEmitter<boolean>();
@Output() readonly hideCallback = new EventEmitter<boolean>();

checked: boolean = false;
isVisible: boolean = true;

getPercent(): number {
if (this.index <= 1) {
return 0;
} else if (this.index > this.items.length) {
return 100;
} else {
return ((this.index - 1) / this.items.length) * 100;
}
}

constructor(private cdr: ChangeDetectorRef) {}

clearModel(): void {
this.hideCallback.emit(this.checked);
}

cancel(visible: boolean): void {
this.isVisible = visible;
this.cdr.markForCheck();
}
}
104 changes: 104 additions & 0 deletions components/check-list/check-list.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
inject,
Input,
OnInit,
Output,
TemplateRef,
ViewEncapsulation
} from '@angular/core';
import { takeUntil } from 'rxjs/operators';

import { NzItemProps } from 'ng-zorro-antd/check-list/typings';
import { NzDestroyService } from 'ng-zorro-antd/core/services';
import { NzCheckListI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n';
import { NzPopoverModule } from 'ng-zorro-antd/popover';

import { NzCheckListButtonComponent } from './check-list-button.component';
import { NzCheckListContentComponent } from './check-list-content.component';

@Component({
selector: 'nz-check-list',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
imports: [NzCheckListButtonComponent, NzPopoverModule, NzCheckListContentComponent],
providers: [NzDestroyService],
template: `
<nz-check-list-button
[locale]="locale"
[triggerRender]="nzTriggerRender"
nz-popover
[nzPopoverContent]="checklistTemplate"
nzPopoverTrigger="click"
nzPopoverPlacement="topRight"
[nzPopoverOverlayClickable]="false"
[nzPopoverVisible]="nzVisible"
(nzPopoverVisibleChange)="popoverVisibleChange($event)"
></nz-check-list-button>
<ng-template #checklistTemplate>
<nz-check-list-content
[locale]="locale"
[items]="nzItems"
[index]="nzIndex"
[title]="nzTitle"
[progress]="nzProgress"
[footer]="nzFooter"
(closePopover)="closePopover($event)"
(hideCallback)="hideCallback($event)"
></nz-check-list-content>
</ng-template>
`,
host: {
class: 'ant-checklist',
'[class.ant-checklist-hide]': `!nzShow`
}
})
export class NzCheckListComponent implements OnInit {
@Input() nzShow: boolean = true;
@Input() nzItems: NzItemProps[] = [];
@Input() nzVisible: boolean = false;
@Input() nzIndex: number = 1;
@Input() nzProgress: boolean = true;
@Input() nzTriggerRender: TemplateRef<void> | string | null = null;
@Input() nzTitle: TemplateRef<void> | string | null = null;
@Input() nzFooter: TemplateRef<void> | string | null = null;
@Output() readonly nzHideCallback = new EventEmitter<boolean>();

private destroy$ = inject(NzDestroyService);
locale!: NzCheckListI18nInterface;

constructor(
private cdr: ChangeDetectorRef,
private i18n: NzI18nService
) {}

ngOnInit(): void {
this.i18n.localeChange.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.locale = this.i18n.getLocaleData('CheckList');
this.cdr.markForCheck();
});
}

hideCallback(check: boolean): void {
this.nzVisible = false;
this.nzHideCallback.emit(check);
}

closePopover(visible: boolean): void {
this.nzVisible = visible;
this.cdr.markForCheck();
}

popoverVisibleChange(visible: boolean): void {
this.nzVisible = visible;
this.cdr.markForCheck();
}
}
14 changes: 14 additions & 0 deletions components/check-list/check-list.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { NgModule } from '@angular/core';

import { NzCheckListComponent } from './check-list.component';

@NgModule({
imports: [NzCheckListComponent],
exports: [NzCheckListComponent]
})
export class NzCheckListModule {}
15 changes: 15 additions & 0 deletions components/check-list/demo/basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
order: 0
title:
zh-CN: 任务清单
en-US: CheckList
---

## zh-CN

最简单的用法。

## en-US

The simplest usage.

69 changes: 69 additions & 0 deletions components/check-list/demo/basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Component } from '@angular/core';

import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzCheckListModule, NzItemProps } from 'ng-zorro-antd/check-list';
import { NzWaveDirective } from 'ng-zorro-antd/core/wave';
import { NzModalModule } from 'ng-zorro-antd/modal';

@Component({
selector: 'nz-demo-check-list-basic',
imports: [NzCheckListModule, NzButtonModule, NzWaveDirective, NzModalModule],
template: `
<nz-check-list [nzItems]="nzItems" [nzIndex]="index" (nzHideCallback)="hideCancel($event)"></nz-check-list>
<nz-modal [(nzVisible)]="isVisible" nzTitle="The first Modal" (nzOnCancel)="handleCancel()" (nzOnOk)="handleOk()">
<ng-container *nzModalContent>
<p>Content one</p>
<p>Content two</p>
<p>Content three</p>
</ng-container>
<ng-container *nzModalFooter>
<button nz-button nzType="default" (click)="handleCancel()">Cancel</button>
<button nz-button nzType="primary" (click)="handleOk()">Finish</button>
</ng-container>
</nz-modal>
`
})
export class NzDemoCheckListBasicComponent {
index: number = 1;
isVisible: boolean = false;
nzItems: NzItemProps[] = [
{
description: '第一步',
onClick: () => {
console.log(1);
this.index++;
}
},
{
description: '第二步',
onClick: () => {
this.isVisible = true;
this.index++;
}
},
{
description: '第三步',
onClick: () => {
this.index++;
}
},
{
description: '第四步',
onClick: () => {
this.index++;
}
}
];

handleOk(): void {
this.isVisible = false;
}

handleCancel(): void {
this.isVisible = false;
}

hideCancel(check: boolean): void {
console.log(check);
}
}
Loading

0 comments on commit ded0fa4

Please sign in to comment.