1import { Button } from "~/components/ui/button";2import {3 Card,4 CardContent,5 CardDescription,6 CardFooter,7 CardHeader,8 CardTitle,9} from "~/components/ui/card";10import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";11import {12 TextField,13 TextFieldInput,14 TextFieldLabel,15} from "~/components/ui/text-field";16
17export default function TabsDemo() {18 return (19 <Tabs defaultValue="account">20 <TabsList class="grid w-xs grid-cols-2">21 <TabsTrigger value="account">Account</TabsTrigger>22 <TabsTrigger value="password">Password</TabsTrigger>23 </TabsList>24 <TabsContent value="account" class="w-xs">25 <Card>26 <CardHeader>27 <CardTitle>Account</CardTitle>28 <CardDescription>29 Make changes to your account here. Click save when you're done.30 </CardDescription>31 </CardHeader>32 <CardContent class="space-y-2">33 <TextField class="space-y-1">34 <TextFieldLabel>Name</TextFieldLabel>35 <TextFieldInput value="Pedro Duarte" type="text" />36 </TextField>37 <TextField class="space-y-1">38 <TextFieldLabel>Username</TextFieldLabel>39 <TextFieldInput value="@peduarte" type="text" />40 </TextField>41 </CardContent>42 <CardFooter>43 <Button>Save changes</Button>44 </CardFooter>45 </Card>46 </TabsContent>47 <TabsContent value="password" class="w-sm">48 <Card>49 <CardHeader>50 <CardTitle>Password</CardTitle>51 <CardDescription>52 Change your password here. After saving, you'll be logged out.53 </CardDescription>54 </CardHeader>55 <CardContent class="space-y-2">56 <TextField class="space-y-1">57 <TextFieldLabel>Current password</TextFieldLabel>58 <TextFieldInput type="password" />59 </TextField>60 <TextField class="space-y-1">61 <TextFieldLabel>New password</TextFieldLabel>62 <TextFieldInput type="password" />63 </TextField>64 </CardContent>65 <CardFooter>66 <Button>Save password</Button>67 </CardFooter>68 </Card>69 </TabsContent>70 </Tabs>71 );72}
npx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/tabs.json
yarn shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/tabs.json
pnpm dlx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/tabs.json
bunx --bun shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/tabs.json
Install the following dependencies
npm install @kobalte/core
yarn add @kobalte/core
pnpm add @kobalte/core
bun add @kobalte/core
Copy and paste the following code into your project
1import type { PolymorphicProps } from "@kobalte/core/polymorphic";2import type { ValidComponent } from "solid-js";3
4import { splitProps } from "solid-js";5import * as TabsPrimitive from "@kobalte/core/tabs";6
7import { cn } from "~/lib/utils";8
9const Tabs = <T extends ValidComponent = "div">(10 props: PolymorphicProps<T, TabsPrimitive.TabsRootProps<T>>,11) => {12 return <TabsPrimitive.Root data-slot="tabs" {...props} />;13};14
15type TabsListProps<T extends ValidComponent = "div"> =16 TabsPrimitive.TabsListProps<T> & {17 class?: string | undefined;18 };19
20const TabsList = <T extends ValidComponent = "div">(21 props: PolymorphicProps<T, TabsListProps<T>>,22) => {23 const [local, others] = splitProps(props as TabsListProps, ["class"]);24 return (25 <TabsPrimitive.List26 data-slot="tabs-list"27 class={cn(28 "inline-flex h-12 items-center justify-center rounded-base border-2 border-border bg-background p-1 text-foreground",29 local.class,30 )}31 {...others}32 />33 );34};35
36type TabsTriggerProps<T extends ValidComponent = "button"> =37 TabsPrimitive.TabsTriggerProps<T> & {38 class?: string | undefined;39 };40
41const TabsTrigger = <T extends ValidComponent = "button">(42 props: PolymorphicProps<T, TabsTriggerProps<T>>,43) => {44 const [local, others] = splitProps(props as TabsTriggerProps, ["class"]);45 return (46 <TabsPrimitive.Trigger47 data-slot="tabs-trigger"48 class={cn(49 "inline-flex items-center justify-center gap-1.5 rounded-base border-2 border-transparent px-2 py-1 text-sm font-heading whitespace-nowrap ring-offset-white transition-all focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 ui-selected:border-border ui-selected:bg-primary ui-selected:text-primary-foreground",50 local.class,51 )}52 {...others}53 />54 );55};56
57type TabsContentProps<T extends ValidComponent = "div"> =58 TabsPrimitive.TabsContentProps<T> & {59 class?: string | undefined;60 };61
62const TabsContent = <T extends ValidComponent = "div">(63 props: PolymorphicProps<T, TabsContentProps<T>>,64) => {65 const [local, others] = splitProps(props as TabsContentProps, ["class"]);66 return (67 <TabsPrimitive.Content68 data-slot="tabs-content"69 class={cn(70 "mt-2 ring-offset-white focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none",71 local.class,72 )}73 {...others}74 />75 );76};77
78type TabsIndicatorProps<T extends ValidComponent = "div"> =79 TabsPrimitive.TabsIndicatorProps<T> & {80 class?: string | undefined;81 };82
83const TabsIndicator = <T extends ValidComponent = "div">(84 props: PolymorphicProps<T, TabsIndicatorProps<T>>,85) => {86 const [local, others] = splitProps(props as TabsIndicatorProps, ["class"]);87 return (88 <TabsPrimitive.Indicator89 data-slot="tabs-indicator"90 class={cn(91 "duration-250ms absolute transition-all data-[orientation=horizontal]:-bottom-px data-[orientation=horizontal]:h-[2px] data-[orientation=vertical]:-right-px data-[orientation=vertical]:w-[2px]",92 local.class,93 )}94 {...others}95 />96 );97};98
99export { Tabs, TabsList, TabsTrigger, TabsContent, TabsIndicator };
Update the import paths to match your project setup.
1import {2 Tabs,3 TabsContent,4 TabsIndicator,5 TabsList,6 TabsTrigger,7} from "~/components/ui/tabs";
1<Tabs defaultValue="tab1">2 <TabList>3 <Tab value="tab1">Tab 1</Tab>4 <Tab value="tab2">Tab 2</Tab>5 <Tab value="tab3">Tab 3</Tab>6 </TabList>7 <TabsContent value="tab1">Content for Tab 1</TabsContent>8 <TabsContent value="tab2">Content for Tab 2</TabsContent>9 <TabsContent value="tab3">Content for Tab 3</TabsContent>10</Tabs>