From ed2e288da8390fafa5f7cdb23c46944cc3883f74 Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Wed, 24 Feb 2021 21:11:43 +0800 Subject: [PATCH 01/10] fix: #1610 #1577 --- components/select/Select.js | 39 ++++++++++++++++++------------ docs/demo/select/section-async.jsx | 2 ++ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/components/select/Select.js b/components/select/Select.js index d14901757..3ad0e01d4 100644 --- a/components/select/Select.js +++ b/components/select/Select.js @@ -129,9 +129,13 @@ const InternalSelect = (props) => { setSelectedItems(selectedItems) if (dataSource && type === 'multiple') { setCacheSelectItem(selectedItems) - !dropdownShow && setDropdownItems(selectedItems) + !dropdownShow && searchable && setDropdownItems(selectedItems) } else { - setDropdownItems(_data) + if (dataSource) { + searchable && setDropdownItems(_data) + } else { + setDropdownItems(_data) + } } }, [data, value]) @@ -449,19 +453,22 @@ const InternalSelect = (props) => { }, []) // 过滤筛选项 - const onFilterItems = (keyword) => { - setKeyword(keyword) - if (typeof onSearch === 'function') { - onSearch(keyword) - return - } - if (dataSource && (autoload || keyword)) { - remoteSearch(keyword) - } - if (dataSource && keyword === '' && selectedItems.length > 0) { - setDropdownItems(cacheSelectItem) - } - } + const onFilterItems = useCallback( + (keyword) => { + setKeyword(keyword) + if (typeof onSearch === 'function') { + onSearch(keyword) + return + } + if (dataSource && (autoload || keyword) && searchable) { + remoteSearch(keyword) + } + if (dataSource && searchable && keyword === '' && selectedItems.length > 0) { + setDropdownItems(cacheSelectItem) + } + }, + [dataSource, cacheSelectItem, keyword, selectedItems, searchable, onSearch, remoteSearch, autoload] + ) // 重置下标 const resetFocusedIndex = () => { let _dropdownItems = dropdownItems || [] @@ -527,7 +534,7 @@ const InternalSelect = (props) => { resetFocusedIndex() }) setCacheSelectItem([]) - dataSource && setDropdownItems([]) + dataSource && searchable && setDropdownItems([]) } // 防抖 const debouncedFilterItems = _.debounce(onFilterItems, 300) diff --git a/docs/demo/select/section-async.jsx b/docs/demo/select/section-async.jsx index 8166d9532..b5bff80b6 100644 --- a/docs/demo/select/section-async.jsx +++ b/docs/demo/select/section-async.jsx @@ -20,6 +20,8 @@ class Demo extends React.Component { return ( Date: Wed, 24 Feb 2021 22:25:38 +0800 Subject: [PATCH 03/10] feat: #1612 --- CHANGELOG.md | 1 + components/form/Form.js | 4 +++- components/form/SchemaForm.js | 16 ++++++++++--- components/form/index.d.ts | 2 +- docs/demo/form/section-schema.jsx | 37 +++++++++++++++++++------------ docs/zh-CN/components/form.mdx | 3 ++- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b21596165..59ec42cf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 更新日志 ## 3.5.0 +- 新增 `Form` SchemaForm 中 component 属性接受 ReactNode,SchemaForm 新增 schemaFormforceUpdate 强制更新函数 [#1612](https://github.com/XiaoMi/hiui/issues/1612) - 新增 `DatePicker` onSelect 选择日期的回调函数 [#1592](https://github.com/XiaoMi/hiui/issues/1592) - 新增 `Transfer` 组件 render 自定义菜单渲染函数 [#1575](https://github.com/XiaoMi/hiui/issues/1575) - 修复 `DatePicker` type 为 week 或者 weekrange 时 输入相应格式日期解析错误问题 [#1579](https://github.com/XiaoMi/hiui/issues/1579) diff --git a/components/form/Form.js b/components/form/Form.js index ad107b4bf..44e43d114 100644 --- a/components/form/Form.js +++ b/components/form/Form.js @@ -27,6 +27,7 @@ const InternalForm = (props) => { innerRef: formRef, initialValues, onValuesChange, + schemaFormforceUpdate, _type // SchemaForm 内部配置变量 } = props const _Immutable = useRef(new Immutable()) @@ -192,7 +193,8 @@ const InternalForm = (props) => { resetValidates, validateField, validate, - setFieldsValue + setFieldsValue, + schemaFormforceUpdate } }, [fields]) diff --git a/components/form/SchemaForm.js b/components/form/SchemaForm.js index 7ec77b2f5..18b84c09f 100644 --- a/components/form/SchemaForm.js +++ b/components/form/SchemaForm.js @@ -18,9 +18,14 @@ const FormComponent = Provider(Form) const InternalSchemaForm = (props) => { const { schema: schemaProps, children: childrenProps, submit, reset, innerRef } = props const [schema, setSchema] = useState(schemaProps) + const [updateIndex, setUpdateIndex] = useState(0) + const setUpdateIndexFn = useCallback(() => { + setUpdateIndex(updateIndex + 1) + }, [updateIndex]) + useEffect(() => { setSchema(schemaProps) - }, [schemaProps]) + }, [schemaProps, updateIndex]) const renderSchemaFormItem = useCallback(() => { if (Array.isArray(schema)) { @@ -31,7 +36,7 @@ const InternalSchemaForm = (props) => { const ChildComponent = HIUI[component] || Group[component] child = } else { - child =

