'use client'; import * as React from 'react'; import { cva, type VariantProps } from '@/lib/cva'; import * as TabsPrimitive from 'radix-ui/tabs'; import { cn } from '@/lib/utils'; import { colorPalettes, disabledState, focusRing, iconSizing } from '@/lib/cva-presets'; /* * CBAR splits Tabs into two component sets — the strip and the item — and gives * each the same `variant` × `size` axes. They are kept in step here through * `data-variant` / `data-size` on the list, which the trigger reads with the * `group-data-*` selectors below; that way a caller sets the shape once. * * CBAR's third axis, `state`, is deliberately *not* a prop. Its values are * default / hover / active / disabled, which are CSS states — expressing them * as variants would let a caller render a tab that looks selected without being * selected, and screen readers would disagree with the pixels. */ const tabsListVariants = cva( cn( 'group/tabs-list inline-flex w-fit items-center justify-center', 'group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col' ), { variants: { variant: { /** Bottom rule across the strip; the selected tab recolours its own segment. */ line: '', /** Selected tab sits on a tinted, rounded fill. */ subtle: '', /** Selected tab reads as a folder tab joined to the panel below it. */ outline: '', /** Nothing but the label — colour alone marks the selection. */ plain: '', /** Segmented control on a filled track. Pre-CBAR; not one of its four. */ default: 'gap-1 rounded-lg bg-muted p-[3px]', }, colorPalette: colorPalettes, size: { md: 'group-data-[orientation=horizontal]/tabs:h-9 text-sm', lg: 'group-data-[orientation=horizontal]/tabs:h-11 text-base', }, }, defaultVariants: { variant: 'line', colorPalette: 'secondary', size: 'md', }, } ); export type TabsProps = React.ComponentProps; export interface TabsListProps extends React.ComponentProps, VariantProps {} /** * Switches between sibling panels without leaving the page. * * Tabs are for alternate views of the same subject. If the panels are separate * destinations, use links and routes so they can be shared and bookmarked. */ function Tabs({ className, orientation = 'horizontal', ...props }: TabsProps) { return ( ); } function TabsList({ className, variant = 'line', colorPalette, size = 'md', ...props }: TabsListProps) { return ( ); } function TabsTrigger({ className, ...props }: React.ComponentProps) { return ( ); } /* * The panel is a real tab stop, so it gets a real focus ring. * * Radix renders it with `role="tabpanel"` and `tabIndex: 0`, which means Tab * from the strip lands here — this is the one element in the kit that took * `outline-none` without putting an indicator back. `focusRing` opens with * `outline-none` itself, so nothing about the resting state changes; the ring * shows on `:focus-visible` only, never on a click. */ function TabsContent({ className, ...props }: React.ComponentProps) { return ( ); } export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };