Skip to content

Commit ff04816

Browse files
committed
fix: custom keys
1 parent b1bdb6d commit ff04816

File tree

3 files changed

+38
-35
lines changed

3 files changed

+38
-35
lines changed

packages/components/select/base/Select.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ const Select = forwardRefWithStatics(
100100
} = props;
101101

102102
const [value, onChange] = useControlled(props, 'value', props.onChange);
103+
104+
const { valueKey, labelKey, disabledKey } = useMemo(() => getKeyMapping(keys), [keys]);
105+
103106
const selectInputRef = useRef(null);
104107
const { classPrefix } = useConfig();
105108
const { overlayClassName, onScroll, onScrollToBottom, ...restPopupProps } = popupProps || {};
@@ -124,9 +127,7 @@ const Select = forwardRefWithStatics(
124127
const isDisabledCheckAll = (opt: TdOptionProps) => opt.checkAll && opt.disabled;
125128
if (!multiple || currentOptions.some((opt) => !isSelectOptionGroup(opt) && isDisabledCheckAll(opt))) return;
126129

127-
const { valueKey } = getKeyMapping(keys);
128130
const isObjectType = valueType === 'object';
129-
130131
const enabledOptions: SelectOption[] = [];
131132

132133
currentOptions.forEach((option) => {
@@ -184,16 +185,15 @@ const Select = forwardRefWithStatics(
184185
selectedOptions: currentSelectedOptions,
185186
});
186187
},
187-
[currentOptions, keys, multiple, onChange, value, valueToOption, valueType],
188+
[currentOptions, keys, multiple, value, valueKey, valueToOption, valueType, onChange],
188189
);
189190

190191
const selectedLabel = useMemo(() => {
191-
const { labelKey } = getKeyMapping(keys);
192192
if (multiple) {
193193
return selectedOptions.map((selectedOption) => get(selectedOption || {}, labelKey) || '');
194194
}
195195
return get(selectedOptions[0] || {}, labelKey) || undefined;
196-
}, [selectedOptions, keys, multiple]);
196+
}, [multiple, selectedOptions, labelKey]);
197197

