From 4a5541ae0c4eaf8cd1d7ef1355df6bd8a822da90 Mon Sep 17 00:00:00 2001 From: helloqian12138 Date: Tue, 4 Jan 2022 18:22:26 +0800 Subject: [PATCH 1/3] refactor: split render method of components in attributes form --- docs/drip-table-generator/guide/fast-start.md | 17 +- docs/drip-table-generator/preview/sample.tsx | 35 +-- .../index.module.less | 0 .../{ArrayComponent => array-list}/index.tsx | 0 .../components/auto-complete/index.tsx | 66 ++++ .../CustomForm/components/cascade/index.tsx | 50 +++ .../CustomForm/components/checkbox/index.tsx | 57 ++++ .../components/code-editor/index.tsx | 40 +++ .../index.module.css | 0 .../{ColorPicker => color-picker}/index.tsx | 0 .../components/CustomForm/components/index.ts | 28 +- .../CustomForm/components/input/index.tsx | 64 ++++ .../CustomForm/components/number/index.tsx | 49 +++ .../CustomForm/components/radio/index.tsx | 59 ++++ .../CustomForm/components/select/index.tsx | 52 +++ .../CustomForm/components/switch/index.tsx | 57 ++++ .../CustomForm/components/text/index.tsx | 69 ++++ .../src/components/CustomForm/index.tsx | 297 ++++-------------- .../src/index.module.less | 1 - .../src/layout/configs.ts | 2 +- .../src/table-components/links.ts | 2 +- .../src/table-components/render-html.ts | 9 +- .../src/table-components/tag.ts | 8 +- .../src/table-components/text.ts | 2 +- packages/drip-table-generator/src/typing.ts | 6 + .../drip-table-generator/src/utils/index.ts | 15 + 26 files changed, 695 insertions(+), 290 deletions(-) rename packages/drip-table-generator/src/components/CustomForm/components/{ArrayComponent => array-list}/index.module.less (100%) rename packages/drip-table-generator/src/components/CustomForm/components/{ArrayComponent => array-list}/index.tsx (100%) create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/auto-complete/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/cascade/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/checkbox/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/code-editor/index.tsx rename packages/drip-table-generator/src/components/CustomForm/components/{ColorPicker => color-picker}/index.module.css (100%) rename packages/drip-table-generator/src/components/CustomForm/components/{ColorPicker => color-picker}/index.tsx (100%) create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/input/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/number/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/radio/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/select/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/switch/index.tsx create mode 100644 packages/drip-table-generator/src/components/CustomForm/components/text/index.tsx diff --git a/docs/drip-table-generator/guide/fast-start.md b/docs/drip-table-generator/guide/fast-start.md index 5d54bcdcd..3d01f200d 100644 --- a/docs/drip-table-generator/guide/fast-start.md +++ b/docs/drip-table-generator/guide/fast-start.md @@ -16,17 +16,18 @@ drip-table-generator 依赖 `antd`、`drip-table` 和 `react`,单独使用不 > yarn ```sh -yarn add drip-table-generator +yarn add drip-table-generator drip-table-driver-antd ``` > npm ```sh -npm install --save drip-table-generator +npm install --save drip-table-generator drip-table-driver-antd ``` ### 依赖引入 ```js +import DripTableDriverAntDesign from 'drip-table-driver-antd'; import DripTableGenerator from 'drip-table-generator'; import 'drip-table-generator/index.css'; ``` @@ -34,7 +35,10 @@ import 'drip-table-generator/index.css'; ### 页面引入 ```js - + ``` ### 代码演示 @@ -46,11 +50,16 @@ import 'drip-table-generator/index.css'; * hideActions: ["CSB"] */ import React from 'react'; +import DripTableDriverAntDesign from 'drip-table-driver-antd'; import DripTableGenerator from 'drip-table-generator'; +import 'drip-table-generator/index.css'; const Demo = () => { return ( - + ); }; diff --git a/docs/drip-table-generator/preview/sample.tsx b/docs/drip-table-generator/preview/sample.tsx index 3cb6499a8..62a6e9c13 100755 --- a/docs/drip-table-generator/preview/sample.tsx +++ b/docs/drip-table-generator/preview/sample.tsx @@ -5,13 +5,13 @@ */ import React from 'react'; -import { Button, Row } from 'antd'; import { DripTableSchema } from 'drip-table'; import DripTableDriverAntDesign from 'drip-table-driver-antd'; import DripTableGenerator, { DripTableGeneratorHandler } from 'drip-table-generator'; import 'antd/dist/antd.css'; import 'drip-table-generator/index.css'; +import { Button, Row } from 'antd'; import { mockData } from '../../global-configs'; import components from './component-settings'; import TextComponent from './TextComponent'; @@ -68,7 +68,7 @@ const Demo = (props: { showHeader: boolean }) => { ) } { onExportSchema={(schema) => { console.log(schema); }} customComponents={{ custom: { TextComponent } }} customComponentPanel={components} - customGlobalConfigPanel={[ - { - name: 'bordered', - 'ui:title': '是否展示边框', - 'ui:type': 'switch', - 'ui:props': {}, - type: 'boolean', - default: false, - }, - { - name: 'size', - 'ui:title': '表格尺寸', - 'ui:type': 'radio', - 'ui:props': { - options: [ - { label: '大号', value: 'large' }, - { label: '中等', value: 'middle' }, - { label: '小号', value: 'small' }, - ], - }, - type: 'string', - default: 'default', - }, - { - name: 'tips', - 'ui:title': '配置说明', - 'ui:type': 'render-html', - type: 'string', - default: '这是一段说明', - }, - ]} /> ); diff --git a/packages/drip-table-generator/src/components/CustomForm/components/ArrayComponent/index.module.less b/packages/drip-table-generator/src/components/CustomForm/components/array-list/index.module.less similarity index 100% rename from packages/drip-table-generator/src/components/CustomForm/components/ArrayComponent/index.module.less rename to packages/drip-table-generator/src/components/CustomForm/components/array-list/index.module.less diff --git a/packages/drip-table-generator/src/components/CustomForm/components/ArrayComponent/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/array-list/index.tsx similarity index 100% rename from packages/drip-table-generator/src/components/CustomForm/components/ArrayComponent/index.tsx rename to packages/drip-table-generator/src/components/CustomForm/components/array-list/index.tsx diff --git a/packages/drip-table-generator/src/components/CustomForm/components/auto-complete/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/auto-complete/index.tsx new file mode 100644 index 000000000..d4cc6716b --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/auto-complete/index.tsx @@ -0,0 +1,66 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { AutoComplete, Select } from 'antd'; +import { StringDataSchema } from 'drip-table'; +import { DTGComponentPropertySchema } from '@/typing'; + +interface Props { + schema: DTGComponentPropertySchema; + value?: string; + onChange?: (value: string) => void; + onValidate?: (errorMessage: string) => void; +} + +type LabeledValue = React.ComponentProps['options']; + +export default class AutoCompleteComponent extends React.PureComponent { + private transform(value: string) { + const transform = (this.props.schema as StringDataSchema).transform; + if (transform) { + transform.forEach((transformType) => { + if (transformType === 'trim') { + value = value.trim(); + } else if (transformType === 'toLowerCase') { + value = value.toLowerCase(); + } else if (transformType === 'toUpperCase') { + value = value.toUpperCase(); + } + }); + } + return value; + } + + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( + { + const formattedValue = this.transform(value); + this.props.onChange?.(formattedValue); + if (config.validate) { + const res = config.validate(formattedValue); + (res instanceof Promise ? res : Promise.resolve(res)) + .then((message) => { + this.props.onValidate?.(message); + return message; + }) + .catch((error) => { throw error; }); + } + }} + /> + ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/cascade/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/cascade/index.tsx new file mode 100644 index 000000000..a12402271 --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/cascade/index.tsx @@ -0,0 +1,50 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { Cascader as Cascade } from 'antd'; +import { DTGComponentPropertySchema } from '@/typing'; + +type CascadeProps = React.ComponentProps; + +interface Props { + schema: DTGComponentPropertySchema; + value?: number; + onChange?: (value: number) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class CascadeComponent extends React.PureComponent { + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( + { + this.props.onChange?.(value); + if (config.validate) { + const res = config.validate(value); + (res instanceof Promise ? res : Promise.resolve(res)) + .then((msg) => { + this.props.onValidate?.(msg); + return msg; + }) + .catch((error) => { throw error; }); + } + }} + /> + ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/checkbox/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/checkbox/index.tsx new file mode 100644 index 000000000..47e2965dc --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/checkbox/index.tsx @@ -0,0 +1,57 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { Checkbox, Popover } from 'antd'; +import { QuestionCircleOutlined } from '@ant-design/icons'; +import { DTGComponentPropertySchema } from '@/typing'; +import { filterAttributes } from '@/utils'; + +type CheckboxGroupProps = React.ComponentProps; +type CheckboxValueType = CheckboxGroupProps['value']; +type CheckboxOptionType = NonNullable[number] & { description?: string }; + +interface Props { + schema: DTGComponentPropertySchema; + value?: CheckboxValueType; + onChange?: (value: CheckboxValueType) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class CheckboxComponent extends React.PureComponent { + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( + { + this.props.onChange?.(value); + }} + > + { (uiProps.options as CheckboxOptionType[])?.map((option, i) => { + if (typeof option === 'string') { + option = { label: option, value: option }; + } + return ( + + { option.label } + { option.description && ( + + + + ) } + + ); + }) } + + ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/code-editor/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/code-editor/index.tsx new file mode 100644 index 000000000..f8a4b484e --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/code-editor/index.tsx @@ -0,0 +1,40 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import MonacoEditor from '@monaco-editor/react'; +import { DTGComponentPropertySchema } from '@/typing'; + +interface Props { + schema: DTGComponentPropertySchema; + value?: string; + onChange?: (value: string) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class CodeEditorComponent extends React.PureComponent { + public render() { + const uiProps = this.props.schema['ui:props'] || {}; + + return ( +
+ { this.props.onChange?.(value || ''); }} + onValidate={(markers) => { + const errorMessages = markers.map(item => item.message).join('\n'); + this.props.onValidate?.(errorMessages); + }} + /> +
+ ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/ColorPicker/index.module.css b/packages/drip-table-generator/src/components/CustomForm/components/color-picker/index.module.css similarity index 100% rename from packages/drip-table-generator/src/components/CustomForm/components/ColorPicker/index.module.css rename to packages/drip-table-generator/src/components/CustomForm/components/color-picker/index.module.css diff --git a/packages/drip-table-generator/src/components/CustomForm/components/ColorPicker/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/color-picker/index.tsx similarity index 100% rename from packages/drip-table-generator/src/components/CustomForm/components/ColorPicker/index.tsx rename to packages/drip-table-generator/src/components/CustomForm/components/color-picker/index.tsx diff --git a/packages/drip-table-generator/src/components/CustomForm/components/index.ts b/packages/drip-table-generator/src/components/CustomForm/components/index.ts index bbfe9f109..24ba3fe1b 100644 --- a/packages/drip-table-generator/src/components/CustomForm/components/index.ts +++ b/packages/drip-table-generator/src/components/CustomForm/components/index.ts @@ -5,10 +5,30 @@ * @modifier : helloqian12138 (johnhello12138@163.com) * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. */ -import ArrayComponent from './ArrayComponent'; -import ColorPicker from './ColorPicker'; +import ArrayComponent from './array-list'; +import ColorPicker from './color-picker'; +import InputComponent from './input'; +import AutoComplete from './auto-complete'; +import TextComponent from './text'; +import Checkbox from './checkbox'; +import RadioComponent from './radio'; +import SwitchComponent from './switch'; +import SelectComponent from './select'; +import InputNumberComponent from './number'; +import CascadeComponent from './cascade'; +import CodeEditorComponent from './code-editor'; export default { - ArrayComponent, - ColorPicker, + input: InputComponent, + text: TextComponent, + number: InputNumberComponent, + checkbox: Checkbox, + radio: RadioComponent, + switch: SwitchComponent, + select: SelectComponent, + cascade: CascadeComponent, + 'code-editor': CodeEditorComponent, + 'auto-complete': AutoComplete, + 'array-list': ArrayComponent, + 'color-picker': ColorPicker, }; diff --git a/packages/drip-table-generator/src/components/CustomForm/components/input/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/input/index.tsx new file mode 100644 index 000000000..4c2e221d8 --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/input/index.tsx @@ -0,0 +1,64 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { Input } from 'antd'; +import { StringDataSchema } from 'drip-table'; +import { DTGComponentPropertySchema } from '@/typing'; + +interface Props { + schema: DTGComponentPropertySchema; + value?: string; + onChange?: (value: string) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class InputComponent extends React.PureComponent { + private transform(value: string) { + const transform = (this.props.schema as StringDataSchema).transform; + if (transform) { + transform.forEach((transformType) => { + if (transformType === 'trim') { + value = value.trim(); + } else if (transformType === 'toLowerCase') { + value = value.toLowerCase(); + } else if (transformType === 'toUpperCase') { + value = value.toUpperCase(); + } + }); + } + return value; + } + + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( + { + const value = this.transform(e.target.value); + this.props.onChange?.(value); + if (config.validate) { + const res = config.validate(value); + (res instanceof Promise ? res : Promise.resolve(res)) + .then((msg) => { + this.props.onValidate?.(msg); + return msg; + }) + .catch((error) => { throw error; }); + } + }} + /> + ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/number/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/number/index.tsx new file mode 100644 index 000000000..ff085bd97 --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/number/index.tsx @@ -0,0 +1,49 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { InputNumber } from 'antd'; +import { DTGComponentPropertySchema } from '@/typing'; + +interface Props { + schema: DTGComponentPropertySchema; + value?: number; + onChange?: (value: number) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class InputNumberComponent extends React.PureComponent { + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( + + {...uiProps} + max={uiProps.max as number} + min={uiProps.min as number} + precision={uiProps.precision as number} + value={this.props.value} + placeholder={uiProps.placeholder as string} + disabled={uiProps.disabled as boolean} + style={{ width: 420, ...uiProps.style }} + onChange={(value) => { + this.props.onChange?.(value); + if (config.validate) { + const res = config.validate(value); + (res instanceof Promise ? res : Promise.resolve(res)) + .then((msg) => { + this.props.onValidate?.(msg); + return msg; + }) + .catch((error) => { throw error; }); + } + }} + /> + ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/radio/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/radio/index.tsx new file mode 100644 index 000000000..f7b7a925c --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/radio/index.tsx @@ -0,0 +1,59 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { Popover, Radio } from 'antd'; +import { QuestionCircleOutlined } from '@ant-design/icons'; +import { DTGComponentPropertySchema } from '@/typing'; +import { filterAttributes } from '@/utils'; + +const RadioGroup = Radio.Group; + + type RadioGroupProps = React.ComponentProps; + type RadioValueType = RadioGroupProps['value']; + type RadioOptionType = NonNullable[number] & { description?: string }; + +interface Props { + schema: DTGComponentPropertySchema; + value?: RadioValueType; + onChange?: (value: RadioValueType) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class RadioComponent extends React.PureComponent { + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( + { + this.props.onChange?.(e.target.value); + }} + > + { (uiProps.options as RadioOptionType[])?.map((option, i) => { + if (typeof option === 'string') { + option = { label: option, value: option }; + } + return ( + + { option.label } + { option.description && ( + + + + ) } + + ); + }) } + + ); + } +} diff --git a/packages/drip-table-generator/src/components/CustomForm/components/select/index.tsx b/packages/drip-table-generator/src/components/CustomForm/components/select/index.tsx new file mode 100644 index 000000000..c692884a9 --- /dev/null +++ b/packages/drip-table-generator/src/components/CustomForm/components/select/index.tsx @@ -0,0 +1,52 @@ +/** + * This file is part of the jd-mkt5 launch. + * @link : https://ace.jd.com/ + * @author : qianjing29 (qianjing29@jd.com) + * @modifier : qianjing29 (qianjing29@jd.com) + * @copyright: Copyright (c) 2020 JD Network Technology Co., Ltd. + */ +import React from 'react'; +import { Select } from 'antd'; +import { DTGComponentPropertySchema } from '@/typing'; + +type SelectProps = React.ComponentProps; +type SelectValueType = SelectProps['value']; +type SelectOptionType = NonNullable[number]; + +interface Props { + schema: DTGComponentPropertySchema; + value?: SelectValueType; + onChange?: (value: SelectValueType) => void; + onValidate?: (errorMessage: string) => void; +} + +export default class SelectComponent extends React.PureComponent { + private get formattedValue() { + const uiProps = this.props.schema['ui:props'] || {}; + if ((uiProps.mode === 'multiple' || uiProps.mode === 'tags') && !Array.isArray(this.props.value)) { + return this.props.value ? [this.props.value] : []; + } + return this.props.value; + } + + public render() { + const config = this.props.schema; + const uiProps = this.props.schema['ui:props'] || {}; + + return ( +