import type { HTMLAttributes } from "react"; import { forwardRef } from "react"; import { bem, useIsUserInteractionMode, useKeyboardFocus, } from "@react-md/utils"; import cn from "classnames"; import type { TabsConfig } from "./types"; import { useTabIndicatorStyles } from "./useTabIndicatorStyles"; export interface TabsListProps extends HTMLAttributes, TabsConfig { /** * The current active tab index to determine which tabs to animate in and out * of view. */ activeIndex: number; /** * A function to call when the `activeIndex` should change due to keyboard * movement or clicking on a tab. */ onActiveIndexChange(activeIndex: number): void; /** * Boolean if the indicator transition should be disabled while the active tab * index changes. * * @defaultValue `false` */ disableTransition?: boolean; } const styles = bem("rmd-tabs"); /** * The `TabsList` component is the container for all the individual `Tab`s that * should be rendered. This handles adding an active indicator underneath the * active tab and animating it to the new location when a new tab becomes * active. It also handles the ability update which tab is selected when it has * been clicked or updated with keyboard movement. * * This should probably not be used outside of this package unless a custom * implementation is desired. */ export const TabsList = forwardRef( function TabsList( { style, className, onFocus, onKeyDown, children, activeIndex, align = "left", automatic = false, padded = false, orientation = "horizontal", onActiveIndexChange, disableTransition = false, ...props }, ref ) { const horizontal = orientation === "horizontal"; const isKeyboard = useIsUserInteractionMode("keyboard"); const { focusIndex: _focusIndex, ...eventHandlers } = useKeyboardFocus({ onFocus, onKeyDown, onFocusChange(element, focusIndex) { element.focus(); if (automatic) { onActiveIndexChange(focusIndex); } }, }); const { refCallback, indicatorStyles } = useTabIndicatorStyles({ ref, activeIndex, }); return (
{children}
); } );