mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: avatar 组件 (#1684)
* feat:avatar 组件初步 * 补充文档及样式 * 修复错误的文字 * 完善 schema 描述
This commit is contained in:
parent
2d44f6a29a
commit
41ba93a486
172
docs/zh-CN/components/avatar.md
Normal file
172
docs/zh-CN/components/avatar.md
Normal file
@ -0,0 +1,172 @@
|
||||
---
|
||||
title: Avatar 头像
|
||||
description:
|
||||
type: 0
|
||||
group: ⚙ 组件
|
||||
menuName: Avatar 头像
|
||||
icon:
|
||||
order: 27
|
||||
---
|
||||
|
||||
用来显示用户头像
|
||||
|
||||
## 基本使用
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "avatar",
|
||||
"src": "../../../examples/static/ai-fake-face.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
## 文字
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "avatar",
|
||||
"text": "AM"
|
||||
}
|
||||
```
|
||||
|
||||
## 图标
|
||||
|
||||
通过 icon 设置图标
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "avatar",
|
||||
"icon": "fa fa-user"
|
||||
}
|
||||
```
|
||||
|
||||
> 如果同时存在 src、text 和 icon,会优先用 src、接着 text、最后 icon
|
||||
|
||||
## 动态图片或文字
|
||||
|
||||
src、text 都支持变量,可以从上下文中动态获取图片或文字,下面的例子中第一个获取到了,而第二个没获取到,因此降级为显示 icon
|
||||
|
||||
```schema
|
||||
{
|
||||
"data": {
|
||||
"myAvatar": "../../../examples/static/ai-fake-face.jpg"
|
||||
},
|
||||
"type": "page",
|
||||
"body": [
|
||||
{
|
||||
"type": "avatar",
|
||||
"icon": "fa fa-user",
|
||||
"src": "$myAvatar"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"icon": "fa fa-user",
|
||||
"src": "$other"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 方形和圆角形
|
||||
|
||||
可以通过 shape 改成方形或圆角形
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "avatar",
|
||||
"shape": "square",
|
||||
"text": "AM"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"shape": "rounded",
|
||||
"text": "AM",
|
||||
"style": {
|
||||
"marginLeft": "10px"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
## 大小
|
||||
|
||||
通过 size 可以控制头像的大小
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "avatar",
|
||||
"size": 20,
|
||||
"src": "../../../examples/static/ai-fake-face.jpg"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"size": 60,
|
||||
"src": "../../../examples/static/ai-fake-face.jpg"
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
## 图片拉伸方式
|
||||
|
||||
通过 `fit` 可以控制图片拉伸方式,默认是 `cover`,具体细节可以参考 MDN [文档](https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit)
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "avatar",
|
||||
"fit": "cover",
|
||||
"src": "../../../examples/static/plumeria.jpeg"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"fit": "fill",
|
||||
"src": "../../../examples/static/plumeria.jpeg"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"fit": "contain",
|
||||
"src": "../../../examples/static/plumeria.jpeg"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"fit": "none",
|
||||
"src": "../../../examples/static/plumeria.jpeg"
|
||||
},
|
||||
{
|
||||
"type": "avatar",
|
||||
"fit": "scale-down",
|
||||
"src": "../../../examples/static/plumeria.jpeg"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 样式
|
||||
|
||||
可以通过 style 来控制背景及文字颜色
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "avatar",
|
||||
"text": "AM",
|
||||
"style": {
|
||||
"background": "#DB3E35",
|
||||
"color": "#FFFFFF"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --------- | -------- | ------ | --------------------- |
|
||||
| className | `string` | | 外层 dom 的类名 |
|
||||
| fit | `string` | cover | 图片缩放类型 |
|
||||
| src | `string` | | 图片地址 |
|
||||
| text | `string` | | 文字 |
|
||||
| icon | `string` | | 图标 |
|
||||
| shape | `string` | circle | 形状,也可以是 square |
|
||||
| size | `number` | 40 | 大小 |
|
||||
| style | `object` | | 外层 dom 的样式 |
|
@ -1088,6 +1088,16 @@ export const components = [
|
||||
{
|
||||
label: '其他',
|
||||
children: [
|
||||
{
|
||||
label: 'Avatar 头像',
|
||||
path: '/zh-CN/components/avatar',
|
||||
getComponent: () =>
|
||||
// @ts-ignore
|
||||
import('../../docs/zh-CN/components/avatar.md').then(
|
||||
makeMarkdownRenderer
|
||||
)
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Audio 音频',
|
||||
path: '/zh-CN/components/audio',
|
||||
|
BIN
examples/static/ai-fake-face.jpg
Normal file
BIN
examples/static/ai-fake-face.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
examples/static/plumeria.jpeg
Normal file
BIN
examples/static/plumeria.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
@ -37,8 +37,7 @@ fis.set('project.files', [
|
||||
'/scss/themes/*.scss',
|
||||
'/examples/*.html',
|
||||
'/examples/*.tpl',
|
||||
'/examples/static/*.png',
|
||||
'/examples/static/*.svg',
|
||||
'/examples/static/*',
|
||||
'/src/**.html',
|
||||
'mock/**'
|
||||
]);
|
||||
|
@ -160,6 +160,9 @@
|
||||
--Audio-volume-width: #{px2rem(20px)};
|
||||
--Audio-volumeControl-width: #{px2rem(110px)};
|
||||
|
||||
--Avatar-bg: #{$gray300};
|
||||
--Avatar-width: #{px2rem(40px)};
|
||||
|
||||
--Button--danger-bg: var(--danger);
|
||||
--Button--danger-border: var(--Button--danger-bg);
|
||||
--Button--danger-color: var(--button-color);
|
||||
|
37
scss/components/_avatar.scss
Normal file
37
scss/components/_avatar.scss
Normal file
@ -0,0 +1,37 @@
|
||||
.#{$ns}Avatar {
|
||||
background: var(--Avatar-bg);
|
||||
width: var(--Avatar-width);
|
||||
height: var(--Avatar-width);
|
||||
line-height: var(--Avatar-width);
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
|
||||
&--square {
|
||||
border-radius: 0%;
|
||||
}
|
||||
|
||||
&--rounded {
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: var(--fontSizeLg);
|
||||
}
|
||||
|
||||
img {
|
||||
color: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
img,
|
||||
i {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
@import '../layout/hbox';
|
||||
@import '../layout/vbox';
|
||||
@import '../components/button'; // 这个要放在最前面
|
||||
@import '../components/avatar';
|
||||
@import '../components/breadcrumb';
|
||||
@import '../components/modal';
|
||||
@import '../components/drawer';
|
||||
|
@ -63,6 +63,7 @@ export type SchemaType =
|
||||
| 'alert'
|
||||
| 'app'
|
||||
| 'audio'
|
||||
| 'avatar'
|
||||
| 'button-group'
|
||||
| 'button-toolbar'
|
||||
| 'breadcrumb'
|
||||
|
@ -48,6 +48,7 @@ export * from './Schema';
|
||||
import './renderers/Action';
|
||||
import './renderers/Alert';
|
||||
import './renderers/App';
|
||||
import './renderers/Avatar';
|
||||
import './renderers/Remark';
|
||||
import './renderers/ButtonGroup';
|
||||
import './renderers/ButtonToolbar';
|
||||
|
142
src/renderers/Avatar.tsx
Normal file
142
src/renderers/Avatar.tsx
Normal file
@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @file 用来展示用户头像
|
||||
*/
|
||||
import React from 'react';
|
||||
import {Renderer, RendererProps} from '../factory';
|
||||
import {
|
||||
BaseSchema,
|
||||
SchemaClassName,
|
||||
SchemaIcon,
|
||||
SchemaUrlPath
|
||||
} from '../Schema';
|
||||
import {resolveVariable, resolveVariableAndFilter} from '../utils/tpl-builtin';
|
||||
|
||||
/**
|
||||
* Avatar 用户头像显示
|
||||
* 文档:https://baidu.gitee.io/amis/docs/components/avatar
|
||||
*/
|
||||
export interface AvatarSchema extends BaseSchema {
|
||||
/**
|
||||
* 指定为用户头像控件
|
||||
*/
|
||||
type: 'avatar';
|
||||
|
||||
/**
|
||||
* 大小
|
||||
*/
|
||||
size?: number;
|
||||
|
||||
/**
|
||||
* 形状
|
||||
*/
|
||||
shape?: 'circle' | 'square';
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
icon?: string;
|
||||
|
||||
/**
|
||||
* 文本
|
||||
*/
|
||||
text?: string;
|
||||
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
src?: string;
|
||||
|
||||
/**
|
||||
* 图片相对于容器的缩放方式
|
||||
*/
|
||||
fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down';
|
||||
|
||||
/**
|
||||
* 图片无法显示时的替换文字地址
|
||||
*/
|
||||
alt?: string;
|
||||
|
||||
/**
|
||||
* 类名
|
||||
*/
|
||||
className?: SchemaClassName;
|
||||
|
||||
/**
|
||||
* 自定义样式
|
||||
*/
|
||||
style?: {
|
||||
[propName: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AvatarProps
|
||||
extends RendererProps,
|
||||
Omit<AvatarSchema, 'type' | 'className'> {}
|
||||
|
||||
export class AvatarField extends React.Component<AvatarProps, object> {
|
||||
static defaultProps = {
|
||||
size: 40,
|
||||
shape: 'circle',
|
||||
fit: 'cover',
|
||||
icon: 'fa fa-user'
|
||||
};
|
||||
|
||||
render() {
|
||||
let {
|
||||
className,
|
||||
icon,
|
||||
text,
|
||||
src,
|
||||
fit,
|
||||
data,
|
||||
shape,
|
||||
size,
|
||||
style,
|
||||
classnames: cx,
|
||||
props
|
||||
} = this.props;
|
||||
|
||||
let sizeStyle = {
|
||||
height: size,
|
||||
width: size,
|
||||
lineHeight: size + 'px'
|
||||
};
|
||||
|
||||
let avatar = <i className={icon} />;
|
||||
|
||||
if (typeof text === 'string' && text[0] === '$') {
|
||||
text = resolveVariable(text, data);
|
||||
}
|
||||
|
||||
if (typeof src === 'string' && src[0] === '$') {
|
||||
src = resolveVariable(src, data);
|
||||
}
|
||||
|
||||
if (text) {
|
||||
if (text.length > 2) {
|
||||
text = text.substring(0, 2).toUpperCase();
|
||||
}
|
||||
avatar = <span>{text}</span>;
|
||||
}
|
||||
|
||||
if (src) {
|
||||
avatar = <img src={src} style={{objectFit: fit}} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx('Avatar', className, `Avatar--${shape}`)}
|
||||
style={{...sizeStyle, ...style}}
|
||||
{...props}
|
||||
>
|
||||
{avatar}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Renderer({
|
||||
test: /(^|\/)avatar$/,
|
||||
name: 'avatar'
|
||||
})
|
||||
export class AvatarFieldRenderer extends AvatarField {}
|
Loading…
Reference in New Issue
Block a user