diff --git a/packages/atomic/src/components/common/items-per-page/choices.tsx b/packages/atomic/src/components/common/items-per-page/choices.tsx index 85354f2b796..18f50ccae5b 100644 --- a/packages/atomic/src/components/common/items-per-page/choices.tsx +++ b/packages/atomic/src/components/common/items-per-page/choices.tsx @@ -60,6 +60,7 @@ export const Choices: FunctionalComponent = ({ class="btn-page focus-visible:bg-neutral-light" part={parts.join(' ')} text={text} + selectWhenFocused={false} > ); })} diff --git a/packages/atomic/src/components/common/pager/pager-buttons.tsx b/packages/atomic/src/components/common/pager/pager-buttons.tsx index 6dab16cdc2e..3a17e465f16 100644 --- a/packages/atomic/src/components/common/pager/pager-buttons.tsx +++ b/packages/atomic/src/components/common/pager/pager-buttons.tsx @@ -69,6 +69,7 @@ export const PagerPageButton: FunctionalComponent = ( return ( = ( ) => { return ( diff --git a/packages/atomic/src/components/common/radio-button.tsx b/packages/atomic/src/components/common/radio-button.tsx index b615bd0cd8e..03bf63a00eb 100644 --- a/packages/atomic/src/components/common/radio-button.tsx +++ b/packages/atomic/src/components/common/radio-button.tsx @@ -9,6 +9,7 @@ import { export interface RadioButtonProps { groupName: string; + selectWhenFocused?: boolean; onChecked?(): void; style?: ButtonStyle; key?: string | number; @@ -39,6 +40,61 @@ export const RadioButton: FunctionalComponent = (props) => { classNames.push(props.class); } + const handleKeyDown = (event: KeyboardEvent) => { + if (props.selectWhenFocused !== false) { + return; + } + const {key} = event; + const radioGroup = (event.currentTarget as HTMLElement).parentNode; + + if (!radioGroup || !isArrowKey(key)) { + return; + } + + event.preventDefault(); + + const buttons = getRadioButtons(radioGroup); + const currentIndex = getCurrentIndex( + buttons, + event.currentTarget as HTMLInputElement + ); + const newIndex = getNewIndex(key, currentIndex, buttons.length); + + if (buttons[newIndex]) { + buttons[newIndex].focus(); + } + }; + + const isArrowKey = (key: string) => { + return ['ArrowLeft', 'ArrowRight', 'ArrowDown', 'ArrowUp'].includes(key); + }; + + const getRadioButtons = (radioGroup: ParentNode) => { + return Array.from( + radioGroup.querySelectorAll('[type="radio"]') + ) as HTMLInputElement[]; + }; + + const getCurrentIndex = ( + buttons: HTMLInputElement[], + currentButton: HTMLInputElement + ) => { + return buttons.findIndex((button) => button === currentButton); + }; + + const getNewIndex = (key: string, currentIndex: number, length: number) => { + switch (key) { + case 'ArrowLeft': + case 'ArrowUp': + return (currentIndex - 1 + length) % length; + case 'ArrowRight': + case 'ArrowDown': + return (currentIndex + 1) % length; + default: + return currentIndex; + } + }; + const attributes = { name: props.groupName, key: props.key, @@ -53,6 +109,7 @@ export const RadioButton: FunctionalComponent = (props) => { return ( (e.currentTarget as HTMLInputElement).checked && props.onChecked?.() diff --git a/packages/atomic/src/components/search/atomic-results-per-page/atomic-results-per-page.tsx b/packages/atomic/src/components/search/atomic-results-per-page/atomic-results-per-page.tsx index 922de482400..1f89297257f 100644 --- a/packages/atomic/src/components/search/atomic-results-per-page/atomic-results-per-page.tsx +++ b/packages/atomic/src/components/search/atomic-results-per-page/atomic-results-per-page.tsx @@ -102,7 +102,7 @@ export class AtomicResultsPerPage implements InitializableComponent { hasItems={this.searchStatusState.hasResults} isAppLoaded={this.bindings.store.isAppLoaded()} > -
+