Skip to content

Commit

Permalink
fix(combobox): prevent selection of disabled items (#3260)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSisb committed Jun 8, 2023
1 parent 9e5b3b7 commit 1ada1e3
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changeset/neat-donuts-enjoy.md
@@ -0,0 +1,6 @@
---
'@twilio-paste/combobox': patch
'@twilio-paste/core': patch
---

[Combobox] prevent selection of disabled items when using keyboard navigation and the enter key
6 changes: 6 additions & 0 deletions .changeset/thin-kids-beam.md
@@ -0,0 +1,6 @@
---
'@twilio-paste/combobox-primitive': patch
'@twilio-paste/core': patch
---

[Combobox Primitive] export new type `UseComboboxPrimitiveStateChangeOptions` to help type stateReducers
Expand Up @@ -100,6 +100,7 @@ const Combobox = React.forwardRef<HTMLInputElement, ComboboxProps>(
state,
getA11yStatusMessage,
getA11ySelectionMessage,
disabledItems,
});

if (
Expand Down
@@ -1,6 +1,11 @@
import * as React from 'react';
import {useComboboxPrimitive} from '@twilio-paste/combobox-primitive';
import type {UseComboboxPrimitiveStateChange, UseComboboxPrimitiveReturnValue} from '@twilio-paste/combobox-primitive';
import type {
UseComboboxPrimitiveState,
UseComboboxPrimitiveStateChange,
UseComboboxPrimitiveStateChangeOptions,
UseComboboxPrimitiveReturnValue,
} from '@twilio-paste/combobox-primitive';
import isEmpty from 'lodash/isEmpty';

import type {ComboboxProps} from '../types';
Expand All @@ -16,6 +21,7 @@ type DefaultStateProps = {
selectedItem: ComboboxProps['selectedItem'];
initialSelectedItem: ComboboxProps['initialSelectedItem'];
items: ComboboxProps['items'];
disabledItems: ComboboxProps['disabledItems'];
getA11yStatusMessage: ComboboxProps['getA11yStatusMessage'];
getA11ySelectionMessage: ComboboxProps['getA11ySelectionMessage'];
};
Expand All @@ -33,10 +39,24 @@ const getDefaultState = ({
items,
getA11yStatusMessage,
getA11ySelectionMessage,
disabledItems,
}: DefaultStateProps): Partial<UseComboboxPrimitiveReturnValue<any>> => {
const stateReducer = (
state: UseComboboxPrimitiveState<any>,
actionAndChanges: UseComboboxPrimitiveStateChangeOptions<any>
): Partial<UseComboboxPrimitiveState<any>> => {
// If the item to be selected is disabled, return the current state without changes
if (disabledItems?.includes(actionAndChanges.changes.selectedItem)) {
return state;
}

return actionAndChanges.changes;
};

return useComboboxPrimitive({
initialSelectedItem,
items,
stateReducer,
onHighlightedIndexChange: React.useCallback(
(changes: UseComboboxPrimitiveStateChange<string>) => {
if (onHighlightedIndexChange) {
Expand Down
Expand Up @@ -484,6 +484,7 @@ export const ComboboxObject: StoryFn = () => {
}
}}
itemToString={(item: ObjectItem) => (item ? item.label : '')}
disabledItems={objectItems.slice(2, 5)}
/>
);
};
Expand Down
1 change: 1 addition & 0 deletions packages/paste-core/primitives/combobox/src/index.tsx
Expand Up @@ -13,6 +13,7 @@ export type {
UseComboboxState as UseComboboxPrimitiveState,
UseComboboxReturnValue as UseComboboxPrimitiveReturnValue,
UseComboboxStateChange as UseComboboxPrimitiveStateChange,
UseComboboxStateChangeOptions as UseComboboxPrimitiveStateChangeOptions,
UseComboboxGetItemPropsOptions as UseComboboxPrimitiveGetItemPropsOptions,
UseComboboxGetMenuPropsOptions as UseComboboxPrimitiveGetMenuPropsOptions,
GetPropsCommonOptions as GetComboboxPrimitivePropsCommonOptions,
Expand Down

0 comments on commit 1ada1e3

Please sign in to comment.