Skip to content

Commit 9eed16b

Browse files
BoyYangzai洋
andauthored
feat: add groupLabel FieldName (#941)
* fix: OptGroup label not display when set fieldNames * feat: groupLabel fieldName * chore: add test case * chore: put groupLabel api in fileName * chore: separate label and groupLabel * chore: coding style * fix: coding style again * fix: style --------- Co-authored-by: 洋 <[email protected]>
1 parent 0c8db0c commit 9eed16b

File tree

5 files changed

+206
-29
lines changed

5 files changed

+206
-29
lines changed

src/Select.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export type FilterFunc<OptionType> = (inputValue: string, option?: OptionType) =
8383
export interface FieldNames {
8484
value?: string;
8585
label?: string;
86+
groupLabel?: string;
8687
options?: string;
8788
}
8889

@@ -410,7 +411,10 @@ const Select = React.forwardRef(
410411

411412
const displayOptions = React.useMemo(
412413
() =>
413-
flattenOptions(orderedFilteredOptions, { fieldNames: mergedFieldNames, childrenAsData }),
414+
flattenOptions(orderedFilteredOptions, {
415+
fieldNames: mergedFieldNames,
416+
childrenAsData,
417+
}),
414418
[orderedFilteredOptions, mergedFieldNames, childrenAsData],
415419
);
416420

src/utils/valueUtil.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ function getKey(data: BaseOptionType, index: number) {
2121
}
2222

2323
export function fillFieldNames(fieldNames: FieldNames | undefined, childrenAsData: boolean) {
24-
const { label, value, options } = fieldNames || {};
24+
const { label, value, options, groupLabel } = fieldNames || {};
25+
const mergedLabel = label || (childrenAsData ? 'children' : 'label');
2526

2627
return {
27-
label: label || (childrenAsData ? 'children' : 'label'),
28+
label: mergedLabel,
2829
value: value || 'value',
2930
options: options || 'options',
31+
groupLabel: groupLabel || mergedLabel,
3032
};
3133
}
3234

@@ -45,11 +47,13 @@ export function flattenOptions<OptionType extends BaseOptionType = DefaultOption
4547
label: fieldLabel,
4648
value: fieldValue,
4749
options: fieldOptions,
50+
groupLabel
4851
} = fillFieldNames(fieldNames, false);
4952

5053
function dig(list: OptionType[], isGroupOption: boolean) {
5154
list.forEach((data) => {
52-
const label = data[fieldLabel];
55+
56+
const label = data[isGroupOption ? groupLabel : fieldLabel];
5357

5458
if (isGroupOption || !(fieldOptions in data)) {
5559
const value = data[fieldValue];

tests/Select.test.tsx

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,51 @@ describe('Select.Basic', () => {
104104
);
105105
expect(wrapper).toMatchSnapshot();
106106
});
107+
108+
it('should support fieldName', () => {
109+
// groupLabel > fieldNames > self-label
110+
function genOpts(OptLabelName) {
111+
return [
112+
{
113+
groupLabel: 'Manager',
114+
options: [
115+
{
116+
data: 'value',
117+
[OptLabelName]: 'label',
118+
},
119+
],
120+
},
121+
];
122+
}
123+
124+
const { container: containerFirst } = testingRender(
125+
<Select
126+
options={genOpts('test')}
127+
fieldNames={{
128+
value: 'data',
129+
label: 'test',
130+
groupLabel: 'groupLabel',
131+
}}
132+
/>,
133+
);
134+
const { container: containerSecond } = testingRender(
135+
<Select
136+
options={genOpts('groupLabel')}
137+
fieldNames={{ value: 'data', label: 'groupLabel' }}
138+
/>,
139+
);
140+
const { container: containerThird } = testingRender(
141+
<Select
142+
options={genOpts('noGroupLabel')}
143+
fieldNames={{ value: 'data', label: 'noGroupLabel' }}
144+
/>,
145+
);
146+
147+
// these generate the same snapshots
148+
expect(containerFirst).toMatchSnapshot();
149+
expect(containerSecond).toMatchSnapshot();
150+
expect(containerThird).toMatchSnapshot();
151+
});
107152
});
108153

109154
it('convert value to array', () => {
@@ -1925,30 +1970,13 @@ describe('Select.Basic', () => {
19251970
});
19261971

19271972
it('should support title', () => {
1928-
const wrapper1 = mount(
1929-
<Select
1930-
defaultValue="lucy"
1931-
options={[]}
1932-
/>,
1933-
);
1973+
const wrapper1 = mount(<Select defaultValue="lucy" options={[]} />);
19341974
expect(wrapper1.find('.rc-select').prop('title')).toBe(undefined);
19351975
expect(wrapper1.find('.rc-select-selection-item').prop('title')).toBe('lucy');
1936-
const wrapper2 = mount(
1937-
<Select
1938-
defaultValue="lucy"
1939-
options={[]}
1940-
title=""
1941-
/>,
1942-
);
1976+
const wrapper2 = mount(<Select defaultValue="lucy" options={[]} title="" />);
19431977
expect(wrapper2.find('.rc-select').prop('title')).toBe('');
19441978
expect(wrapper2.find('.rc-select-selection-item').prop('title')).toBe('');
1945-
const wrapper3 = mount(
1946-
<Select
1947-
defaultValue="lucy"
1948-
options={[]}
1949-
title="title"
1950-
/>,
1951-
);
1979+
const wrapper3 = mount(<Select defaultValue="lucy" options={[]} title="title" />);
19521980
expect(wrapper3.find('.rc-select').prop('title')).toBe('title');
19531981
expect(wrapper3.find('.rc-select-selection-item').prop('title')).toBe('title');
19541982
});

tests/__snapshots__/Select.test.tsx.snap

Lines changed: 145 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`Select.Basic does not filter when filterOption value is false 1`] = `
44
<div
55
class="rc-select-dropdown rc-select-dropdown-placement-bottomLeft"
6-
style="left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
6+
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
77
>
88
<div>
99
<div
@@ -94,7 +94,7 @@ exports[`Select.Basic does not filter when filterOption value is false 1`] = `
9494
exports[`Select.Basic filterOption could be true as described in default value 1`] = `
9595
<div
9696
class="rc-select-dropdown rc-select-dropdown-empty rc-select-dropdown-placement-bottomLeft"
97-
style="left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
97+
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
9898
>
9999
<div>
100100
<div
@@ -433,10 +433,151 @@ exports[`Select.Basic render renders role prop correctly 1`] = `
433433
</div>
434434
`;
435435

436+
exports[`Select.Basic render should support fieldName 1`] = `
437+
<div>
438+
<div
439+
class="rc-select rc-select-single rc-select-show-arrow"
440+
>
441+
<div
442+
class="rc-select-selector"
443+
>
444+
<span
445+
class="rc-select-selection-search"
446+
>
447+
<input
448+
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
449+
aria-autocomplete="list"
450+
aria-controls="rc_select_TEST_OR_SSR_list"
451+
aria-expanded="false"
452+
aria-haspopup="listbox"
453+
aria-owns="rc_select_TEST_OR_SSR_list"
454+
autocomplete="off"
455+
class="rc-select-selection-search-input"
456+
id="rc_select_TEST_OR_SSR"
457+
readonly=""
458+
role="combobox"
459+
style="opacity: 0;"
460+
type="search"
461+
unselectable="on"
462+
value=""
463+
/>
464+
</span>
465+
<span
466+
class="rc-select-selection-placeholder"
467+
/>
468+
</div>
469+
<span
470+
aria-hidden="true"
471+
class="rc-select-arrow"
472+
style="user-select: none;"
473+
unselectable="on"
474+
>
475+
<span
476+
class="rc-select-arrow-icon"
477+
/>
478+
</span>
479+
</div>
480+
</div>
481+
`;
482+
483+
exports[`Select.Basic render should support fieldName 2`] = `
484+
<div>
485+
<div
486+
class="rc-select rc-select-single rc-select-show-arrow"
487+
>
488+
<div
489+
class="rc-select-selector"
490+
>
491+
<span
492+
class="rc-select-selection-search"
493+
>
494+
<input
495+
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
496+
aria-autocomplete="list"
497+
aria-controls="rc_select_TEST_OR_SSR_list"
498+
aria-expanded="false"
499+
aria-haspopup="listbox"
500+
aria-owns="rc_select_TEST_OR_SSR_list"
501+
autocomplete="off"
502+
class="rc-select-selection-search-input"
503+
id="rc_select_TEST_OR_SSR"
504+
readonly=""
505+
role="combobox"
506+
style="opacity: 0;"
507+
type="search"
508+
unselectable="on"
509+
value=""
510+
/>
511+
</span>
512+
<span
513+
class="rc-select-selection-placeholder"
514+
/>
515+
</div>
516+
<span
517+
aria-hidden="true"
518+
class="rc-select-arrow"
519+
style="user-select: none;"
520+
unselectable="on"
521+
>
522+
<span
523+
class="rc-select-arrow-icon"
524+
/>
525+
</span>
526+
</div>
527+
</div>
528+
`;
529+
530+
exports[`Select.Basic render should support fieldName 3`] = `
531+
<div>
532+
<div
533+
class="rc-select rc-select-single rc-select-show-arrow"
534+
>
535+
<div
536+
class="rc-select-selector"
537+
>
538+
<span
539+
class="rc-select-selection-search"
540+
>
541+
<input
542+
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
543+
aria-autocomplete="list"
544+
aria-controls="rc_select_TEST_OR_SSR_list"
545+
aria-expanded="false"
546+
aria-haspopup="listbox"
547+
aria-owns="rc_select_TEST_OR_SSR_list"
548+
autocomplete="off"
549+
class="rc-select-selection-search-input"
550+
id="rc_select_TEST_OR_SSR"
551+
readonly=""
552+
role="combobox"
553+
style="opacity: 0;"
554+
type="search"
555+
unselectable="on"
556+
value=""
557+
/>
558+
</span>
559+
<span
560+
class="rc-select-selection-placeholder"
561+
/>
562+
</div>
563+
<span
564+
aria-hidden="true"
565+
class="rc-select-arrow"
566+
style="user-select: none;"
567+
unselectable="on"
568+
>
569+
<span
570+
class="rc-select-arrow-icon"
571+
/>
572+
</span>
573+
</div>
574+
</div>
575+
`;
576+
436577
exports[`Select.Basic should contain falsy children 1`] = `
437578
<div
438579
class="rc-select-dropdown rc-select-dropdown-placement-bottomLeft"
439-
style="left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
580+
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
440581
>
441582
<div>
442583
<div
@@ -529,7 +670,7 @@ exports[`Select.Basic should contain falsy children 1`] = `
529670
exports[`Select.Basic should render custom dropdown correctly 1`] = `
530671
<div
531672
class="rc-select-dropdown rc-select-dropdown-placement-bottomLeft"
532-
style="left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
673+
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
533674
>
534675
<div>
535676
<div>

tests/__snapshots__/Tags.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ exports[`Select.Tags OptGroup renders correctly 1`] = `
100100
</div>
101101
<div
102102
class="rc-select-dropdown rc-select-dropdown-placement-bottomLeft"
103-
style="left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
103+
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 0; width: 0px;"
104104
>
105105
<div>
106106
<div

0 commit comments

Comments
 (0)