From a365c07f31728b12d1afbeceeb99ef3e84e6604e Mon Sep 17 00:00:00 2001 From: anlyyao Date: Fri, 16 Jan 2026 15:05:22 +0800 Subject: [PATCH] feat(Cascader): support header and middleContent props --- src/cascader/Cascader.tsx | 22 ++++++++++++++++++---- src/cascader/cascader.en-US.md | 21 ++++++++++++--------- src/cascader/cascader.md | 9 ++++++--- src/cascader/defaultProps.ts | 2 ++ src/cascader/type.ts | 24 +++++++++++++++++++----- 5 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/cascader/Cascader.tsx b/src/cascader/Cascader.tsx index 152bbb49e..169b0ce07 100644 --- a/src/cascader/Cascader.tsx +++ b/src/cascader/Cascader.tsx @@ -26,10 +26,13 @@ const Cascader: React.FC = (props) => { defaultValue, visible, title, + header, + middleContent, placeholder, theme, subTitles, options: inputOptions, + overlayProps, keys, checkStrictly, closeBtn, @@ -45,13 +48,14 @@ const Cascader: React.FC = (props) => { // 根据 inputOptions 和 key 重新构建 options const options = useMemo(() => { - const { label = 'label', value = 'value', children = 'children' } = keys || {}; + const { label = 'label', value = 'value', children = 'children', disabled = 'disabled' } = keys || {}; const convert = (options: TreeOptionData[]) => options.map((item) => ({ label: item[label], value: item[value], children: Array.isArray(item[children]) ? convert(item[children]) : false, + disabled: item[disabled], })); return convert(inputOptions); @@ -168,6 +172,7 @@ const Cascader: React.FC = (props) => { { setInternalVisible(visible); onClose?.(trigger); @@ -189,6 +194,7 @@ const Cascader: React.FC = (props) => { > {closeBtn === true ? : parseTNode(closeBtn)} + {parseTNode(header)}
{labelList.length && (
@@ -235,6 +241,7 @@ const Cascader: React.FC = (props) => { ) : null}
)} + {parseTNode(middleContent)} {subTitles[stepIndex] ? (
{subTitles[stepIndex]}
) : null} @@ -255,16 +262,23 @@ const Cascader: React.FC = (props) => { value={internalSelectedValues[index]} options={curOptions} onChange={(value: string | number) => { + const targetIndex = curOptions.findIndex((item) => item.value === value); + const target = curOptions[targetIndex]; + const selectedValues = [...internalSelectedValues].slice(0, index); selectedValues.push(value); setInternalSelectedValues(selectedValues); setStepIndex(index + 1); - onPick?.(value, index); + onPick?.({ + value, + label: String(target?.label || ''), + index: targetIndex, + level: index, + }); - const next = curOptions.find((item) => item.value === value); - if (Array.isArray(next?.children)) { + if (Array.isArray(target?.children)) { return; } diff --git a/src/cascader/cascader.en-US.md b/src/cascader/cascader.en-US.md index 8ec6b96da..16e8870c2 100644 --- a/src/cascader/cascader.en-US.md +++ b/src/cascader/cascader.en-US.md @@ -7,23 +7,26 @@ name | type | default | description | required -- | -- | -- | -- | -- className | String | - | className of component | N -style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N +style | Object | - | CSS(Cascading Style Sheets),Typescript: `React.CSSProperties` | N checkStrictly | Boolean | false | \- | N -closeBtn | TNode | true | Typescript:`boolean \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -keys | Object | - | Typescript:`CascaderKeysType` `type CascaderKeysType = TreeKeysType`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts) | N +closeBtn | TNode | true | Typescript: `boolean \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +header | TElement | - | `0.21.2`。Typescript: `TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +keys | Object | - | Typescript: `CascaderKeysType` `type CascaderKeysType = TreeKeysType`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts) | N lazy | Boolean | false | \- | N loadCompleted | Boolean | false | \- | N -options | Array | [] | Typescript:`Array` | N +middleContent | TElement | - | `0.21.2`。Typescript: `TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +options | Array | [] | Typescript: `Array` | N +overlayProps | Object | {} | `0.21.2`。Typescript: `OverlayProps`,[Overlay API Documents](./overlay?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts) | N placeholder | String | 选择选项 | \- | N -subTitles | Array | [] | Typescript:`Array` | N +subTitles | Array | [] | Typescript: `Array` | N theme | String | step | options: step/tab | N -title | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +title | TNode | - | Typescript: `string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N value | String / Number | - | \- | N defaultValue | String / Number | - | uncontrolled property | N visible | Boolean | false | \- | N -onChange | Function | | Typescript:`(value: string \| number, selectedOptions: CascaderOption[]) => void`
| N -onClose | Function | | Typescript:`(trigger: TriggerSource) => void`
[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts)。
`type TriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
| N -onPick | Function | | Typescript:`(value: string \| number, index: number) => void`
| N +onChange | Function | | Typescript: `(value: string \| number, selectedOptions: CascaderOption[]) => void`
| N +onClose | Function | | Typescript: `(trigger: CascaderTriggerSource) => void`
[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts)。
`type CascaderTriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
| N +onPick | Function | | Typescript: `(context: { value: string \| number, label: string, index: number, level: number }) => void`
| N ### CSS Variables diff --git a/src/cascader/cascader.md b/src/cascader/cascader.md index a7c2b2ca9..d4513e2d4 100644 --- a/src/cascader/cascader.md +++ b/src/cascader/cascader.md @@ -51,10 +51,13 @@ className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N checkStrictly | Boolean | false | 父子节点选中状态不再关联,可各自选中或取消 | N closeBtn | TNode | true | 关闭按钮。TS 类型:`boolean \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -keys | Object | - | 用来定义 value / label 在 `options` 中对应的字段别名。TS 类型:`CascaderKeysType` `type CascaderKeysType = TreeKeysType`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts) | N +header | TElement | - | `0.21.2`。头部。TS 类型:`TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +keys | Object | - | 用来定义 value / label / children / disabled 在 `options` 中对应的字段别名。TS 类型:`CascaderKeysType` `type CascaderKeysType = TreeKeysType`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts) | N lazy | Boolean | false | 是否异步加载 | N loadCompleted | Boolean | false | 是否完成异步加载 | N +middleContent | TElement | - | `0.21.2`。中间内容。TS 类型:`TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N options | Array | [] | 可选项数据源。TS 类型:`Array` | N +overlayProps | Object | {} | `0.21.2`。遮罩层的属性,透传至 overlay。TS 类型:`OverlayProps`,[Overlay API Documents](./overlay?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts) | N placeholder | String | 选择选项 | 未选中时的提示文案 | N subTitles | Array | [] | 每级展示的次标题。TS 类型:`Array` | N theme | String | step | 展示风格。可选项:step/tab | N @@ -63,8 +66,8 @@ value | String / Number | - | 选项值 | N defaultValue | String / Number | - | 选项值。非受控属性 | N visible | Boolean | false | 是否展示 | N onChange | Function | | TS 类型:`(value: string \| number, selectedOptions: CascaderOption[]) => void`
值发生变更时触发 | N -onClose | Function | | TS 类型:`(trigger: TriggerSource) => void`
关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts)。
`type TriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
| N -onPick | Function | | TS 类型:`(value: string \| number, index: number) => void`
选择后触发 | N +onClose | Function | | TS 类型:`(trigger: CascaderTriggerSource) => void`
关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/cascader/type.ts)。
`type CascaderTriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
| N +onPick | Function | | TS 类型:`(context: { value: string \| number, label: string, index: number, level: number }) => void`
选择后触发 | N ### CSS Variables diff --git a/src/cascader/defaultProps.ts b/src/cascader/defaultProps.ts index e9b0b5197..3f8198c78 100644 --- a/src/cascader/defaultProps.ts +++ b/src/cascader/defaultProps.ts @@ -5,10 +5,12 @@ import { TdCascaderProps } from './type'; export const cascaderDefaultProps: TdCascaderProps = { + checkStrictly: false, closeBtn: true, lazy: false, loadCompleted: false, options: [], + overlayProps: {}, placeholder: '选择选项', subTitles: [], theme: 'step', diff --git a/src/cascader/type.ts b/src/cascader/type.ts index 8c7d12b84..915d39a5d 100644 --- a/src/cascader/type.ts +++ b/src/cascader/type.ts @@ -4,7 +4,8 @@ * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC * */ -import { TNode, TreeKeysType, TreeOptionData } from '../common'; +import { OverlayProps } from '../overlay'; +import { TNode, TElement, TreeOptionData, TreeKeysType } from '../common'; export interface TdCascaderProps { /** @@ -18,7 +19,11 @@ export interface TdCascaderProps; + /** + * 遮罩层的属性,透传至 overlay + * @default {} + */ + overlayProps?: OverlayProps; /** * 未选中时的提示文案 * @default 选择选项 @@ -75,13 +89,13 @@ export interface TdCascaderProps void; + onClose?: (trigger: CascaderTriggerSource) => void; /** * 选择后触发 */ - onPick?: (value: string | number, index: number) => void; + onPick?: (context: { value: string | number; label: string; index: number; level: number }) => void; } export type CascaderKeysType = TreeKeysType; -export type TriggerSource = 'overlay' | 'close-btn' | 'finish'; +export type CascaderTriggerSource = 'overlay' | 'close-btn' | 'finish';