From 14859c8f69cb94db9bf9dd4080a82c2273243b31 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Thu, 10 Jan 2019 19:14:15 +0800 Subject: [PATCH 1/5] feat(module:comment): add comment component close #2731 --- components/comment/demo/basic.md | 15 +++ components/comment/demo/basic.ts | 44 +++++++++ components/comment/demo/editor.md | 14 +++ components/comment/demo/editor.ts | 55 +++++++++++ components/comment/demo/list.md | 14 +++ components/comment/demo/list.ts | 37 ++++++++ components/comment/demo/nested.md | 15 +++ components/comment/demo/nested.ts | 60 ++++++++++++ components/comment/doc/index.en-US.md | 19 ++++ components/comment/doc/index.zh-CN.md | 20 ++++ components/comment/index.ts | 1 + components/comment/nz-comment-cells.ts | 68 ++++++++++++++ components/comment/nz-comment.component.html | 24 +++++ .../comment/nz-comment.component.spec.ts | 25 +++++ components/comment/nz-comment.component.ts | 41 ++++++++ components/comment/nz-comment.module.ts | 28 ++++++ components/comment/public-api.ts | 3 + components/comment/style/index.less | 93 +++++++++++++++++++ components/components.less | 1 + components/ng-zorro-antd.module.ts | 3 + 20 files changed, 580 insertions(+) create mode 100644 components/comment/demo/basic.md create mode 100644 components/comment/demo/basic.ts create mode 100644 components/comment/demo/editor.md create mode 100644 components/comment/demo/editor.ts create mode 100644 components/comment/demo/list.md create mode 100644 components/comment/demo/list.ts create mode 100644 components/comment/demo/nested.md create mode 100644 components/comment/demo/nested.ts create mode 100644 components/comment/doc/index.en-US.md create mode 100644 components/comment/doc/index.zh-CN.md create mode 100644 components/comment/index.ts create mode 100644 components/comment/nz-comment-cells.ts create mode 100644 components/comment/nz-comment.component.html create mode 100644 components/comment/nz-comment.component.spec.ts create mode 100644 components/comment/nz-comment.component.ts create mode 100644 components/comment/nz-comment.module.ts create mode 100644 components/comment/public-api.ts create mode 100644 components/comment/style/index.less diff --git a/components/comment/demo/basic.md b/components/comment/demo/basic.md new file mode 100644 index 00000000000..ecd84bf2635 --- /dev/null +++ b/components/comment/demo/basic.md @@ -0,0 +1,15 @@ +--- +order: 0 +title: + zh-CN: 基本评论 + en-US: Basic comment +--- + +## zh-CN + +一个基本的评论组件,带有作者、头像、时间和操作。 + +## en-US + +A basic comment with author, avatar, time and actions. + diff --git a/components/comment/demo/basic.ts b/components/comment/demo/basic.ts new file mode 100644 index 00000000000..e7e5b8d23d4 --- /dev/null +++ b/components/comment/demo/basic.ts @@ -0,0 +1,44 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-comment-basic', + template: ` + + + +

We supply a series of design principles, practical patterns and high quality design resources + (Sketch and Axure), to help people create their product prototypes beautifully and efficiently. +

+
+ + + {{likes}} + + + + {{dislikes}} + + Reply to +
+ `, + styles : [` + .count { + padding-left: 8px; + cursor: auto; + } + `] +}) +export class NzDemoCommentBasicComponent { + likes = 0; + dislikes = 0; + + like(): void { + this.likes = 1; + this.dislikes = 0; + } + + dislike(): void { + this.likes = 0; + this.dislikes = 1; + } +} diff --git a/components/comment/demo/editor.md b/components/comment/demo/editor.md new file mode 100644 index 00000000000..01d105e27a1 --- /dev/null +++ b/components/comment/demo/editor.md @@ -0,0 +1,14 @@ +--- +order: 3 +title: + zh-CN: 回复框 + en-US: Reply Editor +--- + +## zh-CN + +评论编辑器组件提供了相同样式的封装以支持自定义评论编辑器。 + +## en-US + +Comment can be used as editor, user can customize the editor component. diff --git a/components/comment/demo/editor.ts b/components/comment/demo/editor.ts new file mode 100644 index 00000000000..3ca32defe61 --- /dev/null +++ b/components/comment/demo/editor.ts @@ -0,0 +1,55 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-comment-editor', + template: ` + + + + + +

