import clsx from "clsx"; import { TriangleAlert } from "lucide-react"; import { Tab, TabList, type TabListProps, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps, } from "react-aria-components"; import { useMainContentWidth } from "~/hooks/useMainContentWidth"; import buttonStyles from "./Button.module.css"; import styles from "./Tabs.module.css"; interface SendouTabsProps extends TabsProps { /** Should there be padding above the panels. Defaults to true, pass in false if the panel content is managing its own padding. */ padded?: boolean; /** Hide tabs if only one tab shown? Defaults to true. */ disappearing?: boolean; /** When orientation is "vertical", switch to horizontal once the main content width drops below this many pixels. */ horizontalBelow?: number; } /** * Renders a set of accessible tabs using the provided props. * * This component is a wrapper around the `Tabs` component, forwarding all props. * * @param props - The properties to pass to the underlying `Tabs` component. * @returns The rendered tab interface. * * @url https://react-spectrum.adobe.com/react-aria/Tabs.html * * @example * * * Shooter * Roller * Charger * * * Splattershot, Aerospray, etc. * * * Splat Roller, Dynamo Roller, etc. * * * Splat Charger, E-liter, etc. * * */ export function SendouTabs({ padded = true, disappearing = true, horizontalBelow, className, orientation, onSelectionChange, ...rest }: SendouTabsProps) { const mainWidth = useMainContentWidth(); const collapsedToHorizontal = orientation === "vertical" && typeof horizontalBelow === "number" && mainWidth > 0 && mainWidth < horizontalBelow; const effectiveOrientation = collapsedToHorizontal ? "horizontal" : orientation; const isVertical = effectiveOrientation === "vertical"; return ( ); } interface SendouTabProps extends TabProps { icon?: React.ReactNode; number?: number; /** Render a warning-colored alert icon to draw attention to this tab. */ alert?: boolean; children?: React.ReactNode; } export function SendouTab({ icon, children, number, alert, ...rest }: SendouTabProps) { return (
{icon} {children} {typeof number === "number" && number !== 0 && ( {number} )} {alert ? : null}
); } interface SendouTabListProps extends TabListProps { sticky?: boolean; /** Should tabs take 100% width with equal distribution? */ fullWidth?: boolean; } export function SendouTabList({ sticky, fullWidth, ...rest }: SendouTabListProps) { return (
); } interface SendouTabPanelProps extends TabPanelProps { className?: string; } export function SendouTabPanel({ className, ...rest }: SendouTabPanelProps) { return ; }