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 (