feat: 按钮、链接、模板、图表支持角标; 角标支持动画效果 (#2427)

This commit is contained in:
吴多益 2021-08-24 14:17:45 +08:00 committed by GitHub
parent 937c8bd8ef
commit e59201c290
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 151 additions and 14 deletions

View File

@ -10,7 +10,11 @@ order: 30
## 基本用法 ## 基本用法
部分组件可以设置 `badge` 属性来显示角标,目前只支持头像组件,后续将增加更多组件。 部分组件可以设置 `badge` 属性来显示角标。
> 1.2.2 及之前版本只支持头像组件
>
> 1.2.3 开始支持按钮、链接、模板组件。
```schema: scope="body" ```schema: scope="body"
[ [
@ -20,6 +24,50 @@ order: 30
"mode": "text", "mode": "text",
"text": 10 "text": 10
} }
},
{
"type": "divider"
},
{
"type": "action",
"label": "按钮",
"badge": {
"mode": "text",
"text": 15
}
},
{
"type": "divider"
},
{
"type": "link",
"href": "https://www.baidu.com",
"body": "百度一下,你就知道",
"badge": {
"position": "top-right"
}
},
{
"type": "divider"
},
{
"type": "tpl",
"tpl": "Hello ${text}",
"badge": {
"mode": "text",
"text": 25
}
},
{
"type": "divider"
},
{
"type": "icon",
"icon": "cloud",
"className": "text-info text-xl",
"badge": {
"position": "top-left"
}
} }
] ]
``` ```
@ -174,7 +222,7 @@ order: 30
}, },
{ {
"type": "avatar", "type": "avatar",
"className": "m-l" "className": "m-l",
"badge": { "badge": {
"mode": "text", "mode": "text",
"text": 10, "text": 10,
@ -183,7 +231,7 @@ order: 30
}, },
{ {
"type": "avatar", "type": "avatar",
"className": "m-l" "className": "m-l",
"badge": { "badge": {
"size": 12 "size": 12
} }
@ -198,6 +246,21 @@ order: 30
] ]
``` ```
## 是否显示动画
在默认点状态下,可以通过设置 `animation` 属性来控制是否显示动画
```schema: scope="body"
[
{
"type": "avatar",
"badge": {
"animation": true
}
}
]
```
## 自定义样式 ## 自定义样式
通过 `style` 来控制展现样式,比如背景及文字的颜色 通过 `style` 来控制展现样式,比如背景及文字的颜色
@ -230,10 +293,11 @@ order: 30
## 属性表 ## 属性表
| 属性名 | 类型 | 默认值 | 说明 | | 属性名 | 类型 | 默认值 | 说明 |
| --------- | -------- | ------ | ------------------------- | | --------- | --------- | ------ | ------------------------- |
| className | `string` | | 外层 dom 的类名 | | className | `string` | | 外层 dom 的类名 |
| text | `text` | | 数字 | | text | `text` | | 数字 |
| mode | `string` | | 角标类型,可以是 dot/text | | mode | `string` | | 角标类型,可以是 dot/text |
| className | `string` | | 外层 dom 的类名 | | className | `string` | | 外层 dom 的类名 |
| style | `object` | | 角标的自定义样式 | | animation | `boolean` | | 角标是否显示动画 |
| style | `object` | | 角标的自定义样式 |

View File

@ -55,4 +55,17 @@
height: var(--Badge-size); height: var(--Badge-size);
border-radius: 50%; border-radius: 50%;
} }
// 小红点的动画
@keyframes badgeDotAnimation {
0% {
transform: scale(0.8);
opacity: 0.4;
}
to {
transform: scale(3.2);
opacity: 0;
}
}
} }

View File

@ -39,6 +39,11 @@ export interface BadgeSchema extends BaseSchema {
*/ */
visibleOn?: SchemaExpression; visibleOn?: SchemaExpression;
/**
*
*/
animation?: boolean;
/** /**
* *
*/ */
@ -78,7 +83,8 @@ export class Badge extends React.Component<BadgeProps, object> {
style, style,
position = 'top-right', position = 'top-right',
visibleOn, visibleOn,
className className,
animation
} = badge; } = badge;
if (visibleOn) { if (visibleOn) {
@ -115,6 +121,27 @@ export class Badge extends React.Component<BadgeProps, object> {
sizeStyle = {width: size, height: size}; sizeStyle = {width: size, height: size};
} }
let animationBackground = 'var(--danger)';
if (style && style.background) {
animationBackground = style.background;
}
const animationElement = animation ? (
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
border: `1px solid ${animationBackground}`,
borderRadius: '50%',
animation: 'badgeDotAnimation 1.2s infinite ease-in-out'
}}
></div>
) : null;
return ( return (
<div className={cx('Badge', className)}> <div className={cx('Badge', className)}>
{children} {children}
@ -123,17 +150,19 @@ export class Badge extends React.Component<BadgeProps, object> {
<span <span
className={cx('Badge-dot', `Badge--${position}`)} className={cx('Badge-dot', `Badge--${position}`)}
style={{...sizeStyle, ...style}} style={{...sizeStyle, ...style}}
></span> >
{animationElement}
</span>
) : ( ) : (
<span <span
className={cx('Badge-text', `Badge--${position}`)} className={cx('Badge-text', `Badge--${position}`)}
style={{...sizeStyle, ...style}} style={{...sizeStyle, ...style}}
> >
{text} {text}
{animationElement}
</span> </span>
) )
) : null} ) : null}
{}
</div> </div>
); );
} }

