feat: Alert组件支持自定义操作项目

This commit is contained in:
lurunze1226 2023-11-15 20:45:05 +08:00
parent 3e2963d4b5
commit f63b43a70e
6 changed files with 129 additions and 13 deletions

View File

@ -202,17 +202,82 @@ order: 27
]
```
## 操作区域
> `3.6.0`及以上版本
配置`actions`属性,可以添加操作区域。
```schema: scope="body"
[
{
"type": "alert",
"level": "success",
"className": "mb-3",
"showIcon": true,
"showCloseButton": true,
"title": "标题",
"body": "创建成功",
"actions": [
{
"type": "button",
"label": "查看详情",
"size": "xs",
"level": "link",
"style": {
"position": "relative",
"top": "25px",
"left": "30px"
}
}
]
},
{
"type": "alert",
"level": "info",
"showIcon": true,
"showCloseButton": true,
"body": "创建成功",
"actions": {
"type": "flex",
"justify": "flex-start",
"alignItems": "flex-start",
"direction": "column",
"style": {"padding": "6px"},
"items": [
{
"type": "button",
"label": "详情",
"size": "xs",
"level": "primary",
"style": {
"marginBottom": "5px"
}
},
{
"type": "button",
"label": "关闭",
"size": "xs",
"level": "danger"
}
]
}
}
]
```
## 属性表
| 属性名 | 类型 | 默认值 | 说明 |
| -------------------- | ----------------------------------------- | --------- | -------------------------------------------------------- |
| 属性名 | 类型 | 默认值 | 说明 | 版本 |
| -------------------- | ----------------------------------------- | --------- | -------------------------------------------------------- | --- |
| type | `string` | `"alert"` | 指定为 alert 渲染器 |
| title | `string` | | alert标题 |
| className | `string` | | 外层 Dom 的类名 |
| level | `string` | `info` | 级别,可以是:`info`、`success`、`warning` 或者 `danger` |
| body | [SchemaNode](../../docs/types/schemanode) | | 显示内容 |
| body | [`SchemaNode[] \| SchemaNode`](../../docs/types/schemanode) | | 显示内容 |
| showCloseButton | `boolean` | `false` | 是否显示关闭按钮 |
| closeButtonClassName | `string` | | 关闭按钮的 CSS 类名 |
| showIcon | `boolean` | `false` | 是否显示 icon |
| icon | `string` | | 自定义 icon |
| iconClassName | `string` | | icon 的 CSS 类名 |
| actions | [`SchemaNode[] \| SchemaNode`](../../docs/types/schemanode) | | 操作区域 | `3.6.0` |

View File

@ -3282,6 +3282,7 @@
--Alert-fontColor: var(--colors-neutral-text-4);
--Alert-title-fontColor: var(--colors-neutral-text-2);
--Alert-height: var(--sizes-base-20);
--Alert-actions-marginRight: var(--sizes-base-4);
--spinner-base-color: var(--colors-link-5);
--spinner-base-fontSize: var(--fonts-size-8);

View File

@ -52,6 +52,10 @@
}
}
&-actions {
margin-right: var(--Alert-actions-marginRight);
}
&-close {
outline: none;
padding: 0;

View File

@ -21,6 +21,7 @@ export interface AlertProps {
classnames: ClassNamesFn;
classPrefix: string;
children?: React.ReactNode | Array<React.ReactNode>;
actions?: React.ReactNode | React.ReactNode[];
}
export interface AlertState {
@ -68,6 +69,7 @@ export class Alert extends React.Component<AlertProps, AlertState> {
style,
level,
children,
actions,
showCloseButton,
title,
icon,
@ -98,6 +100,7 @@ export class Alert extends React.Component<AlertProps, AlertState> {
{title ? <div className={cx('Alert-title')}>{title}</div> : null}
<div className={cx('Alert-desc')}>{children}</div>
</div>
{actions ? <div className={cx('Alert-actions')}>{actions}</div> : null}
{showCloseButton ? (
<button
className={cx('Alert-close', closeButtonClassName)}

View File

@ -212,3 +212,31 @@ test('Renderer:alert with showCloseButton & closeButtonClassName', () => {
expect(container.querySelector('.cxd-Alert')).not.toBeInTheDocument();
});
test('Renderer:alert with actions', () => {
const {container} = render(amisRender({
"type": "alert",
"level": "success",
"className": "mb-3",
"showIcon": true,
"showCloseButton": true,
"title": "标题",
"body": "创建成功",
"actions": [
{
"type": "button",
"label": "查看详情",
"size": "xs",
"level": "link"
}
]
}, {}, makeEnv({})));
const alert = container.querySelector('.cxd-Alert');
expect(alert).toBeInTheDocument();
const actions = container.querySelector('.cxd-Alert-actions')!;
expect(actions).toBeInTheDocument();
expect(actions.childNodes.length).toEqual(1);
});

View File

@ -1,14 +1,10 @@
import {Renderer, RendererProps} from 'amis-core';
import React from 'react';
import {Renderer, RendererProps} from 'amis-core';
import {Alert2 as Alert} from 'amis-ui';
import {
BaseSchema,
SchemaObject,
SchemaCollection,
SchemaIcon
} from '../Schema';
import {isPureVariable, resolveVariableAndFilter} from 'amis-core';
import type {AlertProps} from 'amis-ui/lib/components/Alert2';
import type {BaseSchema, SchemaCollection, SchemaIcon} from '../Schema';
/**
* Alert
@ -59,14 +55,21 @@ export interface AlertSchema extends BaseSchema {
* CSS类名
*/
iconClassName?: string;
/**
*
*/
actions?: SchemaCollection;
}
@Renderer({
type: 'alert'
})
export class TplRenderer extends React.Component<AlertProps & RendererProps> {
export class AlertRenderer extends React.Component<
Omit<AlertProps, 'actions'> & RendererProps
> {
render() {
let {render, body, level, icon, showIcon, ...rest} = this.props;
let {render, body, level, icon, showIcon, actions, ...rest} = this.props;
if (isPureVariable(level)) {
level = resolveVariableAndFilter(level, this.props.data);
}
@ -77,8 +80,20 @@ export class TplRenderer extends React.Component<AlertProps & RendererProps> {
showIcon = resolveVariableAndFilter(showIcon, this.props.data);
}
const actionsDom: React.ReactNode = actions
? React.isValidElement(actions)
? actions
: render('alert-actions', actions)
: null;
return (
<Alert {...rest} level={level} icon={icon} showIcon={showIcon}>
<Alert
{...rest}
level={level}
icon={icon}
showIcon={showIcon}
actions={actionsDom}
>
{render('body', body)}
</Alert>
);