198198
// 可以根据触发来源,自由定制标签变化时的筛选器行为
199199
const onTagChange = (_currentTags: SelectInputValue, context) => {
@@ -291,6 +291,7 @@ const Select = forwardRefWithStatics(
291291
};
292292

293293
const { hoverIndex, handleKeyDown } = useKeyboardControl({
294+
keys,
294295
displayOptions: flattenedOptions as TdOptionProps[],
295296
max,
296297
multiple,
@@ -440,7 +441,6 @@ const Select = forwardRefWithStatics(
440441
}
441442
return ({ value: val }) =>
442443
val.slice(0, minCollapsedNum ? minCollapsedNum : val.length).map((_, index: number) => {
443-
const { valueKey, labelKey, disabledKey } = getKeyMapping(keys);
444444
const targetVal = get(selectedOptions[index], valueKey);
445445
const targetLabel = get(selectedOptions[index], labelKey);
446446
const targetOption = valueToOption[targetVal];

packages/components/select/hooks/useKeyboardControl.ts

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { useEffect, useRef, useState } from 'react';
1+
import { useEffect, useMemo, useRef, useState } from 'react';
22

33
import useConfig from '../../hooks/useConfig';
4-
import { getSelectValueArr } from '../util/helper';
4+
import { getKeyMapping, getSelectValueArr } from '../util/helper';
55

6-
import type { SelectOption, SelectValue, SelectValueChangeTrigger, TdOptionProps } from '../type';
6+
import type { SelectOption, SelectValue, SelectValueChangeTrigger, TdOptionProps, TdSelectProps } from '../type';
77

88
export type useKeyboardControlType = {
9+
keys: TdSelectProps['keys'];
910
max: number;
1011
multiple: boolean;
1112
value: SelectValue<SelectOption>;
@@ -25,6 +26,7 @@ export type useKeyboardControlType = {
2526
};
2627

2728
export default function useKeyboardControl({
29+
keys,
2830
max,
2931
multiple,
3032
value,
@@ -36,11 +38,26 @@ export default function useKeyboardControl({
3638
selectInputRef,
3739
toggleIsScrolling,
3840
}: useKeyboardControlType) {
39-
const [hoverIndex, changeHoverIndex] = useState(-1);
40-
4141
const { classPrefix } = useConfig();
42-
// 全选判断
42+
4343
const isCheckAll = useRef(false);
44+
const [hoverIndex, changeHoverIndex] = useState(-1);
45+
46+
const { valueKey, disabledKey } = useMemo(() => getKeyMapping(keys), [keys]);
47+
48+
useEffect(() => {
49+
if (!innerPopupVisible) {
50+
changeHoverIndex(-1);
51+
} else if (!multiple) {
52+
// 单选时,hoverIndex 初始值为选中值的索引
53+
const index = displayOptions.findIndex((option) => option.value === value);
54+
changeHoverIndex(index >= 0 ? index : -1);
55+
} else {
56+
changeHoverIndex(-1);
57+
}
58+
// eslint-disable-next-line react-hooks/exhaustive-deps
59+
}, [innerPopupVisible]);
60+
4461
useEffect(() => {
4562
if (!Array.isArray(value)) return;
4663
isCheckAll.current =
@@ -67,19 +84,6 @@ export default function useKeyboardControl({
6784
}
6885
};
6986

70-
useEffect(() => {
71-
if (!innerPopupVisible) {
72-
changeHoverIndex(-1);
73-
} else if (!multiple) {
74-
// 单选时,hoverIndex 初始值为选中值的索引
75-
const index = displayOptions.findIndex((option) => option.value === value);
76-
changeHoverIndex(index >= 0 ? index : -1);
77-
} else {
78-
changeHoverIndex(-1);
79-
}
80-
// eslint-disable-next-line react-hooks/exhaustive-deps
81-
}, [innerPopupVisible]);
82-
8387
const handleKeyDown = (_value: string, { e }: { e: React.KeyboardEvent<HTMLInputElement> }) => {
8488
const optionsListLength = displayOptions.length;
8589

@@ -92,7 +96,7 @@ export default function useKeyboardControl({
9296
else if (hoverIndex === 0 || hoverIndex > optionsListLength - 1) newIndex = optionsListLength - 1;
9397
else newIndex -= 1;
9498

95-
if (displayOptions[newIndex]?.disabled) newIndex -= 1;
99+
if (displayOptions[newIndex]?.[disabledKey]) newIndex -= 1;
96100

97101
changeHoverIndex(newIndex);
98102
handleKeyboardScroll(newIndex);
@@ -119,7 +123,7 @@ export default function useKeyboardControl({
119123
const selectedOptions = displayOptions[hoverIndex];
120124

121125
if (selectedOptions)
122-
handleChange(selectedOptions.value, {
126+
handleChange(selectedOptions[valueKey], {
123127
trigger: 'check',
124128
e,
125129
});
@@ -128,17 +132,16 @@ export default function useKeyboardControl({
128132
handleKeyboardScroll(0);
129133
} else {
130134
if (displayOptions[hoverIndex].checkAll) {
131-
onCheckAllChange(!isCheckAll.current);
135+
onCheckAllChange(!isCheckAll.current, e);
132136
return;
133137
}
134138

135-
const optionValue = displayOptions[hoverIndex]?.value;
136-
139+
const optionValue = displayOptions[hoverIndex]?.[valueKey];
137140
if (!optionValue) return;
141+
138142
const newValue = value as Array<SelectValue>;
139143
const valueIndex = newValue.indexOf(optionValue);
140144
const isSelected = valueIndex > -1;
141-
142145
const values = getSelectValueArr(value, optionValue, isSelected);
143146

144147
if (max > 0 && values.length > max) return; // 如果已选达到最大值 则不处理

packages/components/select/hooks/useOptions.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import React, { ReactElement, ReactNode, useEffect, useMemo, useState } from 'react';
12
import { get } from 'lodash-es';
2-
import React, { ReactElement, ReactNode, useEffect, useState } from 'react';
3+
34
import Option from '../base/Option';
45
import OptionGroup from '../base/OptionGroup';
56
import { getKeyMapping, getValueToOption, type ValueToOption } from '../util/helper';
@@ -42,6 +43,8 @@ function useOptions(
4243
const [tmpPropOptions, setTmpPropOptions] = useState<SelectOption[]>([]);
4344
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
4445

46+
const { valueKey, labelKey } = useMemo(() => getKeyMapping(keys), [keys]);
47+
4548
useEffect(() => {
4649
setFlattenedOptions(flattenOptions(currentOptions));
4750
}, [currentOptions]);
@@ -74,7 +77,6 @@ function useOptions(
7477
transformedOptions = arrayChildren?.map<SelectOption>((v) => handlerOptionElement(v));
7578
}
7679
if (keys) {
77-
const { valueKey, labelKey } = getKeyMapping(keys);
7880
// 如果有定制 keys 先做转换
7981
transformedOptions = transformedOptions?.map<SelectOption>((option) => ({
8082
...option,
@@ -91,8 +93,6 @@ function useOptions(
9193

9294
// 同步 value 对应的 options
9395
useEffect(() => {
94-
const { valueKey, labelKey } = getKeyMapping(keys);
95-
9696
setSelectedOptions((oldSelectedOptions: SelectOption[]) => {
9797
const createOptionFromValue = (item: OptionValueType) => {
9898
if (valueType === 'value') {

0 commit comments

Comments
 (0)