@instructure/ui-select 10.11.1-snapshot-17 → 10.11.1-snapshot-18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -1
- package/es/Select/__new-tests__/Select.test.js +312 -13
- package/es/Select/index.js +87 -28
- package/es/Select/props.js +2 -1
- package/lib/Select/__new-tests__/Select.test.js +315 -13
- package/lib/Select/index.js +87 -28
- package/lib/Select/props.js +2 -1
- package/package.json +24 -24
- package/src/Select/__new-tests__/Select.test.tsx +510 -0
- package/src/Select/index.tsx +89 -3
- package/src/Select/props.ts +19 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Select/index.d.ts +38 -8
- package/types/Select/index.d.ts.map +1 -1
- package/types/Select/props.d.ts +16 -0
- package/types/Select/props.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [10.11.1-snapshot-
|
|
6
|
+
## [10.11.1-snapshot-18](https://github.com/instructure/instructure-ui/compare/v10.11.0...v10.11.1-snapshot-18) (2025-02-21)
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
### Bug Fixes
|
|
@@ -14,6 +14,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
14
14
|
### Features
|
|
15
15
|
|
|
16
16
|
* **ui-popover, ui-select:** allow overriding Select's dropdown border ([90d59d3](https://github.com/instructure/instructure-ui/commit/90d59d3c3689c3a1500c37db363fa43c1b8403d7))
|
|
17
|
+
* **ui-select,ui-simple-select:** add support for rendering selected option's before and after content in Select and SimpleSelect input ([87dc52d](https://github.com/instructure/instructure-ui/commit/87dc52dcd2a23acfe50856c05b8ff28c1046f85a))
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
|
|
@@ -34,6 +34,7 @@ import { runAxeCheck } from '@instructure/ui-axe-check';
|
|
|
34
34
|
import Select from '../index';
|
|
35
35
|
import SelectExamples from '../__examples__/Select.examples';
|
|
36
36
|
import * as utils from '@instructure/ui-utils';
|
|
37
|
+
import { IconAddLine, IconCheckSolid, IconDownloadSolid, IconEyeSolid } from '@instructure/ui-icons';
|
|
37
38
|
const defaultOptions = ['foo', 'bar', 'baz'];
|
|
38
39
|
const getOptions = (highlighted, selected, disabled) => defaultOptions.map(opt => /*#__PURE__*/React.createElement(Select.Option, {
|
|
39
40
|
id: opt,
|
|
@@ -43,6 +44,151 @@ const getOptions = (highlighted, selected, disabled) => defaultOptions.map(opt =
|
|
|
43
44
|
isSelected: opt === selected,
|
|
44
45
|
isDisabled: opt === disabled
|
|
45
46
|
}, opt));
|
|
47
|
+
const optionsWithBeforeContent = [{
|
|
48
|
+
id: 'opt1',
|
|
49
|
+
label: 'Text',
|
|
50
|
+
renderBeforeLabel: 'XY'
|
|
51
|
+
}, {
|
|
52
|
+
id: 'opt2',
|
|
53
|
+
label: 'Icon',
|
|
54
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconCheckSolid, null)
|
|
55
|
+
}, {
|
|
56
|
+
id: 'opt3',
|
|
57
|
+
label: 'Colored Icon',
|
|
58
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconEyeSolid, null)
|
|
59
|
+
}];
|
|
60
|
+
const groupOptionsWithBeforeContent = {
|
|
61
|
+
Options1: [{
|
|
62
|
+
id: 'opt1',
|
|
63
|
+
label: 'Text1',
|
|
64
|
+
renderBeforeLabel: 'XY'
|
|
65
|
+
}, {
|
|
66
|
+
id: 'opt2',
|
|
67
|
+
label: 'Icon1',
|
|
68
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconCheckSolid, null)
|
|
69
|
+
}, {
|
|
70
|
+
id: 'opt3',
|
|
71
|
+
label: 'Colored Icon1',
|
|
72
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconEyeSolid, null)
|
|
73
|
+
}],
|
|
74
|
+
Options2: [{
|
|
75
|
+
id: 'opt4',
|
|
76
|
+
label: 'Text2',
|
|
77
|
+
renderBeforeLabel: 'AB'
|
|
78
|
+
}, {
|
|
79
|
+
id: 'opt5',
|
|
80
|
+
label: 'Icon2',
|
|
81
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconAddLine, null)
|
|
82
|
+
}, {
|
|
83
|
+
id: 'opt6',
|
|
84
|
+
label: 'Colored Icon2',
|
|
85
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconDownloadSolid, null)
|
|
86
|
+
}]
|
|
87
|
+
};
|
|
88
|
+
const optionsWithAfterContent = [{
|
|
89
|
+
id: 'opt1',
|
|
90
|
+
label: 'Text',
|
|
91
|
+
renderAfterLabel: 'XY'
|
|
92
|
+
}, {
|
|
93
|
+
id: 'opt2',
|
|
94
|
+
label: 'Icon',
|
|
95
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconCheckSolid, null)
|
|
96
|
+
}, {
|
|
97
|
+
id: 'opt3',
|
|
98
|
+
label: 'Colored Icon',
|
|
99
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconEyeSolid, null)
|
|
100
|
+
}];
|
|
101
|
+
const groupOptionsWithAfterContent = {
|
|
102
|
+
Options1: [{
|
|
103
|
+
id: 'opt1',
|
|
104
|
+
label: 'Text1',
|
|
105
|
+
renderAfterLabel: 'XY'
|
|
106
|
+
}, {
|
|
107
|
+
id: 'opt2',
|
|
108
|
+
label: 'Icon1',
|
|
109
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconCheckSolid, null)
|
|
110
|
+
}, {
|
|
111
|
+
id: 'opt3',
|
|
112
|
+
label: 'Colored Icon1',
|
|
113
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconEyeSolid, null)
|
|
114
|
+
}],
|
|
115
|
+
Options2: [{
|
|
116
|
+
id: 'opt4',
|
|
117
|
+
label: 'Text2',
|
|
118
|
+
renderAfterLabel: 'AB'
|
|
119
|
+
}, {
|
|
120
|
+
id: 'opt5',
|
|
121
|
+
label: 'Icon2',
|
|
122
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconAddLine, null)
|
|
123
|
+
}, {
|
|
124
|
+
id: 'opt6',
|
|
125
|
+
label: 'Colored Icon2',
|
|
126
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconDownloadSolid, null)
|
|
127
|
+
}]
|
|
128
|
+
};
|
|
129
|
+
const optionsWithBeforeAndAfterContent = [{
|
|
130
|
+
id: 'opt1',
|
|
131
|
+
label: 'Text',
|
|
132
|
+
renderBeforeLabel: 'XY',
|
|
133
|
+
renderAfterLabel: 'ZZ'
|
|
134
|
+
}, {
|
|
135
|
+
id: 'opt2',
|
|
136
|
+
label: 'Icon',
|
|
137
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconCheckSolid, null),
|
|
138
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconEyeSolid, null)
|
|
139
|
+
}, {
|
|
140
|
+
id: 'opt3',
|
|
141
|
+
label: 'Colored Icon',
|
|
142
|
+
renderBeforeLabel: /*#__PURE__*/React.createElement(IconEyeSolid, null),
|
|
143
|
+
renderAfterLabel: /*#__PURE__*/React.createElement(IconCheckSolid, null)
|
|
144
|
+
}];
|
|
145
|
+
const getOptionsWithBeforeContent = selected => optionsWithBeforeContent.map(opt => /*#__PURE__*/React.createElement(Select.Option, Object.assign({}, opt, {
|
|
146
|
+
key: opt.id,
|
|
147
|
+
isSelected: opt.id === selected
|
|
148
|
+
})));
|
|
149
|
+
const getGroupOptionsWithBeforeContent = selected => {
|
|
150
|
+
return Object.keys(groupOptionsWithBeforeContent).map((key, index) => {
|
|
151
|
+
return /*#__PURE__*/React.createElement(Select.Group, {
|
|
152
|
+
key: index,
|
|
153
|
+
renderLabel: key
|
|
154
|
+
}, groupOptionsWithBeforeContent[key].map(opt => /*#__PURE__*/React.createElement(Select.Option, {
|
|
155
|
+
id: opt.id,
|
|
156
|
+
key: opt.id,
|
|
157
|
+
value: opt.label,
|
|
158
|
+
renderBeforeLabel: opt.renderBeforeLabel,
|
|
159
|
+
isSelected: opt.id === selected
|
|
160
|
+
})));
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
const getOptionsWithAfterContent = selected => optionsWithAfterContent.map(opt => /*#__PURE__*/React.createElement(Select.Option, {
|
|
164
|
+
id: opt.id,
|
|
165
|
+
key: opt.id,
|
|
166
|
+
value: opt.label,
|
|
167
|
+
renderAfterLabel: opt.renderAfterLabel,
|
|
168
|
+
isSelected: opt.id === selected
|
|
169
|
+
}));
|
|
170
|
+
const getGroupOptionsWithAfterContent = selected => {
|
|
171
|
+
return Object.keys(groupOptionsWithAfterContent).map((key, index) => {
|
|
172
|
+
return /*#__PURE__*/React.createElement(Select.Group, {
|
|
173
|
+
key: index,
|
|
174
|
+
renderLabel: key
|
|
175
|
+
}, groupOptionsWithAfterContent[key].map(opt => /*#__PURE__*/React.createElement(Select.Option, {
|
|
176
|
+
id: opt.id,
|
|
177
|
+
key: opt.id,
|
|
178
|
+
value: opt.label,
|
|
179
|
+
renderAfterLabel: opt.renderAfterLabel,
|
|
180
|
+
isSelected: opt.id === selected
|
|
181
|
+
})));
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
const getOptionsWithBeforeAndAfterContent = selected => optionsWithBeforeAndAfterContent.map(opt => /*#__PURE__*/React.createElement(Select.Option, {
|
|
185
|
+
id: opt.id,
|
|
186
|
+
key: opt.id,
|
|
187
|
+
value: opt.label,
|
|
188
|
+
renderBeforeLabel: opt.renderBeforeLabel,
|
|
189
|
+
renderAfterLabel: opt.renderAfterLabel,
|
|
190
|
+
isSelected: opt.id === selected
|
|
191
|
+
}));
|
|
46
192
|
vi.mock('@instructure/ui-utils', async importOriginal => {
|
|
47
193
|
const originalModule = await importOriginal();
|
|
48
194
|
return {
|
|
@@ -311,6 +457,159 @@ describe('<Select />', () => {
|
|
|
311
457
|
expect(inputRef).toHaveBeenCalledWith(input);
|
|
312
458
|
});
|
|
313
459
|
});
|
|
460
|
+
it("should not render option's before content in input field when isOptionContentAppliedToInput is set to false ", async () => {
|
|
461
|
+
const _render8 = render(/*#__PURE__*/React.createElement(Select, {
|
|
462
|
+
renderLabel: "Choose an option",
|
|
463
|
+
isOptionContentAppliedToInput: false,
|
|
464
|
+
inputValue: optionsWithBeforeContent[0].label
|
|
465
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
466
|
+
container = _render8.container;
|
|
467
|
+
const beforeContent = container.querySelector('span[class$="-textInput__layout"]');
|
|
468
|
+
expect(beforeContent).not.toHaveTextContent('XY');
|
|
469
|
+
});
|
|
470
|
+
it('should render arrow in input field when isOptionContentAppliedToInput is set to false', async () => {
|
|
471
|
+
const _render9 = render(/*#__PURE__*/React.createElement(Select, {
|
|
472
|
+
renderLabel: "Choose an option",
|
|
473
|
+
isOptionContentAppliedToInput: false,
|
|
474
|
+
inputValue: optionsWithBeforeContent[0].label
|
|
475
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
476
|
+
container = _render9.container;
|
|
477
|
+
const spanElement = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
478
|
+
const svgElement = spanElement.querySelector('svg[name="IconArrowOpenDown"]');
|
|
479
|
+
expect(svgElement).toBeInTheDocument();
|
|
480
|
+
});
|
|
481
|
+
it("should render option's before content in input field when isOptionContentAppliedToInput is set to true", async () => {
|
|
482
|
+
const _render10 = render(/*#__PURE__*/React.createElement(Select, {
|
|
483
|
+
renderLabel: "Choose an option",
|
|
484
|
+
isOptionContentAppliedToInput: true,
|
|
485
|
+
inputValue: optionsWithBeforeContent[0].label
|
|
486
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
487
|
+
container = _render10.container;
|
|
488
|
+
const beforeContent = container.querySelector('span[class$="-textInput__layout"]');
|
|
489
|
+
expect(beforeContent).toHaveTextContent('XY');
|
|
490
|
+
});
|
|
491
|
+
it('should render arrow icon when isOptionContentAppliedToInput is set to true with before content', async () => {
|
|
492
|
+
const _render11 = render(/*#__PURE__*/React.createElement(Select, {
|
|
493
|
+
renderLabel: "Choose an option",
|
|
494
|
+
isOptionContentAppliedToInput: true,
|
|
495
|
+
inputValue: optionsWithBeforeContent[0].label
|
|
496
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
497
|
+
container = _render11.container;
|
|
498
|
+
const spanElement = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
499
|
+
const svgElement = spanElement.querySelector('svg[name="IconArrowOpenDown"]');
|
|
500
|
+
expect(svgElement).toBeInTheDocument();
|
|
501
|
+
});
|
|
502
|
+
it("should render option's after content in input field when isOptionContentAppliedToInput is set to true", async () => {
|
|
503
|
+
const _render12 = render(/*#__PURE__*/React.createElement(Select, {
|
|
504
|
+
renderLabel: "Choose an option",
|
|
505
|
+
isOptionContentAppliedToInput: true,
|
|
506
|
+
inputValue: optionsWithAfterContent[0].label
|
|
507
|
+
}, getOptionsWithAfterContent('opt1'))),
|
|
508
|
+
container = _render12.container;
|
|
509
|
+
const beforeContent = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
510
|
+
expect(beforeContent).toHaveTextContent('XY');
|
|
511
|
+
});
|
|
512
|
+
it("should render option's before content in input field when isOptionContentAppliedToInput is set to true but renderBeforeInput is also set", async () => {
|
|
513
|
+
const _render13 = render(/*#__PURE__*/React.createElement(Select, {
|
|
514
|
+
renderLabel: "Choose an option",
|
|
515
|
+
isOptionContentAppliedToInput: true,
|
|
516
|
+
inputValue: optionsWithBeforeContent[0].label,
|
|
517
|
+
renderBeforeInput: "ZZ"
|
|
518
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
519
|
+
container = _render13.container;
|
|
520
|
+
const beforeContent = container.querySelector('span[class$="-textInput__layout"]');
|
|
521
|
+
expect(beforeContent).toHaveTextContent('XY');
|
|
522
|
+
});
|
|
523
|
+
it("should render option's after content in input field when isOptionContentAppliedToInput is set to true but renderAfterInput is also set", async () => {
|
|
524
|
+
const _render14 = render(/*#__PURE__*/React.createElement(Select, {
|
|
525
|
+
renderLabel: "Choose an option",
|
|
526
|
+
isOptionContentAppliedToInput: true,
|
|
527
|
+
inputValue: optionsWithAfterContent[0].label,
|
|
528
|
+
renderAfterInput: "ZZ"
|
|
529
|
+
}, getOptionsWithAfterContent('opt1'))),
|
|
530
|
+
container = _render14.container;
|
|
531
|
+
const afterContent = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
532
|
+
expect(afterContent).toHaveTextContent('XY');
|
|
533
|
+
});
|
|
534
|
+
it("should not render option's before content in input field when isOptionContentAppliedToInput is set to true but inputValue is not set", async () => {
|
|
535
|
+
const _render15 = render(/*#__PURE__*/React.createElement(Select, {
|
|
536
|
+
renderLabel: "Choose an option",
|
|
537
|
+
isOptionContentAppliedToInput: true
|
|
538
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
539
|
+
container = _render15.container;
|
|
540
|
+
const beforeContent = container.querySelector('span[class$="-textInput__layout"]');
|
|
541
|
+
expect(beforeContent).not.toHaveTextContent('XY');
|
|
542
|
+
});
|
|
543
|
+
it("should render option's before content in input field when isOptionContentAppliedToInput is set to true and both optionBeforeContent and optionAfterContent are provided", async () => {
|
|
544
|
+
const _render16 = render(/*#__PURE__*/React.createElement(Select, {
|
|
545
|
+
renderLabel: "Choose an option",
|
|
546
|
+
isOptionContentAppliedToInput: true,
|
|
547
|
+
inputValue: optionsWithBeforeAndAfterContent[0].label
|
|
548
|
+
}, getOptionsWithBeforeAndAfterContent('opt1'))),
|
|
549
|
+
container = _render16.container;
|
|
550
|
+
const beforeContent = container.querySelector('span[class$="-textInput__layout"]');
|
|
551
|
+
expect(beforeContent).toHaveTextContent('XY');
|
|
552
|
+
});
|
|
553
|
+
it("should render option's after content in input field when isOptionContentAppliedToInput is set to true and both optionBeforeContent and optionAfterContent are provided", async () => {
|
|
554
|
+
const _render17 = render(/*#__PURE__*/React.createElement(Select, {
|
|
555
|
+
renderLabel: "Choose an option",
|
|
556
|
+
isOptionContentAppliedToInput: true,
|
|
557
|
+
inputValue: optionsWithBeforeAndAfterContent[0].label
|
|
558
|
+
}, getOptionsWithBeforeAndAfterContent('opt1'))),
|
|
559
|
+
container = _render17.container;
|
|
560
|
+
const afterContent = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
561
|
+
expect(afterContent).toHaveTextContent('ZZ');
|
|
562
|
+
});
|
|
563
|
+
it('should render arrow in input field when isOptionContentAppliedToInput is set to true but inputValue is not set', async () => {
|
|
564
|
+
const _render18 = render(/*#__PURE__*/React.createElement(Select, {
|
|
565
|
+
renderLabel: "Choose an option",
|
|
566
|
+
isOptionContentAppliedToInput: true
|
|
567
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
568
|
+
container = _render18.container;
|
|
569
|
+
const spanElement = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
570
|
+
const svgElement = spanElement.querySelector('svg[name="IconArrowOpenDown"]');
|
|
571
|
+
expect(svgElement).toBeInTheDocument();
|
|
572
|
+
});
|
|
573
|
+
it("should not render option's after content in input field when isOptionContentAppliedToInput is set to true but inputValue is not set", async () => {
|
|
574
|
+
const _render19 = render(/*#__PURE__*/React.createElement(Select, {
|
|
575
|
+
renderLabel: "Choose an option",
|
|
576
|
+
isOptionContentAppliedToInput: true
|
|
577
|
+
}, getOptionsWithBeforeContent('opt1'))),
|
|
578
|
+
container = _render19.container;
|
|
579
|
+
const afterContent = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
580
|
+
expect(afterContent).not.toHaveTextContent('XY');
|
|
581
|
+
});
|
|
582
|
+
it("should render option's before content input field when isOptionContentAppliedToInput is set to true with group options", async () => {
|
|
583
|
+
const _render20 = render(/*#__PURE__*/React.createElement(Select, {
|
|
584
|
+
renderLabel: "Choose an option",
|
|
585
|
+
isOptionContentAppliedToInput: true,
|
|
586
|
+
inputValue: groupOptionsWithBeforeContent.Options1[0].label
|
|
587
|
+
}, getGroupOptionsWithBeforeContent('opt1'))),
|
|
588
|
+
container = _render20.container;
|
|
589
|
+
const beforeContent = container.querySelector('span[class$="-textInput__layout"]');
|
|
590
|
+
expect(beforeContent).toHaveTextContent('XY');
|
|
591
|
+
});
|
|
592
|
+
it('should render arrow icon when isOptionContentAppliedToInput is set to true with before content and group options', async () => {
|
|
593
|
+
const _render21 = render(/*#__PURE__*/React.createElement(Select, {
|
|
594
|
+
renderLabel: "Choose an option",
|
|
595
|
+
isOptionContentAppliedToInput: true,
|
|
596
|
+
inputValue: groupOptionsWithBeforeContent.Options1[0].label
|
|
597
|
+
}, getGroupOptionsWithBeforeContent('opt1'))),
|
|
598
|
+
container = _render21.container;
|
|
599
|
+
const spanElement = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
600
|
+
const svgElement = spanElement.querySelector('svg[name="IconArrowOpenDown"]');
|
|
601
|
+
expect(svgElement).toBeInTheDocument();
|
|
602
|
+
});
|
|
603
|
+
it("should render option's after content input field when isOptionContentAppliedToInput is set to true with group options", async () => {
|
|
604
|
+
const _render22 = render(/*#__PURE__*/React.createElement(Select, {
|
|
605
|
+
renderLabel: "Choose an option",
|
|
606
|
+
isOptionContentAppliedToInput: true,
|
|
607
|
+
inputValue: groupOptionsWithAfterContent.Options2[0].label
|
|
608
|
+
}, getGroupOptionsWithAfterContent('opt4'))),
|
|
609
|
+
container = _render22.container;
|
|
610
|
+
const afterContent = container.querySelector('span[class$="-textInput__afterElement"]');
|
|
611
|
+
expect(afterContent).toHaveTextContent('AB');
|
|
612
|
+
});
|
|
314
613
|
});
|
|
315
614
|
describe('list', () => {
|
|
316
615
|
it('should set aria-selected on options with isSelected={true}', () => {
|
|
@@ -356,12 +655,12 @@ describe('<Select />', () => {
|
|
|
356
655
|
describe('should fire onRequestShowOptions', () => {
|
|
357
656
|
it('when root is clicked', async () => {
|
|
358
657
|
const onRequestShowOptions = vi.fn();
|
|
359
|
-
const
|
|
658
|
+
const _render23 = render(/*#__PURE__*/React.createElement(Select, {
|
|
360
659
|
renderLabel: "Choose an option",
|
|
361
660
|
onRequestShowOptions: onRequestShowOptions
|
|
362
661
|
}, getOptions())),
|
|
363
|
-
container =
|
|
364
|
-
rerender =
|
|
662
|
+
container = _render23.container,
|
|
663
|
+
rerender = _render23.rerender;
|
|
365
664
|
const icon = container.querySelector('svg[name="IconArrowOpenDown"]');
|
|
366
665
|
const label = screen.getByText('Choose an option');
|
|
367
666
|
expect(icon).toBeInTheDocument();
|
|
@@ -386,11 +685,11 @@ describe('<Select />', () => {
|
|
|
386
685
|
});
|
|
387
686
|
it('when input is clicked', async () => {
|
|
388
687
|
const onRequestShowOptions = vi.fn();
|
|
389
|
-
const
|
|
688
|
+
const _render24 = render(/*#__PURE__*/React.createElement(Select, {
|
|
390
689
|
renderLabel: "Choose an option",
|
|
391
690
|
onRequestShowOptions: onRequestShowOptions
|
|
392
691
|
}, getOptions())),
|
|
393
|
-
rerender =
|
|
692
|
+
rerender = _render24.rerender;
|
|
394
693
|
const input = screen.getByLabelText('Choose an option');
|
|
395
694
|
await userEvent.click(input);
|
|
396
695
|
await waitFor(() => {
|
|
@@ -424,11 +723,11 @@ describe('<Select />', () => {
|
|
|
424
723
|
});
|
|
425
724
|
it('when space is pressed', async () => {
|
|
426
725
|
const onRequestShowOptions = vi.fn();
|
|
427
|
-
const
|
|
726
|
+
const _render25 = render(/*#__PURE__*/React.createElement(Select, {
|
|
428
727
|
renderLabel: "Choose an option",
|
|
429
728
|
onRequestShowOptions: onRequestShowOptions
|
|
430
729
|
}, getOptions())),
|
|
431
|
-
rerender =
|
|
730
|
+
rerender = _render25.rerender;
|
|
432
731
|
const input = screen.getByLabelText('Choose an option');
|
|
433
732
|
await userEvent.type(input, '{space}');
|
|
434
733
|
await waitFor(() => {
|
|
@@ -448,12 +747,12 @@ describe('<Select />', () => {
|
|
|
448
747
|
describe('should fire onRequestHideOptions', () => {
|
|
449
748
|
it('when root is clicked and isShowingOptions is true', async () => {
|
|
450
749
|
const onRequestHideOptions = vi.fn();
|
|
451
|
-
const
|
|
750
|
+
const _render26 = render(/*#__PURE__*/React.createElement(Select, {
|
|
452
751
|
renderLabel: "Choose an option",
|
|
453
752
|
isShowingOptions: true,
|
|
454
753
|
onRequestHideOptions: onRequestHideOptions
|
|
455
754
|
}, getOptions())),
|
|
456
|
-
container =
|
|
755
|
+
container = _render26.container;
|
|
457
756
|
const icon = container.querySelector('svg[name="IconArrowOpenUp"]');
|
|
458
757
|
const label = screen.getByText('Choose an option');
|
|
459
758
|
expect(icon).toBeInTheDocument();
|
|
@@ -483,12 +782,12 @@ describe('<Select />', () => {
|
|
|
483
782
|
});
|
|
484
783
|
it('when input is clicked', async () => {
|
|
485
784
|
const onRequestHideOptions = vi.fn();
|
|
486
|
-
const
|
|
785
|
+
const _render27 = render(/*#__PURE__*/React.createElement(Select, {
|
|
487
786
|
renderLabel: "Choose an option",
|
|
488
787
|
isShowingOptions: true,
|
|
489
788
|
onRequestHideOptions: onRequestHideOptions
|
|
490
789
|
}, getOptions())),
|
|
491
|
-
rerender =
|
|
790
|
+
rerender = _render27.rerender;
|
|
492
791
|
const input = screen.getByLabelText('Choose an option');
|
|
493
792
|
await userEvent.click(input);
|
|
494
793
|
await waitFor(() => {
|
|
@@ -573,8 +872,8 @@ describe('<Select />', () => {
|
|
|
573
872
|
it.each(generatedComponents)('should be accessible with example: $description', async ({
|
|
574
873
|
content
|
|
575
874
|
}) => {
|
|
576
|
-
const
|
|
577
|
-
container =
|
|
875
|
+
const _render28 = render(content),
|
|
876
|
+
container = _render28.container;
|
|
578
877
|
const axeCheck = await runAxeCheck(container);
|
|
579
878
|
expect(axeCheck).toBe(true);
|
|
580
879
|
});
|
package/es/Select/index.js
CHANGED
|
@@ -430,27 +430,85 @@ let Select = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gen
|
|
|
430
430
|
inline: false
|
|
431
431
|
})));
|
|
432
432
|
}
|
|
433
|
+
renderContentBeforeOrAfterInput(position) {
|
|
434
|
+
for (const child of this.childrenArray) {
|
|
435
|
+
if (matchComponentTypes(child, [Group])) {
|
|
436
|
+
// Group found
|
|
437
|
+
const options = this.getGroupChildrenArray(child);
|
|
438
|
+
for (const option of options) {
|
|
439
|
+
if (option.props.isSelected) {
|
|
440
|
+
return position === 'before' ? option.props.renderBeforeLabel : option.props.renderAfterLabel ? option.props.renderAfterLabel : this.renderIcon();
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
} else {
|
|
444
|
+
// Ungrouped option found
|
|
445
|
+
if (child.props.isSelected) {
|
|
446
|
+
return position === 'before' ? child.props.renderBeforeLabel : child.props.renderAfterLabel ? child.props.renderAfterLabel : this.renderIcon();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// if no option with isSelected is found
|
|
451
|
+
if (position === 'after') {
|
|
452
|
+
return this.renderIcon();
|
|
453
|
+
}
|
|
454
|
+
return void 0;
|
|
455
|
+
}
|
|
456
|
+
handleInputContentRender(renderLabelInput, inputValue, isOptionContentAppliedToInput, position, defaultReturn) {
|
|
457
|
+
const isInputValueEmpty = !inputValue || inputValue === '';
|
|
458
|
+
if (renderLabelInput && isOptionContentAppliedToInput) {
|
|
459
|
+
if (!isInputValueEmpty) {
|
|
460
|
+
return this.renderContentBeforeOrAfterInput(position);
|
|
461
|
+
}
|
|
462
|
+
return renderLabelInput;
|
|
463
|
+
}
|
|
464
|
+
if (isOptionContentAppliedToInput) {
|
|
465
|
+
if (isInputValueEmpty) {
|
|
466
|
+
return defaultReturn;
|
|
467
|
+
}
|
|
468
|
+
return this.renderContentBeforeOrAfterInput(position);
|
|
469
|
+
}
|
|
470
|
+
if (renderLabelInput) {
|
|
471
|
+
return renderLabelInput;
|
|
472
|
+
}
|
|
473
|
+
return defaultReturn;
|
|
474
|
+
}
|
|
475
|
+
handleRenderBeforeInput() {
|
|
476
|
+
const _this$props8 = this.props,
|
|
477
|
+
renderBeforeInput = _this$props8.renderBeforeInput,
|
|
478
|
+
inputValue = _this$props8.inputValue,
|
|
479
|
+
isOptionContentAppliedToInput = _this$props8.isOptionContentAppliedToInput;
|
|
480
|
+
return this.handleInputContentRender(renderBeforeInput, inputValue, isOptionContentAppliedToInput, 'before', null // default for before
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
handleRenderAfterInput() {
|
|
484
|
+
const _this$props9 = this.props,
|
|
485
|
+
renderAfterInput = _this$props9.renderAfterInput,
|
|
486
|
+
inputValue = _this$props9.inputValue,
|
|
487
|
+
isOptionContentAppliedToInput = _this$props9.isOptionContentAppliedToInput;
|
|
488
|
+
return this.handleInputContentRender(renderAfterInput, inputValue, isOptionContentAppliedToInput, 'after', this.renderIcon() // default for after
|
|
489
|
+
);
|
|
490
|
+
}
|
|
433
491
|
renderInput(data) {
|
|
434
492
|
const getInputProps = data.getInputProps,
|
|
435
493
|
getTriggerProps = data.getTriggerProps;
|
|
436
|
-
const _this$
|
|
437
|
-
renderLabel = _this$
|
|
438
|
-
inputValue = _this$
|
|
439
|
-
placeholder = _this$
|
|
440
|
-
isRequired = _this$
|
|
441
|
-
shouldNotWrap = _this$
|
|
442
|
-
size = _this$
|
|
443
|
-
isInline = _this$
|
|
444
|
-
width = _this$
|
|
445
|
-
htmlSize = _this$
|
|
446
|
-
messages = _this$
|
|
447
|
-
renderBeforeInput = _this$
|
|
448
|
-
renderAfterInput = _this$
|
|
449
|
-
onFocus = _this$
|
|
450
|
-
onBlur = _this$
|
|
451
|
-
onInputChange = _this$
|
|
452
|
-
onRequestHideOptions = _this$
|
|
453
|
-
rest = _objectWithoutProperties(_this$
|
|
494
|
+
const _this$props10 = this.props,
|
|
495
|
+
renderLabel = _this$props10.renderLabel,
|
|
496
|
+
inputValue = _this$props10.inputValue,
|
|
497
|
+
placeholder = _this$props10.placeholder,
|
|
498
|
+
isRequired = _this$props10.isRequired,
|
|
499
|
+
shouldNotWrap = _this$props10.shouldNotWrap,
|
|
500
|
+
size = _this$props10.size,
|
|
501
|
+
isInline = _this$props10.isInline,
|
|
502
|
+
width = _this$props10.width,
|
|
503
|
+
htmlSize = _this$props10.htmlSize,
|
|
504
|
+
messages = _this$props10.messages,
|
|
505
|
+
renderBeforeInput = _this$props10.renderBeforeInput,
|
|
506
|
+
renderAfterInput = _this$props10.renderAfterInput,
|
|
507
|
+
onFocus = _this$props10.onFocus,
|
|
508
|
+
onBlur = _this$props10.onBlur,
|
|
509
|
+
onInputChange = _this$props10.onInputChange,
|
|
510
|
+
onRequestHideOptions = _this$props10.onRequestHideOptions,
|
|
511
|
+
rest = _objectWithoutProperties(_this$props10, _excluded2);
|
|
454
512
|
const interaction = this.interaction;
|
|
455
513
|
const passthroughProps = omitProps(rest, Select.allowedProps);
|
|
456
514
|
const _getTriggerProps = getTriggerProps({
|
|
@@ -492,8 +550,8 @@ let Select = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gen
|
|
|
492
550
|
isRequired,
|
|
493
551
|
shouldNotWrap,
|
|
494
552
|
display: isInline ? 'inline-block' : 'block',
|
|
495
|
-
renderBeforeInput,
|
|
496
|
-
renderAfterInput:
|
|
553
|
+
renderBeforeInput: this.handleRenderBeforeInput(),
|
|
554
|
+
renderAfterInput: this.handleRenderAfterInput(),
|
|
497
555
|
// If `inputValue` is provided, we need to pass a default onChange handler,
|
|
498
556
|
// because TextInput `value` is a controlled prop,
|
|
499
557
|
// and onChange is not required for Select
|
|
@@ -506,13 +564,13 @@ let Select = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gen
|
|
|
506
564
|
return jsx(TextInput, Object.assign({}, triggerProps, getInputProps(inputProps)));
|
|
507
565
|
}
|
|
508
566
|
render() {
|
|
509
|
-
const _this$
|
|
510
|
-
constrain = _this$
|
|
511
|
-
placement = _this$
|
|
512
|
-
mountNode = _this$
|
|
513
|
-
assistiveText = _this$
|
|
514
|
-
isShowingOptions = _this$
|
|
515
|
-
styles = _this$
|
|
567
|
+
const _this$props11 = this.props,
|
|
568
|
+
constrain = _this$props11.constrain,
|
|
569
|
+
placement = _this$props11.placement,
|
|
570
|
+
mountNode = _this$props11.mountNode,
|
|
571
|
+
assistiveText = _this$props11.assistiveText,
|
|
572
|
+
isShowingOptions = _this$props11.isShowingOptions,
|
|
573
|
+
styles = _this$props11.styles;
|
|
516
574
|
// clear temporary option store
|
|
517
575
|
this._optionIds = [];
|
|
518
576
|
const highlightedOptionId = this.highlightedOptionId;
|
|
@@ -565,7 +623,8 @@ let Select = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gen
|
|
|
565
623
|
placement: 'bottom stretch',
|
|
566
624
|
constrain: 'window',
|
|
567
625
|
shouldNotWrap: false,
|
|
568
|
-
scrollToHighlightedOption: true
|
|
626
|
+
scrollToHighlightedOption: true,
|
|
627
|
+
isOptionContentAppliedToInput: false
|
|
569
628
|
}, _Select.Option = Option, _Select.Group = Group, _Select)) || _class) || _class) || _class);
|
|
570
629
|
export default Select;
|
|
571
630
|
export { Select };
|
package/es/Select/props.js
CHANGED
|
@@ -51,6 +51,7 @@ const propTypes = {
|
|
|
51
51
|
width: PropTypes.string,
|
|
52
52
|
htmlSize: PropTypes.number,
|
|
53
53
|
visibleOptionsCount: PropTypes.number,
|
|
54
|
+
isOptionContentAppliedToInput: PropTypes.bool,
|
|
54
55
|
optionsMaxHeight: PropTypes.string,
|
|
55
56
|
optionsMaxWidth: PropTypes.string,
|
|
56
57
|
messages: PropTypes.arrayOf(FormPropTypes.message),
|
|
@@ -73,5 +74,5 @@ const propTypes = {
|
|
|
73
74
|
shouldNotWrap: PropTypes.bool,
|
|
74
75
|
scrollToHighlightedOption: PropTypes.bool
|
|
75
76
|
};
|
|
76
|
-
const allowedProps = ['renderLabel', 'inputValue', 'isShowingOptions', 'id', 'size', 'assistiveText', 'placeholder', 'interaction', 'isRequired', 'isInline', 'width', 'htmlSize', 'visibleOptionsCount', 'optionsMaxHeight', 'optionsMaxWidth', 'messages', 'placement', 'constrain', 'mountNode', 'onFocus', 'onBlur', 'onInputChange', 'onRequestShowOptions', 'onRequestHideOptions', 'onRequestHighlightOption', 'onRequestSelectOption', 'inputRef', 'listRef', 'renderBeforeInput', 'renderAfterInput', 'children', 'shouldNotWrap', 'scrollToHighlightedOption'];
|
|
77
|
+
const allowedProps = ['renderLabel', 'inputValue', 'isShowingOptions', 'id', 'size', 'assistiveText', 'placeholder', 'interaction', 'isRequired', 'isInline', 'width', 'htmlSize', 'visibleOptionsCount', 'isOptionContentAppliedToInput', 'optionsMaxHeight', 'optionsMaxWidth', 'messages', 'placement', 'constrain', 'mountNode', 'onFocus', 'onBlur', 'onInputChange', 'onRequestShowOptions', 'onRequestHideOptions', 'onRequestHighlightOption', 'onRequestSelectOption', 'inputRef', 'listRef', 'renderBeforeInput', 'renderAfterInput', 'children', 'shouldNotWrap', 'scrollToHighlightedOption'];
|
|
77
78
|
export { propTypes, allowedProps };
|