From d8431869c598c6bc5d4d84c820252bf70957d57c Mon Sep 17 00:00:00 2001 From: Eric Giovanola Date: Fri, 29 Nov 2024 21:56:09 -0800 Subject: [PATCH] Fix disabled items still selectable via hint (#835, #865) --- .../Typeahead/Typeahead.stories.tsx | 10 ++++++ src/components/Typeahead/Typeahead.test.tsx | 17 ++++++++++ .../__snapshots__/Typeahead.test.tsx.snap | 32 +++++++++++++++++++ src/utils/getHintText.test.ts | 12 +++++++ src/utils/getHintText.ts | 2 ++ 5 files changed, 73 insertions(+) diff --git a/src/components/Typeahead/Typeahead.stories.tsx b/src/components/Typeahead/Typeahead.stories.tsx index 06832884..c87ddb96 100644 --- a/src/components/Typeahead/Typeahead.stories.tsx +++ b/src/components/Typeahead/Typeahead.stories.tsx @@ -95,6 +95,16 @@ AllowNew.args = { allowNew: true, }; +export const DisabledItem = Template.bind({}); +DisabledItem.args = { + ...defaultProps, + options: options.map((option) => + option.name === 'Alabama' + ? { ...option, disabled: true } + : { ...option, disabled: false } + ), +}; + export const CustomInput = Template.bind({}); CustomInput.args = { ...defaultProps, diff --git a/src/components/Typeahead/Typeahead.test.tsx b/src/components/Typeahead/Typeahead.test.tsx index b133bcc2..0f8fa6c9 100644 --- a/src/components/Typeahead/Typeahead.test.tsx +++ b/src/components/Typeahead/Typeahead.test.tsx @@ -57,6 +57,7 @@ const { InputValidation, Pagination, AllowNew, + DisabledItem, CustomMenu, Controlled, } = composeStories(stories); @@ -736,6 +737,22 @@ describe('', () => { expect(getMenu()).not.toBeInTheDocument(); expect(hint).toHaveValue(''); }); + + it('only displays a hint for non-disabled items', async () => { + const user = userEvent.setup(); + const { container } = render(); + const input = getInput(); + const hint = getHint(container); + + await user.type(input, 'Ala'); + + // The hint should not display if the initial item is disabled. + expect(hint).toHaveValue(''); + + await user.clear(input); + await user.type(input, 'Ari'); + expect(hint).toHaveValue('Arizona'); + }); }); describe('behavior when selecting the hinted result', () => { diff --git a/src/components/Typeahead/__snapshots__/Typeahead.test.tsx.snap b/src/components/Typeahead/__snapshots__/Typeahead.test.tsx.snap index 67ca69a7..18befd09 100644 --- a/src/components/Typeahead/__snapshots__/Typeahead.test.tsx.snap +++ b/src/components/Typeahead/__snapshots__/Typeahead.test.tsx.snap @@ -223,6 +223,38 @@ exports[` Default story renders snapshot 1`] = ` `; +exports[` DisabledItem story renders snapshot 1`] = ` +
+
+ + +
+
+`; + exports[` InputGrouping story renders snapshot 1`] = `
{ expect(hintText).toBe(''); }); + it('returns an empty string when the initial item is disabled', () => { + const initialItem = { ...props.initialItem, disabled: true }; + const hintText = getHintText({ ...props, initialItem }); + expect(hintText).toBe(''); + }); + + it('returns the hint string when the initial item is not disabled', () => { + const initialItem = { ...props.initialItem, disabled: false }; + const hintText = getHintText({ ...props, initialItem }); + expect(hintText).toBe('alAbama'); + }); + it('handles string with composed diacritical marks', () => { const hintText = getHintText({ ...props, diff --git a/src/utils/getHintText.ts b/src/utils/getHintText.ts index 1648dd18..32545103 100644 --- a/src/utils/getHintText.ts +++ b/src/utils/getHintText.ts @@ -38,6 +38,8 @@ function getHintText({ !initialItem || // The initial item is a custom option. (!isString(initialItem) && hasOwnProperty(initialItem, 'customOption')) || + // The initial item is disabled + (!isString(initialItem) && initialItem.disabled) || // One of the menu items is active. activeIndex > -1 || // There's already a selection in single-select mode.