Skip to content

Commit

Permalink
feat(module:comment): add comment component (NG-ZORRO#2767)
Browse files Browse the repository at this point in the history
* feat(module:comment): add comment component

close NG-ZORRO#2731

* test(module:comment): add test

* test(module:comment): fix test

* test(module:empty): refactor test

* test(module:empty): fix test
  • Loading branch information
hsuanxyz authored and vthinkxie committed Feb 25, 2019
1 parent 02f4bc8 commit c28709c
Show file tree
Hide file tree
Showing 21 changed files with 733 additions and 0 deletions.
15 changes: 15 additions & 0 deletions components/comment/demo/basic.md
Original file line number Diff line number Diff line change
@@ -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.

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

@Component({
selector: 'nz-demo-comment-basic',
template: `
<nz-comment nzAuthor="Han Solo" [nzDatetime]="time">
<nz-avatar nz-comment-avatar nzIcon="user" nzSrc="//zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"></nz-avatar>
<nz-comment-content>
<p>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.
</p>
</nz-comment-content>
<nz-comment-action>
<i nz-tooltip nzTitle="Like" nz-icon type="like" [theme]="likes > 0 ? 'twotone' : 'outline'" (click)="like()"></i>
<span class="count like">{{likes}}</span>
</nz-comment-action>
<nz-comment-action>
<i nz-tooltip nzTitle="Dislike" nz-icon type="dislike" [theme]="dislikes > 0 ? 'twotone' : 'outline'" (click)="dislike()"></i>
<span class="count dislike">{{dislikes}}</span>
</nz-comment-action>
<nz-comment-action>Reply to</nz-comment-action>
</nz-comment>
`,
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;
}
}
14 changes: 14 additions & 0 deletions components/comment/demo/editor.md
Original file line number Diff line number Diff line change
@@ -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.
62 changes: 62 additions & 0 deletions components/comment/demo/editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Component } from '@angular/core';
import { distanceInWords } from 'date-fns';

@Component({
selector: 'nz-demo-comment-editor',
template: `
<nz-list *ngIf="data.length" [nzDataSource]="data" [nzRenderItem]="item" [nzItemLayout]="'horizontal'">
<ng-template #item let-item>
<nz-comment [nzAuthor]="item.author" [nzDatetime]="item.displayTime">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="item.avatar"></nz-avatar>
<nz-comment-content>
<p>{{item.content}}</p>
</nz-comment-content>
</nz-comment>
</ng-template>
</nz-list>
<nz-comment>
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="user.avatar"></nz-avatar>
<nz-comment-content>
<nz-form-item>
<textarea [(ngModel)]="inputValue" nz-input rows="4"></textarea>
</nz-form-item>
<nz-form-item>
<button nz-button nzType="primary" [nzLoading]="submitting" [disabled]="!inputValue" (click)="handleSubmit()">
Add Comment
</button>
</nz-form-item>
</nz-comment-content>
</nz-comment>
`,
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);
}

}
14 changes: 14 additions & 0 deletions components/comment/demo/list.md
Original file line number Diff line number Diff line change
@@ -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.
38 changes: 38 additions & 0 deletions components/comment/demo/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component } from '@angular/core';
import { addDays, distanceInWords } from 'date-fns';

@Component({
selector: 'nz-demo-comment-list',
template: `
<nz-list [nzDataSource]="data" [nzRenderItem]="item" [nzItemLayout]="'horizontal'">
<ng-template #item let-item>
<nz-comment [nzAuthor]="item.author" [nzDatetime]="item.datetime">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="item.avatar"></nz-avatar>
<nz-comment-content>
<p>{{item.content}}</p>
</nz-comment-content>
<nz-comment-action>Reply to</nz-comment-action>
</nz-comment>
</ng-template>
</nz-list>
`,
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))
}
];
}
15 changes: 15 additions & 0 deletions components/comment/demo/nested.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
order: 2
title:
zh-CN: 嵌套评论
en-US: Nested comments
---

## zh-CN

评论可以嵌套。

## en-US

Comments can be nested.

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

@Component({
selector: 'nz-demo-comment-nested',
template: `
<ng-template #commentTemplateRef let-comment="comment">
<nz-comment [nzAuthor]="comment.author">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="comment.avatar"></nz-avatar>
<nz-comment-content>
<p>{{comment.content}}</p>
</nz-comment-content>
<nz-comment-action>Reply to</nz-comment-action>
<ng-container *ngIf="comment.children && comment.children.length">
<ng-template ngFor let-child [ngForOf]="comment.children">
<ng-template
[ngTemplateOutlet]="commentTemplateRef"
[ngTemplateOutletContext]="{ comment: child }">
</ng-template>
</ng-template>
</ng-container>
</nz-comment>
</ng-template>
<ng-template
[ngTemplateOutlet]="commentTemplateRef"
[ngTemplateOutletContext]="{ comment: data }">
</ng-template>
`,
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.'
}
]
}
]
};
}
26 changes: 26 additions & 0 deletions components/comment/doc/index.en-US.md
Original file line number Diff line number Diff line change
@@ -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<void>` | - |
| [nzDatetime] | A datetime element containing the time to be displayed | `string|TemplateRef<void>` | - |

### Comment sections
| Element | Description |
| ----- | ----------- |
| `<nz-avatar nz-comment-avatar>` | The element to display as the comment avatar |
| `<nz-comment-content>` | The main content of the comment |
| `<nz-comment-action>` | The element items rendered below the comment content |
27 changes: 27 additions & 0 deletions components/comment/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
category: Components
type: Data Display
title: Comment
subtitle: 评论
cols: 1
---

对网站内容的反馈、评价和讨论。

## 何时使用

评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。

## API

| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| [nzAuthor] | 显示评论的作者 | `string|TemplateRef<void>` | - |
| [nzDatetime] | 展示时间描述 | `string|TemplateRef<void>` | - |

### 评论组成部分
| 元素 | 说明 |
| ----- | ----------- |
| `<nz-avatar nz-comment-avatar>` | 要显示为评论头像的元素 |
| `<nz-comment-content>` | 评论的主要内容 |
| `<nz-comment-action>` | 在评论内容下面呈现的操作项 |
1 change: 1 addition & 0 deletions components/comment/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './public-api';
68 changes: 68 additions & 0 deletions components/comment/nz-comment-cells.ts
Original file line number Diff line number Diff line change
@@ -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 : '<ng-template><ng-content></ng-content></ng-template>'
})
export class NzCommentActionComponent implements OnInit {
@ViewChild(TemplateRef) implicitContent: TemplateRef<void>;
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);
}
}
Loading

0 comments on commit c28709c

Please sign in to comment.