Skip to content

Commit fe62023

Browse files
committed
fix(combobox): handle select-only collapse listbox on space/enter
1 parent 66ec279 commit fe62023

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

packages/combobox/.size-snapshot.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
{
22
"index.cjs.js": {
3-
"bundled": 25990,
4-
"minified": 14055,
5-
"gzipped": 3987
3+
"bundled": 26606,
4+
"minified": 14322,
5+
"gzipped": 4032
66
},
77
"index.esm.js": {
8-
"bundled": 24979,
9-
"minified": 13045,
10-
"gzipped": 3967,
8+
"bundled": 25519,
9+
"minified": 13236,
10+
"gzipped": 4012,
1111
"treeshaked": {
1212
"rollup": {
1313
"code": 1296,
1414
"import_statements": 177
1515
},
1616
"webpack": {
17-
"code": 12979
17+
"code": 13181
1818
}
1919
}
2020
}

packages/combobox/src/ComboboxContainer.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ describe('ComboboxContainer', () => {
604604

605605
expect(trigger).toHaveAttribute('aria-expanded', 'true');
606606

607-
await user.keyboard('{Escape}');
607+
await user.keyboard('{Enter}');
608608

609609
expect(trigger).toHaveAttribute('aria-expanded', 'false');
610610
});

packages/combobox/src/useCombobox.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,10 @@ export const useCombobox = <
348348

349349
useLayoutEffect(
350350
() => {
351-
// Trigger autocomplete selection override. Use layout effect to prevent
352-
// `defaultActiveIndex` flash.
351+
// Trigger autocomplete/select-only selection override. Use layout effect
352+
// to prevent `defaultActiveIndex` flash.
353353
if (
354-
isAutocomplete &&
354+
(isAutocomplete || !isEditable) &&
355355
_isExpanded &&
356356
!previousStateRef.current?.isOpen &&
357357
_selectionValue &&
@@ -374,6 +374,7 @@ export const useCombobox = <
374374
/* eslint-disable-line react-hooks/exhaustive-deps */ [
375375
/* matchValue, // prevent match active index reset */
376376
isAutocomplete,
377+
isEditable,
377378
_isExpanded,
378379
_selectionValue,
379380
_inputValue,
@@ -478,8 +479,24 @@ export const useCombobox = <
478479
const handleKeyDown = (event: KeyboardEvent) => {
479480
event.stopPropagation();
480481

482+
/* istanbul ignore else */
481483
if (!_isExpanded && (event.key === KEYS.SPACE || event.key === KEYS.ENTER)) {
484+
event.preventDefault();
482485
openListbox();
486+
} else if (
487+
_isExpanded &&
488+
!matchValue &&
489+
(event.key === KEYS.SPACE || event.key === KEYS.ENTER)
490+
) {
491+
event.preventDefault();
492+
493+
if (_activeIndex !== -1) {
494+
setDownshiftSelection(values[_activeIndex]);
495+
}
496+
497+
if (!isMultiselectable) {
498+
closeListbox();
499+
}
483500
} else if (/^(?:\S| ){1}$/u.test(event.key)) {
484501
// Handle option matching described under
485502
// https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/#kbd_label
@@ -547,12 +564,14 @@ export const useCombobox = <
547564
closeListbox,
548565
openListbox,
549566
setActiveIndex,
567+
setDownshiftSelection,
550568
matchValue,
551569
values,
552570
labels,
553571
triggerContainsInput,
554572
isAutocomplete,
555573
isEditable,
574+
isMultiselectable,
556575
inputRef
557576
]
558577
);
@@ -666,21 +685,27 @@ export const useCombobox = <
666685
const triggerContainsTag =
667686
event.target instanceof Element && triggerRef.current?.contains(event.target);
668687

688+
if (triggerContainsTag && !isEditable) {
689+
event.stopPropagation();
690+
}
691+
669692
if (
670693
triggerContainsTag &&
671-
(event.key === KEYS.DOWN || event.key === KEYS.UP || event.key === KEYS.ESCAPE)
694+
(event.key === KEYS.DOWN ||
695+
event.key === KEYS.UP ||
696+
event.key === KEYS.ESCAPE ||
697+
(!isEditable && (event.key === KEYS.ENTER || event.key === KEYS.SPACE)))
672698
) {
673699
const inputProps = getDownshiftInputProps();
674700

675701
if (isEditable) {
676702
inputRef.current?.focus();
677703
} else {
704+
event.preventDefault();
678705
triggerRef.current?.focus();
679706
}
680707

681708
inputProps.onKeyDown(event);
682-
} else if (triggerContainsTag && !isEditable) {
683-
event.stopPropagation();
684709
}
685710
}
686711
};

0 commit comments

Comments
 (0)