{{item.content}}

+
+
+
+
+ + + + + + + + + + + + `, + styles : [] +}) +export class NzDemoCommentEditorComponent { + data = []; + submitting = false; + user = { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png' + }; + inputValue = ''; + + handleSubmit(): void { + this.submitting = true; + const content = this.inputValue; + this.inputValue = ''; + setTimeout(() => { + this.submitting = false; + this.data = this.data.concat({ + ...this.user, + content, + datetime: new Date().toLocaleString() + }); + }, 800); + } + +} diff --git a/components/comment/demo/list.md b/components/comment/demo/list.md new file mode 100644 index 00000000000..bd574ac8c01 --- /dev/null +++ b/components/comment/demo/list.md @@ -0,0 +1,14 @@ +--- +order: 1 +title: + zh-CN: 配合 List 组件 + en-US: Usage with list +--- + +## zh-CN + +配合 List 组件展现评论列表。 + +## en-US + +Displaying a series of comments using the `antd` List Component. diff --git a/components/comment/demo/list.ts b/components/comment/demo/list.ts new file mode 100644 index 00000000000..3e17ad1544c --- /dev/null +++ b/components/comment/demo/list.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-comment-list', + template: ` + + + + + +

{{item.content}}

+
+ Reply to +
+
+
+ `, + styles : [] +}) +export class NzDemoCommentListComponent { + data = [ + { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', + content: 'We supply a series of design principles, practical patterns and high quality design resources' + + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + datetime: '1 天前' + }, + { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', + content: 'We supply a series of design principles, practical patterns and high quality design resources' + + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + datetime: '2 天前' + } + ]; +} diff --git a/components/comment/demo/nested.md b/components/comment/demo/nested.md new file mode 100644 index 00000000000..a42405d4c1a --- /dev/null +++ b/components/comment/demo/nested.md @@ -0,0 +1,15 @@ +--- +order: 2 +title: + zh-CN: 嵌套评论 + en-US: Nested comments +--- + +## zh-CN + +评论可以嵌套。 + +## en-US + +Comments can be nested. + diff --git a/components/comment/demo/nested.ts b/components/comment/demo/nested.ts new file mode 100644 index 00000000000..2b4c207ee5c --- /dev/null +++ b/components/comment/demo/nested.ts @@ -0,0 +1,60 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-comment-nested', + template: ` + + + + +

{{comment.content}}

