feat: add optionLabel slot

pull/5223/head
tangjinzhou 2022-01-27 15:12:15 +08:00
parent 5c23d97daf
commit 53fa27771d
5 changed files with 29 additions and 16 deletions

View File

@ -14,10 +14,10 @@ function isSelectOptionOrSelectOptGroup(child: any): boolean {
} }
const autoCompleteProps = { const autoCompleteProps = {
...selectProps(), ...omit(selectProps(), ['loading', 'mode', 'optionLabelProp', 'labelInValue']),
dataSource: PropTypes.array, dataSource: PropTypes.array,
dropdownMenuStyle: PropTypes.style, dropdownMenuStyle: PropTypes.style,
optionLabelProp: PropTypes.string, // optionLabelProp: PropTypes.string,
dropdownMatchSelectWidth: { type: [Number, Boolean], default: true }, dropdownMatchSelectWidth: { type: [Number, Boolean], default: true },
}; };
@ -38,7 +38,7 @@ const AutoComplete = defineComponent({
choiceTransitionName: PropTypes.string.def('zoom'), choiceTransitionName: PropTypes.string.def('zoom'),
autofocus: PropTypes.looseBool, autofocus: PropTypes.looseBool,
backfill: PropTypes.looseBool, backfill: PropTypes.looseBool,
optionLabelProp: PropTypes.string.def('children'), // optionLabelProp: PropTypes.string.def('children'),
filterOption: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.func]).def(false), filterOption: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.func]).def(false),
defaultActiveFirstOption: PropTypes.looseBool.def(true), defaultActiveFirstOption: PropTypes.looseBool.def(true),
}, },
@ -121,19 +121,22 @@ const AutoComplete = defineComponent({
} }
} }
const selectProps = { const selectProps = omit(
...omit(props, ['dataSource', 'optionLabelProp']), {
...attrs, ...props,
mode: Select.SECRET_COMBOBOX_MODE_DO_NOT_USE, ...(attrs as any),
// optionLabelProp, mode: Select.SECRET_COMBOBOX_MODE_DO_NOT_USE,
getInputElement, // optionLabelProp,
notFoundContent, getInputElement,
// placeholder: '', notFoundContent,
class: cls, // placeholder: '',
ref: selectRef, class: cls,
}; ref: selectRef,
},
['dataSource', 'loading'],
);
return ( return (
<Select {...selectProps} v-slots={{ option: slots.option }}> <Select {...selectProps} v-slots={omit(slots, ['default', 'dataSource', 'options'])}>
{optionChildren} {optionChildren}
</Select> </Select>
); );

View File

