From 4b92d9dd4f44e12b299b7d0d08ddeeaaeff556fd Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Tue, 28 Apr 2026 23:38:59 +0300 Subject: [PATCH] correct tab indexes for buttons --- src/components/Chips/Chip/Chip.tsx | 2 +- src/components/MetaPreview/MetaPreview.js | 8 +++---- .../useContentGamepadNavigation.tsx | 24 ++++++++++++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/components/Chips/Chip/Chip.tsx b/src/components/Chips/Chip/Chip.tsx index cbb2487f7..4cde13bb4 100644 --- a/src/components/Chips/Chip/Chip.tsx +++ b/src/components/Chips/Chip/Chip.tsx @@ -33,7 +33,7 @@ const Chip = memo(({ label, value, active, onSelect }: Props) => { ref={ref} key={value} className={classNames(styles['chip'], { [styles['active']]: active })} - tabIndex={-1} + tabIndex={0} data-value={value} onClick={onClick} > diff --git a/src/components/MetaPreview/MetaPreview.js b/src/components/MetaPreview/MetaPreview.js index 5fa7d8ff0..6fba9c098 100644 --- a/src/components/MetaPreview/MetaPreview.js +++ b/src/components/MetaPreview/MetaPreview.js @@ -159,7 +159,7 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou title={linksGroups.get(CONSTANTS.IMDB_LINK_CATEGORY).label} href={linksGroups.get(CONSTANTS.IMDB_LINK_CATEGORY).href} target={'_blank'} - {...(compact ? { tabIndex: -1 } : null)} + tabIndex={0} >
{linksGroups.get(CONSTANTS.IMDB_LINK_CATEGORY).label}
@@ -214,7 +214,7 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou className={styles['action-button']} icon={'trailer'} label={t('TRAILER')} - tabIndex={compact ? -1 : 0} + tabIndex={0} href={trailerHref} tooltip={compact} /> @@ -232,7 +232,7 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou className={classnames(styles['action-button'], styles['show-button'])} icon={'play'} label={t('SHOW')} - tabIndex={compact ? -1 : 0} + tabIndex={0} href={showHref} /> : @@ -255,7 +255,7 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou icon={'share'} label={t('CTX_SHARE')} tooltip={true} - tabIndex={compact ? -1 : 0} + tabIndex={0} onClick={openShareModal} /> { diff --git a/src/services/GamepadNavigation/useContentGamepadNavigation.tsx b/src/services/GamepadNavigation/useContentGamepadNavigation.tsx index 22162d77d..10c65dfe5 100644 --- a/src/services/GamepadNavigation/useContentGamepadNavigation.tsx +++ b/src/services/GamepadNavigation/useContentGamepadNavigation.tsx @@ -3,6 +3,18 @@ import { useEffect } from 'react'; import { useGamepad } from '../GamepadContext'; +const FOCUSABLE = '[tabindex="0"]'; + +const getActiveScope = (fallback: HTMLDivElement | null): HTMLElement | null => { + const modal = document.querySelector('.modals-container'); + if (modal && modal.children.length > 0) return modal; + + const dropdown = fallback?.querySelector('[class*="dropdown"][class*="open"]'); + if (dropdown) return dropdown; + + return fallback; +}; + const useContentGamepadNavigation = ( sectionRef: React.RefObject, gamepadHandlerId: string @@ -13,12 +25,13 @@ const useContentGamepadNavigation = ( const handleGamepadNavigation = ( direction: 'left' | 'right' | 'up' | 'down' ) => { + const scope = getActiveScope(sectionRef.current); const elements = Array.from( - sectionRef.current?.querySelectorAll('[tabindex="0"]') || [] + scope?.querySelectorAll(FOCUSABLE) || [] ); if (elements.length === 0) return; - const activeElement = sectionRef.current?.querySelector(':focus'); + const activeElement = (scope ?? document)?.querySelector(':focus'); if (!activeElement) { elements[0].focus(); @@ -26,9 +39,7 @@ const useContentGamepadNavigation = ( } let closestElement: HTMLDivElement | null = null; - const currentRect = activeElement.getBoundingClientRect(); - let closestDistance = Infinity; elements.forEach((el) => { @@ -92,12 +103,13 @@ const useContentGamepadNavigation = ( }; const onSelect = () => { + const scope = getActiveScope(sectionRef.current); const elements = Array.from( - sectionRef.current?.querySelectorAll('[tabindex="0"]') || [] + scope?.querySelectorAll(FOCUSABLE) || [] ); if (elements.length === 0) return; - const activeElement = sectionRef.current?.querySelector(':focus'); + const activeElement = (scope ?? document)?.querySelector(':focus'); if (!activeElement) { elements[0].focus();