diff --git a/src/Tabs.tsx b/src/Tabs.tsx index 35600dec9..1a5543b2b 100644 --- a/src/Tabs.tsx +++ b/src/Tabs.tsx @@ -83,13 +83,14 @@ export const Tabs = memo( return index === -1 ? 0 : index; }; + const buttonRefs = React.useRef>([]); + const [selectedTabIndex, setSelectedTabIndex] = useState(getSelectedTabIndex); useEffect(() => { if (selectedTabId === undefined) { return; } - setSelectedTabIndex(getSelectedTabIndex()); }, [selectedTabId]); @@ -104,6 +105,34 @@ export const Tabs = memo( } }); + const onKeyboardNavigation = ( + event: React.KeyboardEvent | React.KeyboardEvent + ) => { + let targetIndex = selectedTabIndex; + switch (event.key) { + case "ArrowRight": + targetIndex = selectedTabIndex < tabs.length - 1 ? selectedTabIndex + 1 : 0; + break; + case "ArrowLeft": + targetIndex = selectedTabIndex === 0 ? tabs.length - 1 : selectedTabIndex - 1; + break; + case "Home": + targetIndex = 0; + break; + case "End": + targetIndex = tabs.length - 1; + break; + } + buttonRefs.current[targetIndex]?.click(); + }; + + React.useEffect(() => { + const targetTabButton = buttonRefs.current[selectedTabIndex]; + if (targetTabButton) { + targetTabButton.focus(); + } + }, [selectedTabIndex]); + const { getPanelId, getTabId } = (function useClosure() { const id = useId(); @@ -124,10 +153,16 @@ export const Tabs = memo( style={style} {...rest} > -
    +
      onKeyboardNavigation(e)} + > {tabs.map(({ label, iconId }, tabIndex) => (