mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:39:05 +08:00
Merge pull request #9071 from Hsirius/feat-progress-event
feat: Progress组件支持事件动作
This commit is contained in:
commit
8ed279ab28
@ -316,3 +316,75 @@ List 的内容、Card 卡片的内容配置同上
|
||||
| strokeWidth | `number` | line 类型为`10`,circle、dashboard 类型为`6` | 进度条线宽度 |
|
||||
| gapDegree | `number` | `75` | 仪表盘缺角角度,可取值 0 ~ 295 |
|
||||
| gapPosition | `string` | `bottom` | 仪表盘进度条缺口位置,可选`top bottom left right` |
|
||||
|
||||
## 动作表
|
||||
|
||||
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
|
||||
|
||||
| 动作名称 | 动作配置 | 说明 |
|
||||
| -------- | ------------------------------------ | ------------ |
|
||||
| reset | - | 将值重置为 0 |
|
||||
| setValue | `value: string` \| `number` 更新的值 | 更新数据 |
|
||||
|
||||
### reset
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "page",
|
||||
"body": [
|
||||
{
|
||||
"type": "progress",
|
||||
"name": "progress",
|
||||
"id": "progress",
|
||||
"value": 67
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"label": "重置值",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "reset",
|
||||
"componentId": "progress"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### setValue
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "page",
|
||||
"body": [
|
||||
{
|
||||
"type": "progress",
|
||||
"name": "progress",
|
||||
"id": "progress",
|
||||
"value": 67
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"label": "设置值",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "setValue",
|
||||
"componentId": "progress",
|
||||
"args": {
|
||||
"value": 20
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {registerEditorPlugin, RendererPluginAction} from 'amis-editor-core';
|
||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
@ -32,6 +32,20 @@ export class ProgressPlugin extends BasePlugin {
|
||||
...this.scaffold
|
||||
};
|
||||
|
||||
// 动作定义
|
||||
actions: RendererPluginAction[] = [
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置为默认值'
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
}
|
||||
];
|
||||
|
||||
panelTitle = '进度';
|
||||
|
||||
panelJustify = true;
|
||||
|
@ -209,7 +209,11 @@ export class Progress extends React.Component<ProgressProps, Object> {
|
||||
];
|
||||
}
|
||||
|
||||
return <div className={cx('Progress', className)} style={style}>{viewValue}</div>;
|
||||
return (
|
||||
<div className={cx('Progress', className)} style={style}>
|
||||
{viewValue}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,12 @@
|
||||
* 6. 环形模式和仪表盘样式
|
||||
* 7. 线条宽度 strokeWidth
|
||||
* 8. 自定义 value 显示 valueTpl
|
||||
* 9. 事件动作
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {render} from '@testing-library/react';
|
||||
import {fireEvent, render} from '@testing-library/react';
|
||||
import {act} from 'react-test-renderer';
|
||||
import '../../src';
|
||||
import {render as amisRender} from '../../src';
|
||||
import {makeEnv, wait} from '../helper';
|
||||
@ -249,3 +251,61 @@ test('Renderer:Progress with valueTpl', async () => {
|
||||
expect(container).toHaveTextContent('67个');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('9.Renderer:Process reset and setValue actions', async () => {
|
||||
const {container, getByText, rerender} = render(
|
||||
amisRender({
|
||||
type: 'page',
|
||||
body: [
|
||||
{
|
||||
type: 'progress',
|
||||
name: 'progress',
|
||||
id: 'progress',
|
||||
value: 67
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
label: '重置值',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'reset',
|
||||
componentId: 'progress'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
label: '设置值',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'setValue',
|
||||
componentId: 'progress',
|
||||
args: {
|
||||
value: 20
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
);
|
||||
|
||||
fireEvent.click(getByText('重置值'));
|
||||
expect(container.querySelector('.cxd-Progress-line-bar')).toHaveStyle({
|
||||
width: '0%'
|
||||
});
|
||||
|
||||
await wait(200);
|
||||
fireEvent.click(getByText('设置值'));
|
||||
expect(container.querySelector('.cxd-Progress-line-bar')).toHaveStyle({
|
||||
width: '20%'
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,15 @@
|
||||
import React from 'react';
|
||||
import {Renderer, RendererProps, filter} from 'amis-core';
|
||||
import {
|
||||
Renderer,
|
||||
RendererProps,
|
||||
filter,
|
||||
ActionObject,
|
||||
ScopedContext,
|
||||
IScopedContext,
|
||||
ScopedComponentType
|
||||
} from 'amis-core';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import pick from 'lodash/pick';
|
||||
import cx from 'classnames';
|
||||
import {BaseSchema, SchemaClassName, SchemaTpl} from '../Schema';
|
||||
import {autobind, getPropValue, createObject} from 'amis-core';
|
||||
@ -96,7 +106,16 @@ export interface ProgressProps
|
||||
extends RendererProps,
|
||||
Omit<ProgressSchema, 'type' | 'className'> {}
|
||||
|
||||
export class ProgressField extends React.Component<ProgressProps, object> {
|
||||
interface ProgressState {
|
||||
value: number;
|
||||
}
|
||||
|
||||
const COMPARE_KEYS = ['name', 'value', 'data', 'defaultValue'];
|
||||
|
||||
export class ProgressField extends React.Component<
|
||||
ProgressProps,
|
||||
ProgressState
|
||||
> {
|
||||
static defaultProps = {
|
||||
placeholder: '-',
|
||||
progressClassName: '',
|
||||
@ -108,6 +127,32 @@ export class ProgressField extends React.Component<ProgressProps, object> {
|
||||
animate: false
|
||||
};
|
||||
|
||||
constructor(props: ProgressProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
value: this.getValue()
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Readonly<ProgressProps>): void {
|
||||
if (
|
||||
!isEqual(pick(prevProps, COMPARE_KEYS), pick(this.props, COMPARE_KEYS))
|
||||
) {
|
||||
this.setState({value: this.getValue()});
|
||||
}
|
||||
}
|
||||
|
||||
getValue() {
|
||||
let value = getPropValue(this.props);
|
||||
value = typeof value === 'number' ? value : filter(value, this.props.data);
|
||||
|
||||
if (/^\d*\.?\d+$/.test(value)) {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@autobind
|
||||
format(value: number) {
|
||||
const {valueTpl, render, data} = this.props;
|
||||
@ -135,13 +180,7 @@ export class ProgressField extends React.Component<ProgressProps, object> {
|
||||
threshold,
|
||||
showThresholdText
|
||||
} = this.props;
|
||||
|
||||
let value = getPropValue(this.props);
|
||||
value = typeof value === 'number' ? value : filter(value, data);
|
||||
|
||||
if (/^\d*\.?\d+$/.test(value)) {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
const {value} = this.state;
|
||||
|
||||
if (threshold) {
|
||||
if (Array.isArray(threshold)) {
|
||||
@ -184,4 +223,32 @@ export class ProgressField extends React.Component<ProgressProps, object> {
|
||||
@Renderer({
|
||||
type: 'progress'
|
||||
})
|
||||
export class ProgressFieldRenderer extends ProgressField {}
|
||||
export class ProgressFieldRenderer extends ProgressField {
|
||||
static contextType = ScopedContext;
|
||||
|
||||
constructor(props: ProgressProps, context: IScopedContext) {
|
||||
super(props);
|
||||
const scoped = context;
|
||||
scoped.registerComponent(this as unknown as ScopedComponentType);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
super.componentWillUnmount?.();
|
||||
const scoped = this.context as IScopedContext;
|
||||
scoped.unRegisterComponent(this as unknown as ScopedComponentType);
|
||||
}
|
||||
|
||||
doAction(action: ActionObject, args: any, throwErrors: boolean): any {
|
||||
const actionType = action?.actionType as string;
|
||||
|
||||
if (actionType === 'reset') {
|
||||
this.setState({value: 0});
|
||||
}
|
||||
}
|
||||
|
||||
setData(value: number) {
|
||||
if (typeof value === 'number' || typeof +value === 'number') {
|
||||
this.setState({value: +value});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user