Skip to content

Commit

Permalink
feat(select-input): 新增valueDisplayOptions,可配置在使用valueDisplay时也使用自带的占位…
Browse files Browse the repository at this point in the history
…符与输入回显实现(select也透传) (#3342)
  • Loading branch information
ngyyuusora authored Sep 13, 2023
1 parent 158d34d commit b46b660
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/select-input/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ export default {
valueDisplay: {
type: [String, Function] as PropType<TdSelectInputProps['valueDisplay']>,
},
/** 自定义值呈现的选项,useInputDisplay表示在使用时仍然使用组件自带的输入回显实现,usePlaceholder表示在使用时仍然使用自带的占位符实现 */
valueDisplayOptions: {
type: Object as PropType<TdSelectInputProps['valueDisplayOptions']>,
},
/** 失去焦点时触发,`context.inputValue` 表示输入框的值;`context.tagInputValue` 表示标签输入框的值 */
onBlur: Function as PropType<TdSelectInputProps['onBlur']>,
/** 清空按钮点击时触发 */
Expand Down
8 changes: 8 additions & 0 deletions src/select-input/select-input.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ tagProps | Object | - | Typescript:`TagProps`,[Tag API Documents](./tag?tab=
tips | String / Slot / Function | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
value | String / Number / Boolean / Object / Array / Date | - | Typescript:`SelectInputValue` `type SelectInputValue = string \| number \| boolean \| Date \| Object \| Array<any> \| Array<SelectInputValue>`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts) | N
valueDisplay | String / Slot / Function | - | Typescript:`string \| TNode<{ value: TagInputValue; onClose: (index: number, item?: any) => void }>`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
valueDisplayOptions | Object | - | Custom value display. See `SelectInputValueDisplayOptions` below. TypeScript: `SelectInputValueDisplayOptions` | N
onBlur | Function | | Typescript:`(value: SelectInputValue, context: SelectInputBlurContext) => void`<br/>trigger on blur。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts)。<br/>`type SelectInputBlurContext = PopupVisibleChangeContext & { inputValue: string; tagInputValue?: TagInputValue; }`<br/> | N
onClear | Function | | Typescript:`(context: { e: MouseEvent }) => void`<br/> | N
onEnter | Function | | Typescript:`(value: SelectInputValue, context: { e: KeyboardEvent; inputValue: InputValue; tagInputValue?: TagInputValue }) => void`<br/> | N
Expand All @@ -60,3 +61,10 @@ mouseleave | `(context: { e: MouseEvent })` | trigger on mouseleave
paste | `(context: { e: ClipboardEvent; pasteValue: string })` | \-
popup-visible-change | `(visible: boolean, context: PopupVisibleChangeContext)` | [see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts)。<br/>`import { PopupVisibleChangeContext } from '@Popup'`<br/>
tag-change | `(value: TagInputValue, context: SelectInputChangeContext)` | [see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts)。<br/>`type SelectInputChangeContext = TagInputChangeContext`<br/>

### SelectInputValueDisplayOptions

name | type | default | description | required
-- | -- | -- | -- | --
useInputDisplay | Boolean | false | Use with valueDisplay, enable component's integrated input display when single select(multiple disabled) with filterable enabled. In default need to render valueDisplay via input event. This option is not used when multiple select(multiple enabled), will use component's integrated input display by default. | N
usePlaceholder | Boolean | false | Use with valueDisplay, enable component's integrated placeholder implementation when single select(multiple disabled). In default need to render valueDisplay via param value(while param placeholder not rendered). This option is not used when multiple select(multiple enabled), will use component's integrated placeholder implementation by default. | N
8 changes: 8 additions & 0 deletions src/select-input/select-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ tagProps | Object | - | 透传 Tag 标签组件全部属性。TS 类型:`TagPr
tips | String / Slot / Function | - | 输入框下方提示文本,会根据不同的 `status` 呈现不同的样式。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
value | String / Number / Boolean / Object / Array / Date | - | 全部标签值。值为数组表示多个标签,值为非数组表示单个数值。TS 类型:`SelectInputValue` `type SelectInputValue = string \| number \| boolean \| Date \| Object \| Array<any> \| Array<SelectInputValue>`[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts) | N
valueDisplay | String / Slot / Function | - | 自定义值呈现的全部内容,参数为所有标签的值。TS 类型:`string \| TNode<{ value: TagInputValue; onClose: (index: number, item?: any) => void }>`[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
valueDisplayOptions | Object | - | 自定义值呈现的选项。具体属性请看下方 `SelectInputValueDisplayOptions` 文档。TS 类型:`SelectInputValueDisplayOptions` | N
onBlur | Function | | TS 类型:`(value: SelectInputValue, context: SelectInputBlurContext) => void`<br/>失去焦点时触发,`context.inputValue` 表示输入框的值;`context.tagInputValue` 表示标签输入框的值。[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts)。<br/>`type SelectInputBlurContext = PopupVisibleChangeContext & { inputValue: string; tagInputValue?: TagInputValue; }`<br/> | N
onClear | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>清空按钮点击时触发 | N
onEnter | Function | | TS 类型:`(value: SelectInputValue, context: { e: KeyboardEvent; inputValue: InputValue; tagInputValue?: TagInputValue }) => void`<br/>按键按下 Enter 时触发 | N
Expand All @@ -60,3 +61,10 @@ mouseleave | `(context: { e: MouseEvent })` | 离开输入框时触发
paste | `(context: { e: ClipboardEvent; pasteValue: string })` | 粘贴事件,`pasteValue` 表示粘贴板的内容
popup-visible-change | `(visible: boolean, context: PopupVisibleChangeContext)` | 下拉框显示或隐藏时触发。[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts)。<br/>`import { PopupVisibleChangeContext } from '@Popup'`<br/>
tag-change | `(value: TagInputValue, context: SelectInputChangeContext)` | 值变化时触发,参数 `context.trigger` 表示数据变化的触发来源;`context.index` 指当前变化项的下标;`context.item` 指当前变化项;`context.e` 表示事件参数。[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select-input/type.ts)。<br/>`type SelectInputChangeContext = TagInputChangeContext`<br/>

### SelectInputValueDisplayOptions

名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
useInputDisplay | Boolean | false | 配合valueDisplay使用,单选模式(未启用multiple)时仍然使用组件自带的输入回显实现(启用filterable),默认需自行通过输入事件维护valueDisplay实现。多选模式(启用multiple)时此选项无效,会使用自带的输入回显实现。 | N
usePlaceholder | Boolean | false | 配合valueDisplay使用,单选模式(未启用multiple)时仍然使用自带的占位符实现,默认需自行通过value参数维护valueDisplay实现(同时placeholder参数无效)。多选模式(启用multiple)时此选项无效,会使用自带的占位符实现。 | N
9 changes: 9 additions & 0 deletions src/select-input/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ export interface TdSelectInputProps {
* 自定义值呈现的全部内容,参数为所有标签的值
*/
valueDisplay?: string | TNode<{ value: TagInputValue; onClose: (index: number, item?: any) => void }>;
/**
* 自定义值呈现的选项,useInputDisplay表示在使用时仍然使用组件自带的输入回显实现,usePlaceholder表示在使用时仍然使用自带的占位符实现
*/
valueDisplayOptions?: SelectInputValueDisplayOptions;
/**
* 失去焦点时触发,`context.inputValue` 表示输入框的值;`context.tagInputValue` 表示标签输入框的值
*/
Expand Down Expand Up @@ -211,3 +215,8 @@ export interface SelectInputValueChangeContext {
}

export type SelectInputChangeContext = TagInputChangeContext;

export interface SelectInputValueDisplayOptions {
useInputDisplay: boolean;
usePlaceholder: boolean;
}
44 changes: 41 additions & 3 deletions src/select-input/useSingle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ export default function useSingle(props: TdSelectInputProps, context: SetupConte
const renderSelectSingle = (popupVisible: boolean) => {
const singleValueDisplay = renderTNode('valueDisplay');
const displayedValue = popupVisible && props.allowInput ? inputValue.value : getInputValue(value.value, keys.value);
const prefixContent = [renderTNode('label'), singleValueDisplay];
const prefixContent = renderPrefixContent(singleValueDisplay, popupVisible);
const inputProps = {
...commonInputProps.value,
value: singleValueDisplay ? undefined : displayedValue,
value: renderInputDisplay(singleValueDisplay, displayedValue, popupVisible),
label: prefixContent.length ? () => prefixContent : undefined,
autoWidth: props.autoWidth,
readonly: !props.allowInput || props.readonly,
placeholder: singleValueDisplay ? '' : props.placeholder,
placeholder: renderPlaceholder(singleValueDisplay),
suffixIcon: !disable.value && props.loading ? () => <Loading loading size="small" /> : props.suffixIcon,
showClearIconOnEmpty: Boolean(
props.clearable && (inputValue.value || displayedValue) && !disable.value && !props.readonly,
Expand Down Expand Up @@ -118,6 +118,44 @@ export default function useSingle(props: TdSelectInputProps, context: SetupConte
);
};

const renderPrefixContent = (singleValueDisplay: any, popupVisible: boolean) => {
// 需要隐藏valueDisplay的两个情况
// 1 用户传入usePlaceholder希望使用自带占位符实现,则应在未选择值时隐藏valueDisplay,只展示占位符
// 2 用户传入useInputDisplay希望使用自带输入回显实现,激活选择器浮层时只展示input值(待讨论是否修改为激活后真的输入字符再隐藏valueDisplay,此处实现效果与不使用valueDisplay只使用filterable时不同)
if (singleValueDisplay) {
if (
(props.valueDisplayOptions?.usePlaceholder && !value.value) ||
(props.valueDisplayOptions?.useInputDisplay && popupVisible)
) {
return [renderTNode('label')];
}
}
return [renderTNode('label'), singleValueDisplay];
};

const renderInputDisplay = (singleValueDisplay: any, displayedValue: any, popupVisible: boolean) => {
// 使用valueDisplay插槽时,如用户传入useInputDisplay使用自带输入回显实现,未传则认为用户自行实现。
if (singleValueDisplay)
if (
!props.valueDisplayOptions?.useInputDisplay ||
(props.valueDisplayOptions?.useInputDisplay && !popupVisible)
) {
return undefined;
}
return displayedValue;
};

const renderPlaceholder = (singleValueDisplay: any) => {
// 使用valueDisplay插槽时,如用户传入usePlaceholder使用自带占位符实现,未传则认为用户自行实现。
// 如果当前存在value(对应直接使用组件和select组件调用时),不显示占位符。
if (singleValueDisplay) {
if (!props.valueDisplayOptions?.usePlaceholder || (props.valueDisplayOptions?.usePlaceholder && value.value)) {
return '';
}
}
return props.placeholder;
};

return {
inputRef,
commonInputProps,
Expand Down
4 changes: 4 additions & 0 deletions src/select/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ export default {
valueDisplay: {
type: [String, Function] as PropType<TdSelectProps['valueDisplay']>,
},
/** 自定义值呈现的选项,useInputDisplay表示在使用时仍然使用组件自带的输入回显实现,usePlaceholder表示在使用时仍然使用自带的占位符实现 */
valueDisplayOptions: {
type: Object as PropType<TdSelectProps['valueDisplayOptions']>,
},
/** 用于控制选中值的类型。假设数据选项为:`[{ label: '姓名', value: 'name' }]`,value 表示值仅返回数据选项中的 value, object 表示值返回全部数据。 */
valueType: {
type: String as PropType<TdSelectProps['valueType']>,
Expand Down
8 changes: 8 additions & 0 deletions src/select/select.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ tips | String / Slot / Function | - | Typescript:`string \| TNode`。[see more
value | String / Number / Boolean / Object / Array | - | `v-model` and `v-model:value` is supported。Typescript:`SelectValue` `type SelectValue<T extends SelectOption = SelectOption> = string \| number \| boolean \| T \| Array<SelectValue<T>>`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select/type.ts) | N
defaultValue | String / Number / Boolean / Object / Array | - | uncontrolled property。Typescript:`SelectValue` `type SelectValue<T extends SelectOption = SelectOption> = string \| number \| boolean \| T \| Array<SelectValue<T>>`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select/type.ts) | N
valueDisplay | String / Slot / Function | - | `MouseEvent<SVGElement>`。Typescript:`string \| TNode<{ value: SelectValue; onClose: (index: number) => void; displayValue?: SelectValue }>`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
valueDisplayOptions | Object | - | Custom select item display. See `SelectInputValueDisplayOptions` below. TypeScript: `SelectInputValueDisplayOptions` | N
valueType | String | value | options: value/object | N
onBlur | Function | | Typescript:`(context: { value: SelectValue; e: FocusEvent \| KeyboardEvent }) => void`<br/> | N
onChange | Function | | Typescript:`(value: SelectValue, context: { option?: T, selectedOptions: T[], trigger: SelectValueChangeTrigger; e?: MouseEvent \| KeyboardEvent }) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select/type.ts)。<br/>`type SelectValueChangeTrigger = 'clear' \| 'tag-remove' \| 'backspace' \| 'check' \| 'uncheck' \| 'default'`<br/> | N
Expand Down Expand Up @@ -103,3 +104,10 @@ isFixedRowHeight | Boolean | false | \- | N
rowHeight | Number | - | \- | N
threshold | Number | 100 | \- | N
type | String | - | required。options: lazy/virtual | Y

