mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-01 19:47:56 +08:00
feat:steps 里的 title、subTitle、description 支持变量 (#1800)
* feat:steps 里的 title、subTitle、description 支持变量 * format 强制使用 prittier
This commit is contained in:
parent
cc10cdb5e9
commit
649a59f28a
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -1,5 +1,7 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.tabSize": 2,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"gitHistory.showEditorTitleMenuBarIcons": false,
|
||||
"search.exclude": {
|
||||
|
@ -70,7 +70,8 @@ order: 68
|
||||
"type": "page",
|
||||
"data": {
|
||||
"step": 1,
|
||||
"status": "error"
|
||||
"status": "error",
|
||||
"secondTitle": "Second"
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
@ -84,7 +85,7 @@ order: 68
|
||||
"description": "this is description"
|
||||
},
|
||||
{
|
||||
"title": "Second"
|
||||
"title": "${secondTitle}"
|
||||
},
|
||||
{
|
||||
"title": "Last"
|
||||
@ -237,12 +238,13 @@ order: 68
|
||||
### step
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --------- | -------- | ------ | --------------------------------------- |
|
||||
| title | `string` | `-` | 标题 |
|
||||
| subTitle | `string` | `-` | 子标题 |
|
||||
| ----------- | --------------- | ------ | --------------------------------------- |
|
||||
| title | `string \| tpl` | | 标题 |
|
||||
| subTitle | `string \| tpl` | | 子标题 |
|
||||
| description | `string \| tpl` | | 详细描述 |
|
||||
| icon | `string` | | icon 名,支持 fontawesome v4 或使用 url |
|
||||
| value | `string` | | value |
|
||||
| className | `string` | `-` | 自定义类名 |
|
||||
| className | `string` | | 自定义类名 |
|
||||
|
||||
### StepStatus
|
||||
|
||||
|
@ -2,15 +2,19 @@ import React from 'react';
|
||||
import {Renderer, RendererProps} from '../factory';
|
||||
import {BaseSchema} from '../Schema';
|
||||
import {Icon} from '../components/icons';
|
||||
import {RemoteOptionsProps, withRemoteConfig} from '../components/WithRemoteConfig';
|
||||
import {
|
||||
RemoteOptionsProps,
|
||||
withRemoteConfig
|
||||
} from '../components/WithRemoteConfig';
|
||||
import {resolveVariable} from '../utils/tpl-builtin';
|
||||
import {filter} from '../utils/tpl';
|
||||
|
||||
enum StepStatus {
|
||||
wait = 'wait',
|
||||
process = 'process',
|
||||
finish = 'finish',
|
||||
error = 'error'
|
||||
};
|
||||
}
|
||||
|
||||
export type StepSchema = {
|
||||
/**
|
||||
@ -28,7 +32,6 @@ export type StepSchema = {
|
||||
*/
|
||||
icon?: string;
|
||||
|
||||
|
||||
value?: string | number;
|
||||
|
||||
/**
|
||||
@ -63,9 +66,11 @@ export interface StepsSchema extends BaseSchema {
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
status?: StepStatus | {
|
||||
status?:
|
||||
| StepStatus
|
||||
| {
|
||||
[propName: string]: StepStatus;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 展示模式
|
||||
@ -73,27 +78,48 @@ export interface StepsSchema extends BaseSchema {
|
||||
mode?: 'horizontal' | 'vertical';
|
||||
}
|
||||
|
||||
export interface StepsProps extends RendererProps, Omit<StepsSchema, 'className'> {}
|
||||
export interface StepsProps
|
||||
extends RendererProps,
|
||||
Omit<StepsSchema, 'className'> {}
|
||||
|
||||
export function Steps(props: StepsProps) {
|
||||
const {className, classnames: cx, steps, value = 0, status, data, source, config} = props;
|
||||
const stepsRow = resolveVariable(source, data) as Array<StepSchema> || config || steps || [];
|
||||
const resolveValue = typeof value === 'string' && isNaN(+value)
|
||||
? resolveVariable(value, data) as string || +value : +value;
|
||||
const valueIndex = stepsRow.findIndex(item => item.value && item.value === resolveValue);
|
||||
const {
|
||||
className,
|
||||
classnames: cx,
|
||||
steps,
|
||||
value = 0,
|
||||
status,
|
||||
data,
|
||||
source,
|
||||
config
|
||||
} = props;
|
||||
const stepsRow =
|
||||
(resolveVariable(source, data) as Array<StepSchema>) ||
|
||||
config ||
|
||||
steps ||
|
||||
[];
|
||||
const resolveValue =
|
||||
typeof value === 'string' && isNaN(+value)
|
||||
? (resolveVariable(value, data) as string) || +value
|
||||
: +value;
|
||||
const valueIndex = stepsRow.findIndex(
|
||||
item => item.value && item.value === resolveValue
|
||||
);
|
||||
const currentValue = valueIndex !== -1 ? valueIndex : resolveValue;
|
||||
const FINISH_ICON = 'check';
|
||||
const ERROR_ICON = 'close';
|
||||
|
||||
function getStepStatus(step: StepSchema, i: number): {stepStatus: StepStatus, icon?: string} {
|
||||
function getStepStatus(
|
||||
step: StepSchema,
|
||||
i: number
|
||||
): {stepStatus: StepStatus; icon?: string} {
|
||||
let stepStatus = StepStatus.wait;
|
||||
let icon = step.icon;
|
||||
|
||||
if (i < currentValue) {
|
||||
stepStatus = StepStatus.finish;
|
||||
!icon && (icon = FINISH_ICON);
|
||||
}
|
||||
else if (i === currentValue) {
|
||||
} else if (i === currentValue) {
|
||||
stepStatus = StepStatus.process;
|
||||
}
|
||||
|
||||
@ -103,8 +129,7 @@ export function Steps(props: StepsProps) {
|
||||
stepStatus = resolveStatus || status || StepStatus.process;
|
||||
stepStatus === StepStatus.error && !icon && (icon = ERROR_ICON);
|
||||
}
|
||||
}
|
||||
else if (typeof status === 'object') {
|
||||
} else if (typeof status === 'object') {
|
||||
const key = step.value;
|
||||
key && status[key] && (stepStatus = status[key]);
|
||||
}
|
||||
@ -112,7 +137,7 @@ export function Steps(props: StepsProps) {
|
||||
return {
|
||||
stepStatus,
|
||||
icon
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
@ -121,30 +146,40 @@ export function Steps(props: StepsProps) {
|
||||
const {stepStatus, icon} = getStepStatus(step, i);
|
||||
|
||||
return (
|
||||
<li key={i} className={cx('StepsItem', `is-${stepStatus}`, step.className)}>
|
||||
<li
|
||||
key={i}
|
||||
className={cx('StepsItem', `is-${stepStatus}`, step.className)}
|
||||
>
|
||||
<div className={cx('StepsItem-container')}>
|
||||
<div className={cx('StepsItem-containerIcon')}>
|
||||
<span className={cx('StepsItem-icon')}>
|
||||
{
|
||||
icon ? <Icon icon={icon} className="icon" /> : (i + 1)
|
||||
}
|
||||
{icon ? <Icon icon={icon} className="icon" /> : i + 1}
|
||||
</span>
|
||||
</div>
|
||||
<div className={cx('StepsItem-containerWrapper')}>
|
||||
<div className={cx('StepsItem-body')}>
|
||||
<div className={cx('StepsItem-title', i < currentValue && 'is-success')}>
|
||||
<span>{step.title}</span>
|
||||
<span className={cx('StepsItem-subTitle')}>{step.subTitle || step.value}</span>
|
||||
<div
|
||||
className={cx(
|
||||
'StepsItem-title',
|
||||
i < currentValue && 'is-success'
|
||||
)}
|
||||
>
|
||||
<span>{filter(step.title, data)}</span>
|
||||
<span className={cx('StepsItem-subTitle')}>
|
||||
{filter(step.subTitle || step.value, data)}
|
||||
</span>
|
||||
</div>
|
||||
<div className={cx('StepsItem-description')}>
|
||||
{filter(step.description, data)}
|
||||
</div>
|
||||
<div className={cx('StepsItem-description')}>{step.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const StepsWithRemoteConfig = withRemoteConfig({
|
||||
@ -155,12 +190,10 @@ const StepsWithRemoteConfig = withRemoteConfig({
|
||||
> {
|
||||
render() {
|
||||
const {config, ...rest} = this.props;
|
||||
return (
|
||||
<Steps config={config} {...rest} />
|
||||
return <Steps config={config} {...rest} />;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@Renderer({
|
||||
test: /(^|\/)steps$/,
|
||||
|
@ -16,7 +16,7 @@ export function registerTplEnginer(name: string, enginer: Enginer) {
|
||||
}
|
||||
|
||||
export function filter(
|
||||
tpl?: string,
|
||||
tpl?: any,
|
||||
data: object = {},
|
||||
...rest: Array<any>
|
||||
): string {
|
||||
|
Loading…
Reference in New Issue
Block a user