@thecb/components 6.0.0-beta.3 → 6.0.0-beta.6
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/package.json
CHANGED
|
@@ -74,10 +74,10 @@ const DropdownItemWrapper = styled.div`
|
|
|
74
74
|
|
|
75
75
|
const SearchInput = styled.input`
|
|
76
76
|
border: none;
|
|
77
|
-
background-color:
|
|
78
|
-
themeValues.hoverColor && themeValues.hoverColor};
|
|
77
|
+
background-color: transparent;
|
|
79
78
|
font-size: 16px;
|
|
80
79
|
height: 24px;
|
|
80
|
+
min-width: 80%;
|
|
81
81
|
`;
|
|
82
82
|
|
|
83
83
|
const Dropdown = ({
|
|
@@ -94,7 +94,9 @@ const Dropdown = ({
|
|
|
94
94
|
widthFitOptions = false,
|
|
95
95
|
disabled,
|
|
96
96
|
hasTitles = false,
|
|
97
|
-
autoEraseTypeAhead = true // legacy behavior as of 05/22
|
|
97
|
+
autoEraseTypeAhead = true, // legacy behavior as of 05/22
|
|
98
|
+
ariaLabelledby,
|
|
99
|
+
autocompleteValue = "" // autofill item for browsers, like country-name or address-level1 for state
|
|
98
100
|
}) => {
|
|
99
101
|
const [inputValue, setInputValue] = useState("");
|
|
100
102
|
const [optionsState, setOptionsState] = useState([]);
|
|
@@ -161,10 +163,18 @@ const Dropdown = ({
|
|
|
161
163
|
break;
|
|
162
164
|
case "Backspace" || "Delete":
|
|
163
165
|
e.preventDefault();
|
|
164
|
-
console.log("input value is", inputValue);
|
|
165
|
-
console.log("new input value will be", inputValue.slice(0, -1));
|
|
166
166
|
setInputValue(inputValue.slice(0, -1));
|
|
167
167
|
break;
|
|
168
|
+
case "Home":
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
optionRefs.current[0].current.focus();
|
|
171
|
+
break;
|
|
172
|
+
case "End":
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
optionRefs.current[
|
|
175
|
+
optionRefs?.current?.length ?? 0 - 1
|
|
176
|
+
].current.focus();
|
|
177
|
+
break;
|
|
168
178
|
}
|
|
169
179
|
if ((keyCode > 64 && keyCode < 91) || keyCode == 32 || keyCode == 189) {
|
|
170
180
|
e.preventDefault();
|
|
@@ -179,7 +189,11 @@ const Dropdown = ({
|
|
|
179
189
|
);
|
|
180
190
|
console.log("selected refs in isopen useffect", selectedRef);
|
|
181
191
|
console.log("value in isopen useffect", value);
|
|
182
|
-
if (isOpen &&
|
|
192
|
+
if (isOpen && selectedRef !== undefined) {
|
|
193
|
+
// WAI-ARIA requires the selected option to receive focus
|
|
194
|
+
selectedRef.current.focus();
|
|
195
|
+
} else if (isOpen && optionRefs.current[0].current) {
|
|
196
|
+
// If no selected option, first option receives focus
|
|
183
197
|
optionRefs.current[0].current.focus();
|
|
184
198
|
}
|
|
185
199
|
clearTimeout(timer);
|
|
@@ -207,6 +221,8 @@ const Dropdown = ({
|
|
|
207
221
|
!disabledValues.includes(filteredOptions[0].value) &&
|
|
208
222
|
filteredOptions[0].text != placeholder
|
|
209
223
|
) {
|
|
224
|
+
console.log("filtered options are", filteredOptions);
|
|
225
|
+
console.log("option refs are", optionRefs);
|
|
210
226
|
onSelect(filteredOptions[0].value);
|
|
211
227
|
}
|
|
212
228
|
if (optionRefs.current[0].current) {
|
|
@@ -224,6 +240,10 @@ const Dropdown = ({
|
|
|
224
240
|
width="100%"
|
|
225
241
|
hoverStyles={`background-color: ${themeValues.hoverColor};`}
|
|
226
242
|
aria-expanded={isOpen}
|
|
243
|
+
role="combobox"
|
|
244
|
+
aria-owns={`${ariaLabelledby}_listbox`}
|
|
245
|
+
aria-haspopup="listbox"
|
|
246
|
+
aria-labelledby={ariaLabelledby}
|
|
227
247
|
extraStyles={
|
|
228
248
|
disabled &&
|
|
229
249
|
`color: #6e727e;
|
|
@@ -256,27 +276,28 @@ const Dropdown = ({
|
|
|
256
276
|
pointer-events: none;`}
|
|
257
277
|
`}
|
|
258
278
|
>
|
|
259
|
-
<Stack
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
279
|
+
<Stack
|
|
280
|
+
direction="row"
|
|
281
|
+
bottomItem={2}
|
|
282
|
+
extraStyles={`position: relative;`}
|
|
283
|
+
>
|
|
284
|
+
<SearchInput
|
|
285
|
+
aria-label={getSelection()}
|
|
286
|
+
placeholder={getSelection()}
|
|
287
|
+
value={inputValue}
|
|
288
|
+
onChange={noop}
|
|
289
|
+
themeValues={themeValues}
|
|
290
|
+
role="searchbox"
|
|
291
|
+
type="text"
|
|
292
|
+
aria-multiline="false"
|
|
293
|
+
aria-autocomplete="list"
|
|
294
|
+
aria-controls={`${ariaLabelledby}_listbox`}
|
|
295
|
+
aria-activedescendant="selected_option"
|
|
296
|
+
isOpen={isOpen}
|
|
297
|
+
tabIndex={-1}
|
|
298
|
+
name={autocompleteValue}
|
|
299
|
+
autocomplete={autocompleteValue}
|
|
300
|
+
/>
|
|
280
301
|
<IconWrapper open={isOpen}>
|
|
281
302
|
<DropdownIcon />
|
|
282
303
|
</IconWrapper>
|
|
@@ -289,14 +310,20 @@ const Dropdown = ({
|
|
|
289
310
|
ref={dropdownRef}
|
|
290
311
|
widthFitOptions={widthFitOptions}
|
|
291
312
|
tabIndex={0}
|
|
313
|
+
role="listbox"
|
|
314
|
+
id={`${ariaLabelledby}_listbox`}
|
|
292
315
|
>
|
|
293
316
|
<Stack childGap="0">
|
|
294
317
|
{filteredOptions.map((choice, i) => {
|
|
295
|
-
if (
|
|
318
|
+
if (
|
|
319
|
+
choice.value === value &&
|
|
320
|
+
selectedRef !== optionRefs.current[i]
|
|
321
|
+
) {
|
|
296
322
|
setSelectedRef(optionRefs.current[i]);
|
|
297
323
|
}
|
|
298
324
|
return (
|
|
299
325
|
<DropdownItemWrapper
|
|
326
|
+
id={choice.value === value ? "selected_option" : choice.value}
|
|
300
327
|
key={choice.value}
|
|
301
328
|
ref={optionRefs.current[i]}
|
|
302
329
|
as="button"
|
|
@@ -304,13 +331,18 @@ const Dropdown = ({
|
|
|
304
331
|
onClick={
|
|
305
332
|
disabledValues.includes(choice.value)
|
|
306
333
|
? evt => evt.preventDefault()
|
|
307
|
-
: () =>
|
|
334
|
+
: () => {
|
|
335
|
+
setSelectedRef(optionRefs.current[i]);
|
|
336
|
+
onSelect(choice.value);
|
|
337
|
+
}
|
|
308
338
|
}
|
|
309
339
|
selected={choice.value === value}
|
|
340
|
+
aria-selected={choice.value === value}
|
|
310
341
|
disabled={disabledValues.includes(choice.value)}
|
|
311
342
|
data-qa={choice.text}
|
|
312
343
|
themeValues={themeValues}
|
|
313
344
|
title={hasTitles ? choice.text : null}
|
|
345
|
+
role="option"
|
|
314
346
|
>
|
|
315
347
|
<Text
|
|
316
348
|
variant="p"
|
|
@@ -58,7 +58,7 @@ const FormSelect = ({
|
|
|
58
58
|
</Cluster>
|
|
59
59
|
</Box>
|
|
60
60
|
<Dropdown
|
|
61
|
-
|
|
61
|
+
ariaLabelledby={labelTextWhenNoError.replace(/\s+/g, "-")}
|
|
62
62
|
maxHeight={dropdownMaxHeight}
|
|
63
63
|
hasTitles={hasTitles}
|
|
64
64
|
placeholder={options[0] ? options[0].text : ""}
|