### SelectInputValueDisplayOptions

name | type | default | description | required
-- | -- | -- | -- | --
useInputDisplay | Boolean | false | Use with valueDisplay, enable component's integrated input display when single select(multiple disabled) with filterable enabled. In default need to render valueDisplay via input event. This option is not used when multiple select(multiple enabled), will use component's integrated input display by default. | N
usePlaceholder | Boolean | false | Use with valueDisplay, enable component's integrated placeholder implementation when single select(multiple disabled). In default need to render valueDisplay via param value(while param placeholder not rendered). This option is not used when multiple select(multiple enabled), will use component's integrated placeholder implementation by default. | N
8 changes: 8 additions & 0 deletions src/select/select.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ tips | String / Slot / Function | - | 输入框下方提示文本,会根据不
value | String / Number / Boolean / Object / Array | - | 选中值。支持语法糖 `v-model``v-model:value`。TS 类型:`SelectValue` `type SelectValue<T extends SelectOption = SelectOption> = string \| number \| boolean \| T \| Array<SelectValue<T>>`[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select/type.ts) | N
defaultValue | String / Number / Boolean / Object / Array | - | 选中值。非受控属性。TS 类型:`SelectValue` `type SelectValue<T extends SelectOption = SelectOption> = string \| number \| boolean \| T \| Array<SelectValue<T>>`[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select/type.ts) | N
valueDisplay | String / Slot / Function | - | 自定义选中项呈现的内容。TS 类型:`string \| TNode<{ value: SelectValue; onClose: (index: number) => void; displayValue?: SelectValue }>`[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
valueDisplayOptions | Object | - | 自定义选中项呈现的选项。具体属性请看下方 `SelectInputValueDisplayOptions` 文档。TS 类型:`SelectInputValueDisplayOptions` | N
valueType | String | value | 用于控制选中值的类型。假设数据选项为:`[{ label: '姓名', value: 'name' }]`,value 表示值仅返回数据选项中的 value, object 表示值返回全部数据。。可选项:value/object | N
onBlur | Function | | TS 类型:`(context: { value: SelectValue; e: FocusEvent \| KeyboardEvent }) => void`<br/>输入框失去焦点时触发 | N
onChange | Function | | TS 类型:`(value: SelectValue, context: { option?: T, selectedOptions: T[], trigger: SelectValueChangeTrigger; e?: MouseEvent \| KeyboardEvent }) => void`<br/>选中值变化时触发。`context.trigger` 表示触发变化的来源;`context.selectedOptions` 表示选中值的完整对象,数组长度一定和 `value` 相同;`context.option` 表示当前操作的选项,不一定存在。[详细类型定义](https://github.com/Tencent/tdesign-vue-next/tree/develop/src/select/type.ts)。<br/>`type SelectValueChangeTrigger = 'clear' \| 'tag-remove' \| 'backspace' \| 'check' \| 'uncheck' \| 'default'`<br/> | N
Expand Down Expand Up @@ -103,3 +104,10 @@ isFixedRowHeight | Boolean | false | 表示每行内容是否同一个固定高
rowHeight | Number | - | 行高,不会给`<tr>`元素添加样式高度,仅作为滚动时的行高参考。一般情况不需要设置该属性。如果设置,可尽量将该属性设置为每行平均高度,从而使得滚动过程更加平滑 | N
threshold | Number | 100 | 启动虚拟滚动的阈值。为保证组件收益最大化,当数据量小于阈值 `scroll.threshold` 时,无论虚拟滚动的配置是否存在,组件内部都不会开启虚拟滚动 | N
type | String | - | 必需。滚动加载类型,有两种:懒加载和虚拟滚动。<br />值为 `lazy` ,表示滚动时会进行懒加载,非可视区域内的内容将不会默认渲染,直到该内容可见时,才会进行渲染,并且已渲染的内容滚动到不可见时,不会被销毁;<br />值为`virtual`时,表示会进行虚拟滚动,无论滚动条滚动到哪个位置,同一时刻,仅渲染该可视区域内的内容,当需要展示的数据量较大时,建议开启该特性。可选项:lazy/virtual | Y

### SelectInputValueDisplayOptions

名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
useInputDisplay | Boolean | false | 配合valueDisplay使用,单选模式(未启用multiple)时仍然使用组件自带的输入回显实现(启用filterable),默认需自行通过输入事件维护valueDisplay实现。多选模式(启用multiple)时此选项无效,会使用自带的输入回显实现。 | N
usePlaceholder | Boolean | false | 配合valueDisplay使用,单选模式(未启用multiple)时仍然使用自带的占位符实现,默认需自行通过value参数维护valueDisplay实现(同时placeholder参数无效)。多选模式(启用multiple)时此选项无效,会使用自带的占位符实现。 | N
1 change: 1 addition & 0 deletions src/select/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ export default defineComponent({
minCollapsedNum: props.minCollapsedNum,
autofocus: props.autofocus,
suffix: props.suffix,
valueDisplayOptions: props.valueDisplayOptions,
}}
ref={selectInputRef}
class={COMPONENT_NAME.value}
Expand Down
Loading

0 comments on commit b46b660

Please sign in to comment.