Tabs
A set of layered sections of content—known as tab panels—that are displayed one at a time.
Preview
Upcoming
You have 3 meetings today.
Planning meeting with the new client
In 32 minutes
Call Sarah Graves
In 3 hours
Lunch with the team
In 4 hours
Completed
Your past meetings.
Sales pitch with the client
Yesterday
Release the new library
Yesterday
Get feedback from the team
Last week
<script setup lang="ts">
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
import {
Card,
CardTitle,
CardDescription,
CardHeader,
CardContent,
CardFooter,
} from "~/components/ui/card";
import { Button } from "~/components/ui/button";
const meetingsToday = [
{
title: "Planning meeting with the new client",
time: "In 32 minutes",
color: "bg-sky-500",
},
{
title: "Call Sarah Graves",
time: "In 3 hours",
color: "bg-sky-200",
},
{
title: "Lunch with the team",
time: "In 4 hours",
color: "bg-sky-200",
},
];
const previousMeetings = [
{
title: "Sales pitch with the client",
time: "Yesterday",
},
{
title: "Release the new library",
time: "Yesterday",
},
{
title: "Get feedback from the team",
time: "Last week",
},
];
</script>
<template>
<Tabs default-value="Upcoming" class="w-full max-w-[350px]">
<TabsList class="w-full grid grid-cols-2">
<TabsTrigger value="Upcoming">Upcoming</TabsTrigger>
<TabsTrigger value="Completed">Completed</TabsTrigger>
</TabsList>
<TabsContent value="Upcoming">
<Card class="w-full">
<CardHeader>
<CardTitle>Upcoming</CardTitle>
<CardDescription>You have 3 meetings today.</CardDescription>
</CardHeader>
<CardContent>
<div
v-for="meeting in meetingsToday"
class="grid grid-cols-[25px_1fr] items-start pb-4 last:mb-0 last:pb-0"
>
<span class="flex h-full w-1 rounded-full" :class="meeting.color" />
<div class="space-y-1">
<p class="text-sm font-medium leading-none">
{{ meeting.title }}
</p>
<p class="text-sm text-muted-foreground">
{{ meeting.time }}
</p>
</div>
</div>
</CardContent>
<CardFooter>
<Button class="w-full" variant="outline">View all</Button>
</CardFooter>
</Card>
</TabsContent>
<TabsContent value="Completed" class="w-full">
<Card class="w-full">
<CardHeader>
<CardTitle>Completed</CardTitle>
<CardDescription>Your past meetings.</CardDescription>
</CardHeader>
<CardContent>
<div
v-for="meeting in previousMeetings"
class="grid grid-cols-[25px_1fr] items-start pb-4 last:mb-0 last:pb-0"
>
<span class="flex h-full w-1 rounded-full bg-gray-400" />
<div class="space-y-1">
<p class="text-sm font-medium leading-none">
{{ meeting.title }}
</p>
<p class="text-sm text-muted-foreground">
{{ meeting.time }}
</p>
</div>
</div>
</CardContent>
<CardFooter>
<Button class="w-full" variant="outline">View all</Button>
</CardFooter>
</Card>
</TabsContent>
</Tabs>
</template>
Installation
Copy this code into your project
// ~/components/ui/tabs.tsx
import { TabContent, TabList, Tabs, TabTrigger } from "@ark-ui/vue";
import { defineComponent } from "vue";
import { cn } from "~/lib/utils";
const TabsList = defineComponent({
setup(_, { slots, attrs }) {
return () => (
<TabList
class={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
attrs.class ?? ""
)}
>
{slots.default?.()}
</TabList>
);
},
});
const TabsTrigger = defineComponent({
props: {
value: {
type: String,
required: true,
},
},
setup(props, { slots, attrs }) {
return () => (
<TabTrigger value={props.value}>
<button
class={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[selected]:bg-background data-[selected]:text-foreground data-[selected]:shadow-sm",
attrs.class ?? ""
)}
>
{slots.default?.()}
</button>
</TabTrigger>
);
},
});
const TabsContent = defineComponent({
props: {
value: {
type: String,
required: true,
},
},
setup(props, { slots, attrs }) {
return () => (
<TabContent
value={props.value}
class={cn(
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
attrs.class ?? ""
)}
>
{slots.default?.()}
</TabContent>
);
},
});
export { Tabs, TabsList, TabsTrigger, TabsContent };
Usage
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
<Tabs default-value="one">
<TabsList>
<TabsTrigger value="one">Tab 1</TabsTrigger>
<TabsTrigger value="two">Tab 2</TabsTrigger>
<TabsTrigger value="three">Tab 3</TabsTrigger>
</TabsList>
<TabsContent value="one">Tab 1 content</TabsContent>
<TabsContent value="two">Tab 2 content</TabsContent>
<TabsContent value="three">Tab 3 content</TabsContent>
</Tabs>