feat:steps 里的 title、subTitle、description 支持变量 (#1800)

* feat:steps 里的 title、subTitle、description 支持变量

* format 强制使用 prittier
This commit is contained in:
吴多益 2021-04-14 11:11:04 +08:00 committed by GitHub
parent cc10cdb5e9
commit 649a59f28a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 175 additions and 138 deletions

View File

@ -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": {

View File

@ -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

View File

@ -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$/,

View File

@ -16,7 +16,7 @@ export function registerTplEnginer(name: string, enginer: Enginer) {
}
export function filter(
tpl?: string,
tpl?: any,
data: object = {},
...rest: Array<any>
): string {