import { type Dispatch, type Ref } from "react"; import { type SlideDirection } from "../transition/SlideContainer.js"; import { type UseStateInitializer, type UseStateSetter } from "../types.js"; /** * @since 6.0.0 */ export interface TabsHookOptions { /** * This can be used to generate the ids for the different components within * the tab widget. * * @defaultValue `"tab-" + useId()` */ baseId?: string; /** * Set this to an **ordered** list of tab values when: * - using a `string` tab value * - using a `number` tab value does not represent a tab index * * See the examples on the {@link useTabs} for usage. */ tabs?: readonly TabValue[]; /** * Provide this value and {@link setActiveTab} to control the active tab * behavior. */ activeTab?: TabValue; /** @see {@link activeTab} */ setActiveTab?: Dispatch; /** * Set this to the default tab index when not controlling the active tab value * through {@link activeTab} and {@link setActiveTab}. * * @defaultValue `0` */ defaultActiveTab?: UseStateInitializer; /** Convenience pass-through prop to {@link TabProps.stacked} */ stacked?: boolean; /** Convenience pass-through prop to {@link TabProps.iconAfter} */ iconAfter?: boolean; /** Convenience pass-through props to {@link TabListProps.vertical} */ vertical?: boolean; /** * Set this to `true` if changing active tabs should no longer attempt to * scroll to the top of the tab panels container when using the * {@link TabsImplementation.getTabPanelsProps}. * * @defaultValue `false` */ disableScrollFix?: boolean; /** * Convenience prop to disable all transitions for the * {@link TabsImplementation.getTabProps} and * {@link TabsImplementation.getTabListProps}. */ disableTransition?: boolean; } /** * @since 6.0.0 */ export interface ProvidedTabProps { "aria-controls": string; id: string; active: boolean; /** Convenience pass-through prop from {@link TabsHookOptions.stacked} */ stacked?: boolean; /** Convenience pass-through prop from {@link TabsHookOptions.iconAfter} */ iconAfter?: boolean; /** Convenience pass-through prop from {@link TabsHookOptions.disableTransition} */ activeIndicator?: boolean; /** Convenience pass-through prop from {@link TabsHookOptions.vertical} and {@link TabsHookOptions.disableTransition} */ verticalActiveIndicator?: boolean; } /** * @since 6.0.0 */ export interface ProvidedTabListProps { activeIndex: number; setActiveIndex: Dispatch; vertical?: boolean; disableTransition?: boolean; } /** * @since 6.0.0 */ export interface ProvidedTabPanelProps { "aria-labelledby": string; id: string; role: "tabpanel"; active: boolean; } /** * @since 6.0.0 */ export interface ProvidedTabPanelsProps { ref: Ref; direction: SlideDirection; } /** * @since 6.0.0 */ export interface TabsImplementation { direction: SlideDirection; setDirection: UseStateSetter; activeTab?: TabValue; setActiveTab?: (nextActiveTab: TabValue) => void; getTabProps: (tabValue: TabValue) => ProvidedTabProps; getTabListProps: () => ProvidedTabListProps; getTabPanelProps: (tabValue: TabValue) => ProvidedTabPanelProps; getTabPanelsProps: (ref?: Ref) => ProvidedTabPanelsProps; } /** * @example Super Simple * ```tsx * "use client"; * * import { Tab } from "@react-md/core/tabs/Tab"; * import { TabList } from "@react-md/core/tabs/TabList"; * import { useTabs } from "@react-md/core/tabs/useTabs"; * import { Slide } from "@react-md/core/transition/Slide"; * import { SlideContainer } from "@react-md/core/transition/SlideContainer"; * import { type ReactElement } from "react"; * * function Example(): ReactElement { * const { * activeTab, * setActiveTab, * direction, * setDirection, * getTabListProps, * getTabPanelProps, * getTabPanelsProps, * getTabProps, * } = useTabs(); * * return ( * <> * * Tab 1 * Tab 2 * Tab 3 * * * Tab 1 Content * Tab 2 Content * Tab 3 Content * * * ); * } * ``` * * @see {@link https://react-md.dev/components/tabs | Tabs Demos} * @since 6.0.0 */ export declare function useTabs(): TabsImplementation & { activeTab: number; setActiveTab: number; }; /** * The tab behavior can be controlled by providing the `activeTab` and * `setActiveTab` options. * * @example Controlled * ```tsx * "use client"; * * import { Tab } from "@react-md/core/tabs/Tab"; * import { TabList } from "@react-md/core/tabs/TabList"; * import { useTabs } from "@react-md/core/tabs/useTabs"; * import { Slide } from "@react-md/core/transition/Slide"; * import { SlideContainer } from "@react-md/core/transition/SlideContainer"; * import { type ReactElement, useState } from "react"; * * function Example(): ReactElement { * const [activeTab, setActiveTab] = useState(1); * * const { * direction, * setDirection, * getTabListProps, * getTabPanelProps, * getTabPanelsProps, * getTabProps, * } = useTabs({ * activeTab, * setActiveTab, * }); * * return ( * <> * * Tab 1 * Tab 2 * Tab 3 * * * Tab 1 Content * Tab 2 Content * Tab 3 Content * * * ); * } * ``` * * @see {@link https://react-md.dev/components/tabs | Tabs Demos} * @since 6.0.0 */ export declare function useTabs(options: TabsHookOptions & { tabs?: readonly TabValue[]; activeTab: TabValue; setActiveTab: Dispatch; defaultActiveTab?: never; }): TabsImplementation & { activeTab?: never; setActiveTab?: never; }; export declare function useTabs(options: TabsHookOptions & { tabs?: readonly TabValue[]; activeTab?: never; setActiveTab?: never; defaultActiveTab?: UseStateInitializer; }): TabsImplementation & { activeTab: TabValue; setActiveTab: Dispatch; }; /** * When using string values, the {@link TabsHookOptions.tabs} option **must** be * provided to determine the correct active tab index. * * @example String Value Simple * ```tsx * "use client"; * * import { Tab } from "@react-md/core/tabs/Tab"; * import { TabList } from "@react-md/core/tabs/TabList"; * import { useTabs } from "@react-md/core/tabs/useTabs"; * import { Slide } from "@react-md/core/transition/Slide"; * import { SlideContainer } from "@react-md/core/transition/SlideContainer"; * import { type ReactElement } from "react"; * * const tabs = ["value-1", "value-2", "value-3"]; * * function Example(): ReactElement { * const { * activeTab, * setActiveTab, * direction, * setDirection, * getTabListProps, * getTabPanelProps, * getTabPanelsProps, * getTabProps, * } = useTabs({ tabs }); * * return ( * <> * * {tabs.map((value) => ( * {value} * ))} * * * {tabs.map((value) => ( * {value} Content * ))} * * * ); * } * ``` * * @see {@link https://react-md.dev/components/tabs | Tabs Demos} * @since 6.0.0 */ export declare function useTabs(options: TabsHookOptions & { tabs: readonly TabValue[]; activeTab?: never; setActiveTab?: never; defaultActiveTab?: UseStateInitializer; }): TabsImplementation & { activeTab: TabValue; setActiveTab: Dispatch; }; /** * When using string values, the {@link TabsHookOptions.tabs} option **must** be * provided to determine the correct active tab index. * * @example String Controlled Simple * ```tsx * import { Tab } from "@react-md/core/tabs/Tab"; * import { TabList } from "@react-md/core/tabs/TabList"; * import { useTabs } from "@react-md/core/tabs/useTabs"; * import { Slide } from "@react-md/core/transition/Slide"; * import { SlideContainer } from "@react-md/core/transition/SlideContainer"; * import { type ReactElement } from "react"; * * const tabs = ["value-1", "value-2", "value-3"] as const; * * function Example(): ReactElement { * const [activeTab, setActiveTab] = useState(tabs[0]); * * const { * direction, * setDirection, * getTabListProps, * getTabPanelProps, * getTabPanelsProps, * getTabProps, * } = useTabs({ * tabs, * activeTab, * setActiveTab, * }); * * return ( * <> * * {tabs.map((value) => ( * {value} * ))} * * * {tabs.map((value) => ( * {value} Content * ))} * * * ); * } * ``` * * @example Navigation Tabs * ```tsx * "use client"; * * import { Tab } from "@react-md/core/tabs/Tab"; * import { TabList } from "@react-md/core/tabs/TabList"; * import { useTabs } from "@react-md/core/tabs/useTabs"; * import Link from "next/link.js"; * import { usePathname } from "next/navigation.js"; * import { * type AnchorHTMLAttributes, * type ReactElement, * forwardRef, * useEffect, * useState, * } from "react"; * * // this just fixes the `href` type definition causing errors * const SimpleLink = forwardRef< * HTMLAnchorElement, * AnchorHTMLAttributes & { href: string } * >(function SimpleLink(props, ref) { * return ; * }); * * const PATHNAME_TABS = ["/", "/page-1", "/page-2"]; * * function Layout({ children }: PropsWithChildren) { * const pathname = usePathname(); * const { getTabListProps, getTabProps } = useTabs({ * tabs: PATHNAME_TABS, * activeTab: pathname, * setActiveTab: noop, * }); * * return ( * <> * * Home * Page 1 * Page 2 * *
{children}
* * ); * } * ``` * * @see {@link https://react-md.dev/components/tabs | Tabs Demos} * @since 6.0.0 */ export declare function useTabs(options: TabsHookOptions & { tabs: readonly TabValue[]; activeTab: TabValue; setActiveTab: Dispatch; defaultActiveTab?: never; }): TabsImplementation & { activeTab?: never; setActiveTab?: never; };