{'not found ' + component}

+ child = component } return React.createElement(FormItem, { ..._.omit(schemaItem, 'component', 'componentProps'), @@ -43,7 +48,12 @@ const InternalSchemaForm = (props) => { }, [schema]) return (
- + {renderSchemaFormItem()} {childrenProps} {(submit || reset) && ( diff --git a/components/form/index.d.ts b/components/form/index.d.ts index 53f2264f8..d39e9971f 100644 --- a/components/form/index.d.ts +++ b/components/form/index.d.ts @@ -23,7 +23,7 @@ interface ItemProps { showColon?: boolean } interface SchemaItem extends ItemProps { - component?: string + component?: string | JSX.Element componentProps?: string } interface SchemaProps { diff --git a/docs/demo/form/section-schema.jsx b/docs/demo/form/section-schema.jsx index 95598b63f..7a232fa41 100644 --- a/docs/demo/form/section-schema.jsx +++ b/docs/demo/form/section-schema.jsx @@ -26,6 +26,21 @@ const code = [ class Demo extends React.Component { constructor(props){ super(props) + this.form = React.createRef() + this.list = [{ + content: '手机', + id: 'Phone' + },{ + content: '电脑', + id: 'Computer' + },{ + content: '智能', + id: 'Intelli' + },{ + content: '出行', + id: 'Transfer', + disabled: true + }] this.state = { initialValues : { inputField: 'test schema', @@ -67,20 +82,7 @@ const code = [ required:true, componentProps:{ placeholder:'schema', - data:[{ - content: '手机', - id: 'Phone' - },{ - content: '电脑', - id: 'Computer' - },{ - content: '智能', - id: 'Intelli' - },{ - content: '出行', - id: 'Transfer', - disabled: true - }], + data:this.list, onChange:(data) => console.log("Checkbox data",data) } }, @@ -97,7 +99,13 @@ const code = [ } ] } + setTimeout(()=>{ + console.log(this.form.current) + this.list = [] + this.form.current.schemaFormforceUpdate() + },5000) } + render () { const SchemaForm = Form.SchemaForm const {initialValues} = this.state @@ -105,6 +113,7 @@ const code = [ return ( void) | 对指定表单字段进行校验 | | resetValidates(callback:() => void, fields:Array, toDefault:boolean) | 重置整个表单的验证,对应 [Form.Reset](#Form.Reset)中的 API | | setFieldsValue(field: Object) | 设置表单的值,在异步获取的数据回显的时候,使用该方法 | +| schemaFormforceUpdate | 当 **SchemaItem** 中对应的 **schema** 数据更新时,请调用次方法更新 | ## rules From 2105e9d85c95442df6b78e1326b512104c1ab432 Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Wed, 24 Feb 2021 22:26:45 +0800 Subject: [PATCH 04/10] feat: #1612 --- docs/zh-CN/components/form.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-CN/components/form.mdx b/docs/zh-CN/components/form.mdx index a229dca04..27f9e5e2e 100755 --- a/docs/zh-CN/components/form.mdx +++ b/docs/zh-CN/components/form.mdx @@ -153,7 +153,7 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx' | validateField(fields: string, callback: errors => void) | 对指定表单字段进行校验 | | resetValidates(callback:() => void, fields:Array, toDefault:boolean) | 重置整个表单的验证,对应 [Form.Reset](#Form.Reset)中的 API | | setFieldsValue(field: Object) | 设置表单的值,在异步获取的数据回显的时候,使用该方法 | -| schemaFormforceUpdate | 当 **SchemaItem** 中对应的 **schema** 数据更新时,请调用次方法更新 | +| schemaFormforceUpdate | 当 **SchemaItem** 中对应的 **schema** 数据更新时,请调用该方法更新 | ## rules From 83c53024fd2a4359871971ec52508c634c9b0240 Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Wed, 24 Feb 2021 22:28:59 +0800 Subject: [PATCH 05/10] feat: #1612 --- docs/demo/form/section-schema.jsx | 37 ++++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/docs/demo/form/section-schema.jsx b/docs/demo/form/section-schema.jsx index 7a232fa41..95598b63f 100644 --- a/docs/demo/form/section-schema.jsx +++ b/docs/demo/form/section-schema.jsx @@ -26,21 +26,6 @@ const code = [ class Demo extends React.Component { constructor(props){ super(props) - this.form = React.createRef() - this.list = [{ - content: '手机', - id: 'Phone' - },{ - content: '电脑', - id: 'Computer' - },{ - content: '智能', - id: 'Intelli' - },{ - content: '出行', - id: 'Transfer', - disabled: true - }] this.state = { initialValues : { inputField: 'test schema', @@ -82,7 +67,20 @@ const code = [ required:true, componentProps:{ placeholder:'schema', - data:this.list, + data:[{ + content: '手机', + id: 'Phone' + },{ + content: '电脑', + id: 'Computer' + },{ + content: '智能', + id: 'Intelli' + },{ + content: '出行', + id: 'Transfer', + disabled: true + }], onChange:(data) => console.log("Checkbox data",data) } }, @@ -99,13 +97,7 @@ const code = [ } ] } - setTimeout(()=>{ - console.log(this.form.current) - this.list = [] - this.form.current.schemaFormforceUpdate() - },5000) } - render () { const SchemaForm = Form.SchemaForm const {initialValues} = this.state @@ -113,7 +105,6 @@ const code = [ return ( Date: Thu, 25 Feb 2021 14:20:02 +0800 Subject: [PATCH 06/10] feat: useClickOutside.setEventName --- components/popper/Overlay.js | 1 - components/popper/utils/useClickOutside.js | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/components/popper/Overlay.js b/components/popper/Overlay.js index 7348ceedf..ce3a49c4d 100644 --- a/components/popper/Overlay.js +++ b/components/popper/Overlay.js @@ -52,7 +52,6 @@ const Overlay = (props) => { onClickOutside && onClickOutside(e) }, undefined, - 'click', attachEle ) } diff --git a/components/popper/utils/useClickOutside.js b/components/popper/utils/useClickOutside.js index dcffbed28..040cf5340 100644 --- a/components/popper/utils/useClickOutside.js +++ b/components/popper/utils/useClickOutside.js @@ -1,9 +1,13 @@ import { useEffect, useCallback, useRef } from 'react' - -const useClickOutside = (onClickOutside, dom, eventName = 'click', attachEle) => { +let eventName = 'click' +const setEventName = (name = 'click') => { + eventName = name +} +const useClickOutside = (onClickOutside, dom, attachEle) => { const element = useRef('') const handleOutside = useCallback( (e) => { + console.log('eventName', eventName) const targetElement = typeof dom === 'function' ? dom() : dom const el = targetElement || element.current if (el) { @@ -25,4 +29,5 @@ const useClickOutside = (onClickOutside, dom, eventName = 'click', attachEle) => }, [eventName, onClickOutside, element]) return element } +useClickOutside.setEventName = setEventName export default useClickOutside From eb1e61e3cc53019aa138bc2e417baa4ec8923aed Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 25 Feb 2021 14:29:58 +0800 Subject: [PATCH 07/10] feat: remove log --- components/popper/utils/useClickOutside.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/popper/utils/useClickOutside.js b/components/popper/utils/useClickOutside.js index 040cf5340..41b1ecf5d 100644 --- a/components/popper/utils/useClickOutside.js +++ b/components/popper/utils/useClickOutside.js @@ -7,7 +7,6 @@ const useClickOutside = (onClickOutside, dom, attachEle) => { const element = useRef('') const handleOutside = useCallback( (e) => { - console.log('eventName', eventName) const targetElement = typeof dom === 'function' ? dom() : dom const el = targetElement || element.current if (el) { From 2cd0dd22de45c3a7d6a43eade771e02d1efc14fe Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 25 Feb 2021 14:54:45 +0800 Subject: [PATCH 08/10] feat: Datepicker Select --- components/date-picker/BasePicker.jsx | 4 ++++ components/popper/Overlay.js | 4 +++- components/popper/utils/useClickOutside.js | 8 ++------ components/select/Select.js | 4 +++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/components/date-picker/BasePicker.jsx b/components/date-picker/BasePicker.jsx index 369780753..55240fbd0 100644 --- a/components/date-picker/BasePicker.jsx +++ b/components/date-picker/BasePicker.jsx @@ -43,6 +43,8 @@ const BasePicker = ({ bordered = true, disabledDate, onSelect: propsOnSelect, + setOverlayContainer, + overlayClickOutSideEventName = 'click', ...otherPorps }) => { // 兼容2.x api -> max,min @@ -228,6 +230,8 @@ const BasePicker = ({ width={false} className={popperCls} placement={placement} + setOverlayContainer={setOverlayContainer} + overlayClickOutSideEventName={overlayClickOutSideEventName} onClickOutside={clickOutsideEvent} > {type.includes('range') || type === 'timeperiod' ? : } diff --git a/components/popper/Overlay.js b/components/popper/Overlay.js index ce3a49c4d..dd9905781 100644 --- a/components/popper/Overlay.js +++ b/components/popper/Overlay.js @@ -29,7 +29,8 @@ const Overlay = (props) => { onMouseLeave, onClickOutside, overlayClassName, - onKeyDown + onKeyDown, + overlayClickOutSideEventName = 'click' } = props const [isAddevent, setIsAddevent] = useState(false) const [state, setState] = useState({ @@ -52,6 +53,7 @@ const Overlay = (props) => { onClickOutside && onClickOutside(e) }, undefined, + overlayClickOutSideEventName, attachEle ) } diff --git a/components/popper/utils/useClickOutside.js b/components/popper/utils/useClickOutside.js index 41b1ecf5d..dcffbed28 100644 --- a/components/popper/utils/useClickOutside.js +++ b/components/popper/utils/useClickOutside.js @@ -1,9 +1,6 @@ import { useEffect, useCallback, useRef } from 'react' -let eventName = 'click' -const setEventName = (name = 'click') => { - eventName = name -} -const useClickOutside = (onClickOutside, dom, attachEle) => { + +const useClickOutside = (onClickOutside, dom, eventName = 'click', attachEle) => { const element = useRef('') const handleOutside = useCallback( (e) => { @@ -28,5 +25,4 @@ const useClickOutside = (onClickOutside, dom, attachEle) => { }, [eventName, onClickOutside, element]) return element } -useClickOutside.setEventName = setEventName export default useClickOutside diff --git a/components/select/Select.js b/components/select/Select.js index 3ad0e01d4..6004b33a5 100644 --- a/components/select/Select.js +++ b/components/select/Select.js @@ -40,7 +40,8 @@ const InternalSelect = (props) => { fieldNames, overlayClassName, setOverlayContainer, - bordered = true + bordered = true, + overlayClickOutSideEventName = 'click' } = props const selectInputContainer = useRef() const autoloadFlag = useRef(autoload) // 多选情况下,需要记录是否进行了筛选 @@ -628,6 +629,7 @@ const InternalSelect = (props) => { topGap={5} leftGap={0} overlayClassName={overlayClassName} + overlayClickOutSideEventName={overlayClickOutSideEventName} setOverlayContainer={setOverlayContainer} // 是否防止溢出功能 暂时不开放 preventOverflow={preventOverflow} From 07e520cc56802e45a33d73a66e9ac951b4250fff Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Tue, 2 Mar 2021 13:48:41 +0800 Subject: [PATCH 09/10] feat: #1612 --- components/form/Form.js | 4 ++-- components/form/SchemaForm.js | 33 ++++++++++++++++++++++------ docs/demo/form/section-schema.jsx | 36 ++++++++++++++++++++++++++++++- docs/zh-CN/components/form.mdx | 2 +- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/components/form/Form.js b/components/form/Form.js index 44e43d114..6ca3be311 100644 --- a/components/form/Form.js +++ b/components/form/Form.js @@ -27,7 +27,7 @@ const InternalForm = (props) => { innerRef: formRef, initialValues, onValuesChange, - schemaFormforceUpdate, + updateFormSchema, _type // SchemaForm 内部配置变量 } = props const _Immutable = useRef(new Immutable()) @@ -194,7 +194,7 @@ const InternalForm = (props) => { validateField, validate, setFieldsValue, - schemaFormforceUpdate + updateFormSchema } }, [fields]) diff --git a/components/form/SchemaForm.js b/components/form/SchemaForm.js index 18b84c09f..eea5fac9c 100644 --- a/components/form/SchemaForm.js +++ b/components/form/SchemaForm.js @@ -18,14 +18,35 @@ const FormComponent = Provider(Form) const InternalSchemaForm = (props) => { const { schema: schemaProps, children: childrenProps, submit, reset, innerRef } = props const [schema, setSchema] = useState(schemaProps) - const [updateIndex, setUpdateIndex] = useState(0) - const setUpdateIndexFn = useCallback(() => { - setUpdateIndex(updateIndex + 1) - }, [updateIndex]) + const updateSchema = useCallback( + (schemaItems = {}) => { + let _schema = _.cloneDeep(schema) + _schema = _schema.map((item) => { + const _item = _.cloneDeep(item) + const { field } = _item + const schemaItem = schemaItems[field] + if (field && schemaItem) { + const mergeSchema = _.mergeWith( + { [field]: { ..._item } }, + { [field]: { ...schemaItem } }, + (objValue, srcValue) => { + if (_.isArray(objValue)) { + return srcValue + } + } + ) + return mergeSchema[field] + } + return item + }) + setSchema(_schema) + }, + [schema] + ) useEffect(() => { setSchema(schemaProps) - }, [schemaProps, updateIndex]) + }, [schemaProps]) const renderSchemaFormItem = useCallback(() => { if (Array.isArray(schema)) { @@ -50,7 +71,7 @@ const InternalSchemaForm = (props) => {
diff --git a/docs/demo/form/section-schema.jsx b/docs/demo/form/section-schema.jsx index 95598b63f..07fc966e3 100644 --- a/docs/demo/form/section-schema.jsx +++ b/docs/demo/form/section-schema.jsx @@ -9,6 +9,7 @@ import Cascader from '../../../components/cascader' import Radio from '../../../components/radio' import Checkbox from '../../../components/checkbox' import Switch from '../../../components/switch' +import SelectTree from '../../../components/select-tree' import DatePicker from '../../../components/date-picker' import Rate from '../../../components/rate' import Upload from '../../../components/upload' @@ -97,17 +98,20 @@ const code = [ } ] } + this.form = React.createRef() } render () { const SchemaForm = Form.SchemaForm const {initialValues} = this.state return ( +
+ +
+ ) } }` @@ -360,7 +393,8 @@ const DemoRow = () => ( DatePicker, Rate, Upload, - Grid + Grid, + SelectTree }} prefix={prefix} desc={desc} diff --git a/docs/zh-CN/components/form.mdx b/docs/zh-CN/components/form.mdx index 27f9e5e2e..07adf6d33 100755 --- a/docs/zh-CN/components/form.mdx +++ b/docs/zh-CN/components/form.mdx @@ -153,7 +153,7 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx' | validateField(fields: string, callback: errors => void) | 对指定表单字段进行校验 | | resetValidates(callback:() => void, fields:Array, toDefault:boolean) | 重置整个表单的验证,对应 [Form.Reset](#Form.Reset)中的 API | | setFieldsValue(field: Object) | 设置表单的值,在异步获取的数据回显的时候,使用该方法 | -| schemaFormforceUpdate | 当 **SchemaItem** 中对应的 **schema** 数据更新时,请调用该方法更新 | +| updateSchema( schemaData: {fileName: [SchemaItem](#SchemaItem) } ) => void | 当 **SchemaItem** 中对应的 **schema** 数据更新时,请调用该方法更新 | ## rules From b8e2c8bcab2836a2ee60bba578a54448bf278d5e Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Tue, 2 Mar 2021 14:21:21 +0800 Subject: [PATCH 10/10] feat: filter columns --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59ec42cf8..6c0de2992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 更新日志 ## 3.5.0 -- 新增 `Form` SchemaForm 中 component 属性接受 ReactNode,SchemaForm 新增 schemaFormforceUpdate 强制更新函数 [#1612](https://github.com/XiaoMi/hiui/issues/1612) +- 新增 `Form` SchemaForm 中 component 属性接受 ReactNode,SchemaForm 新增 updateSchema 更新函数 [#1612](https://github.com/XiaoMi/hiui/issues/1612) - 新增 `DatePicker` onSelect 选择日期的回调函数 [#1592](https://github.com/XiaoMi/hiui/issues/1592) - 新增 `Transfer` 组件 render 自定义菜单渲染函数 [#1575](https://github.com/XiaoMi/hiui/issues/1575) - 修复 `DatePicker` type 为 week 或者 weekrange 时 输入相应格式日期解析错误问题 [#1579](https://github.com/XiaoMi/hiui/issues/1579)