Skip to content

Commit 9dc016a

Browse files
committed
fix: valueType='object'
1 parent ff04816 commit 9dc016a

File tree

4 files changed

+49
-61
lines changed

4 files changed

+49
-61
lines changed

packages/components/select/base/PopupContent.tsx

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { isEqual } from 'lodash-es';
66
import useConfig from '../../hooks/useConfig';
77
import { useLocaleReceiver } from '../../locale/LocalReceiver';
88
import usePanelVirtualScroll from '../hooks/usePanelVirtualScroll';
9-
import { getSelectValueArr } from '../util/helper';
9+
import { getKeyMapping, getSelectValueArr } from '../util/helper';
1010
import Option, { type SelectOptionProps } from './Option';
1111
import OptionGroup from './OptionGroup';
1212

@@ -83,12 +83,12 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
8383
scroll: propsScroll,
8484
hoverIndex,
8585
} = props;
86+
const { classPrefix } = useConfig();
8687

87-
// 国际化文本初始化
8888
const [local, t] = useLocaleReceiver('select');
8989
const emptyText = t(local.empty);
90-
const popupContentRef = useRef<HTMLDivElement>(null);
9190

91+
const popupContentRef = useRef<HTMLDivElement>(null);
9292
popupContentRef.current = getPopupInstance();
9393

9494
const { visibleData, handleRowMounted, isVirtual, panelStyle, cursorStyle } = usePanelVirtualScroll({
@@ -98,6 +98,9 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
9898
size,
9999
});
100100

