From 0560aebb8b59b63970602b872dfd195c365139d7 Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Wed, 3 Dec 2025 12:44:46 +0100 Subject: [PATCH] UI: Fix kb nav bug on reset options in Select --- .../components/Select/Select.stories.tsx | 41 +++++++++++++++++++ .../components/components/Select/Select.tsx | 13 ++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/code/core/src/components/components/Select/Select.stories.tsx b/code/core/src/components/components/Select/Select.stories.tsx index 18b232b3a7c5..0cf7721783a3 100644 --- a/code/core/src/components/components/Select/Select.stories.tsx +++ b/code/core/src/components/components/Select/Select.stories.tsx @@ -429,6 +429,47 @@ export const KeyboardSelectionMultiSS = meta.story({ play: kbMultiSelectionTest(' ', ' '), }); +export const FullArrowNavigation = meta.story({ + play: async ({ canvas, step }) => { + const selectButton = await canvas.findByRole('button'); + await step('Open select', async () => { + selectButton.focus(); + await userEvent.keyboard('{ArrowDown}'); + expect(selectButton).toHaveTextContent('Tadpole'); + }); + + await step('Navigate to option 2 with ArrowDown', async () => { + await userEvent.keyboard('{ArrowDown}'); + expect(selectButton).toHaveTextContent('Pollywog'); + }); + + await step('Navigate to option 3 with ArrowDown', async () => { + await userEvent.keyboard('{ArrowDown}'); + expect(selectButton).toHaveTextContent('Frog'); + }); + + await step('Loop back to option 1 with ArrowDown', async () => { + await userEvent.keyboard('{ArrowDown}'); + expect(selectButton).toHaveTextContent('Tadpole'); + }); + + await step('Navigate backwards with ArrowUp', async () => { + await userEvent.keyboard('{ArrowUp}'); + expect(selectButton).toHaveTextContent('Frog'); + }); + + await step('Navigate backwards with ArrowUp', async () => { + await userEvent.keyboard('{ArrowUp}'); + expect(selectButton).toHaveTextContent('Pollywog'); + }); + + await step('Navigate back to option 1 with ArrowUp', async () => { + await userEvent.keyboard('{ArrowUp}'); + expect(selectButton).toHaveTextContent('Tadpole'); + }); + }, +}); + export const MouseOpenNoAutoselect = meta.story({ name: 'AutoSelect - nothing selected on Mouse open (single)', play: async ({ canvas, args, step }) => { diff --git a/code/core/src/components/components/Select/Select.tsx b/code/core/src/components/components/Select/Select.tsx index 961e2990e9e6..c8c051ef72c6 100644 --- a/code/core/src/components/components/Select/Select.tsx +++ b/code/core/src/components/components/Select/Select.tsx @@ -325,8 +325,10 @@ export const Select = forwardRef( return; } - const currentIndex = options.findIndex( - (option) => externalToValue(option.value) === activeOption.value + const currentIndex = options.findIndex((option) => + activeOption.type === 'reset' + ? 'type' in option && option.type === 'reset' + : externalToValue(option.value) === activeOption.value ); const nextIndex = currentIndex + step; @@ -349,8 +351,11 @@ export const Select = forwardRef( setActiveOption(options[Math.max(0, options.length - step)]); return; } - const currentIndex = options.findIndex( - (option) => externalToValue(option.value) === activeOption.value + + const currentIndex = options.findIndex((option) => + activeOption.type === 'reset' + ? 'type' in option && option.type === 'reset' + : externalToValue(option.value) === activeOption.value ); const nextIndex = currentIndex - step;