From 4988b4797ab9501c96157b10d86fb14ee16d7ad9 Mon Sep 17 00:00:00 2001 From: haolin Date: Thu, 30 Nov 2023 20:24:22 +0800 Subject: [PATCH] feat(TagInput): expand the deletion function of collapsedItems(#2625) --- src/cascader/Cascader.tsx | 2 +- src/cascader/_example/collapsed.jsx | 75 +++++++++++++----- src/cascader/cascader.en-US.md | 2 +- src/cascader/cascader.md | 2 +- src/cascader/type.ts | 9 ++- src/select-input/_example/collapsed-items.jsx | 63 +++++++++++++-- src/select-input/select-input.en-US.md | 2 +- src/select-input/select-input.md | 2 +- src/select-input/type.ts | 5 +- src/select/_example/collapsed.jsx | 77 +++++++++++++++---- src/select/base/Select.tsx | 29 ++++--- src/select/select.en-US.md | 4 +- src/select/select.md | 4 +- src/select/type.ts | 4 +- src/tag-input/TagInput.tsx | 2 +- src/tag-input/_example/collapsed.jsx | 70 +++++++++++++---- src/tag-input/tag-input.en-US.md | 2 +- src/tag-input/tag-input.md | 2 +- src/tag-input/type.ts | 9 ++- src/tag-input/useTagList.tsx | 13 ++-- src/tree-select/TreeSelect.tsx | 5 +- src/tree-select/_example/collapsed.jsx | 59 ++++++++++++-- src/tree-select/tree-select.en-US.md | 2 +- src/tree-select/tree-select.md | 2 +- src/tree-select/type.ts | 7 +- 25 files changed, 344 insertions(+), 109 deletions(-) diff --git a/src/cascader/Cascader.tsx b/src/cascader/Cascader.tsx index 6a9b2bd126..468555281e 100644 --- a/src/cascader/Cascader.tsx +++ b/src/cascader/Cascader.tsx @@ -72,7 +72,7 @@ const Cascader: React.FC = (originalProps) => { popupVisible={visible} allowInput={isFilterable} minCollapsedNum={props.minCollapsedNum} - collapsedItems={props.collapsedItems as any} + collapsedItems={props.collapsedItems} readonly={props.readonly} clearable={props.clearable} placeholder={inputPlaceholder} diff --git a/src/cascader/_example/collapsed.jsx b/src/cascader/_example/collapsed.jsx index 76deb2a0df..af36ed843e 100644 --- a/src/cascader/_example/collapsed.jsx +++ b/src/cascader/_example/collapsed.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Cascader, Space } from 'tdesign-react'; +import { Cascader, Space, Popup, Tag, Radio, Checkbox } from 'tdesign-react'; export default function Example() { const [value, setValue] = useState(['1.1', '1.2', '1.3']); @@ -38,31 +38,66 @@ export default function Example() { }, ]; - const onChange = (value) => { - setValue(value); - }; + const [size, setSize] = useState('medium'); + const [disabled, setDisabled] = useState(false); + const [readonly, setReadonly] = useState(false); + const [minCollapsedNum] = useState(1); + + const renderCollapsedItems = ({ value, onClose }) => { + const count = value.length - minCollapsedNum; + const collapsedTags = value.slice(minCollapsedNum, value.length); + if (count <= 0) return null; + return ( + ( + onClose({ e: context.e, index: minCollapsedNum + index })} + > + {item} + + ))} + > + More({count}) + + ); + } return ( - - + + +

default:

+ + +

use collapsedItems:

+ +
size control:
+ +
+ + disabled control: + + + + readonly control: + + - count > 0 && ( - - +{count - 1} - - ) - } - /> + minCollapsedNum={minCollapsedNum} + collapsedItems={renderCollapsedItems} + size={size} + disabled={disabled} + readonly={readonly} + >
); } diff --git a/src/cascader/cascader.en-US.md b/src/cascader/cascader.en-US.md index 8b3fe8b378..f003b4c1ce 100644 --- a/src/cascader/cascader.en-US.md +++ b/src/cascader/cascader.en-US.md @@ -11,7 +11,7 @@ autofocus | Boolean | - | \- | N checkProps | Object | - | Typescript:`CheckboxProps`,[Checkbox API Documents](./checkbox?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/cascader/type.ts) | N checkStrictly | Boolean | false | \- | N clearable | Boolean | false | \- | N -collapsedItems | TElement | - | Typescript:`TNode<{ value: CascaderOption[]; collapsedSelectedItems: CascaderOption[]; count: number }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | Typescript:`TNode<{ value: CascaderOption[]; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N disabled | Boolean | - | \- | N empty | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N filter | Function | - | Typescript:`(filterWords: string, node: TreeNodeModel) => boolean \| Promise` | N diff --git a/src/cascader/cascader.md b/src/cascader/cascader.md index e9d7cb5b2c..f8a60acb85 100644 --- a/src/cascader/cascader.md +++ b/src/cascader/cascader.md @@ -11,7 +11,7 @@ autofocus | Boolean | - | 自动聚焦 | N checkProps | Object | - | 参考 checkbox 组件 API。TS 类型:`CheckboxProps`,[Checkbox API Documents](./checkbox?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/cascader/type.ts) | N checkStrictly | Boolean | false | 父子节点选中状态不再关联,可各自选中或取消 | N clearable | Boolean | false | 是否支持清空选项 | N -collapsedItems | TElement | - | 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量。TS 类型:`TNode<{ value: CascaderOption[]; collapsedSelectedItems: CascaderOption[]; count: number }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`onClose` 表示关闭标签时触发的事件。TS 类型:`TNode<{ value: CascaderOption[]; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N disabled | Boolean | - | 是否禁用组件 | N empty | TNode | - | 无匹配选项时的内容,默认全局配置为 '暂无数据'。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N filter | Function | - | 自定义过滤方法,用于对现有数据进行搜索过滤,判断是否过滤某一项数据。TS 类型:`(filterWords: string, node: TreeNodeModel) => boolean \| Promise` | N diff --git a/src/cascader/type.ts b/src/cascader/type.ts index 406a14369f..6b9b5c3736 100644 --- a/src/cascader/type.ts +++ b/src/cascader/type.ts @@ -13,7 +13,7 @@ import { TagProps } from '../tag'; import { TreeNodeModel } from '../tree'; import { PopupVisibleChangeContext } from '../popup'; import { TNode, TElement, TreeOptionData, SizeEnum } from '../common'; -import { FocusEvent } from 'react'; +import { FocusEvent, MouseEvent } from 'react'; export interface TdCascaderProps { /** @@ -35,9 +35,12 @@ export interface TdCascaderProps; + collapsedItems?: TNode<{ + value: CascaderOption[]; + onClose: (p: { e?: MouseEvent; index: number }) => void; + }>; /** * 是否禁用组件 */ diff --git a/src/select-input/_example/collapsed-items.jsx b/src/select-input/_example/collapsed-items.jsx index 846eb108a2..e8367048e8 100644 --- a/src/select-input/_example/collapsed-items.jsx +++ b/src/select-input/_example/collapsed-items.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { SelectInput, Checkbox, Tag, Space } from 'tdesign-react'; +import { SelectInput, Checkbox, Tag, Space, Popup, Radio } from 'tdesign-react'; import { ChevronDownIcon } from 'tdesign-icons-react'; const classStyles = ` @@ -47,6 +47,11 @@ export default function SelectInputCollapsedItems() { const [options, setOptions] = useState([...OPTIONS]); const [value, setValue] = useState(OPTIONS.slice(1)); + const [size, setSize] = useState('medium'); + const [disabled, setDisabled] = useState(false); + const [readonly, setReadonly] = useState(false); + const [minCollapsedNum] = useState(1); + const getCheckboxValue = () => { const arr = []; const list = value; @@ -97,6 +102,34 @@ export default function SelectInputCollapsedItems() { } }; + const renderCollapsedItems = ({ value, onClose }) => { + const count = value.length - minCollapsedNum; + const collapsedTags = value.slice(minCollapsedNum, value.length); + if (count <= 0) return null; + return ( + ( + onClose({ e: context.e, index: minCollapsedNum + index })} + > + {item} + + ))} + > + More({count}) + + ); + } + const CheckboxPanel = ( + +

default:

{/* */} -

+ {/* 使用 collapsedItems 自定义折叠标签 */} +

use collapsedItems:

+ +
size control:
+ +
+ + disabled control: + + + + readonly control: + + } - collapsedItems={({ collapsedTags }) => More(+{collapsedTags.length})} clearable multiple onTagChange={onTagChange} + minCollapsedNum={minCollapsedNum} + collapsedItems={renderCollapsedItems} + tagInputProps={{ + size, + }} + disabled={disabled} + readonly={readonly} />
); -} \ No newline at end of file +} diff --git a/src/select-input/select-input.en-US.md b/src/select-input/select-input.en-US.md index 3bd6d9cf78..1d8ee09989 100644 --- a/src/select-input/select-input.en-US.md +++ b/src/select-input/select-input.en-US.md @@ -12,7 +12,7 @@ autoWidth | Boolean | false | \- | N autofocus | Boolean | false | \- | N borderless | Boolean | false | \- | N clearable | Boolean | false | \- | N -collapsedItems | TElement | - | Typescript:`TNode<{ value: SelectInputValue; collapsedTags: SelectInputValue; count: number }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | Typescript:`TNode<{ value: SelectInputValue; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N disabled | Boolean | - | \- | N inputProps | Object | - | Typescript:`InputProps`,[Input API Documents](./input?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/select-input/type.ts) | N inputValue | String / Number | - | input value。Typescript:`InputValue`,[Input API Documents](./input?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/select-input/type.ts) | N diff --git a/src/select-input/select-input.md b/src/select-input/select-input.md index 398f9fdbd2..b46f304460 100644 --- a/src/select-input/select-input.md +++ b/src/select-input/select-input.md @@ -12,7 +12,7 @@ autoWidth | Boolean | false | 宽度随内容自适应 | N autofocus | Boolean | false | 自动聚焦 | N borderless | Boolean | false | 无边框模式 | N clearable | Boolean | false | 是否可清空 | N -collapsedItems | TElement | - | 标签过多的情况下,折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 `collapsedItems` 自定义。`value` 表示所有标签值,`collapsedTags` 表示折叠标签值,`count` 表示折叠的数量。TS 类型:`TNode<{ value: SelectInputValue; collapsedTags: SelectInputValue; count: number }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | 标签过多的情况下,折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 `collapsedItems` 自定义。`value` 表示所有标签值,`collapsedTags` 表示折叠标签值,`count` 表示折叠的数量。TS 类型:`TNode<{ value: SelectInputValue; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N disabled | Boolean | - | 是否禁用 | N inputProps | Object | - | 透传 Input 输入框组件全部属性。TS 类型:`InputProps`,[Input API Documents](./input?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/select-input/type.ts) | N inputValue | String / Number | - | 输入框的值。TS 类型:`InputValue`,[Input API Documents](./input?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/select-input/type.ts) | N diff --git a/src/select-input/type.ts b/src/select-input/type.ts index 539950dea1..3fd5b7ff5b 100644 --- a/src/select-input/type.ts +++ b/src/select-input/type.ts @@ -42,7 +42,10 @@ export interface TdSelectInputProps { /** * 标签过多的情况下,折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 `collapsedItems` 自定义。`value` 表示所有标签值,`collapsedTags` 表示折叠标签值,`count` 表示折叠的数量 */ - collapsedItems?: TNode<{ value: SelectInputValue; collapsedTags: SelectInputValue; count: number }>; + collapsedItems?: TNode<{ + value: SelectInputValue; + onClose: (p: { e?: MouseEvent; index: number }) => void; + }>; /** * 是否禁用 */ diff --git a/src/select/_example/collapsed.jsx b/src/select/_example/collapsed.jsx index d24c7e98ae..a129e9cb0e 100644 --- a/src/select/_example/collapsed.jsx +++ b/src/select/_example/collapsed.jsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; -import { Select, Space } from 'tdesign-react'; +import { Select, Popup, Tag, Space, Radio, Checkbox } from 'tdesign-react'; const options = [ { label: '选项一', value: '1' }, @@ -10,28 +10,71 @@ const options = [ const MultipleSelect = () => { const [value, setValue] = useState(['1', '3']); - const onChange = (value) => { - setValue(value); - }; + + const [size, setSize] = useState('medium'); + const [disabled, setDisabled] = useState(false); + const [readonly, setReadonly] = useState(false); + const [minCollapsedNum] = useState(1); + + const renderCollapsedItems = ({ value, onClose }) => { + const count = value.length - minCollapsedNum; + const collapsedTags = value.slice(minCollapsedNum, value.length); + if (count <= 0) return null; + return ( + ( + onClose({ e: context.e, index: minCollapsedNum + index })} + > + {item} + + ))} + > + More({count}) + + ); + } + return ( - + + +

default:

+ -
); }; diff --git a/src/select/base/Select.tsx b/src/select/base/Select.tsx index 8432faaf0f..6b2f6e89aa 100644 --- a/src/select/base/Select.tsx +++ b/src/select/base/Select.tsx @@ -2,6 +2,7 @@ import React, { useEffect, Ref, useMemo, + MouseEvent, KeyboardEvent, useRef, useCallback, @@ -118,6 +119,20 @@ const Select = forwardRefWithStatics( return get(selectedOptions[0] || {}, keys?.label || 'label') || undefined; }, [selectedOptions, keys, multiple]); + // 点击标签关闭按钮,删除标签 + const onClose = useCallback( + (p: { e?: MouseEvent; index: number }) => { + const { e, index } = p; + + e?.stopPropagation(); + const values = getSelectValueArr(value, value[index], true, valueType, keys); + const selectedOptions = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); + onChange(values, { e, selectedOptions, trigger: 'uncheck' }); + tagProps?.onClose?.({ e }); + }, + [value, valueType, keys, multiple, tagProps, tmpPropOptions, onChange], + ); + const handleShowPopup = (visible: boolean, ctx: PopupVisibleChangeContext) => { if (disabled) return; setShowPopup(visible, ctx); @@ -327,14 +342,7 @@ const Select = forwardRefWithStatics( closable={!filterOption?.disabled && !disabled && !readonly} size={size} {...tagProps} - onClose={({ e }) => { - e.stopPropagation(); - const values = getSelectValueArr(value, value[key], true, valueType, keys); - - const selectedOptions = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); - onChange(values, { e, selectedOptions, trigger: 'uncheck' }); - tagProps?.onClose?.({ e }); - }} + onClose={(context) => onClose({ e: context.e, index: key })} > {v} @@ -355,11 +363,10 @@ const Select = forwardRefWithStatics( collapsedItems ? parseContentTNode(collapsedItems, { value: selectedLabel, - collapsedSelectedItems: selectedLabel.slice(minCollapsedNum, selectedLabel.length), - count: selectedLabel.length - minCollapsedNum, + onClose, }) : null, - [selectedLabel, collapsedItems, minCollapsedNum], + [selectedLabel, collapsedItems, onClose], ); // 将第一个选中的 option 置于列表可见范围的最后一位 diff --git a/src/select/select.en-US.md b/src/select/select.en-US.md index 09952ca1d6..fddbc5a8d2 100644 --- a/src/select/select.en-US.md +++ b/src/select/select.en-US.md @@ -11,7 +11,7 @@ autoWidth | Boolean | false | \- | N autofocus | Boolean | false | \- | N borderless | Boolean | false | \- | N clearable | Boolean | false | \- | N -collapsedItems | TElement | - | Typescript:`TNode<{ value: T[]; collapsedSelectedItems: T[]; count: number }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | Typescript:`TNode<{ value: T[]; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N creatable | Boolean | false | \- | N disabled | Boolean | - | \- | N empty | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N @@ -93,4 +93,4 @@ bufferSize | Number | 20 | \- | N isFixedRowHeight | Boolean | false | \- | N rowHeight | Number | - | \- | N threshold | Number | 100 | \- | N -type | String | - | required。options:lazy/virtual | Y \ No newline at end of file +type | String | - | required。options:lazy/virtual | Y diff --git a/src/select/select.md b/src/select/select.md index c066d31b18..60be338188 100644 --- a/src/select/select.md +++ b/src/select/select.md @@ -11,7 +11,7 @@ autoWidth | Boolean | false | 宽度随内容自适应 | N autofocus | Boolean | false | 自动聚焦 | N borderless | Boolean | false | 无边框模式 | N clearable | Boolean | false | 是否可以清空选项 | N -collapsedItems | TElement | - | 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,泛型 `T` 继承 `SelectOption`,表示选项数据;`count` 表示折叠的数量。TS 类型:`TNode<{ value: T[]; collapsedSelectedItems: T[]; count: number }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`onClose` 表示关闭标签时触发的事件。TS 类型:`TNode<{ value: T[]; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N creatable | Boolean | false | 是否允许用户创建新条目,需配合 filterable 使用 | N disabled | Boolean | - | 是否禁用组件 | N empty | TNode | - | 当下拉列表为空时显示的内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N @@ -93,4 +93,4 @@ bufferSize | Number | 20 | 表示除可视区域外,额外渲染的行数, isFixedRowHeight | Boolean | false | 表示每行内容是否同一个固定高度,仅在 `scroll.type` 为 `virtual` 时有效,该属性设置为 `true` 时,可用于简化虚拟滚动内部计算逻辑,提升性能,此时则需要明确指定 `scroll.rowHeight` 属性的值 | N rowHeight | Number | - | 行高,不会给``元素添加样式高度,仅作为滚动时的行高参考。一般情况不需要设置该属性。如果设置,可尽量将该属性设置为每行平均高度,从而使得滚动过程更加平滑 | N threshold | Number | 100 | 启动虚拟滚动的阈值。为保证组件收益最大化,当数据量小于阈值 `scroll.threshold` 时,无论虚拟滚动的配置是否存在,组件内部都不会开启虚拟滚动 | N -type | String | - | 必需。滚动加载类型,有两种:懒加载和虚拟滚动。
值为 `lazy` ,表示滚动时会进行懒加载,非可视区域内的内容将不会默认渲染,直到该内容可见时,才会进行渲染,并且已渲染的内容滚动到不可见时,不会被销毁;
值为`virtual`时,表示会进行虚拟滚动,无论滚动条滚动到哪个位置,同一时刻,仅渲染该可视区域内的内容,当需要展示的数据量较大时,建议开启该特性。可选项:lazy/virtual | Y \ No newline at end of file +type | String | - | 必需。滚动加载类型,有两种:懒加载和虚拟滚动。
值为 `lazy` ,表示滚动时会进行懒加载,非可视区域内的内容将不会默认渲染,直到该内容可见时,才会进行渲染,并且已渲染的内容滚动到不可见时,不会被销毁;
值为`virtual`时,表示会进行虚拟滚动,无论滚动条滚动到哪个位置,同一时刻,仅渲染该可视区域内的内容,当需要展示的数据量较大时,建议开启该特性。可选项:lazy/virtual | Y diff --git a/src/select/type.ts b/src/select/type.ts index 1f32030582..5c29aebc72 100644 --- a/src/select/type.ts +++ b/src/select/type.ts @@ -37,9 +37,9 @@ export interface TdSelectProps { */ clearable?: boolean; /** - * 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,泛型 `T` 继承 `SelectOption`,表示选项数据;`count` 表示折叠的数量 + * 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`onClose` 表示关闭标签时触发的事件 */ - collapsedItems?: TNode<{ value: T[]; collapsedSelectedItems: T[]; count: number }>; + collapsedItems?: TNode<{ value: T[]; onClose: (p: { e?: MouseEvent; index: number }) => void }>; /** * 是否允许用户创建新条目,需配合 filterable 使用 * @default false diff --git a/src/tag-input/TagInput.tsx b/src/tag-input/TagInput.tsx index 900963af8b..66394d173a 100644 --- a/src/tag-input/TagInput.tsx +++ b/src/tag-input/TagInput.tsx @@ -114,7 +114,7 @@ const TagInput = forwardRef((props: TagInputProps, ref: React.RefObject onClose({ index, item }), + onClose: (index) => onClose({ index }), }) : valueDisplay; diff --git a/src/tag-input/_example/collapsed.jsx b/src/tag-input/_example/collapsed.jsx index 3eba8ac62d..928a33bae3 100644 --- a/src/tag-input/_example/collapsed.jsx +++ b/src/tag-input/_example/collapsed.jsx @@ -1,24 +1,66 @@ import React, { useState } from 'react'; -import { TagInput, Popup, Tag, Space } from 'tdesign-react'; +import { TagInput, Popup, Tag, Space, Radio, Checkbox } from 'tdesign-react'; export default function TagInputCollapsedExample() { const [tags, setTags] = useState(['Vue', 'React', 'Miniprogram', 'Angular', 'Flutter']); - const renderCollapsedItems = ({ collapsedTags }) => ( - ( - - {item} - - ))} - > - More({collapsedTags?.length}) - - ); + + const [size, setSize] = useState('medium'); + const [disabled, setDisabled] = useState(false); + const [readonly, setReadonly] = useState(false); + const [minCollapsedNum] = useState(1); + + const renderCollapsedItems = ({ value, onClose }) => { + const count = value.length - minCollapsedNum; + const collapsedTags = value.slice(minCollapsedNum, value.length); + if (count <= 0) return null; + return ( + ( + onClose({ e: context.e, index: minCollapsedNum + index })} + > + {item} + + ))} + > + More({count}) + + ); + } return ( + +

default:

- + +

use collapsedItems:

+ +
size control:
+ +
+ + disabled control: + + + + readonly control: + + +
); } diff --git a/src/tag-input/tag-input.en-US.md b/src/tag-input/tag-input.en-US.md index 30e4601081..abe7795e48 100644 --- a/src/tag-input/tag-input.en-US.md +++ b/src/tag-input/tag-input.en-US.md @@ -9,7 +9,7 @@ className | String | - | 类名 | N style | Object | - | 样式,Typescript:`React.CSSProperties` | N autoWidth | Boolean | false | \- | N clearable | Boolean | false | \- | N -collapsedItems | TElement | - | Typescript:`TNode<{ value: TagInputValue; collapsedTags: TagInputValue; count: number }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | Typescript:`TNode<{ value: TagInputValue; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N disabled | Boolean | - | \- | N dragSort | Boolean | false | \- | N excessTagsDisplayType | String | break-line | options:scroll/break-line | N diff --git a/src/tag-input/tag-input.md b/src/tag-input/tag-input.md index 2563e4fd7e..5b38f8a4b9 100644 --- a/src/tag-input/tag-input.md +++ b/src/tag-input/tag-input.md @@ -9,7 +9,7 @@ className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N autoWidth | Boolean | false | 宽度随内容自适应 | N clearable | Boolean | false | 是否可清空 | N -collapsedItems | TElement | - | 标签过多的情况下,折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量。TS 类型:`TNode<{ value: TagInputValue; collapsedTags: TagInputValue; count: number }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | 标签过多的情况下,折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量。TS 类型:`TNode<{ value: TagInputValue; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N disabled | Boolean | - | 是否禁用标签输入框 | N dragSort | Boolean | false | 拖拽调整标签顺序 | N excessTagsDisplayType | String | break-line | 标签超出时的呈现方式,有两种:横向滚动显示 和 换行显示。可选项:scroll/break-line | N diff --git a/src/tag-input/type.ts b/src/tag-input/type.ts index 2eb02a5c04..40b6ad6dd0 100644 --- a/src/tag-input/type.ts +++ b/src/tag-input/type.ts @@ -7,7 +7,7 @@ import { InputProps } from '../input'; import { InputValue } from '../input'; import { TagProps } from '../tag'; -import { TNode, TElement } from '../common'; +import { TNode, TElement, SizeEnum } from '../common'; import { MouseEvent, KeyboardEvent, ClipboardEvent, FocusEvent, FormEvent, CompositionEvent } from 'react'; export interface TdTagInputProps { @@ -24,7 +24,10 @@ export interface TdTagInputProps { /** * 标签过多的情况下,折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量 */ - collapsedItems?: TNode<{ value: TagInputValue; collapsedTags: TagInputValue; count: number }>; + collapsedItems?: TNode<{ + value: TagInputValue; + onClose: (p: { e?: MouseEvent; index: number }) => void; + }>; /** * 是否禁用标签输入框 */ @@ -79,7 +82,7 @@ export interface TdTagInputProps { * 尺寸 * @default medium */ - size?: 'small' | 'medium' | 'large'; + size?: SizeEnum; /** * 输入框状态 */ diff --git a/src/tag-input/useTagList.tsx b/src/tag-input/useTagList.tsx index ada2f48ab8..439056afbd 100644 --- a/src/tag-input/useTagList.tsx +++ b/src/tag-input/useTagList.tsx @@ -22,11 +22,11 @@ export default function useTagList(props: TagInputProps) { const [oldInputValue, setOldInputValue] = useState(); // 点击标签关闭按钮,删除标签 - const onClose = (p: { e?: MouseEvent; index: number; item: string | number }) => { + const onClose = (p: { e?: MouseEvent; index: number }) => { const arr = [...tagValue]; - arr.splice(p.index, 1); - setTagValue(arr, { trigger: 'tag-remove', ...p }); - onRemove?.({ ...p, trigger: 'tag-remove', value: arr }); + const [item] = arr.splice(p.index, 1); // 当前删除的item无需参数传递 + setTagValue(arr, { trigger: 'tag-remove', ...p, item }); + onRemove?.({ ...p, item, trigger: 'tag-remove', value: arr }); }; const clearAll = (context: { e: MouseEvent }) => { @@ -80,7 +80,7 @@ export default function useTagList(props: TagInputProps) { key={index} size={size} disabled={disabled} - onClose={(context) => onClose({ e: context.e, item, index })} + onClose={(context) => onClose({ e: context.e, index })} closable={!readonly && !disabled} {...getDragProps?.(index, item)} {...tagProps} @@ -101,8 +101,7 @@ export default function useTagList(props: TagInputProps) { const len = tagValue.length - newList.length; const params = { value: tagValue, - count: tagValue.length - minCollapsedNum, - collapsedTags: tagValue.slice(minCollapsedNum, tagValue.length), + onClose, }; const more = isFunction(collapsedItems) ? collapsedItems(params) : collapsedItems; list.push({more ?? +{len}}); diff --git a/src/tree-select/TreeSelect.tsx b/src/tree-select/TreeSelect.tsx index 75bed7adc0..b4547ac48e 100644 --- a/src/tree-select/TreeSelect.tsx +++ b/src/tree-select/TreeSelect.tsx @@ -298,12 +298,11 @@ const TreeSelect = forwardRef((props: TreeSelectProps, ref) => { const renderCollapsedItems = useMemo( () => props.collapsedItems - ? () => + ? ({ onClose }) => isFunction(props.collapsedItems) ? props.collapsedItems({ value: normalizedValue, - collapsedSelectedItems: normalizedValue.slice(props.minCollapsedNum, normalizedValue.length), - count: normalizedValue.length - props.minCollapsedNum, + onClose, }) : props.collapsedItems : null, diff --git a/src/tree-select/_example/collapsed.jsx b/src/tree-select/_example/collapsed.jsx index 9096ca22ca..82c73e202e 100644 --- a/src/tree-select/_example/collapsed.jsx +++ b/src/tree-select/_example/collapsed.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { TreeSelect, Tag, Tooltip, Space } from 'tdesign-react'; +import { TreeSelect, Tag, Space, Popup, Radio, Checkbox } from 'tdesign-react'; const options = [ { @@ -35,8 +35,40 @@ const options = [ export default function Example() { const [value, setValue] = useState(['guangzhou', 'shenzhen']); const [customizeValue, setCustomizeValue] = useState(['guangzhou', 'shenzhen']); + + const [size, setSize] = useState('medium'); + const [disabled, setDisabled] = useState(false); + const [readonly, setReadonly] = useState(false); + const [minCollapsedNum] = useState(1); + + const renderCollapsedItems = ({ value, onClose }) => { + const count = value.length - minCollapsedNum; + const collapsedTags = value.slice(minCollapsedNum, value.length); + if (count <= 0) return null; + return ( + ( + onClose({ e: context.e, index: minCollapsedNum + index })} + > + {item.label} + + ))} + > + More({count}) + + ); + } + return ( +

default:

setValue(val)} /> + +

use collapsedItems:

+ +
size control:
+ +
+ + disabled control: + + + + readonly control: + + ( - item.label).join('、')}> - 更多... - - )} value={customizeValue} onChange={(val) => setCustomizeValue(val)} + minCollapsedNum={minCollapsedNum} + collapsedItems={renderCollapsedItems} + size={size} + disabled={disabled} + readonly={readonly} />
); diff --git a/src/tree-select/tree-select.en-US.md b/src/tree-select/tree-select.en-US.md index a6154103eb..277b9a9378 100644 --- a/src/tree-select/tree-select.en-US.md +++ b/src/tree-select/tree-select.en-US.md @@ -11,7 +11,7 @@ autoWidth | Boolean | false | \- | N autofocus | Boolean | false | \- | N borderless | Boolean | false | \- | N clearable | Boolean | false | \- | N -collapsedItems | TElement | - | Typescript:`TNode<{ value: DataOption[]; collapsedSelectedItems: DataOption[]; count: number }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | Typescript:`TNode<{ value: DataOption[]; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N data | Array | [] | Typescript:`Array` | N disabled | Boolean | - | \- | N empty | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N diff --git a/src/tree-select/tree-select.md b/src/tree-select/tree-select.md index 3c7c92bb55..c2dd757895 100644 --- a/src/tree-select/tree-select.md +++ b/src/tree-select/tree-select.md @@ -11,7 +11,7 @@ autoWidth | Boolean | false | 宽度随内容自适应 | N autofocus | Boolean | false | 自动聚焦 | N borderless | Boolean | false | 无边框模式 | N clearable | Boolean | false | 是否允许清空 | N -collapsedItems | TElement | - | 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量。TS 类型:`TNode<{ value: DataOption[]; collapsedSelectedItems: DataOption[]; count: number }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +collapsedItems | TElement | - | 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量。TS 类型:`TNode<{ value: DataOption[]; onClose: (p: { e?: MouseEvent; index: number }) => void; }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N data | Array | [] | 树选择的数据列表。结构:`[{ label: TNode, value: string \| number, text: string, ... }]`,其中 `label` 表示选项呈现的内容,可自定义;`value` 表示选项的唯一值;表示当 `label` 用于选项复杂内容呈现时,`text` 用于搜索功能。
其中 `label` 和 `value` 可以使用 `keys` 属性定义别名。TS 类型:`Array` | N disabled | Boolean | - | 是否禁用组件 | N empty | TNode | - | 当下拉列表为空时显示的内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N diff --git a/src/tree-select/type.ts b/src/tree-select/type.ts index 2cb9268c2e..09cf5acbf3 100644 --- a/src/tree-select/type.ts +++ b/src/tree-select/type.ts @@ -39,9 +39,12 @@ export interface TdTreeSelectProps< */ clearable?: boolean; /** - * 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`collapsedTags` 表示折叠的标签,`count` 表示折叠的数量 + * 多选情况下,用于设置折叠项内容,默认为 `+N`。如果需要悬浮就显示其他内容,可以使用 collapsedItems 自定义。`value` 表示当前存在的所有标签,`onClose` 表示关闭标签时触发的事件s */ - collapsedItems?: TNode<{ value: DataOption[]; collapsedSelectedItems: DataOption[]; count: number }>; + collapsedItems?: TNode<{ + value: DataOption[]; + onClose: (p: { e?: MouseEvent; index: number }) => void; + }>; /** * 树选择的数据列表。结构:`[{ label: TNode, value: string | number, text: string, ... }]`,其中 `label` 表示选项呈现的内容,可自定义;`value` 表示选项的唯一值;表示当 `label` 用于选项复杂内容呈现时,`text` 用于搜索功能。
其中 `label` 和 `value` 可以使用 `keys` 属性定义别名 * @default []