偏右
8 years ago
committed by
GitHub
16 changed files with 764 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||
import React from 'react'; |
|||
import { mount } from 'enzyme'; |
|||
import Avatar from '..'; |
|||
|
|||
describe('Avatar Render', () => { |
|||
it('Render long string correctly', () => { |
|||
const wrapper = mount(<Avatar>TestString</Avatar>); |
|||
const children = wrapper.find('.ant-avatar-string'); |
|||
expect(children.length).toBe(1); |
|||
}); |
|||
}); |
@ -0,0 +1,389 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`renders ./components/avatar/demo/badge.md correctly 1`] = ` |
|||
<div> |
|||
<span |
|||
style="margin-right:24px;" |
|||
> |
|||
<span |
|||
class="ant-badge" |
|||
title="1" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-square ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
<sup |
|||
class="ant-scroll-number ant-badge-count" |
|||
data-show="true" |
|||
> |
|||
<span |
|||
class="ant-scroll-number-only" |
|||
style="transition:none;-ms-transform:translateY(-1100%);-webkit-transform:translateY(-1100%);transform:translateY(-1100%);" |
|||
> |
|||
<p |
|||
class="" |
|||
> |
|||
0 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
1 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
2 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
3 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
4 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
5 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
6 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
7 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
8 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
9 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
0 |
|||
</p> |
|||
<p |
|||
class="current" |
|||
> |
|||
1 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
2 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
3 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
4 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
5 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
6 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
7 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
8 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
9 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
0 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
1 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
2 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
3 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
4 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
5 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
6 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
7 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
8 |
|||
</p> |
|||
<p |
|||
class="" |
|||
> |
|||
9 |
|||
</p> |
|||
</span> |
|||
</sup> |
|||
</span> |
|||
</span> |
|||
<span> |
|||
<span |
|||
class="ant-badge" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-square ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
<sup |
|||
class="ant-scroll-number ant-badge-dot" |
|||
data-show="true" |
|||
/> |
|||
</span> |
|||
</span> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/avatar/demo/basic.md correctly 1`] = ` |
|||
<div> |
|||
<div |
|||
class="ant-row" |
|||
> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-sm ant-avatar-circle ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
<div |
|||
class="ant-row" |
|||
> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-lg ant-avatar-square ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-square ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-sm ant-avatar-square ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = ` |
|||
<div> |
|||
<span |
|||
class="ant-avatar ant-avatar-lg ant-avatar-circle" |
|||
style="background-color:#f56a00;" |
|||
> |
|||
<span |
|||
class="ant-avatar-string" |
|||
> |
|||
U |
|||
</span> |
|||
</span> |
|||
<button |
|||
class="ant-btn ant-btn-sm" |
|||
style="margin-left:16px;" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Change |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/avatar/demo/type.md correctly 1`] = ` |
|||
<div> |
|||
<div |
|||
class="ant-row" |
|||
> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle ant-avatar-icon" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle" |
|||
> |
|||
<span |
|||
class="ant-avatar-string" |
|||
> |
|||
U |
|||
</span> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle" |
|||
> |
|||
<span |
|||
class="ant-avatar-string" |
|||
> |
|||
USER |
|||
</span> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle ant-avatar-image" |
|||
> |
|||
<img |
|||
src="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png" |
|||
/> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
<div |
|||
class="ant-row" |
|||
> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle" |
|||
style="color:#f56a00;background-color:#fde3cf;" |
|||
> |
|||
<span |
|||
class="ant-avatar-string" |
|||
> |
|||
U |
|||
</span> |
|||
</span> |
|||
</div> |
|||
<div |
|||
class="ant-col-4" |
|||
> |
|||
<span |
|||
class="ant-avatar ant-avatar-circle ant-avatar-icon" |
|||
style="background-color:#87d068;" |
|||
> |
|||
<i |
|||
class="anticon anticon-user" |
|||
/> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
`; |
@ -0,0 +1,3 @@ |
|||
import demoTest from '../../../tests/shared/demoTest'; |
|||
|
|||
demoTest('avatar'); |
@ -0,0 +1,29 @@ |
|||
--- |
|||
order: 3 |
|||
title: |
|||
zh-CN: 带徽标的头像 |
|||
en-US: With Badge |
|||
--- |
|||
|
|||
## zh-CN |
|||
|
|||
通常用于消息提示。 |
|||
|
|||
## en-US |
|||
|
|||
Usually used for messages remind. |
|||
|
|||
````jsx |
|||
import { Avatar, Badge } from 'antd'; |
|||
|
|||
ReactDOM.render( |
|||
<div> |
|||
<span style={{ marginRight: 24 }}> |
|||
<Badge count={1}><Avatar shape="square" icon="user" /></Badge> |
|||
</span> |
|||
<span> |
|||
<Badge dot><Avatar shape="square" icon="user" /></Badge> |
|||
</span> |
|||
</div> |
|||
, mountNode); |
|||
```` |
@ -0,0 +1,33 @@ |
|||
--- |
|||
order: 0 |
|||
title: |
|||
zh-CN: 基本 |
|||
en-US: Basic |
|||
--- |
|||
|
|||
## zh-CN |
|||
|
|||
头像有三种尺寸,两种形状可选。 |
|||
|
|||
## en-US |
|||
|
|||
Three sizes and two shapes are available. |
|||
|
|||
````jsx |
|||
import { Avatar, Row, Col } from 'antd'; |
|||
|
|||
ReactDOM.render( |
|||
<div> |
|||
<Row> |
|||
<Col span={4}><Avatar size="large" icon="user" /></Col> |
|||
<Col span={4}><Avatar icon="user" /></Col> |
|||
<Col span={4}><Avatar size="small" icon="user" /></Col> |
|||
</Row> |
|||
<Row> |
|||
<Col span={4}><Avatar shape="square" size="large" icon="user" /></Col> |
|||
<Col span={4}><Avatar shape="square" icon="user" /></Col> |
|||
<Col span={4}><Avatar shape="square" size="small" icon="user" /></Col> |
|||
</Row> |
|||
</div> |
|||
, mountNode); |
|||
```` |
@ -0,0 +1,49 @@ |
|||
--- |
|||
order: 2 |
|||
title: |
|||
zh-CN: 自动调整字符大小 |
|||
en-US: Autoset Font Size |
|||
--- |
|||
|
|||
## zh-CN |
|||
|
|||
对于字符型的头像,当字符串较长时,字体大小可以根据头像宽度自动调整。 |
|||
|
|||
## en-US |
|||
|
|||
For letter type Avatar, when the letters are too long to display, the font size can be automatically adjusted according to the width of the Avatar. |
|||
|
|||
````jsx |
|||
import { Avatar, Button } from 'antd'; |
|||
|
|||
const UserList = ['U', 'Lucy', 'Tom', 'Edward']; |
|||
const colorList = ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae']; |
|||
|
|||
class Autoset extends React.Component { |
|||
constructor(props) { |
|||
super(props); |
|||
this.state = { |
|||
user: UserList[0], |
|||
color: colorList[0], |
|||
}; |
|||
} |
|||
changeUser = () => { |
|||
const index = UserList.indexOf(this.state.user); |
|||
this.setState({ |
|||
user: index < UserList.length - 1 ? UserList[index + 1] : UserList[0], |
|||
color: index < colorList.length - 1 ? colorList[index + 1] : colorList[0], |
|||
}); |
|||
} |
|||
render() { |
|||
return ( |
|||
<div> |
|||
<Avatar style={{ backgroundColor: this.state.color }} size="large">{this.state.user}</Avatar> |
|||
<Button size="small" style={{ marginLeft: 16 }} onClick={this.changeUser}>Change</Button> |
|||
</div> |
|||
); |
|||
} |
|||
} |
|||
|
|||
ReactDOM.render(<Autoset /> |
|||
, mountNode); |
|||
```` |
@ -0,0 +1,33 @@ |
|||
--- |
|||
order: 1 |
|||
title: |
|||
zh-CN: 类型 |
|||
en-US: Type |
|||
--- |
|||
|
|||
## zh-CN |
|||
|
|||
支持三种类型:图片、Icon 以及字符,其中 Icon 和字符型可以自定义图标颜色及背景色。 |
|||
|
|||
## en-US |
|||
|
|||
Image, Icon and letter are supported, and the latter two kinds avatar can have custom colors and background colors. |
|||
|
|||
````jsx |
|||
import { Avatar, Row, Col } from 'antd'; |
|||
|
|||
ReactDOM.render( |
|||
<div> |
|||
<Row> |
|||
<Col span={4}><Avatar icon="user" /></Col> |
|||
<Col span={4}><Avatar>U</Avatar></Col> |
|||
<Col span={4}><Avatar>USER</Avatar></Col> |
|||
<Col span={4}><Avatar src="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png" /></Col> |
|||
</Row> |
|||
<Row> |
|||
<Col span={4}><Avatar style={{ color: '#f56a00', backgroundColor: '#fde3cf' }}>U</Avatar></Col> |
|||
<Col span={4}><Avatar style={{ backgroundColor: '#87d068' }} icon="user" /></Col> |
|||
</Row> |
|||
</div> |
|||
, mountNode); |
|||
```` |
@ -0,0 +1,16 @@ |
|||
--- |
|||
category: Components |
|||
type: Data Display |
|||
title: Avatar |
|||
--- |
|||
|
|||
Avatars can be used to represent people or object, which supports image, antd-Icon, or letter. |
|||
|
|||
## API |
|||
|
|||
| Property | Description | Type | Default | |
|||
|----------- |--------------------------------------------------------- | ---------- |-------| |
|||
| type | to set the shape of avatar | Enum{ 'circle', 'square' } | `circle` | |
|||
| size | to set the size of avatar | Enum{ 'large', 'small', 'default' } | `default` | |
|||
| src | the address of a image avatar | string | - | |
|||
| icon | the icon type of a icon avatar, see `Icon` Component | string | - | |
@ -0,0 +1,120 @@ |
|||
import React from 'react'; |
|||
import ReactDOM from 'react-dom'; |
|||
import Icon from '../icon'; |
|||
import classNames from 'classnames'; |
|||
|
|||
export interface AvatarProps { |
|||
/** Shape of avatar, options:`circle`, `square` */ |
|||
shape?: 'circle' | 'square'; |
|||
/** Size of avatar, options:`large`, `small`, `default` */ |
|||
size?: 'large' | 'small' | 'default'; |
|||
/** Src of image avatar */ |
|||
src?: string; |
|||
/** Type of the Icon to be used in avatar */ |
|||
icon?: string; |
|||
style?: React.CSSProperties; |
|||
prefixCls?: string; |
|||
className?: string; |
|||
children?: any; |
|||
} |
|||
|
|||
export default class Avatar extends React.Component<AvatarProps, any> { |
|||
static defaultProps = { |
|||
prefixCls: 'ant-avatar', |
|||
shape: 'circle', |
|||
size: 'default', |
|||
}; |
|||
|
|||
private avatarChildren: any; |
|||
|
|||
constructor(props) { |
|||
super(props); |
|||
this.state = { |
|||
scale: 1, |
|||
}; |
|||
} |
|||
|
|||
componentDidMount() { |
|||
this.setScale(); |
|||
} |
|||
|
|||
componentDidUpdate(prevProps, prevState) { |
|||
if (prevProps.children !== this.props.children |
|||
|| (prevState.scale !== this.state.scale && this.state.scale === 1)) { |
|||
this.setScale(); |
|||
} |
|||
} |
|||
|
|||
setScale = () => { |
|||
const childrenNode = this.avatarChildren; |
|||
if (childrenNode) { |
|||
const childrenWidth = childrenNode.offsetWidth; |
|||
const avatarWidth = ReactDOM.findDOMNode(this).getBoundingClientRect().width; |
|||
// add 4px gap for each side to get better performance
|
|||
if (avatarWidth - 8 < childrenWidth) { |
|||
this.setState({ |
|||
scale: (avatarWidth - 8) / childrenWidth, |
|||
}); |
|||
} else { |
|||
this.setState({ |
|||
scale: 1, |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
render() { |
|||
const { |
|||
prefixCls, shape, size, src, icon, className, ...others, |
|||
} = this.props; |
|||
|
|||
const sizeCls = classNames({ |
|||
[`${prefixCls}-lg`]: size === 'large', |
|||
[`${prefixCls}-sm`]: size === 'small', |
|||
}); |
|||
|
|||
const classString = classNames(prefixCls, className, sizeCls, { |
|||
[`${prefixCls}-${shape}`]: shape, |
|||
[`${prefixCls}-image`]: src, |
|||
[`${prefixCls}-icon`]: icon, |
|||
}); |
|||
|
|||
let children = this.props.children; |
|||
if (src) { |
|||
children = <img src={src} />; |
|||
} else if (icon) { |
|||
children = <Icon type={icon} />; |
|||
} else { |
|||
const childrenNode = this.avatarChildren; |
|||
if (childrenNode || this.state.scale !== 1) { |
|||
const childrenStyle: React.CSSProperties = { |
|||
msTransform: `scale(${this.state.scale})`, |
|||
WebkitTransform: `scale(${this.state.scale})`, |
|||
transform: `scale(${this.state.scale})`, |
|||
position: 'absolute', |
|||
display: 'inline-block', |
|||
left: `calc(50% - ${Math.round(childrenNode.offsetWidth / 2)}px)`, |
|||
}; |
|||
children = <span |
|||
className={`${prefixCls}-string`} |
|||
ref={span => this.avatarChildren = span} |
|||
style={childrenStyle} |
|||
> |
|||
{children} |
|||
</span>; |
|||
} else { |
|||
children = <span |
|||
className={`${prefixCls}-string`} |
|||
ref={span => this.avatarChildren = span} |
|||
> |
|||
{children} |
|||
</span>; |
|||
} |
|||
} |
|||
return ( |
|||
<span {...others} className={classString}> |
|||
{children} |
|||
</span> |
|||
); |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
--- |
|||
category: Components |
|||
subtitle: 头像 |
|||
type: Data Display |
|||
title: Avatar |
|||
--- |
|||
|
|||
用来代表用户或事物,支持图片、图标或字符展示。 |
|||
|
|||
## API |
|||
|
|||
| 参数 | 说明 | 类型 | 默认值 | |
|||
|----------- |--------------------------------------------------------- | ---------- | ------- | |
|||
| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` | |
|||
| size | 设置头像的大小 | Enum{ 'large', 'small', 'default' } | `default` | |
|||
| src | 图片类头像的资源地址 | string | - | |
|||
| icon | 设置头像的图标类型,参考 `Icon` 组件 | string | - | |
@ -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; |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
import '../../style/index.less'; |
|||
import './index.less'; |
Loading…
Reference in new issue