101+
const isObjectType = useMemo(() => valueType === 'object', [valueType]);
102+
const { valueKey, labelKey } = useMemo(() => getKeyMapping(keys), [keys]);
103+
101104
const optionsExcludedCheckAll = useMemo(() => {
102105
const uniqueOptions = {};
103106
propsOptions?.forEach((option: SelectOption) => {
@@ -114,36 +117,18 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
114117
return Object.values(uniqueOptions);
115118
}, [propsOptions]);
116119

117-
const { classPrefix } = useConfig();
118-
if (!children && !propsOptions) {
119-
return null;
120-
}
121-
122120
const onSelect: SelectOptionProps['onSelect'] = (selectedValue, { label, selected, event, restData }) => {
123-
const isValObj = valueType === 'object';
124-
let objVal = {};
125-
if (isValObj) {
126-
objVal = { ...restData };
127-
if (!keys?.label) {
128-
Object.assign(objVal, { label });
129-
}
130-
if (!keys?.value) {
131-
Object.assign(objVal, { value: selectedValue });
132-
}
133-
}
134-
135-
if (!Object.keys(objVal).length) {
136-
Object.assign(objVal, { [keys?.label || 'label']: label, [keys?.value || 'value']: selectedValue });
137-
}
121+
const objVal = {
122+
...(isObjectType ? { ...restData } : {}),
123+
[labelKey]: label,
124+
[valueKey]: selectedValue,
125+
};
138126

139127
if (multiple) {
140-
// calc multiple select values
141128
const values = getSelectValueArr(value, selectedValue, selected, valueType, keys, objVal);
142129
onChange(values, { label, value: selectedValue, e: event, trigger: selected ? 'uncheck' : 'check' });
143130
} else {
144-
// calc single select value
145131
const selectVal = valueType === 'object' ? objVal : selectedValue;
146-
147132
if (!isEqual(value, selectVal)) {
148133
onChange(selectVal, { label, value: selectVal, e: event, trigger: 'check' });
149134
}
@@ -159,6 +144,9 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
159144
return child;
160145
});
161146

147+
const isEmpty =
148+
(Array.isArray(childrenWithProps) && !childrenWithProps.length) || (propsOptions && propsOptions.length === 0);
149+
162150
// 渲染 options
163151
const renderOptions = (options: SelectOption[], startIndex = 0) => {
164152
if (options) {
@@ -225,9 +213,6 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
225213
return <ul className={`${classPrefix}-select__list`}>{childrenWithProps}</ul>;
226214
};
227215

228-
const isEmpty =
229-
(Array.isArray(childrenWithProps) && !childrenWithProps.length) || (propsOptions && propsOptions.length === 0);
230-
231216
const renderPanel = (renderedOptions: SelectOption[], extraStyle?: React.CSSProperties) => (
232217
<div
233218
ref={ref}
@@ -245,6 +230,7 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
245230
{!loading && !isEmpty && renderOptions(renderedOptions)}
246231
</div>
247232
);
233+
248234
if (isVirtual) {
249235
return (
250236
<>
@@ -258,6 +244,8 @@ const PopupContent = React.forwardRef<HTMLDivElement, SelectPopupProps>((props,
258244
);
259245
}
260246

247+
if (!children && !propsOptions) return null;
248+
261249
return (
262250
<>
263251
{panelTopContent}

packages/components/select/base/Select.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,17 @@ const Select = forwardRefWithStatics(
291291
};
292292

293293
const { hoverIndex, handleKeyDown } = useKeyboardControl({
294-
keys,
295294
displayOptions: flattenedOptions as TdOptionProps[],
295+
keys,
296+
innerPopupVisible,
296297
max,
297298
multiple,
299+
selectInputRef,
300+
value,
301+
valueType,
298302
handlePopupVisibleChange,
299-
innerPopupVisible,
300303
handleChange,
301-
value,
302304
onCheckAllChange,
303-
selectInputRef,
304305
toggleIsScrolling,
305306
});
306307

packages/components/select/hooks/useKeyboardControl.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import { getKeyMapping, getSelectValueArr } from '../util/helper';
66
import type { SelectOption, SelectValue, SelectValueChangeTrigger, TdOptionProps, TdSelectProps } from '../type';
77

88
export type useKeyboardControlType = {
9-
keys: TdSelectProps['keys'];
109
max: number;
1110
multiple: boolean;
11+
keys: TdSelectProps['keys'];
1212
value: SelectValue<SelectOption>;
13+
valueType: TdSelectProps['valueType'];
1314
handleChange: (
1415
value: SelectValue,
1516
context: {
@@ -26,10 +27,11 @@ export type useKeyboardControlType = {
2627
};
2728

2829
export default function useKeyboardControl({
29-
keys,
3030
max,
3131
multiple,
32+
keys,
3233
value,
34+
valueType,
3335
handleChange,
3436
innerPopupVisible,
3537
handlePopupVisibleChange,
@@ -43,6 +45,7 @@ export default function useKeyboardControl({
4345
const isCheckAll = useRef(false);
4446
const [hoverIndex, changeHoverIndex] = useState(-1);
4547

48+
const isObjectType = useMemo(() => valueType === 'object', [valueType]);
4649
const { valueKey, disabledKey } = useMemo(() => getKeyMapping(keys), [keys]);
4750

4851
useEffect(() => {
@@ -111,46 +114,39 @@ export default function useKeyboardControl({
111114
changeHoverIndex(newIndex);
112115
handleKeyboardScroll(newIndex);
113116
break;
114-
case 'Enter':
115-
if (!innerPopupVisible) {
116-
handlePopupVisibleChange(true, { e });
117-
break;
117+
case 'Enter': {
118+
if (hoverIndex === -1) return;
119+
120+
if (displayOptions[hoverIndex].checkAll) {
121+
onCheckAllChange(!isCheckAll.current, e);
122+
return;
118123
}
119124

120-
if (hoverIndex === -1) return;
125+
const selectedOptions = displayOptions[hoverIndex];
126+
const optionValue = isObjectType ? selectedOptions : selectedOptions[valueKey];
121127

122128
if (!multiple) {
123-
const selectedOptions = displayOptions[hoverIndex];
124-
125-
if (selectedOptions)
126-
handleChange(selectedOptions[valueKey], {
127-
trigger: 'check',
128-
e,
129-
});
129+
handleChange(optionValue, {
130+
trigger: 'check',
131+
e,
132+
});
130133
handlePopupVisibleChange(false, { e });
131134
changeHoverIndex(-1);
132135
handleKeyboardScroll(0);
133136
} else {
134-
if (displayOptions[hoverIndex].checkAll) {
135-
onCheckAllChange(!isCheckAll.current, e);
136-
return;
137-
}
138-
139-
const optionValue = displayOptions[hoverIndex]?.[valueKey];
140-
if (!optionValue) return;
141-
142-
const newValue = value as Array<SelectValue>;
143-
const valueIndex = newValue.indexOf(optionValue);
137+
const valueIndex = (value as SelectValue[]).indexOf(optionValue);
144138
const isSelected = valueIndex > -1;
145-
const values = getSelectValueArr(value, optionValue, isSelected);
139+
const values = getSelectValueArr(value, optionValue, isSelected, valueType, keys, selectedOptions);
146140

147141
if (max > 0 && values.length > max) return; // 如果已选达到最大值 则不处理
142+
148143
handleChange(values, {
149144
trigger: !isSelected ? 'check' : 'uncheck',
150145
e,
151146
});
152147
}
153148
break;
149+
}
154150
case 'Escape':
155151
handlePopupVisibleChange(false, { e });
156152
changeHoverIndex(-1);

packages/components/select/util/helper.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ export const getMultipleTags = (values: SelectValue[], keys: SelectKeysType) =>
193193
return tags;
194194
};
195195

196+
/**
197+
* 计算多选时的 `value` 数组
198+
*/
196199
export const getSelectValueArr = (
197200
values: SelectValue | SelectValue[],
198201
activeValue: SelectValue,
@@ -207,10 +210,10 @@ export const getSelectValueArr = (
207210

208211
if (Array.isArray(values)) {
209212
let currentValues = [...values];
210-
const isValueObj = valueType === 'object';
213+
const isObjectType = valueType === 'object';
211214
if (selected) {
212215
currentValues = currentValues.filter((item: SelectLabeledValue) => {
213-
if (isValueObj) {
216+
if (isObjectType) {
214217
if (isPlainObject(activeValue)) {
215218
return get(item, valueKey) !== get(activeValue, valueKey);
216219
}
@@ -219,7 +222,7 @@ export const getSelectValueArr = (
219222
return item !== activeValue;
220223
});
221224
} else {
222-
const item = isValueObj ? objVal : activeValue;
225+
const item = isObjectType ? objVal : activeValue;
223226

224227
currentValues.push(item as SelectValue);
225228
}

0 commit comments

Comments
 (0)