import React from 'react'; import { composeRenderProps, Tabs as RACTabs, Tab as RACTab, TabPanel as RACTabPanel, TabList as RACTabList, type TabProps as RACTabProps, type TabListProps as RACTabListProps, type TabsProps as RACTabsProps, type TabPanelProps as RACTabPanelProps, } from 'react-aria-components'; import { tv } from 'tailwind-variants'; import { focusRing } from '../utils'; export interface TabsProps extends RACTabsProps { tabs: Array<{ id: string; title: string; content: React.ReactNode }>; orientation?: 'vertical' | 'horizontal'; } const tabs = tv({ base: '', variants: { orientation: { vertical: 'flex flex-row', horizontal: 'flex flex-col', }, }, }); const tabListStyles = tv({ base: 'flex gap-1', variants: { orientation: { horizontal: 'flex-row', vertical: 'flex-col items-start', }, }, }); export function TabList(props: RACTabListProps) { return ( tabListStyles({ ...renderProps, className }), )} /> ); } const tabProps = tv({ extend: focusRing, base: 'flex cursor-default items-center px-4 py-1.5 text-sm font-medium transition', variants: { isSelected: { false: ` text-gray-600 hover:bg-gray-200 hover:text-gray-700 dark:text-zinc-300 dark:hover:bg-zinc-800 dark:hover:text-zinc-200 pressed:bg-gray-200 pressed:text-gray-700 dark:pressed:bg-zinc-800 dark:pressed:text-zinc-200 `, true: ` bg-gray-800 text-white dark:bg-zinc-200 dark:text-black forced-colors:bg-[Highlight] forced-colors:text-[HighlightText] `, }, isDisabled: { true: ` text-gray-200 dark:text-zinc-600 forced-colors:text-[GrayText] selected:bg-gray-200 selected:text-gray-300 dark:selected:bg-zinc-600 dark:selected:text-zinc-500 forced-colors:selected:bg-[GrayText] forced-colors:selected:text-[HighlightText] `, }, }, }); export function Tab(props: RACTabProps) { return ( tabProps({ ...renderProps, className }), )} /> ); } const tabPanelStyles = tv({ extend: focusRing, base: ` flex-1 p-4 text-base text-gray-900 dark:text-zinc-100 `, }); export function TabPanel(props: RACTabPanelProps) { return ( tabPanelStyles({ ...renderProps, className }), )} /> ); } export function Tabs(props: TabsProps) { return ( tabs({ ...renderProps, orientation: props.orientation, className, }), )} > tabListStyles({ ...renderProps, orientation: props.orientation || 'horizontal', className, }), )} > {props.tabs.map((tab) => ( {tab.title} ))} {props.tabs.map((tab) => ( {tab.content} ))} ); }