diff --git a/CHANGELOG.md b/CHANGELOG.md
index b21596165..6c0de2992 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
# 更新日志
## 3.5.0
+- 新增 `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)
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/form/Form.js b/components/form/Form.js
index ad107b4bf..6ca3be311 100644
--- a/components/form/Form.js
+++ b/components/form/Form.js
@@ -27,6 +27,7 @@ const InternalForm = (props) => {
innerRef: formRef,
initialValues,
onValuesChange,
+ updateFormSchema,
_type // SchemaForm 内部配置变量
} = props
const _Immutable = useRef(new Immutable())
@@ -192,7 +193,8 @@ const InternalForm = (props) => {
resetValidates,
validateField,
validate,
- setFieldsValue
+ setFieldsValue,
+ updateFormSchema
}
}, [fields])
diff --git a/components/form/SchemaForm.js b/components/form/SchemaForm.js
index 7ec77b2f5..eea5fac9c 100644
--- a/components/form/SchemaForm.js
+++ b/components/form/SchemaForm.js
@@ -18,6 +18,32 @@ const FormComponent = Provider(Form)
const InternalSchemaForm = (props) => {
const { schema: schemaProps, children: childrenProps, submit, reset, innerRef } = props
const [schema, setSchema] = useState(schemaProps)
+ 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])
@@ -31,7 +57,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 +69,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/components/popper/Overlay.js b/components/popper/Overlay.js
index 7348ceedf..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,7 +53,7 @@ const Overlay = (props) => {
onClickOutside && onClickOutside(e)
},
undefined,
- 'click',
+ overlayClickOutSideEventName,
attachEle
)
}
diff --git a/components/select/Select.js b/components/select/Select.js
index d14901757..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) // 多选情况下,需要记录是否进行了筛选
@@ -129,9 +130,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 +454,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 +535,7 @@ const InternalSelect = (props) => {
resetFocusedIndex()
})
setCacheSelectItem([])
- dataSource && setDropdownItems([])
+ dataSource && searchable && setDropdownItems([])
}
// 防抖
const debouncedFilterItems = _.debounce(onFilterItems, 300)
@@ -621,6 +629,7 @@ const InternalSelect = (props) => {
topGap={5}
leftGap={0}
overlayClassName={overlayClassName}
+ overlayClickOutSideEventName={overlayClickOutSideEventName}
setOverlayContainer={setOverlayContainer}
// 是否防止溢出功能 暂时不开放
preventOverflow={preventOverflow}
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 d05528ae8..07adf6d33 100755
--- a/docs/zh-CN/components/form.mdx
+++ b/docs/zh-CN/components/form.mdx
@@ -123,7 +123,7 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx'
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------------- | ----------------------------------------------------------- | ------ | ------ | ------ |
-| component | 用于渲染的组件名称,(现在组件名称,只限于 HiUI 中的组件名) | string | - | - |
+| component | 用于渲染的组件名称(现在组件名称,只限于 HiUI 中的组件名);如果传入 **ReactNode** 的情况下,**componentProps** 属性失效,同时也会默认控制组件 **value** 属性| string \| ReactNode | - | - |
| componentProps | 组件的属性 | string | - | - |
## Form.Submit
@@ -153,6 +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) | 设置表单的值,在异步获取的数据回显的时候,使用该方法 |
+| updateSchema( schemaData: {fileName: [SchemaItem](#SchemaItem) } ) => void | 当 **SchemaItem** 中对应的 **schema** 数据更新时,请调用该方法更新 |
## rules