/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import {ThemeClassNames} from '@docusaurus/theme-common'; import { useScrollPositionBlocker, useTabsContextValue, useTabs, sanitizeTabsChildren, TabsProvider, } from '@docusaurus/theme-common/internal'; import useIsBrowser from '@docusaurus/useIsBrowser'; import type {Props} from '@theme/Tabs'; import styles from './styles.module.css'; function TabList({className}: {className?: string}) { const {selectedValue, selectValue, tabValues, block} = useTabs(); const tabRefs: (HTMLLIElement | null)[] = []; const {blockElementScrollPositionUntilNextRender} = useScrollPositionBlocker(); const handleTabChange = ( event: | React.FocusEvent | React.MouseEvent | React.KeyboardEvent, ) => { const newTab = event.currentTarget; const newTabIndex = tabRefs.indexOf(newTab); const newTabValue = tabValues[newTabIndex]!.value; if (newTabValue !== selectedValue) { blockElementScrollPositionUntilNextRender(newTab); selectValue(newTabValue); } }; const handleKeydown = (event: React.KeyboardEvent) => { let focusElement: HTMLLIElement | null = null; switch (event.key) { case 'Enter': { handleTabChange(event); break; } case 'ArrowRight': { const nextTab = tabRefs.indexOf(event.currentTarget) + 1; focusElement = tabRefs[nextTab] ?? tabRefs[0]!; break; } case 'ArrowLeft': { const prevTab = tabRefs.indexOf(event.currentTarget) - 1; focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!; break; } default: break; } focusElement?.focus(); }; return (
    {tabValues.map(({value, label, attributes}) => (
  • { tabRefs.push(ref); }} onKeyDown={handleKeydown} onClick={handleTabChange} {...attributes} className={clsx( 'tabs__item', styles.tabItem, attributes?.className as string, { 'tabs__item--active': selectedValue === value, }, )}> {label ?? value}
  • ))}
); } function TabContent({children}: {children: ReactNode}) { return
{children}
; } function TabsContainer({ className, children, }: { className?: string; children: ReactNode; }): ReactNode { return (
{children}
); } export default function Tabs(props: Props): ReactNode { const isBrowser = useIsBrowser(); const value = useTabsContextValue(props); return ( {sanitizeTabsChildren(props.children)} ); }