Skip to content

Commit

Permalink
feat(module:avatar): add nz-avatar component
Browse files Browse the repository at this point in the history
  • Loading branch information
mo-gong committed Aug 18, 2017
1 parent 4473368 commit 5bb3738
Show file tree
Hide file tree
Showing 14 changed files with 420 additions and 1 deletion.
116 changes: 116 additions & 0 deletions src/components/avatar/nz-avatar.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { Component, ViewEncapsulation, Renderer2, ElementRef, Input, ViewChild, OnChanges, SimpleChanges } from '@angular/core';

export type NzAvatarShape = 'square' | 'circle';
export type NzAvatarSize = 'small' | 'large' | 'default';

@Component({
selector: 'nz-avatar',
encapsulation: ViewEncapsulation.None,
template: `
<i class="anticon anticon-{{nzIcon}}" *ngIf="nzIcon && _hasIcon"></i>
<img [src]="nzSrc" *ngIf="nzSrc && _isSrcExist" (error)="_imgError($event)"/>
<span class="ant-avatar-string" #textEl [ngStyle]="_textStyles" *ngIf="nzText && _hasText">{{nzText}}</span>
`,
styleUrls: [
'./style/index.less',
'./style/patch.less'
]
})
export class NzAvatarComponent implements OnChanges {

private _el: HTMLElement;
private _prefixCls = 'ant-avatar';
private _classList: string[] = [];
private _sizeMap = { large: 'lg', small: 'sm' };

_hasText: boolean = false;
@ViewChild('textEl') _textEl: ElementRef;
_textStyles: {};

_isSrcExist: boolean = true;

_hasIcon: boolean = false;

@Input() nzShape: NzAvatarShape = 'circle';

@Input() nzSize: NzAvatarSize = 'default';

@Input() nzText: string;

@Input() nzSrc: string;

@Input() nzIcon: string;

_setClassMap() {
this._classList.forEach(_className => {
this._renderer.removeClass(this._el, _className);
})
this._classList = [
this._sizeMap[this.nzSize] && `${this._prefixCls}-${this._sizeMap[this.nzSize]}`,
this.nzShape && `${this._prefixCls}-${this.nzShape}`,
this.nzIcon && `${this._prefixCls}-icon`,
this.nzSrc && `${this._prefixCls}-image`
].filter((item) => {
return !!item;
});
this._classList.forEach(_className => {
this._renderer.addClass(this._el, _className);
});
return this;
}

_imgError() {
this._isSrcExist = false;
// TODO(i): need force remove [nzSrc] if broken image?
this._hasIcon = false;
this._hasText = false;
if (this.nzIcon) {
this._hasIcon = true;
} else if (this.nzText) {
this._hasText = true;
}
this._setClassMap()._notifyCalc();
}

private _calcStringSize() {
if (!this._hasText) return;

const el = this._textEl && this._textEl.nativeElement;
if (!el) return;

const childrenWidth = el.offsetWidth;
const avatarWidth = this._el.getBoundingClientRect().width;
const scale = avatarWidth - 8 < childrenWidth ? (avatarWidth - 8) / childrenWidth : 1;
if (scale === 1) {
this._textStyles = {};
} else {
this._textStyles = {
transform: `scale(${scale})`,
position: 'absolute',
display: 'inline-block',
left: `calc(50% - ${Math.round(childrenWidth / 2)}px)`
};
}
}

private _notifyCalc() {
// If use ngAfterViewChecked, always demands more computations, so......
setTimeout(() => {
this._calcStringSize();
});
return this;
}

constructor(private _elementRef: ElementRef, private _renderer: Renderer2) {
this._el = _elementRef.nativeElement;
this._renderer.addClass(this._el, this._prefixCls);
}

ngOnChanges(changes: SimpleChanges): void {
this._hasText = !this.nzSrc && !!this.nzText;
this._hasIcon = !this.nzSrc && !!this.nzIcon;

this._setClassMap()._notifyCalc();
}

}
12 changes: 12 additions & 0 deletions src/components/avatar/nz-avatar.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NzAvatarComponent } from './nz-avatar.component';

@NgModule({
declarations: [ NzAvatarComponent ],
exports : [ NzAvatarComponent ],
imports : [ CommonModule ]
})

export class NzAvatarModule {
}
47 changes: 47 additions & 0 deletions src/components/avatar/style/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@import "../../style/themes/default";

@avatar-prefix-cls: ~"@{ant-prefix}-avatar";

.@{avatar-prefix-cls} {
display: inline-block;
text-align: center;
background: @avatar-bg;
color: @avatar-color;
white-space: nowrap;
position: relative;
overflow: hidden;

.avatar-size(@avatar-size-base, @avatar-font-size-base);

&-lg {
.avatar-size(@avatar-size-lg, @avatar-font-size-lg);
}

&-sm {
.avatar-size(@avatar-size-sm, @avatar-font-size-sm);
}

&-square {
border-radius: @avatar-border-radius;
}

& > img {
width: 100%;
height: 100%;
}
}