+
+ Reply to + + + + + + +
+
+ + + + `, + styles : [] +}) +export class NzDemoCommentNestedComponent { + data = { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', + content: 'We supply a series of design principles, practical patterns and high quality design resources' + + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + children: [ + { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', + content: 'We supply a series of design principles, practical patterns and high quality design resources' + + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + children: [ + { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', + content: 'We supply a series of design principles, practical patterns and high quality design resources' + + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + }, + { + author: 'Han Solo', + avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', + content: 'We supply a series of design principles, practical patterns and high quality design resources' + + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + } + ] + } + ] + }; +} diff --git a/components/comment/doc/index.en-US.md b/components/comment/doc/index.en-US.md new file mode 100644 index 00000000000..66d31aff065 --- /dev/null +++ b/components/comment/doc/index.en-US.md @@ -0,0 +1,19 @@ +--- +category: Components +type: Data Display +title: Comment +cols: 1 +--- + +A comment displays user feedback and discussion to website content. + +## When To Use + +Comments can be used to enable discussions on an entity such as a page, blog post, issue or other. + +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| [nzAuthor] | The element to display as the comment author | `string|TemplateRef` | - | +| [nzDatetime] | A datetime element containing the time to be displayed | `string|TemplateRef` | - | diff --git a/components/comment/doc/index.zh-CN.md b/components/comment/doc/index.zh-CN.md new file mode 100644 index 00000000000..62a8d1a5222 --- /dev/null +++ b/components/comment/doc/index.zh-CN.md @@ -0,0 +1,20 @@ +--- +category: Components +type: Data Display +title: Comment +subtitle: 评论 +cols: 1 +--- + +对网站内容的反馈、评价和讨论。 + +## 何时使用 + +评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。 + +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| [nzAuthor]] | 显示评论的作者 | `string|TemplateRef` | - | +| [nzDatetime] | 展示时间描述 | `string|TemplateRef` | - | diff --git a/components/comment/index.ts b/components/comment/index.ts new file mode 100644 index 00000000000..7e1a213e3ea --- /dev/null +++ b/components/comment/index.ts @@ -0,0 +1 @@ +export * from './public-api'; diff --git a/components/comment/nz-comment-cells.ts b/components/comment/nz-comment-cells.ts new file mode 100644 index 00000000000..7ec788c5263 --- /dev/null +++ b/components/comment/nz-comment-cells.ts @@ -0,0 +1,68 @@ +import { CdkPortalOutlet, TemplatePortal } from '@angular/cdk/portal'; +import { + ChangeDetectionStrategy, + Component, ComponentFactoryResolver, + Directive, Input, OnDestroy, + OnInit, + TemplateRef, + ViewChild, + ViewContainerRef, ViewEncapsulation +} from '@angular/core'; + +@Directive({ + selector: 'nz-avatar[nz-comment-avatar]' +}) +export class NzCommentAvatarDirective { +} + +@Directive({ + selector: 'nz-comment-content, [nz-comment-content]', + host : { 'class': 'ant-comment-content-detail' } +}) +export class NzCommentContentDirective { +} + +@Directive({ + selector: '[nzCommentActionHost]' +}) +export class NzCommentActionHostDirective extends CdkPortalOutlet implements OnInit, OnDestroy { + + @Input() nzCommentActionHost: TemplatePortal | null; + + constructor(componentFactoryResolver: ComponentFactoryResolver, + viewContainerRef: ViewContainerRef) { + super(componentFactoryResolver, viewContainerRef); + } + + ngOnInit(): void { + super.ngOnInit(); + this.attach(this.nzCommentActionHost); + } + + ngOnDestroy(): void { + super.ngOnDestroy(); + } +} + +@Component({ + selector : 'nz-comment-action', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + template : '' +}) +export class NzCommentActionComponent implements OnInit { + @ViewChild(TemplateRef) implicitContent: TemplateRef; + private contentPortal: TemplatePortal | null = null; + + get content(): TemplatePortal | null { + return this.contentPortal; + } + + constructor(private viewContainerRef: ViewContainerRef) { + + } + + ngOnInit(): void { + this.contentPortal = new TemplatePortal(this.implicitContent, this.viewContainerRef); + } +} diff --git a/components/comment/nz-comment.component.html b/components/comment/nz-comment.component.html new file mode 100644 index 00000000000..d5b12c00fb7 --- /dev/null +++ b/components/comment/nz-comment.component.html @@ -0,0 +1,24 @@ +
+
+ +
+
+ + +
    +
  • + +
  • +
+
+
+
+ +
\ No newline at end of file diff --git a/components/comment/nz-comment.component.spec.ts b/components/comment/nz-comment.component.spec.ts new file mode 100644 index 00000000000..81399f23c31 --- /dev/null +++ b/components/comment/nz-comment.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NzCommentComponent } from './nz-comment.component'; + +describe('NzCommentComponent', () => { + let component: NzCommentComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NzCommentComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NzCommentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/components/comment/nz-comment.component.ts b/components/comment/nz-comment.component.ts new file mode 100644 index 00000000000..549e502a6b9 --- /dev/null +++ b/components/comment/nz-comment.component.ts @@ -0,0 +1,41 @@ +import { + ChangeDetectionStrategy, + Component, + ContentChildren, + Input, + QueryList, + TemplateRef, + ViewEncapsulation +} from '@angular/core'; +import { NzCommentActionComponent as CommentAction } from './nz-comment-cells'; + +@Component({ + selector : 'nz-comment', + templateUrl : './nz-comment.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + host : { + 'class': 'ant-comment' + }, + styles : [ + ` + nz-comment { + display: block; + } + + nz-comment-content { + display: block; + } + ` + ] +}) +export class NzCommentComponent { + + @Input() nzAuthor: string | TemplateRef; + @Input() nzDatetime: string | TemplateRef; + + @ContentChildren(CommentAction) actions: QueryList; + constructor() { + } + +} diff --git a/components/comment/nz-comment.module.ts b/components/comment/nz-comment.module.ts new file mode 100644 index 00000000000..5d17d71830f --- /dev/null +++ b/components/comment/nz-comment.module.ts @@ -0,0 +1,28 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { NzAddOnModule } from '../core/addon/addon.module'; +import { + NzCommentActionComponent, + NzCommentActionHostDirective, + NzCommentAvatarDirective, + NzCommentContentDirective +} from './nz-comment-cells'; +import { NzCommentComponent } from './nz-comment.component'; + +const NZ_COMMENT_CELLS = [ + NzCommentAvatarDirective, + NzCommentContentDirective, + NzCommentActionComponent, + NzCommentActionHostDirective +]; + +@NgModule({ + imports : [ + CommonModule, + NzAddOnModule + ], + exports : [ NzCommentComponent, ...NZ_COMMENT_CELLS ], + declarations: [ NzCommentComponent, ...NZ_COMMENT_CELLS ] +}) +export class NzCommentModule { +} diff --git a/components/comment/public-api.ts b/components/comment/public-api.ts new file mode 100644 index 00000000000..d14bf41fc5a --- /dev/null +++ b/components/comment/public-api.ts @@ -0,0 +1,3 @@ +export * from './nz-comment.module'; +export * from './nz-comment.component'; +export * from './nz-comment-cells'; diff --git a/components/comment/style/index.less b/components/comment/style/index.less new file mode 100644 index 00000000000..891ea42098d --- /dev/null +++ b/components/comment/style/index.less @@ -0,0 +1,93 @@ +@import '../../style/themes/default'; +@import '../../style/mixins/index'; + +@comment-prefix-cls: ~'@{ant-prefix}-comment'; + +.@{comment-prefix-cls} { + position: relative; + + &-inner { + padding: @comment-padding-base; + display: flex; + } + + &-avatar { + flex-shrink: 0; + position: relative; + margin-right: 12px; + cursor: pointer; + img { + width: 32px; + height: 32px; + border-radius: 50%; + } + } + + &-content { + position: relative; + font-size: 14px; + flex: 1 1 auto; + min-width: 1px; + word-wrap: break-word; + + &-author { + margin-bottom: 4px; + font-size: 14px; + display: flex; + justify-content: flex-start; + & > a, + & > span { + height: 18px; + font-size: 12px; + line-height: 18px; + padding-right: 8px; + } + + &-name { + transition: color 0.3s; + font-size: 14px; + color: @comment-author-name-color; + > * { + color: @comment-author-name-color; + &:hover { + color: @comment-author-name-color; + } + } + } + + &-time { + cursor: auto; + color: @comment-author-time-color; + white-space: nowrap; + } + } + + &-detail p { + white-space: pre-wrap; + } + } + + &-actions { + margin-top: 12px; + padding-left: 0; + > li { + display: inline-block; + color: @comment-action-color; + > span { + padding-right: 10px; + transition: color 0.3s; + font-size: 12px; + color: @comment-action-color; + cursor: pointer; + user-select: none; + &:hover { + color: @comment-action-hover-color; + } + } + } + } + + &-nested { + margin-left: @comment-nest-indent; + } +} diff --git a/components/components.less b/components/components.less index 7131e08b359..36c161eabbe 100644 --- a/components/components.less +++ b/components/components.less @@ -10,6 +10,7 @@ @import "./carousel/style/index.less"; @import "./checkbox/style/index.less"; @import "./collapse/style/index.less"; +@import "./comment/style/index.less"; @import "./core/style/index.less"; @import "./date-picker/style/index.less"; @import "./divider/style/index.less"; diff --git a/components/ng-zorro-antd.module.ts b/components/ng-zorro-antd.module.ts index 4425b4dbf03..c5675b6ccb2 100644 --- a/components/ng-zorro-antd.module.ts +++ b/components/ng-zorro-antd.module.ts @@ -15,6 +15,7 @@ import { NzCarouselModule } from './carousel/nz-carousel.module'; import { NzCascaderModule } from './cascader/nz-cascader.module'; import { NzCheckboxModule } from './checkbox/nz-checkbox.module'; import { NzCollapseModule } from './collapse/nz-collapse.module'; +import { NzCommentModule } from './comment/nz-comment.module'; import { NzWaveModule } from './core/wave/nz-wave.module'; import { NzDatePickerModule } from './date-picker/date-picker.module'; import { NzDividerModule } from './divider/nz-divider.module'; @@ -70,6 +71,7 @@ export * from './card'; export * from './carousel'; export * from './checkbox'; export * from './collapse'; +export * from './comment'; export * from './date-picker'; export * from './divider'; export * from './drawer'; @@ -152,6 +154,7 @@ export * from './core/util'; NzTransferModule, NzCarouselModule, NzCollapseModule, + NzCommentModule, NzTableModule, NzDatePickerModule, NzDividerModule, From 5adc78cbb92f87c4841625a1ca6f7cd812f9ffe6 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Mon, 14 Jan 2019 15:17:38 +0800 Subject: [PATCH 2/5] test(module:comment): add test --- components/comment/demo/basic.ts | 8 +- components/comment/demo/editor.ts | 13 +- components/comment/demo/list.md | 6 +- components/comment/demo/list.ts | 5 +- components/comment/demo/nested.ts | 4 +- components/comment/doc/index.en-US.md | 7 + components/comment/doc/index.zh-CN.md | 9 +- components/comment/nz-comment.component.html | 2 +- .../comment/nz-comment.component.spec.ts | 25 --- components/comment/nz-comment.spec.ts | 143 ++++++++++++++++++ 10 files changed, 182 insertions(+), 40 deletions(-) delete mode 100644 components/comment/nz-comment.component.spec.ts create mode 100644 components/comment/nz-comment.spec.ts diff --git a/components/comment/demo/basic.ts b/components/comment/demo/basic.ts index e7e5b8d23d4..ddb8dd854af 100644 --- a/components/comment/demo/basic.ts +++ b/components/comment/demo/basic.ts @@ -1,9 +1,10 @@ import { Component } from '@angular/core'; +import { distanceInWords } from 'date-fns'; @Component({ selector: 'nz-demo-comment-basic', template: ` - +

