import { JSX, For, createSignal, createContext, useContext, ParentComponent, splitProps, children, Accessor } from "solid-js"; import type { ResolvedChildren } from "solid-js"; // Context for tab state interface TabsContextValue { selectedTab: Accessor; setSelectedTab: (id: string) => void; } const TabsContext = createContext(); const useTabs = () => { const context = useContext(TabsContext); if (!context) { throw new Error("useTabs must be used within a Tabs component"); } return context; }; // Tabs Root Component interface TabsProps { defaultValue: string; value?: string; onValueChange?: (value: string) => void; children: JSX.Element; class?: string; } export const Tabs: ParentComponent = (props) => { const [local, rest] = splitProps(props, ["defaultValue", "value", "onValueChange", "children", "class"]); const [selectedTab, setSelectedTabInternal] = createSignal(local.defaultValue); const setSelectedTab = (id: string) => { setSelectedTabInternal(id); local.onValueChange?.(id); }; // If controlled, use the provided value const currentTab = () => local.value ?? selectedTab(); const contextValue: TabsContextValue = { selectedTab: currentTab, setSelectedTab, }; return (
{local.children}
); }; // Tabs List Component interface TabsListProps extends JSX.HTMLAttributes { variant?: "default" | "pills" | "underline"; } export const TabsList: ParentComponent = (props) => { const [local, rest] = splitProps(props, ["variant", "children", "class"]); const variantClasses = { default: "bg-canvas-muted p-1 rounded-card", pills: "gap-1", underline: "border-b border-border gap-4", }; return (
{local.children}
); }; // Tab Trigger Component interface TabsTriggerProps extends JSX.ButtonHTMLAttributes { value: string; } export const TabsTrigger: ParentComponent = (props) => { const [local, rest] = splitProps(props, ["value", "children", "class"]); const tabs = useTabs(); const isSelected = () => tabs.selectedTab() === local.value; return ( ); }; // Tab Content Component interface TabsContentProps extends JSX.HTMLAttributes { value: string; } export const TabsContent: ParentComponent = (props) => { const [local, rest] = splitProps(props, ["value", "children", "class"]); const tabs = useTabs(); const isSelected = () => tabs.selectedTab() === local.value; return (
{local.children}
); };