From 2c01ef778be02d202293af37c7028967a98539cd Mon Sep 17 00:00:00 2001 From: jzh <1587315093@qq.com> Date: Tue, 11 Jul 2023 15:18:26 +0800 Subject: [PATCH] feat: cascader-view support fieldNames --- .../cascader-view/cascader-view.tsx | 49 +- src/components/cascader-view/index.en.md | 1 + src/components/cascader-view/index.zh.md | 1 + .../__snapshots__/cascader-view.test.tsx.snap | 1098 +++++++++++++++++ .../tests/cascader-view.test.tsx | 41 + src/components/cascader/cascader.tsx | 2 + src/hooks/index.tsx | 2 + src/hooks/useFieldNames.tsx | 22 + 8 files changed, 1195 insertions(+), 21 deletions(-) create mode 100644 src/hooks/index.tsx create mode 100644 src/hooks/useFieldNames.tsx diff --git a/src/components/cascader-view/cascader-view.tsx b/src/components/cascader-view/cascader-view.tsx index fdabd8254eb..c134cfddb3d 100644 --- a/src/components/cascader-view/cascader-view.tsx +++ b/src/components/cascader-view/cascader-view.tsx @@ -10,16 +10,15 @@ import { useConfig } from '../config-provider' import { optionSkeleton } from './option-skeleton' import Skeleton from '../skeleton' import { useUpdateEffect } from 'ahooks' +import { useFieldNames } from '../../hooks' +import type { FieldNamesType } from '../../hooks' const classPrefix = `adm-cascader-view` export type CascaderValue = string export type CascaderOption = { - label: string - value: string - disabled?: boolean - children?: CascaderOption[] + [key: string]: any } export type CascaderValueExtend = { @@ -36,6 +35,7 @@ export type CascaderViewProps = { onTabsChange?: (index: number) => void activeIcon?: ReactNode loading?: boolean + fieldNames?: FieldNamesType } & NativeProps<'--height'> const defaultProps = { @@ -43,40 +43,41 @@ const defaultProps = { } export const CascaderView: FC = p => { - const { locale } = useConfig() const props = mergeProps(defaultProps, p) - const placeholder = props.placeholder || locale.Cascader.placeholder + + const { locale } = useConfig() + const generateValueExtend = useCascaderValueExtend(props.options) + const [labelName, valueName, disabledName, childrenName] = useFieldNames( + props.fieldNames + ) + const [value, setValue] = usePropsValue({ ...props, onChange: val => { props.onChange?.(val, generateValueExtend(val)) }, }) - const [tabActiveIndex, setTabActiveIndex] = useState(0) - useUpdateEffect(() => { - props.onTabsChange?.(tabActiveIndex) - }, [tabActiveIndex]) - - const generateValueExtend = useCascaderValueExtend(props.options) + const [tabActiveIndex, setTabActiveIndex] = useState(0) const levels = useMemo(() => { const ret: { selected: CascaderOption | undefined options: CascaderOption[] }[] = [] + let currentOptions = props.options let reachedEnd = false for (const v of value) { - const target = currentOptions.find(option => option.value === v) + const target = currentOptions.find(option => option[valueName] === v) ret.push({ selected: target, options: currentOptions, }) - if (!target || !target.children) { + if (!target || !target[childrenName]) { reachedEnd = true break } - currentOptions = target.children + currentOptions = target[childrenName] } if (!reachedEnd) { ret.push({ @@ -87,6 +88,9 @@ export const CascaderView: FC = p => { return ret }, [value, props.options]) + useUpdateEffect(() => { + props.onTabsChange?.(tabActiveIndex) + }, [tabActiveIndex]) useEffect(() => { setTabActiveIndex(levels.length - 1) }, [value]) @@ -104,9 +108,12 @@ export const CascaderView: FC = p => { } setValue(next) } + const whetherLoading = (options: T) => props.loading || options === optionSkeleton + const placeholder = props.placeholder || locale.Cascader.placeholder + return withNativeProps( props,
@@ -127,7 +134,7 @@ export const CascaderView: FC = p => { title={
{selected - ? selected.label + ? selected[labelName] : typeof placeholder === 'function' ? placeholder(index) : placeholder} @@ -164,17 +171,17 @@ export const CascaderView: FC = p => { activeIcon={props.activeIcon} > {level.options.map(option => { - const active = value[index] === option.value + const active = value[index] === option[valueName] return ( - {option.label} + {option[labelName]} ) })} diff --git a/src/components/cascader-view/index.en.md b/src/components/cascader-view/index.en.md index f6cbc73f03c..e383a5d87ce 100644 --- a/src/components/cascader-view/index.en.md +++ b/src/components/cascader-view/index.en.md @@ -14,6 +14,7 @@ CascaderView is the content area of [Cascader](/components/cascader). | --- | --- | --- | --- | | activeIcon | The icon displayed when selected | `ReactNode` | - | | defaultValue | Default selected options | `CascaderValue[]` | `[]` | +| fieldNames | Custom field name for label and value and disabled and children | `{ label: string, value: string, disabled: string, children: string }` | `{ label: 'label', value: 'value',disabled:'disabled', children: 'children' }` | | onChange | Triggered when the selected options are changed | `(value: CascaderValue[], extend: CascaderValueExtend) => void` | - | | onTabsChange | Callback when switching panel | `(index: number) => void` | - | | options | Data of the cascade options | `CascaderOption[]` | - | diff --git a/src/components/cascader-view/index.zh.md b/src/components/cascader-view/index.zh.md index 779d3c93b06..047d0b58876 100644 --- a/src/components/cascader-view/index.zh.md +++ b/src/components/cascader-view/index.zh.md @@ -14,6 +14,7 @@ CascaderView 是 [Cascader](/zh/components/cascader) 的内容区域。 | --- | --- | --- | --- | | activeIcon | 选中图标 | `ReactNode` | - | | defaultValue | 默认选中项 | `CascaderValue[]` | `[]` | +| fieldNames | 自定义 options 中 label value disabled children 的字段 | `{ label: string, value: string, disabled: string, children: string }` | `{ label: 'label', value: 'value',disabled:'disabled', children: 'children' }` | | onChange | 选项改变时触发 | `(value: CascaderValue[], extend: CascaderValueExtend) => void` | - | | onTabsChange | 切换面板的回调 | `(index: number) => void` | - | | options | 配置每一列的选项 | `CascaderOption[]` | - | diff --git a/src/components/cascader-view/tests/__snapshots__/cascader-view.test.tsx.snap b/src/components/cascader-view/tests/__snapshots__/cascader-view.test.tsx.snap index fc064bb7bb6..69754cc2b18 100644 --- a/src/components/cascader-view/tests/__snapshots__/cascader-view.test.tsx.snap +++ b/src/components/cascader-view/tests/__snapshots__/cascader-view.test.tsx.snap @@ -2471,3 +2471,1101 @@ exports[`CascaderView same value in options 3`] = `
`; + +exports[`CascaderView test fieldNames 1`] = ` +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+