We supply a series of design principles, practical patterns and high quality design resources @@ -12,11 +13,11 @@ import { Component } from '@angular/core'; - {{likes}} + - {{dislikes}} + {{dislikes}} Reply to @@ -31,6 +32,7 @@ import { Component } from '@angular/core'; export class NzDemoCommentBasicComponent { likes = 0; dislikes = 0; + time = distanceInWords(new Date(), new Date()); like(): void { this.likes = 1; diff --git a/components/comment/demo/editor.ts b/components/comment/demo/editor.ts index 3ca32defe61..6af8b3c7f78 100644 --- a/components/comment/demo/editor.ts +++ b/components/comment/demo/editor.ts @@ -1,11 +1,12 @@ import { Component } from '@angular/core'; +import { distanceInWords } from 'date-fns'; @Component({ selector: 'nz-demo-comment-editor', template: ` - +

{{item.content}}

@@ -44,10 +45,16 @@ export class NzDemoCommentEditorComponent { this.inputValue = ''; setTimeout(() => { this.submitting = false; - this.data = this.data.concat({ + this.data = [...this.data, { ...this.user, content, - datetime: new Date().toLocaleString() + datetime: new Date(), + displayTime: distanceInWords(new Date(), new Date()) + }].map(e => { + return { + ...e, + displayTime: distanceInWords(new Date(), e.datetime) + }; }); }, 800); } diff --git a/components/comment/demo/list.md b/components/comment/demo/list.md index bd574ac8c01..0440dfa8f0d 100644 --- a/components/comment/demo/list.md +++ b/components/comment/demo/list.md @@ -1,14 +1,14 @@ --- order: 1 title: - zh-CN: 配合 List 组件 + zh-CN: 配合列表组件 en-US: Usage with list --- ## zh-CN -配合 List 组件展现评论列表。 +配合 `nz-list` 组件展现评论列表。 ## en-US -Displaying a series of comments using the `antd` List Component. +Displaying a series of comments using the `nz-list` Component. diff --git a/components/comment/demo/list.ts b/components/comment/demo/list.ts index 3e17ad1544c..2e1ed0687b7 100644 --- a/components/comment/demo/list.ts +++ b/components/comment/demo/list.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { addDays, distanceInWords } from 'date-fns'; @Component({ selector: 'nz-demo-comment-list', @@ -24,14 +25,14 @@ export class NzDemoCommentListComponent { avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', content: 'We supply a series of design principles, practical patterns and high quality design resources' + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', - datetime: '1 天前' + datetime: distanceInWords(new Date(), addDays(new Date(), 1)) }, { author: 'Han Solo', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', content: 'We supply a series of design principles, practical patterns and high quality design resources' + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', - datetime: '2 天前' + datetime: distanceInWords(new Date(), addDays(new Date(), 2)) } ]; } diff --git a/components/comment/demo/nested.ts b/components/comment/demo/nested.ts index 2b4c207ee5c..692f0c788a5 100644 --- a/components/comment/demo/nested.ts +++ b/components/comment/demo/nested.ts @@ -45,13 +45,13 @@ export class NzDemoCommentNestedComponent { author: 'Han Solo', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', content: 'We supply a series of design principles, practical patterns and high quality design resources' + - '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.' }, { author: 'Han Solo', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', content: 'We supply a series of design principles, practical patterns and high quality design resources' + - '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + '(Sketch and Axure), to help people create their product prototypes beautifully and efficiently.' } ] } diff --git a/components/comment/doc/index.en-US.md b/components/comment/doc/index.en-US.md index 66d31aff065..fe735326c94 100644 --- a/components/comment/doc/index.en-US.md +++ b/components/comment/doc/index.en-US.md @@ -17,3 +17,10 @@ Comments can be used to enable discussions on an entity such as a page, blog pos | -------- | ----------- | ---- | ------- | | [nzAuthor] | The element to display as the comment author | `string|TemplateRef` | - | | [nzDatetime] | A datetime element containing the time to be displayed | `string|TemplateRef` | - | + +### Comment sections +| Element | Description | +| ----- | ----------- | +| `` | The element to display as the comment avatar | +| `` | The main content of the comment | +| `` | The element items rendered below the comment content | diff --git a/components/comment/doc/index.zh-CN.md b/components/comment/doc/index.zh-CN.md index 62a8d1a5222..dc78a4ae904 100644 --- a/components/comment/doc/index.zh-CN.md +++ b/components/comment/doc/index.zh-CN.md @@ -16,5 +16,12 @@ cols: 1 | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | -| [nzAuthor]] | 显示评论的作者 | `string|TemplateRef` | - | +| [nzAuthor] | 显示评论的作者 | `string|TemplateRef` | - | | [nzDatetime] | 展示时间描述 | `string|TemplateRef` | - | + +### 评论组成部分 +| 元素 | 说明 | +| ----- | ----------- | +| `` | 要显示为评论头像的元素 | +| `` | 评论的主要内容 | +| `` | 在评论内容下面呈现的操作项 | \ No newline at end of file diff --git a/components/comment/nz-comment.component.html b/components/comment/nz-comment.component.html index d5b12c00fb7..08da44f57cc 100644 --- a/components/comment/nz-comment.component.html +++ b/components/comment/nz-comment.component.html @@ -12,7 +12,7 @@ -
    +
    • diff --git a/components/comment/nz-comment.component.spec.ts b/components/comment/nz-comment.component.spec.ts deleted file mode 100644 index 81399f23c31..00000000000 --- a/components/comment/nz-comment.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NzCommentComponent } from './nz-comment.component'; - -describe('NzCommentComponent', () => { - let component: NzCommentComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ NzCommentComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(NzCommentComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/components/comment/nz-comment.spec.ts b/components/comment/nz-comment.spec.ts new file mode 100644 index 00000000000..1a44cace537 --- /dev/null +++ b/components/comment/nz-comment.spec.ts @@ -0,0 +1,143 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, fakeAsync, tick, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { NzListModule } from '../list'; +import { NzDemoCommentBasicComponent } from './demo/basic'; +import { NzDemoCommentEditorComponent } from './demo/editor'; +import { NzDemoCommentListComponent } from './demo/list'; +import { NzDemoCommentNestedComponent } from './demo/nested'; + +import { NzCommentComponent } from './nz-comment.component'; +import { NzCommentModule } from './nz-comment.module'; + +describe('NzCommentComponent', () => { + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports : [ NzCommentModule, NzListModule ], + schemas : [ NO_ERRORS_SCHEMA ], + declarations: [ + NzDemoCommentBasicComponent, + NzDemoCommentEditorComponent, + NzDemoCommentListComponent, + NzDemoCommentNestedComponent + ] + }) + .compileComponents(); + })); + + it('should basic work', () => { + const fixture = TestBed.createComponent(NzDemoCommentBasicComponent); + const component = fixture.componentInstance; + const comment = fixture.debugElement.query(By.directive(NzCommentComponent)); + fixture.detectChanges(); + + expect(comment.nativeElement.classList).toContain('ant-comment'); + expect(comment.nativeElement.querySelector('nz-avatar[nz-comment-avatar]')).toBeTruthy(); + expect(comment.nativeElement.querySelector('nz-comment-content')).toBeTruthy(); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-name')).toBeTruthy(); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-time')).toBeTruthy(); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-name').innerText).toBe('Han Solo'); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-time').innerText).toBe(component.time); + }); + + it('should actions work', () => { + const fixture = TestBed.createComponent(NzDemoCommentBasicComponent); + const component = fixture.componentInstance; + const comment = fixture.debugElement.query(By.directive(NzCommentComponent)); + fixture.detectChanges(); + + expect(component.likes).toBe(0); + expect(component.dislikes).toBe(0); + expect(comment.nativeElement.classList).toContain('ant-comment'); + expect(comment.nativeElement.querySelectorAll('.ant-comment-actions li>span').length).toBe(3); + expect(comment.nativeElement.querySelector('.ant-comment-actions li>span .like').innerText).toBe(component.likes.toString()); + expect(comment.nativeElement.querySelector('.ant-comment-actions li>span .dislike').innerText).toBe(component.dislikes.toString()); + + component.like(); + fixture.detectChanges(); + + expect(component.likes).toBe(1); + expect(component.dislikes).toBe(0); + expect(comment.nativeElement.querySelector('.ant-comment-actions li>span .like').innerText).toBe(component.likes.toString()); + expect(comment.nativeElement.querySelector('.ant-comment-actions li>span .dislike').innerText).toBe(component.dislikes.toString()); + + component.dislike(); + fixture.detectChanges(); + + expect(component.likes).toBe(0); + expect(component.dislikes).toBe(1); + expect(comment.nativeElement.querySelector('.ant-comment-actions li>span .like').innerText).toBe(component.likes.toString()); + expect(comment.nativeElement.querySelector('.ant-comment-actions li>span .dislike').innerText).toBe(component.dislikes.toString()); + }); + + it('should list work', () => { + const fixture = TestBed.createComponent(NzDemoCommentListComponent); + const component = fixture.componentInstance; + fixture.detectChanges(); + let comments = fixture.debugElement.queryAll(By.directive(NzCommentComponent)); + fixture.detectChanges(); + expect(component.data.length === comments.length).toBeTruthy(); + + component.data.forEach((e, i) => { + const comment = comments[ i ]; + expect(comment.nativeElement.querySelector('nz-avatar[nz-comment-avatar]')).toBeTruthy(); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-name').innerText).toBe(e.author); + expect(comment.nativeElement.querySelector('.ant-comment-content-detail p').innerText).toBe(e.content); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-time').innerText).toBe(e.datetime); + }); + + component.data = [ { ...component.data[ 0 ] } ]; + fixture.detectChanges(); + comments = fixture.debugElement.queryAll(By.directive(NzCommentComponent)); + expect(component.data.length === comments.length).toBeTruthy(); + + }); + + it('should editor work', fakeAsync(() => { + const fixture = TestBed.createComponent(NzDemoCommentEditorComponent); + const component = fixture.componentInstance; + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('nz-comment .ant-comment-content-detail textarea'))).toBeTruthy(); + let comments = fixture.debugElement.queryAll(By.css('nz-list nz-comment')); + expect(component.data.length).toBe(0); + expect(component.data.length === comments.length).toBeTruthy(); + + component.inputValue = 'Test Comment 0'; + component.handleSubmit(); + tick(1000); + fixture.detectChanges(); + + component.inputValue = 'Test Comment 1'; + component.handleSubmit(); + tick(1000); + fixture.detectChanges(); + + comments = fixture.debugElement.queryAll(By.css('nz-list nz-comment')); + + component.data.forEach((e, i) => { + const comment = comments[ i ]; + expect(comment.nativeElement.querySelector('nz-avatar[nz-comment-avatar]')).toBeTruthy(); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-name').innerText).toBe(e.author); + expect(comment.nativeElement.querySelector('.ant-comment-content-detail p').innerText).toBe(e.content); + expect(comment.nativeElement.querySelector('.ant-comment-content-author-time').innerText).toBe(e.displayTime); + }); + + })); + + it('should nested work', () => { + const fixture = TestBed.createComponent(NzDemoCommentNestedComponent); + fixture.detectChanges(); + + const rootComment = fixture.debugElement.query(By.directive(NzCommentComponent)); + expect(rootComment.nativeElement).toBeTruthy(); + + const levelTwoComment = rootComment.query(By.directive(NzCommentComponent)); + expect(levelTwoComment.nativeElement).toBeTruthy(); + + const levelThreeComments = levelTwoComment.queryAll(By.directive(NzCommentComponent)); + expect(levelThreeComments.length).toBe(2); + + }); + +}); From ca8599ec90654a1c142fd302f1227b6b332f0802 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Mon, 14 Jan 2019 17:34:31 +0800 Subject: [PATCH 3/5] test(module:comment): fix test --- components/empty/nz-empty.spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/empty/nz-empty.spec.ts b/components/empty/nz-empty.spec.ts index 484835bf0b4..920bc96c4c8 100644 --- a/components/empty/nz-empty.spec.ts +++ b/components/empty/nz-empty.spec.ts @@ -175,6 +175,15 @@ describe('nz-empty', () => { expect(embedComponent.nativeElement.innerText).toBe(''); })); + it('should raise error when set a invalid default value', () => { + expect(() => { + testComponent.changeToInvalid(); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + }).toThrowError(); + }); + it('should support string, template and component', fakeAsync(() => { const refresh = () => { fixture.detectChanges(); From 18c477c1c2908f003033eef1df233fa038b27844 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Thu, 17 Jan 2019 11:35:05 +0800 Subject: [PATCH 4/5] test(module:empty): refactor test --- components/empty/nz-empty.spec.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/empty/nz-empty.spec.ts b/components/empty/nz-empty.spec.ts index 920bc96c4c8..b3dee3891cd 100644 --- a/components/empty/nz-empty.spec.ts +++ b/components/empty/nz-empty.spec.ts @@ -9,6 +9,7 @@ import { NzListModule } from '../list'; import { NzEmbedEmptyComponent } from './nz-embed-empty.component'; import { NZ_DEFAULT_EMPTY_CONTENT, NZ_EMPTY_COMPONENT_NAME } from './nz-empty-config'; +import { getEmptyContentTypeError } from './nz-empty-error'; import { NzEmptyComponent } from './nz-empty.component'; import { NzEmptyModule } from './nz-empty.module'; import { NzEmptyService } from './nz-empty.service'; @@ -178,10 +179,7 @@ describe('nz-empty', () => { it('should raise error when set a invalid default value', () => { expect(() => { testComponent.changeToInvalid(); - fixture.detectChanges(); - tick(); - fixture.detectChanges(); - }).toThrowError(); + }).toThrowError(getEmptyContentTypeError(false).message); }); it('should support string, template and component', fakeAsync(() => { From e2e4f99883351164d9aea1335237ce33bf062683 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Mon, 25 Feb 2019 12:36:47 +0800 Subject: [PATCH 5/5] test(module:empty): fix test --- components/empty/nz-empty.spec.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components/empty/nz-empty.spec.ts b/components/empty/nz-empty.spec.ts index b3dee3891cd..7701a8eb69d 100644 --- a/components/empty/nz-empty.spec.ts +++ b/components/empty/nz-empty.spec.ts @@ -9,7 +9,6 @@ import { NzListModule } from '../list'; import { NzEmbedEmptyComponent } from './nz-embed-empty.component'; import { NZ_DEFAULT_EMPTY_CONTENT, NZ_EMPTY_COMPONENT_NAME } from './nz-empty-config'; -import { getEmptyContentTypeError } from './nz-empty-error'; import { NzEmptyComponent } from './nz-empty.component'; import { NzEmptyModule } from './nz-empty.module'; import { NzEmptyService } from './nz-empty.service'; @@ -177,9 +176,14 @@ describe('nz-empty', () => { })); it('should raise error when set a invalid default value', () => { + expect(() => { - testComponent.changeToInvalid(); - }).toThrowError(getEmptyContentTypeError(false).message); + // tslint:disable-next-line:no-any + testComponent.emptyService.setDefaultContent(false as any); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + }).toThrowError(); }); it('should support string, template and component', fakeAsync(() => {