View File

@ -110,6 +110,11 @@ export interface ButtonSchema extends BaseSchema {
* *
*/ */
countDownTpl?: string; countDownTpl?: string;
/**
*
*/
badge?: BadgeSchema;
} }
export interface AjaxActionSchema extends ButtonSchema { export interface AjaxActionSchema extends ButtonSchema {
@ -345,7 +350,7 @@ import {
import {DialogSchema, DialogSchemaBase} from './Dialog'; import {DialogSchema, DialogSchemaBase} from './Dialog';
import {DrawerSchema, DrawerSchemaBase} from './Drawer'; import {DrawerSchema, DrawerSchemaBase} from './Drawer';
import {generateIcon} from '../utils/icon'; import {generateIcon} from '../utils/icon';
import {withBadge} from '../components/Badge'; import {BadgeSchema, withBadge} from '../components/Badge';
export interface ActionProps export interface ActionProps
extends Omit<ButtonSchema, 'className' | 'iconClassName'>, extends Omit<ButtonSchema, 'className' | 'iconClassName'>,
@ -556,6 +561,8 @@ export default themeable(Action);
@Renderer({ @Renderer({
type: 'action' type: 'action'
}) })
// @ts-ignore 类型没搞定
@withBadge
export class ActionRenderer extends React.Component< export class ActionRenderer extends React.Component<
RendererProps & RendererProps &
Omit<ActionProps, 'onAction' | 'isCurrentUrl' | 'tooltipContainer'> & { Omit<ActionProps, 'onAction' | 'isCurrentUrl' | 'tooltipContainer'> & {

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import {Renderer, RendererProps} from '../factory'; import {Renderer, RendererProps} from '../factory';
import {BaseSchema} from '../Schema'; import {BaseSchema} from '../Schema';
import {BadgeSchema, withBadge} from '../components/Badge';
/** /**
* Icon * Icon
@ -15,6 +16,11 @@ export interface IconSchema extends BaseSchema {
icon: string; icon: string;
vendor?: 'iconfont' | 'fa'; vendor?: 'iconfont' | 'fa';
/**
*
*/
badge?: BadgeSchema;
} }
export interface IconProps export interface IconProps
@ -49,4 +55,6 @@ export class Icon extends React.Component<IconProps, object> {
@Renderer({ @Renderer({
type: 'icon' type: 'icon'
}) })
// @ts-ignore 类型没搞定
@withBadge
export class TplRenderer extends Icon {} export class TplRenderer extends Icon {}

View File

@ -3,6 +3,7 @@ import {Renderer, RendererProps} from '../factory';
import {BaseSchema, SchemaTpl} from '../Schema'; import {BaseSchema, SchemaTpl} from '../Schema';
import {getPropValue} from '../utils/helper'; import {getPropValue} from '../utils/helper';
import {filter} from '../utils/tpl'; import {filter} from '../utils/tpl';
import {BadgeSchema, withBadge} from '../components/Badge';
/** /**
* Link * Link
@ -23,6 +24,11 @@ export interface LinkSchema extends BaseSchema {
* *
*/ */
body?: SchemaTpl; body?: SchemaTpl;
/**
*
*/
badge?: BadgeSchema;
} }
export interface LinkProps export interface LinkProps
@ -68,4 +74,6 @@ export class LinkField extends React.Component<LinkProps, object> {
@Renderer({ @Renderer({
type: 'link' type: 'link'
}) })
// @ts-ignore 类型没搞定
@withBadge
export class LinkFieldRenderer extends LinkField {} export class LinkFieldRenderer extends LinkField {}

View File

@ -5,6 +5,7 @@ import cx from 'classnames';
import {anyChanged, getPropValue} from '../utils/helper'; import {anyChanged, getPropValue} from '../utils/helper';
import {escapeHtml} from '../utils/tpl-builtin'; import {escapeHtml} from '../utils/tpl-builtin';
import {BaseSchema, SchemaTpl} from '../Schema'; import {BaseSchema, SchemaTpl} from '../Schema';
import {BadgeSchema, withBadge} from '../components/Badge';
/** /**
* tpl * tpl
@ -33,6 +34,11 @@ export interface TplSchema extends BaseSchema {
style?: { style?: {
[propName: string]: any; [propName: string]: any;
}; };
/**
*
*/
badge?: BadgeSchema;
} }
export interface TplProps extends RendererProps, TplSchema { export interface TplProps extends RendererProps, TplSchema {
@ -127,4 +133,6 @@ export class Tpl extends React.Component<TplProps, object> {
test: /(^|\/)(?:tpl|html)$/, test: /(^|\/)(?:tpl|html)$/,
name: 'tpl' name: 'tpl'
}) })
// @ts-ignore 类型没搞定
@withBadge
export class TplRenderer extends Tpl {} export class TplRenderer extends Tpl {}