@ -70,6 +70,7 @@ const Select = defineComponent({
'placeholder', 'placeholder',
'tagRender', 'tagRender',
'maxTagPlaceholder', 'maxTagPlaceholder',
'optionLabel', // donot use, maybe remove it
], ],
setup(props, { attrs, emit, slots, expose }) { setup(props, { attrs, emit, slots, expose }) {
const selectRef = ref<BaseSelectRef>(); const selectRef = ref<BaseSelectRef>();
@ -206,6 +207,7 @@ const Select = defineComponent({
transitionName={transitionName.value} transitionName={transitionName.value}
children={slots.default?.()} children={slots.default?.()}
tagRender={props.tagRender || slots.tagRender} tagRender={props.tagRender || slots.tagRender}
optionLabelRender={slots.optionLabel}
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder} maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
></RcSelect> ></RcSelect>
); );

View File

@ -157,6 +157,7 @@ export const baseSelectPropsWithoutPrivate = () => {
return { return {
showSearch: { type: Boolean, default: undefined }, showSearch: { type: Boolean, default: undefined },
tagRender: { type: Function as PropType<(props: CustomTagProps) => any> }, tagRender: { type: Function as PropType<(props: CustomTagProps) => any> },
optionLabelRender: { type: Function as PropType<(option: Record<string, any>) => any> },
direction: { type: String as PropType<'ltr' | 'rtl'> }, direction: { type: String as PropType<'ltr' | 'rtl'> },
// MISC // MISC
@ -664,6 +665,7 @@ export default defineComponent({
// Tags // Tags
tokenSeparators, tokenSeparators,
tagRender, tagRender,
optionLabelRender,
// Events // Events
onPopupScroll, onPopupScroll,
@ -830,6 +832,7 @@ export default defineComponent({
mode={mode} mode={mode}
activeDescendantId={activeDescendantId} activeDescendantId={activeDescendantId}
tagRender={tagRender} tagRender={tagRender}
optionLabelRender={optionLabelRender}
values={displayValues} values={displayValues}
open={mergedOpen.value} open={mergedOpen.value}
onToggleOpen={onToggleOpen} onToggleOpen={onToggleOpen}

View File

@ -9,6 +9,7 @@ import useInjectLegacySelectContext from '../../vc-tree-select/LegacyContext';
interface SelectorProps extends InnerSelectorProps { interface SelectorProps extends InnerSelectorProps {
inputElement: VueNode; inputElement: VueNode;
activeValue: string; activeValue: string;
optionLabelRender: Function;
} }
const props = { const props = {
inputElement: PropTypes.any, inputElement: PropTypes.any,
@ -28,6 +29,7 @@ const props = {
tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
activeValue: PropTypes.string, activeValue: PropTypes.string,
backfill: PropTypes.looseBool, backfill: PropTypes.looseBool,
optionLabelRender: PropTypes.func,
onInputChange: PropTypes.func, onInputChange: PropTypes.func,
onInputPaste: PropTypes.func, onInputPaste: PropTypes.func,
onInputKeyDown: PropTypes.func, onInputKeyDown: PropTypes.func,
@ -98,6 +100,7 @@ const SingleSelector = defineComponent<SelectorProps>({
activeDescendantId, activeDescendantId,
open, open,
tabindex, tabindex,
optionLabelRender,
onInputKeyDown, onInputKeyDown,
onInputMouseDown, onInputMouseDown,
onInputChange, onInputChange,
@ -125,7 +128,7 @@ const SingleSelector = defineComponent<SelectorProps>({
// titleNode = treeSelectContext.value.slots.titleRender(item.option?.data || {}); // titleNode = treeSelectContext.value.slots.titleRender(item.option?.data || {});
// } // }
} else { } else {
titleNode = item?.label; titleNode = optionLabelRender && item ? optionLabelRender(item.option) : item?.label;
} }
return ( return (
<> <>

View File

@ -46,6 +46,7 @@ export interface SelectorProps {
maxTagTextLength?: number; maxTagTextLength?: number;
maxTagPlaceholder?: VueNode | ((omittedValues: DisplayValueType[]) => VueNode); maxTagPlaceholder?: VueNode | ((omittedValues: DisplayValueType[]) => VueNode);
tagRender?: (props: CustomTagProps) => VueNode; tagRender?: (props: CustomTagProps) => VueNode;
optionLabelRender?: (props: Record<string, any>) => VueNode;
/** Check if `tokenSeparators` contains `\n` or `\r\n` */ /** Check if `tokenSeparators` contains `\n` or `\r\n` */
tokenWithEnter?: boolean; tokenWithEnter?: boolean;
@ -100,6 +101,7 @@ const Selector = defineComponent<SelectorProps>({
maxTagTextLength: PropTypes.number, maxTagTextLength: PropTypes.number,
maxTagPlaceholder: PropTypes.any, maxTagPlaceholder: PropTypes.any,
tagRender: PropTypes.func, tagRender: PropTypes.func,
optionLabelRender: PropTypes.func,
/** Check if `tokenSeparators` contains `\n` or `\r\n` */ /** Check if `tokenSeparators` contains `\n` or `\r\n` */
tokenWithEnter: PropTypes.looseBool, tokenWithEnter: PropTypes.looseBool,