From 0cb41bc829866648d33152afdce25d71a3d9c48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?w=C5=AB=20y=C4=81ng?= Date: Thu, 19 Dec 2024 17:24:46 +0800 Subject: [PATCH] fix(Select): fix object type select all and callback params (#3287) * fix(Select): fix object type selectall and callback params * chore: comment * chore: comment --- src/select/base/PopupContent.tsx | 5 ++-- src/select/base/Select.tsx | 51 ++++++++++++++++++++++++-------- src/select/util/helper.ts | 17 +++++++++-- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/select/base/PopupContent.tsx b/src/select/base/PopupContent.tsx index 2bd4a10714..caaaae7182 100644 --- a/src/select/base/PopupContent.tsx +++ b/src/select/base/PopupContent.tsx @@ -30,6 +30,7 @@ interface SelectPopupProps value: SelectValue, context?: { label?: string | number; + value?: SelectValue; restData?: Record; e: React.MouseEvent; trigger: SelectValueChangeTrigger; @@ -109,12 +110,12 @@ const PopupContent = React.forwardRef((props, if (multiple) { // calc multiple select values const values = getSelectValueArr(value, selectedValue, selected, valueType, keys, objVal); - onChange(values, { label, e: event, trigger: 'check' }); + onChange(values, { label, value: selectedValue, e: event, trigger: 'check' }); } else { // calc single select value const selectVal = valueType === 'object' ? objVal : selectedValue; - onChange(selectVal, { label, e: event, trigger: 'check' }); + onChange(selectVal, { label, value: selectVal, e: event, trigger: 'check' }); setShowPopup(!showPopup); } }; diff --git a/src/select/base/Select.tsx b/src/select/base/Select.tsx index 7bebf676ee..e0e3f975b8 100644 --- a/src/select/base/Select.tsx +++ b/src/select/base/Select.tsx @@ -28,7 +28,7 @@ import Option from './Option'; import OptionGroup from './OptionGroup'; import PopupContent from './PopupContent'; import Tag from '../../tag'; -import { TdSelectProps, TdOptionProps, SelectOption, SelectValueChangeTrigger } from '../type'; +import { TdSelectProps, TdOptionProps, SelectOption, SelectValueChangeTrigger, SelectValue } from '../type'; import { StyledProps } from '../../common'; import { selectDefaultProps } from '../defaultProps'; import { PopupVisibleChangeContext } from '../../popup'; @@ -157,7 +157,7 @@ const Select = forwardRefWithStatics( const values = getSelectValueArr(value, value[closest], true, valueType, keys); // 处理onChange回调中的selectedOptions参数 - const currentSelectedOptions = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); + const { currentSelectedOptions } = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); onChange(values, { e, trigger, selectedOptions: currentSelectedOptions }); return; } @@ -172,7 +172,7 @@ const Select = forwardRefWithStatics( e?.stopPropagation?.(); const values = getSelectValueArr(value, value[index], true, valueType, keys); // 处理onChange回调中的selectedOptions参数 - const currentSelectedOptions = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); + const { currentSelectedOptions } = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); onChange(values, { e, trigger, selectedOptions: currentSelectedOptions }); if (isFunction(onRemove)) { @@ -194,19 +194,22 @@ const Select = forwardRefWithStatics( const values = currentOptions .filter((option) => !option.checkAll && !option.disabled) - .map((option) => option[keys?.value || 'value']); + .map((option) => (valueType === 'object' ? option : option[keys?.value || 'value'])); - const selectableOptions = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); + const { currentSelectedOptions } = getSelectedOptions(values, multiple, valueType, keys, tmpPropOptions); const checkAllValue = - !checkAll && selectableOptions.length !== (props.value as Array)?.length ? selectableOptions : []; + !checkAll && currentSelectedOptions.length !== (props.value as Array)?.length + ? currentSelectedOptions + : []; + onChange?.(checkAllValue, { e, trigger: checkAll ? 'check' : 'uncheck', selectedOptions: checkAllValue }); }; // 选中 Popup 某项 const handleChange = ( value: string | number | Array>, - context: { e: React.MouseEvent; trigger: SelectValueChangeTrigger }, + context: { e: React.MouseEvent; trigger: SelectValueChangeTrigger; value?: SelectValue }, ) => { if (multiple) { !reserveKeyword && inputValue && onInputChange('', { e: context.e, trigger: 'change' }); @@ -217,9 +220,22 @@ const Select = forwardRefWithStatics( } } // 处理onChange回调中的selectedOptions参数 - const currentSelectedOptions = getSelectedOptions(value, multiple, valueType, keys, tmpPropOptions); - - onChange?.(value, { ...context, selectedOptions: currentSelectedOptions }); + const selectedValue = multiple ? context.value : value; + const { currentSelectedOptions, currentOption } = getSelectedOptions( + value, + multiple, + valueType, + keys, + tmpPropOptions, + selectedValue, + ); + + onChange?.(value, { + e: context.e, + trigger: context.trigger, + selectedOptions: currentSelectedOptions, + option: currentOption, + }); }; // 处理filter逻辑 @@ -352,8 +368,19 @@ const Select = forwardRefWithStatics( 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' }); + const { currentSelectedOptions } = getSelectedOptions( + values, + multiple, + valueType, + keys, + tmpPropOptions, + value, + ); + onChange(values, { + e, + selectedOptions: currentSelectedOptions, + trigger: 'uncheck', + }); tagProps?.onClose?.({ e }); onRemove?.({ diff --git a/src/select/util/helper.ts b/src/select/util/helper.ts index 0beb1940e7..4d51d493ad 100644 --- a/src/select/util/helper.ts +++ b/src/select/util/helper.ts @@ -4,7 +4,7 @@ import get from 'lodash/get'; import OptionGroup from '../base/OptionGroup'; import Option from '../base/Option'; -import { SelectValue, TdOptionProps, SelectKeysType, TdSelectProps } from '../type'; +import { SelectValue, TdOptionProps, SelectKeysType, TdSelectProps, SelectOption } from '../type'; type SelectLabeledValue = Required>; @@ -192,17 +192,28 @@ export const getSelectedOptions = ( valueType: TdSelectProps['valueType'], keys: SelectKeysType, tmpPropOptions: Array, + selectedValue?: SelectValue, ) => { const isObjectType = valueType === 'object'; + // 当前所有选中的选项 let currentSelectedOptions = []; + // 当前选中的选项 + let currentOption: SelectOption; if (multiple) { currentSelectedOptions = isObjectType - ? (value as Array) + ? (value as Array) : tmpPropOptions?.filter?.((v) => (value as Array).includes?.(v[keys?.value || 'value'])); + currentOption = isObjectType + ? (value as Array).find((v) => v[keys?.value || 'value'] === selectedValue) + : currentSelectedOptions.find((option) => option[keys?.value || 'value'] === selectedValue); } else { currentSelectedOptions = isObjectType ? [value] : tmpPropOptions?.filter?.((v) => value === v[keys?.value || 'value']) || []; + currentOption = isObjectType + ? value + : currentSelectedOptions.find((option) => option[keys?.value || 'value'] === selectedValue); } - return currentSelectedOptions; + + return { currentSelectedOptions, currentOption }; };