.avatar-size(@size, @font-size) {
width: @size;
height: @size;
line-height: @size;
border-radius: @size / 2;

& > * {
line-height: @size;
}

&.@{avatar-prefix-cls}-icon {
font-size: @font-size;
}
}
Empty file.
5 changes: 4 additions & 1 deletion src/components/ng-zorro-antd.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { NzToolTipModule } from './tooltip/nz-tooltip.module';
import { NzBackTopModule } from './back-top/nz-back-top.module';
import { NzAffixModule } from './affix/nz-affix.module';
import { NzAnchorModule } from './anchor/nz-anchor.module';
import { NzAvatarModule } from './avatar/nz-avatar.module';

// Services
import { NzNotificationService } from './notification/nz-notification.service';
Expand Down Expand Up @@ -104,6 +105,7 @@ export { NzToolTipModule } from './tooltip/nz-tooltip.module';
export { NzBackTopModule } from './back-top/nz-back-top.module';
export { NzAffixModule } from './affix/nz-affix.module';
export { NzAnchorModule } from './anchor/nz-anchor.module';
export { NzAvatarModule } from './avatar/nz-avatar.module';

// Services
export { NzNotificationService } from './notification/nz-notification.service';
Expand Down Expand Up @@ -163,7 +165,8 @@ export { NZ_NOTIFICATION_CONFIG } from './notification/nz-notification-config';
NzToolTipModule,
NzBackTopModule,
NzAffixModule,
NzAnchorModule
NzAnchorModule,
NzAvatarModule
]
})
export class NgZorroAntdModule {
Expand Down
32 changes: 32 additions & 0 deletions src/showcase/nz-demo-avatar/nz-demo-avatar-autosize.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Component } from '@angular/core';

const UserList = ['U', 'Lucy', 'Tom', 'Edward'];
const ColorList = ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];

@Component({
selector: 'nz-demo-avatar-autosize',
template: `
<nz-avatar [nzText]="text" nzSize="large" [ngStyle]="{'background-color':color}"></nz-avatar>
<button nz-button [nzType]="'dashed'" (click)="change()">
<span>Change</span>
</button>
`,
styles: [`
:host ::ng-deep .ant-avatar {
margin-top: 16px;
margin-right: 16px;
}
`]
})
export class NzDemoAvatarAutoSizeComponent {
text: string = UserList[3];
color: string = ColorList[3];

change() {
let idx = UserList.indexOf(this.text);
++idx;
if (idx == UserList.length) idx = 0;
this.text = UserList[idx];
this.color = ColorList[idx];
}
}
14 changes: 14 additions & 0 deletions src/showcase/nz-demo-avatar/nz-demo-avatar-badge.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-avatar-badge',
template: `
<nz-badge [nzCount]="5" style="margin-right: 24px;">
<ng-template #content><nz-avatar nzIcon="user" [nzShape]="'square'"></nz-avatar></ng-template>
</nz-badge>
<nz-badge [nzDot]="true">
<ng-template #content><nz-avatar nzIcon="user" [nzShape]="'square'"></nz-avatar></ng-template>
</nz-badge>
`
})
export class NzDemoAvatarBadgeComponent { }
24 changes: 24 additions & 0 deletions src/showcase/nz-demo-avatar/nz-demo-avatar-basic.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-avatar-basic',
template: `
<div>
<nz-avatar nzSize="large" nzIcon="user"></nz-avatar>
<nz-avatar nzIcon="user"></nz-avatar>
<nz-avatar nzSize="small" nzIcon="user"></nz-avatar>
</div>
<div>
<nz-avatar [nzShape]="'square'" [nzSize]="'large'" [nzIcon]="'user'"></nz-avatar>
<nz-avatar [nzShape]="'square'" [nzIcon]="'user'"></nz-avatar>
<nz-avatar [nzShape]="'square'" [nzSize]="'small'" [nzIcon]="'user'"></nz-avatar>
</div>
`,
styles: [`
:host ::ng-deep .ant-avatar {
margin-top: 16px;
margin-right: 16px;
}
`]
})
export class NzDemoAvatarBasicComponent { }
20 changes: 20 additions & 0 deletions src/showcase/nz-demo-avatar/nz-demo-avatar-type.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-avatar-type',
template: `
<nz-avatar nzIcon="user"></nz-avatar>
<nz-avatar nzText="U"></nz-avatar>
<nz-avatar nzText="USER"></nz-avatar>
<nz-avatar nzIcon="user" nzSrc="//zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"></nz-avatar>
<nz-avatar nzText="U" style="color:#f56a00; background-color:#fde3cf;"></nz-avatar>
<nz-avatar nzIcon="user" style="background-color:#87d068;"></nz-avatar>
`,
styles: [`
:host ::ng-deep .ant-avatar {
margin-top: 16px;
margin-right: 16px;
}
`]
})
export class NzDemoAvatarTypeComponent { }
12 changes: 12 additions & 0 deletions src/showcase/nz-demo-avatar/nz-demo-avatar.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component } from '@angular/core';

@Component({
selector : 'nz-demo-avatar',
templateUrl: './nz-demo-avatar.html'
})
export class NzDemoAvatarComponent {
NzDemoAvatarBasicCode = require('!!raw-loader!./nz-demo-avatar-basic.component')
NzDemoAvatarTypeCode = require('!!raw-loader!./nz-demo-avatar-type.component')
NzDemoAvatarAutoSizeCode = require('!!raw-loader!./nz-demo-avatar-autosize.component')
NzDemoAvatarBadgeCode = require('!!raw-loader!./nz-demo-avatar-badge.component')
}
Loading

0 comments on commit 5bb3738

Please sign in to comment.