From 478f61adf0ea72687965349e1ee465e92955c9bb Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Mon, 25 Feb 2019 15:33:12 +0800 Subject: [PATCH] feat(module:comment): add comment component (#2767) * feat(module:comment): add comment component close #2731 * test(module:comment): add test * test(module:comment): fix test * test(module:empty): refactor test * test(module:empty): fix test --- components/comment/demo/basic.md | 15 ++ components/comment/demo/basic.ts | 46 ++++++ components/comment/demo/editor.md | 14 ++ components/comment/demo/editor.ts | 62 ++++++++ components/comment/demo/list.md | 14 ++ components/comment/demo/list.ts | 38 +++++ components/comment/demo/nested.md | 15 ++ components/comment/demo/nested.ts | 60 ++++++++ components/comment/doc/index.en-US.md | 26 ++++ components/comment/doc/index.zh-CN.md | 27 ++++ components/comment/index.ts | 1 + components/comment/nz-comment-cells.ts | 68 +++++++++ components/comment/nz-comment.component.html | 24 ++++ components/comment/nz-comment.component.ts | 41 ++++++ components/comment/nz-comment.module.ts | 28 ++++ components/comment/nz-comment.spec.ts | 143 +++++++++++++++++++ components/comment/public-api.ts | 3 + components/comment/style/index.less | 93 ++++++++++++ components/components.less | 1 + components/empty/nz-empty.spec.ts | 11 ++ components/ng-zorro-antd.module.ts | 3 + 21 files changed, 733 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.ts create mode 100644 components/comment/nz-comment.module.ts create mode 100644 components/comment/nz-comment.spec.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..ddb8dd854af --- /dev/null +++ b/components/comment/demo/basic.ts @@ -0,0 +1,46 @@ +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 + (Sketch and Axure), to help people create their product prototypes beautifully and efficiently. +

+
+ + + + + + + {{dislikes}} + + Reply to +
+ `, + styles : [` + .count { + padding-left: 8px; + cursor: auto; + } + `] +}) +export class NzDemoCommentBasicComponent { + likes = 0; + dislikes = 0; + time = distanceInWords(new Date(), new Date()); + + 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..6af8b3c7f78 --- /dev/null +++ b/components/comment/demo/editor.ts @@ -0,0 +1,62 @@ +import { Component } from '@angular/core'; +import { distanceInWords } from 'date-fns'; + +@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, { + ...this.user, + content, + 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 new file mode 100644 index 00000000000..0440dfa8f0d --- /dev/null +++ b/components/comment/demo/list.md @@ -0,0 +1,14 @@ +--- +order: 1 +title: + zh-CN: 配合列表组件 + en-US: Usage with list +--- + +## zh-CN + +配合 `nz-list` 组件展现评论列表。 + +## en-US + +Displaying a series of comments using the `nz-list` Component. diff --git a/components/comment/demo/list.ts b/components/comment/demo/list.ts new file mode 100644 index 00000000000..2e1ed0687b7 --- /dev/null +++ b/components/comment/demo/list.ts @@ -0,0 +1,38 @@ +import { Component } from '@angular/core'; +import { addDays, distanceInWords } from 'date-fns'; + +@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: 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: distanceInWords(new Date(), addDays(new Date(), 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..692f0c788a5 --- /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..fe735326c94 --- /dev/null +++ b/components/comment/doc/index.en-US.md @@ -0,0 +1,26 @@ +--- +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` | - | + +### 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 new file mode 100644 index 00000000000..dc78a4ae904 --- /dev/null +++ b/components/comment/doc/index.zh-CN.md @@ -0,0 +1,27 @@ +--- +category: Components +type: Data Display +title: Comment +subtitle: 评论 +cols: 1 +--- + +对网站内容的反馈、评价和讨论。 + +## 何时使用 + +评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。 + +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| [nzAuthor] | 显示评论的作者 | `string|TemplateRef` | - | +| [nzDatetime] | 展示时间描述 | `string|TemplateRef` | - | + +### 评论组成部分 +| 元素 | 说明 | +| ----- | ----------- | +| `` | 要显示为评论头像的元素 | +| `` | 评论的主要内容 | +| `` | 在评论内容下面呈现的操作项 | \ No newline at end of file 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..08da44f57cc --- /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.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/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); + + }); + +}); 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/empty/nz-empty.spec.ts b/components/empty/nz-empty.spec.ts index 484835bf0b4..7701a8eb69d 100644 --- a/components/empty/nz-empty.spec.ts +++ b/components/empty/nz-empty.spec.ts @@ -175,6 +175,17 @@ describe('nz-empty', () => { expect(embedComponent.nativeElement.innerText).toBe(''); })); + it('should raise error when set a invalid default value', () => { + + expect(() => { + // 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(() => { const refresh = () => { fixture.detectChanges(); 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,