chore: build registry, add sidebar block
This commit is contained in:
parent
64c0371280
commit
75eb9736e6
217
apps/www/src/lib/registry/default/block/Sidebar01.vue
Normal file
217
apps/www/src/lib/registry/default/block/Sidebar01.vue
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export const iframeHeight = '800px'
|
||||||
|
export const description
|
||||||
|
= 'A simple sidebar with navigation grouped by section.'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Check, ChevronsUpDown, GalleryVerticalEnd, Search } from 'lucide-vue-next'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// Import components from the custom library
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from '@/lib/registry/default/ui/breadcrumb'
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/dropdown-menu'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
import { Separator } from '@/lib/registry/default/ui/separator'
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarHeader,
|
||||||
|
SidebarInput,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarRail,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/sidebar'
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],
|
||||||
|
navMain: [
|
||||||
|
{
|
||||||
|
title: 'Getting Started',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Installation', url: '#' },
|
||||||
|
{ title: 'Project Structure', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Building Your Application',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Routing', url: '#' },
|
||||||
|
{ title: 'Data Fetching', url: '#', isActive: true },
|
||||||
|
{ title: 'Rendering', url: '#' },
|
||||||
|
{ title: 'Caching', url: '#' },
|
||||||
|
{ title: 'Styling', url: '#' },
|
||||||
|
{ title: 'Optimizing', url: '#' },
|
||||||
|
{ title: 'Configuring', url: '#' },
|
||||||
|
{ title: 'Testing', url: '#' },
|
||||||
|
{ title: 'Authentication', url: '#' },
|
||||||
|
{ title: 'Deploying', url: '#' },
|
||||||
|
{ title: 'Upgrading', url: '#' },
|
||||||
|
{ title: 'Examples', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'API Reference',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Components', url: '#' },
|
||||||
|
{ title: 'File Conventions', url: '#' },
|
||||||
|
{ title: 'Functions', url: '#' },
|
||||||
|
{ title: 'next.config.js Options', url: '#' },
|
||||||
|
{ title: 'CLI', url: '#' },
|
||||||
|
{ title: 'Edge Runtime', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Architecture',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Accessibility', url: '#' },
|
||||||
|
{ title: 'Fast Refresh', url: '#' },
|
||||||
|
{ title: 'Next.js Compiler', url: '#' },
|
||||||
|
{ title: 'Supported Browsers', url: '#' },
|
||||||
|
{ title: 'Turbopack', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedVersion = ref(data.versions[0])
|
||||||
|
const dropdownOpen = ref(false)
|
||||||
|
const search = ref('')
|
||||||
|
|
||||||
|
function toggleDropdown() {
|
||||||
|
dropdownOpen.value = !dropdownOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelectedVersion(version: string) {
|
||||||
|
selectedVersion.value = version
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarHeader>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuButton
|
||||||
|
size="lg"
|
||||||
|
:class="{ 'data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground': dropdownOpen }"
|
||||||
|
@click="toggleDropdown"
|
||||||
|
>
|
||||||
|
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||||
|
<GalleryVerticalEnd class="size-4" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-0.5 leading-none">
|
||||||
|
<span class="font-semibold">Documentation</span>
|
||||||
|
<span>v{{ selectedVersion }}</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="ml-auto" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent
|
||||||
|
v-if="dropdownOpen"
|
||||||
|
class="w-[--radix-dropdown-menu-trigger-width]"
|
||||||
|
align="start"
|
||||||
|
>
|
||||||
|
<DropdownMenuItem
|
||||||
|
v-for="version in data.versions"
|
||||||
|
:key="version"
|
||||||
|
@click="setSelectedVersion(version)"
|
||||||
|
>
|
||||||
|
v{{ version }}
|
||||||
|
<Check v-if="version === selectedVersion" class="ml-auto" />
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
|
||||||
|
<form @submit.prevent>
|
||||||
|
<SidebarGroup class="py-0">
|
||||||
|
<SidebarGroupContent class="relative">
|
||||||
|
<Label for="search" class="sr-only">Search</Label>
|
||||||
|
<SidebarInput
|
||||||
|
id="search"
|
||||||
|
v-model="search"
|
||||||
|
placeholder="Search the docs..."
|
||||||
|
class="pl-8"
|
||||||
|
/>
|
||||||
|
<Search class="pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50" />
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</form>
|
||||||
|
</SidebarHeader>
|
||||||
|
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup v-for="item in data.navMain" :key="item.title">
|
||||||
|
<SidebarGroupLabel>{{ item.title }}</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem v-for="subItem in item.items" :key="subItem.title">
|
||||||
|
<SidebarMenuButton :class="{ 'is-active': subItem.isActive }" as-child>
|
||||||
|
<a :href="subItem.url">{{ subItem.title }}</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
|
||||||
|
<SidebarRail />
|
||||||
|
</Sidebar>
|
||||||
|
|
||||||
|
<SidebarInset>
|
||||||
|
<header class="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger class="-ml-1" />
|
||||||
|
<Separator orientation="vertical" class="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem class="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator class="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div class="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
</template>
|
||||||
463
apps/www/src/lib/registry/default/block/Sidebar07.vue
Normal file
463
apps/www/src/lib/registry/default/block/Sidebar07.vue
Normal file
|
|
@ -0,0 +1,463 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export const description
|
||||||
|
= 'A sidebar that collapses to icons.'
|
||||||
|
export const iframeHeight = '800px'
|
||||||
|
export const containerClass = 'w-full h-full'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang=ts>
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
AvatarFallback,
|
||||||
|
AvatarImage,
|
||||||
|
} from '@/lib/registry/default/ui/avatar'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from '@/lib/registry/default/ui/breadcrumb'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Collapsible,
|
||||||
|
CollapsibleContent,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/collapsible'
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuShortcut,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/dropdown-menu'
|
||||||
|
import { Separator } from '@/lib/registry/default/ui/separator'
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarFooter,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarHeader,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuAction,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarMenuSub,
|
||||||
|
SidebarMenuSubButton,
|
||||||
|
SidebarMenuSubItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarRail,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/sidebar'
|
||||||
|
import {
|
||||||
|
AudioWaveform,
|
||||||
|
BadgeCheck,
|
||||||
|
Bell,
|
||||||
|
BookOpen,
|
||||||
|
Bot,
|
||||||
|
ChevronRight,
|
||||||
|
ChevronsUpDown,
|
||||||
|
Command,
|
||||||
|
CreditCard,
|
||||||
|
Folder,
|
||||||
|
Forward,
|
||||||
|
Frame,
|
||||||
|
GalleryVerticalEnd,
|
||||||
|
LogOut,
|
||||||
|
Map,
|
||||||
|
MoreHorizontal,
|
||||||
|
PieChart,
|
||||||
|
Plus,
|
||||||
|
Settings2,
|
||||||
|
Sparkles,
|
||||||
|
SquareTerminal,
|
||||||
|
Trash2,
|
||||||
|
} from 'lucide-vue-next'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// This is sample data.
|
||||||
|
const data = {
|
||||||
|
user: {
|
||||||
|
name: 'shadcn',
|
||||||
|
email: 'm@example.com',
|
||||||
|
avatar: '/avatars/shadcn.jpg',
|
||||||
|
},
|
||||||
|
teams: [
|
||||||
|
{
|
||||||
|
name: 'Acme Inc',
|
||||||
|
logo: GalleryVerticalEnd,
|
||||||
|
plan: 'Enterprise',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Acme Corp.',
|
||||||
|
logo: AudioWaveform,
|
||||||
|
plan: 'Startup',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Evil Corp.',
|
||||||
|
logo: Command,
|
||||||
|
plan: 'Free',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
navMain: [
|
||||||
|
{
|
||||||
|
title: 'Playground',
|
||||||
|
url: '#',
|
||||||
|
icon: SquareTerminal,
|
||||||
|
isActive: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'History',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Starred',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Settings',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Models',
|
||||||
|
url: '#',
|
||||||
|
icon: Bot,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'Genesis',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Explorer',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Quantum',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Documentation',
|
||||||
|
url: '#',
|
||||||
|
icon: BookOpen,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'Introduction',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Get Started',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Tutorials',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Changelog',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Settings',
|
||||||
|
url: '#',
|
||||||
|
icon: Settings2,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'General',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Team',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Billing',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Limits',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'Design Engineering',
|
||||||
|
url: '#',
|
||||||
|
icon: Frame,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Sales & Marketing',
|
||||||
|
url: '#',
|
||||||
|
icon: PieChart,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Travel',
|
||||||
|
url: '#',
|
||||||
|
icon: Map,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeTeam = ref(data.teams[0])
|
||||||
|
|
||||||
|
function setActiveTeam(team: typeof data.teams[number]) {
|
||||||
|
activeTeam.value = team
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar collapsible="icon">
|
||||||
|
<SidebarHeader>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuButton
|
||||||
|
size="lg"
|
||||||
|
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
|
>
|
||||||
|
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||||
|
<component :is="activeTeam.logo" class="size-4" />
|
||||||
|
</div>
|
||||||
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span class="truncate font-semibold">{{ activeTeam.name }}</span>
|
||||||
|
<span class="truncate text-xs">{{ activeTeam.plan }}</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="ml-auto" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent
|
||||||
|
class="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
|
||||||
|
align="start"
|
||||||
|
side="bottom"
|
||||||
|
:side-offset="4"
|
||||||
|
>
|
||||||
|
<DropdownMenuLabel class="text-xs text-muted-foreground">
|
||||||
|
Teams
|
||||||
|
</DropdownMenuLabel>
|
||||||
|
<DropdownMenuItem
|
||||||
|
v-for="(team, index) in data.teams"
|
||||||
|
:key="team.name"
|
||||||
|
class="gap-2 p-2"
|
||||||
|
@click="setActiveTeam(team)"
|
||||||
|
>
|
||||||
|
<div class="flex size-6 items-center justify-center rounded-sm border">
|
||||||
|
<component :is="team.logo" class="size-4 shrink-0" />
|
||||||
|
</div>
|
||||||
|
{{ team.name }}
|
||||||
|
<DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem class="gap-2 p-2">
|
||||||
|
<div class="flex size-6 items-center justify-center rounded-md border bg-background">
|
||||||
|
<Plus class="size-4" />
|
||||||
|
</div>
|
||||||
|
<div class="font-medium text-muted-foreground">
|
||||||
|
Add team
|
||||||
|
</div>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarHeader>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Platform</SidebarGroupLabel>
|
||||||
|
<SidebarMenu>
|
||||||
|
<Collapsible
|
||||||
|
v-for="item in data.navMain"
|
||||||
|
:key="item.title"
|
||||||
|
as-child
|
||||||
|
:default-open="item.isActive"
|
||||||
|
class="group/collapsible"
|
||||||
|
>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<CollapsibleTrigger as-child>
|
||||||
|
<SidebarMenuButton tooltip="item.title">
|
||||||
|
<component :is="item.icon" />
|
||||||
|
<span>{{ item.title }}</span>
|
||||||
|
<ChevronRight class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
<CollapsibleContent>
|
||||||
|
<SidebarMenuSub>
|
||||||
|
<SidebarMenuSubItem
|
||||||
|
v-for="subItem in item.items"
|
||||||
|
:key="subItem.title"
|
||||||
|
>
|
||||||
|
<SidebarMenuSubButton as-child>
|
||||||
|
<a :href="subItem.url">
|
||||||
|
<span>{{ subItem.title }}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuSubButton>
|
||||||
|
</SidebarMenuSubItem>
|
||||||
|
</SidebarMenuSub>
|
||||||
|
</CollapsibleContent>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</Collapsible>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroup>
|
||||||
|
<SidebarGroup class="group-data-[collapsible=icon]:hidden">
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem
|
||||||
|
v-for="item in data.projects"
|
||||||
|
:key="item.name"
|
||||||
|
>
|
||||||
|
<SidebarMenuButton as-child>
|
||||||
|
<a :href="item.url">
|
||||||
|
<component :is="item.icon" />
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuAction show-on-hover>
|
||||||
|
<MoreHorizontal />
|
||||||
|
<span class="sr-only">More</span>
|
||||||
|
</SidebarMenuAction>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent class="w-48 rounded-lg" side="bottom" align="end">
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Folder class="text-muted-foreground" />
|
||||||
|
<span>View Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Forward class="text-muted-foreground" />
|
||||||
|
<span>Share Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Trash2 class="text-muted-foreground" />
|
||||||
|
<span>Delete Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton class="text-sidebar-foreground/70">
|
||||||
|
<MoreHorizontal class="text-sidebar-foreground/70" />
|
||||||
|
<span>More</span>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
<SidebarFooter>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuButton
|
||||||
|
size="lg"
|
||||||
|
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
|
>
|
||||||
|
<Avatar class="h-8 w-8 rounded-lg">
|
||||||
|
<AvatarImage :src="data.user.avatar" :alt="data.user.name" />
|
||||||
|
<AvatarFallback class="rounded-lg">
|
||||||
|
CN
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span class="truncate font-semibold">{{ data.user.name }}</span>
|
||||||
|
<span class="truncate text-xs">{{ data.user.email }}</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="ml-auto size-4" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent class="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg" side="bottom" align="end" :side-offset="4">
|
||||||
|
<DropdownMenuLabel class="p-0 font-normal">
|
||||||
|
<div class="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||||
|
<Avatar class="h-8 w-8 rounded-lg">
|
||||||
|
<AvatarImage :src="data.user.avatar" :alt="data.user.name" />
|
||||||
|
<AvatarFallback class="rounded-lg">
|
||||||
|
CN
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span class="truncate font-semibold">{{ data.user.name }}</span>
|
||||||
|
<span class="truncate text-xs">{{ data.user.email }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DropdownMenuLabel>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuGroup>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Sparkles />
|
||||||
|
Upgrade to Pro
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuGroup>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuGroup>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<BadgeCheck />
|
||||||
|
Account
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<CreditCard />
|
||||||
|
Billing
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Bell />
|
||||||
|
Notifications
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuGroup>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<LogOut />
|
||||||
|
Log out
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarFooter>
|
||||||
|
<SidebarRail />
|
||||||
|
</Sidebar>
|
||||||
|
<SidebarInset>
|
||||||
|
<header class="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
|
||||||
|
<div class="flex items-center gap-2 px-4">
|
||||||
|
<SidebarTrigger class="-ml-1" />
|
||||||
|
<Separator orientation="vertical" class="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem class="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator class="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||||
|
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div class="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
</template>
|
||||||
|
|
@ -3,26 +3,26 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
||||||
export { default as Button } from './Button.vue'
|
export { default as Button } from './Button.vue'
|
||||||
|
|
||||||
export const buttonVariants = cva(
|
export const buttonVariants = cva(
|
||||||
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
default:
|
||||||
|
'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
||||||
destructive:
|
destructive:
|
||||||
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
|
||||||
outline:
|
outline:
|
||||||
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
|
||||||
secondary:
|
secondary:
|
||||||
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
||||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||||
link: 'text-primary underline-offset-4 hover:underline',
|
link: 'text-primary underline-offset-4 hover:underline',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'h-10 px-4 py-2',
|
default: 'h-9 px-4 py-2',
|
||||||
xs: 'h-7 rounded px-2',
|
sm: 'h-8 rounded-md px-3 text-xs',
|
||||||
sm: 'h-9 rounded-md px-3',
|
lg: 'h-10 rounded-md px-8',
|
||||||
lg: 'h-11 rounded-md px-8',
|
icon: 'h-9 w-9',
|
||||||
icon: 'h-10 w-10',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const forwardedProps = useForwardProps(delegatedProps)
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
v-bind="forwardedProps"
|
v-bind="forwardedProps"
|
||||||
:class="cn(
|
:class="cn(
|
||||||
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
|
||||||
inset && 'pl-8',
|
inset && 'pl-8',
|
||||||
props.class,
|
props.class,
|
||||||
)"
|
)"
|
||||||
|
|
|
||||||
217
apps/www/src/lib/registry/new-york/block/Sidebar01.vue
Normal file
217
apps/www/src/lib/registry/new-york/block/Sidebar01.vue
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export const iframeHeight = '800px'
|
||||||
|
export const description
|
||||||
|
= 'A simple sidebar with navigation grouped by section.'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Check, ChevronsUpDown, GalleryVerticalEnd, Search } from 'lucide-vue-next'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// Import components from the custom library
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/dropdown-menu'
|
||||||
|
import { Label } from '@/lib/registry/new-york/ui/label'
|
||||||
|
import { Separator } from '@/lib/registry/new-york/ui/separator'
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarHeader,
|
||||||
|
SidebarInput,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarRail,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/sidebar'
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],
|
||||||
|
navMain: [
|
||||||
|
{
|
||||||
|
title: 'Getting Started',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Installation', url: '#' },
|
||||||
|
{ title: 'Project Structure', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Building Your Application',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Routing', url: '#' },
|
||||||
|
{ title: 'Data Fetching', url: '#', isActive: true },
|
||||||
|
{ title: 'Rendering', url: '#' },
|
||||||
|
{ title: 'Caching', url: '#' },
|
||||||
|
{ title: 'Styling', url: '#' },
|
||||||
|
{ title: 'Optimizing', url: '#' },
|
||||||
|
{ title: 'Configuring', url: '#' },
|
||||||
|
{ title: 'Testing', url: '#' },
|
||||||
|
{ title: 'Authentication', url: '#' },
|
||||||
|
{ title: 'Deploying', url: '#' },
|
||||||
|
{ title: 'Upgrading', url: '#' },
|
||||||
|
{ title: 'Examples', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'API Reference',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Components', url: '#' },
|
||||||
|
{ title: 'File Conventions', url: '#' },
|
||||||
|
{ title: 'Functions', url: '#' },
|
||||||
|
{ title: 'next.config.js Options', url: '#' },
|
||||||
|
{ title: 'CLI', url: '#' },
|
||||||
|
{ title: 'Edge Runtime', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Architecture',
|
||||||
|
url: '#',
|
||||||
|
items: [
|
||||||
|
{ title: 'Accessibility', url: '#' },
|
||||||
|
{ title: 'Fast Refresh', url: '#' },
|
||||||
|
{ title: 'Next.js Compiler', url: '#' },
|
||||||
|
{ title: 'Supported Browsers', url: '#' },
|
||||||
|
{ title: 'Turbopack', url: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedVersion = ref(data.versions[0])
|
||||||
|
const dropdownOpen = ref(false)
|
||||||
|
const search = ref('')
|
||||||
|
|
||||||
|
function toggleDropdown() {
|
||||||
|
dropdownOpen.value = !dropdownOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelectedVersion(version: string) {
|
||||||
|
selectedVersion.value = version
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarHeader>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger>
|
||||||
|
<SidebarMenuButton
|
||||||
|
size="lg"
|
||||||
|
:class="{ 'data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground': dropdownOpen }"
|
||||||
|
@click="toggleDropdown"
|
||||||
|
>
|
||||||
|
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||||
|
<GalleryVerticalEnd class="size-4" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-0.5 leading-none">
|
||||||
|
<span class="font-semibold">Documentation</span>
|
||||||
|
<span>v{{ selectedVersion }}</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="ml-auto" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent
|
||||||
|
v-if="dropdownOpen"
|
||||||
|
class="w-[--radix-dropdown-menu-trigger-width]"
|
||||||
|
align="start"
|
||||||
|
>
|
||||||
|
<DropdownMenuItem
|
||||||
|
v-for="version in data.versions"
|
||||||
|
:key="version"
|
||||||
|
@click="setSelectedVersion(version)"
|
||||||
|
>
|
||||||
|
v{{ version }}
|
||||||
|
<Check v-if="version === selectedVersion" class="ml-auto" />
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
|
||||||
|
<form @submit.prevent>
|
||||||
|
<SidebarGroup class="py-0">
|
||||||
|
<SidebarGroupContent class="relative">
|
||||||
|
<Label for="search" class="sr-only">Search</Label>
|
||||||
|
<SidebarInput
|
||||||
|
id="search"
|
||||||
|
v-model="search"
|
||||||
|
placeholder="Search the docs..."
|
||||||
|
class="pl-8"
|
||||||
|
/>
|
||||||
|
<Search class="pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50" />
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</form>
|
||||||
|
</SidebarHeader>
|
||||||
|
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup v-for="item in data.navMain" :key="item.title">
|
||||||
|
<SidebarGroupLabel>{{ item.title }}</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem v-for="subItem in item.items" :key="subItem.title">
|
||||||
|
<SidebarMenuButton :class="{ 'is-active': subItem.isActive }" as-child>
|
||||||
|
<a :href="subItem.url">{{ subItem.title }}</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
|
||||||
|
<SidebarRail />
|
||||||
|
</Sidebar>
|
||||||
|
|
||||||
|
<SidebarInset>
|
||||||
|
<header class="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger class="-ml-1" />
|
||||||
|
<Separator orientation="vertical" class="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem class="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator class="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div class="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
</template>
|
||||||
463
apps/www/src/lib/registry/new-york/block/Sidebar07.vue
Normal file
463
apps/www/src/lib/registry/new-york/block/Sidebar07.vue
Normal file
|
|
@ -0,0 +1,463 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export const description
|
||||||
|
= 'A sidebar that collapses to icons.'
|
||||||
|
export const iframeHeight = '800px'
|
||||||
|
export const containerClass = 'w-full h-full'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang=ts>
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
AvatarFallback,
|
||||||
|
AvatarImage,
|
||||||
|
} from '@/lib/registry/new-york/ui/avatar'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Collapsible,
|
||||||
|
CollapsibleContent,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/collapsible'
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuShortcut,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/dropdown-menu'
|
||||||
|
import { Separator } from '@/lib/registry/new-york/ui/separator'
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarFooter,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarHeader,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuAction,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarMenuSub,
|
||||||
|
SidebarMenuSubButton,
|
||||||
|
SidebarMenuSubItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarRail,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/sidebar'
|
||||||
|
import {
|
||||||
|
AudioWaveform,
|
||||||
|
BadgeCheck,
|
||||||
|
Bell,
|
||||||
|
BookOpen,
|
||||||
|
Bot,
|
||||||
|
ChevronRight,
|
||||||
|
ChevronsUpDown,
|
||||||
|
Command,
|
||||||
|
CreditCard,
|
||||||
|
Folder,
|
||||||
|
Forward,
|
||||||
|
Frame,
|
||||||
|
GalleryVerticalEnd,
|
||||||
|
LogOut,
|
||||||
|
Map,
|
||||||
|
MoreHorizontal,
|
||||||
|
PieChart,
|
||||||
|
Plus,
|
||||||
|
Settings2,
|
||||||
|
Sparkles,
|
||||||
|
SquareTerminal,
|
||||||
|
Trash2,
|
||||||
|
} from 'lucide-vue-next'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// This is sample data.
|
||||||
|
const data = {
|
||||||
|
user: {
|
||||||
|
name: 'shadcn',
|
||||||
|
email: 'm@example.com',
|
||||||
|
avatar: '/avatars/shadcn.jpg',
|
||||||
|
},
|
||||||
|
teams: [
|
||||||
|
{
|
||||||
|
name: 'Acme Inc',
|
||||||
|
logo: GalleryVerticalEnd,
|
||||||
|
plan: 'Enterprise',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Acme Corp.',
|
||||||
|
logo: AudioWaveform,
|
||||||
|
plan: 'Startup',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Evil Corp.',
|
||||||
|
logo: Command,
|
||||||
|
plan: 'Free',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
navMain: [
|
||||||
|
{
|
||||||
|
title: 'Playground',
|
||||||
|
url: '#',
|
||||||
|
icon: SquareTerminal,
|
||||||
|
isActive: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'History',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Starred',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Settings',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Models',
|
||||||
|
url: '#',
|
||||||
|
icon: Bot,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'Genesis',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Explorer',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Quantum',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Documentation',
|
||||||
|
url: '#',
|
||||||
|
icon: BookOpen,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'Introduction',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Get Started',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Tutorials',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Changelog',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Settings',
|
||||||
|
url: '#',
|
||||||
|
icon: Settings2,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'General',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Team',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Billing',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Limits',
|
||||||
|
url: '#',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'Design Engineering',
|
||||||
|
url: '#',
|
||||||
|
icon: Frame,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Sales & Marketing',
|
||||||
|
url: '#',
|
||||||
|
icon: PieChart,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Travel',
|
||||||
|
url: '#',
|
||||||
|
icon: Map,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeTeam = ref(data.teams[0])
|
||||||
|
|
||||||
|
function setActiveTeam(team: typeof data.teams[number]) {
|
||||||
|
activeTeam.value = team
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar collapsible="icon">
|
||||||
|
<SidebarHeader>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuButton
|
||||||
|
size="lg"
|
||||||
|
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
|
>
|
||||||
|
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||||
|
<component :is="activeTeam.logo" class="size-4" />
|
||||||
|
</div>
|
||||||
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span class="truncate font-semibold">{{ activeTeam.name }}</span>
|
||||||
|
<span class="truncate text-xs">{{ activeTeam.plan }}</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="ml-auto" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent
|
||||||
|
class="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
|
||||||
|
align="start"
|
||||||
|
side="bottom"
|
||||||
|
:side-offset="4"
|
||||||
|
>
|
||||||
|
<DropdownMenuLabel class="text-xs text-muted-foreground">
|
||||||
|
Teams
|
||||||
|
</DropdownMenuLabel>
|
||||||
|
<DropdownMenuItem
|
||||||
|
v-for="(team, index) in data.teams"
|
||||||
|
:key="team.name"
|
||||||
|
class="gap-2 p-2"
|
||||||
|
@click="setActiveTeam(team)"
|
||||||
|
>
|
||||||
|
<div class="flex size-6 items-center justify-center rounded-sm border">
|
||||||
|
<component :is="team.logo" class="size-4 shrink-0" />
|
||||||
|
</div>
|
||||||
|
{{ team.name }}
|
||||||
|
<DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem class="gap-2 p-2">
|
||||||
|
<div class="flex size-6 items-center justify-center rounded-md border bg-background">
|
||||||
|
<Plus class="size-4" />
|
||||||
|
</div>
|
||||||
|
<div class="font-medium text-muted-foreground">
|
||||||
|
Add team
|
||||||
|
</div>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarHeader>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Platform</SidebarGroupLabel>
|
||||||
|
<SidebarMenu>
|
||||||
|
<Collapsible
|
||||||
|
v-for="item in data.navMain"
|
||||||
|
:key="item.title"
|
||||||
|
as-child
|
||||||
|
:default-open="item.isActive"
|
||||||
|
class="group/collapsible"
|
||||||
|
>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<CollapsibleTrigger as-child>
|
||||||
|
<SidebarMenuButton tooltip="item.title">
|
||||||
|
<component :is="item.icon" />
|
||||||
|
<span>{{ item.title }}</span>
|
||||||
|
<ChevronRight class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
<CollapsibleContent>
|
||||||
|
<SidebarMenuSub>
|
||||||
|
<SidebarMenuSubItem
|
||||||
|
v-for="subItem in item.items"
|
||||||
|
:key="subItem.title"
|
||||||
|
>
|
||||||
|
<SidebarMenuSubButton as-child>
|
||||||
|
<a :href="subItem.url">
|
||||||
|
<span>{{ subItem.title }}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuSubButton>
|
||||||
|
</SidebarMenuSubItem>
|
||||||
|
</SidebarMenuSub>
|
||||||
|
</CollapsibleContent>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</Collapsible>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroup>
|
||||||
|
<SidebarGroup class="group-data-[collapsible=icon]:hidden">
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem
|
||||||
|
v-for="item in data.projects"
|
||||||
|
:key="item.name"
|
||||||
|
>
|
||||||
|
<SidebarMenuButton as-child>
|
||||||
|
<a :href="item.url">
|
||||||
|
<component :is="item.icon" />
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuAction show-on-hover>
|
||||||
|
<MoreHorizontal />
|
||||||
|
<span class="sr-only">More</span>
|
||||||
|
</SidebarMenuAction>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent class="w-48 rounded-lg" side="bottom" align="end">
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Folder class="text-muted-foreground" />
|
||||||
|
<span>View Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Forward class="text-muted-foreground" />
|
||||||
|
<span>Share Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Trash2 class="text-muted-foreground" />
|
||||||
|
<span>Delete Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton class="text-sidebar-foreground/70">
|
||||||
|
<MoreHorizontal class="text-sidebar-foreground/70" />
|
||||||
|
<span>More</span>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
<SidebarFooter>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<SidebarMenuButton
|
||||||
|
size="lg"
|
||||||
|
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
|
>
|
||||||
|
<Avatar class="h-8 w-8 rounded-lg">
|
||||||
|
<AvatarImage :src="data.user.avatar" :alt="data.user.name" />
|
||||||
|
<AvatarFallback class="rounded-lg">
|
||||||
|
CN
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span class="truncate font-semibold">{{ data.user.name }}</span>
|
||||||
|
<span class="truncate text-xs">{{ data.user.email }}</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="ml-auto size-4" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent class="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg" side="bottom" align="end" :side-offset="4">
|
||||||
|
<DropdownMenuLabel class="p-0 font-normal">
|
||||||
|
<div class="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||||
|
<Avatar class="h-8 w-8 rounded-lg">
|
||||||
|
<AvatarImage :src="data.user.avatar" :alt="data.user.name" />
|
||||||
|
<AvatarFallback class="rounded-lg">
|
||||||
|
CN
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span class="truncate font-semibold">{{ data.user.name }}</span>
|
||||||
|
<span class="truncate text-xs">{{ data.user.email }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DropdownMenuLabel>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuGroup>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Sparkles />
|
||||||
|
Upgrade to Pro
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuGroup>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuGroup>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<BadgeCheck />
|
||||||
|
Account
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<CreditCard />
|
||||||
|
Billing
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Bell />
|
||||||
|
Notifications
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuGroup>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<LogOut />
|
||||||
|
Log out
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarFooter>
|
||||||
|
<SidebarRail />
|
||||||
|
</Sidebar>
|
||||||
|
<SidebarInset>
|
||||||
|
<header class="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
|
||||||
|
<div class="flex items-center gap-2 px-4">
|
||||||
|
<SidebarTrigger class="-ml-1" />
|
||||||
|
<Separator orientation="vertical" class="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem class="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator class="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||||
|
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div class="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div class="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
</template>
|
||||||
|
|
@ -18,7 +18,7 @@ const forwardedProps = useForwardProps(delegatedProps)
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
v-bind="forwardedProps"
|
v-bind="forwardedProps"
|
||||||
:class="cn(
|
:class="cn(
|
||||||
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
|
||||||
inset && 'pl-8',
|
inset && 'pl-8',
|
||||||
props.class,
|
props.class,
|
||||||
)"
|
)"
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 224 71.4% 4.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 216 12.2% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n\n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n\n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n\n --border: 220 13% 91%;\n --input: 220 13% 91%;\n\n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n\n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n\n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n\n --ring: 224 71.4% 4.1%;\n\n --radius: 0.5rem;\n }\n\n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n\n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n\n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n\n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n\n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n\n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n\n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n\n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 20% 98%;\n\n --ring: 216 12.2% 83.9%;\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 89.3 80.4% 10%;\n \n --muted: 79.6 89.1% 89.2%;\n --muted-foreground: 83.7 80.5% 44.3%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 89.3 80.4% 10%;\n \n --card: 0 0% 100%;\n --card-foreground: 89.3 80.4% 10%;\n \n --border: 80.9 88.5% 79.6%;\n --input: 80.9 88.5% 79.6%;\n \n --primary: 87.6 61.2% 20.2%;\n --primary-foreground: 78.3 92% 95.1%;\n \n --secondary: 79.6 89.1% 89.2%;\n --secondary-foreground: 87.6 61.2% 20.2%;\n \n --accent: 79.6 89.1% 89.2%;\n --accent-foreground: 87.6 61.2% 20.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 78.3 92% 95.1%;\n \n --ring: 89.3 80.4% 10%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 89.3 80.4% 10%;\n --foreground: 78.3 92% 95.1%;\n \n --muted: 86.3 69% 22.7%;\n --muted-foreground: 82.7 78% 55.5%;\n \n --popover: 89.3 80.4% 10%;\n --popover-foreground: 78.3 92% 95.1%;\n \n --card: 89.3 80.4% 10%;\n --card-foreground: 78.3 92% 95.1%;\n \n --border: 86.3 69% 22.7%;\n --input: 86.3 69% 22.7%;\n \n --primary: 78.3 92% 95.1%;\n --primary-foreground: 87.6 61.2% 20.2%;\n \n --secondary: 86.3 69% 22.7%;\n --secondary-foreground: 78.3 92% 95.1%;\n \n --accent: 86.3 69% 22.7%;\n --accent-foreground: 78.3 92% 95.1%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 78.3 92% 95.1%;\n \n --ring: 82 84.5% 67.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 89.3 80.4% 10%;\n\n --muted: 79.6 89.1% 89.2%;\n --muted-foreground: 83.7 80.5% 44.3%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 89.3 80.4% 10%;\n\n --card: 0 0% 100%;\n --card-foreground: 89.3 80.4% 10%;\n\n --border: 80.9 88.5% 79.6%;\n --input: 80.9 88.5% 79.6%;\n\n --primary: 87.6 61.2% 20.2%;\n --primary-foreground: 78.3 92% 95.1%;\n\n --secondary: 79.6 89.1% 89.2%;\n --secondary-foreground: 87.6 61.2% 20.2%;\n\n --accent: 79.6 89.1% 89.2%;\n --accent-foreground: 87.6 61.2% 20.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 78.3 92% 95.1%;\n\n --ring: 89.3 80.4% 10%;\n\n --radius: 0.5rem;\n }\n\n .dark {\n --background: 89.3 80.4% 10%;\n --foreground: 78.3 92% 95.1%;\n\n --muted: 86.3 69% 22.7%;\n --muted-foreground: 82.7 78% 55.5%;\n\n --popover: 89.3 80.4% 10%;\n --popover-foreground: 78.3 92% 95.1%;\n\n --card: 89.3 80.4% 10%;\n --card-foreground: 78.3 92% 95.1%;\n\n --border: 86.3 69% 22.7%;\n --input: 86.3 69% 22.7%;\n\n --primary: 78.3 92% 95.1%;\n --primary-foreground: 87.6 61.2% 20.2%;\n\n --secondary: 86.3 69% 22.7%;\n --secondary-foreground: 78.3 92% 95.1%;\n\n --accent: 86.3 69% 22.7%;\n --accent-foreground: 78.3 92% 95.1%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 78.3 92% 95.1%;\n\n --ring: 82 84.5% 67.1%;\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n \n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n \n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n \n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n \n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 0 0% 3.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n \n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n \n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 0 0% 83.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n\n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n\n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n\n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n\n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n\n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n\n --ring: 0 0% 3.9%;\n\n --radius: 0.5rem;\n }\n\n .dark {\n --background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n\n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n\n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n\n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n\n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n\n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n\n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n\n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n\n --ring: 0 0% 83.1%;\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n \n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n \n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n \n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n \n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n \n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n \n --ring: 222.2 84% 4.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n \n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n \n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n \n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n \n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n \n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n \n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n \n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n \n --ring: 212.7 26.8% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n .dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n\n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n\n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n\n --ring: 212.7 26.8% 83.9%;\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n \n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n \n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n \n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n \n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n \n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --ring: 20 14.3% 4.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n \n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n \n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n \n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n \n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n \n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n \n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n \n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --ring: 24 5.7% 82.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n\n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n\n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n\n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n\n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n\n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n\n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n\n --ring: 20 14.3% 4.1%;\n\n --radius: 0.5rem;\n }\n\n .dark {\n --background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n\n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n\n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n\n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n\n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n\n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n\n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n\n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 60 9.1% 97.8%;\n\n --ring: 24 5.7% 82.9%;\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n \n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n \n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n \n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n \n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 240 10% 3.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n \n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n \n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 240 4.9% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n\n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n\n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n\n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n\n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n\n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n\n --ring: 240 10% 3.9%;\n\n --radius: 0.5rem;\n }\n\n .dark {\n --background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n\n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n\n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n\n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n\n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n\n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n\n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n\n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n\n --ring: 240 4.9% 83.9%;\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -743,6 +743,53 @@
|
||||||
],
|
],
|
||||||
"type": "components:ui"
|
"type": "components:ui"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "sidebar",
|
||||||
|
"dependencies": [
|
||||||
|
"@vueuse/core"
|
||||||
|
],
|
||||||
|
"registryDependencies": [
|
||||||
|
"Sheet.vue",
|
||||||
|
"SheetContent.vue",
|
||||||
|
"utils",
|
||||||
|
"Input.vue",
|
||||||
|
"Tooltip.vue",
|
||||||
|
"TooltipContent.vue",
|
||||||
|
"TooltipTrigger.vue",
|
||||||
|
"Skeleton.vue",
|
||||||
|
"Separator.vue",
|
||||||
|
"Button.vue"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"ui/sidebar/Sidebar.vue",
|
||||||
|
"ui/sidebar/SidebarContent.vue",
|
||||||
|
"ui/sidebar/SidebarFooter.vue",
|
||||||
|
"ui/sidebar/SidebarGroup.vue",
|
||||||
|
"ui/sidebar/SidebarGroupAction.vue",
|
||||||
|
"ui/sidebar/SidebarGroupContent.vue",
|
||||||
|
"ui/sidebar/SidebarGroupLabel.vue",
|
||||||
|
"ui/sidebar/SidebarHeader.vue",
|
||||||
|
"ui/sidebar/SidebarInput.vue",
|
||||||
|
"ui/sidebar/SidebarInset.vue",
|
||||||
|
"ui/sidebar/SidebarMenu.vue",
|
||||||
|
"ui/sidebar/SidebarMenuAction.vue",
|
||||||
|
"ui/sidebar/SidebarMenuBadge.vue",
|
||||||
|
"ui/sidebar/SidebarMenuButton.vue",
|
||||||
|
"ui/sidebar/SidebarMenuButtonChild.vue",
|
||||||
|
"ui/sidebar/SidebarMenuItem.vue",
|
||||||
|
"ui/sidebar/SidebarMenuSkeleton.vue",
|
||||||
|
"ui/sidebar/SidebarMenuSub.vue",
|
||||||
|
"ui/sidebar/SidebarMenuSubButton.vue",
|
||||||
|
"ui/sidebar/SidebarMenuSubItem.vue",
|
||||||
|
"ui/sidebar/SidebarProvider.vue",
|
||||||
|
"ui/sidebar/SidebarRail.vue",
|
||||||
|
"ui/sidebar/SidebarSeparator.vue",
|
||||||
|
"ui/sidebar/SidebarTrigger.vue",
|
||||||
|
"ui/sidebar/index.ts",
|
||||||
|
"ui/sidebar/utils.ts"
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "skeleton",
|
"name": "skeleton",
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "BreadcrumbSeparator.vue",
|
"name": "BreadcrumbSeparator.vue",
|
||||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('[&>svg]:size-3.5', props.class)\"\n >\n <slot>\n <ChevronRight />\n </slot>\n </li>\n</template>\n"
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('[&>svg]:w-3.5 [&>svg]:h-3.5', props.class)\"\n >\n <slot>\n <ChevronRight />\n </slot>\n </li>\n</template>\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "index.ts",
|
"name": "index.ts",
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "index.ts",
|
"name": "index.ts",
|
||||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline:\n 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n xs: 'h-7 rounded px-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n"
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default:\n 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "components:ui"
|
"type": "components:ui"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DropdownMenuItem.vue",
|
"name": "DropdownMenuItem.vue",
|
||||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'radix-vue'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <DropdownMenuItem\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n"
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'radix-vue'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <DropdownMenuItem\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DropdownMenuLabel.vue",
|
"name": "DropdownMenuLabel.vue",
|
||||||
|
|
|
||||||
125
apps/www/src/public/registry/styles/default/sidebar.json
Normal file
125
apps/www/src/public/registry/styles/default/sidebar.json
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
{
|
||||||
|
"name": "sidebar",
|
||||||
|
"dependencies": [
|
||||||
|
"@vueuse/core"
|
||||||
|
],
|
||||||
|
"registryDependencies": [
|
||||||
|
"Sheet.vue",
|
||||||
|
"SheetContent.vue",
|
||||||
|
"utils",
|
||||||
|
"Input.vue",
|
||||||
|
"Tooltip.vue",
|
||||||
|
"TooltipContent.vue",
|
||||||
|
"TooltipTrigger.vue",
|
||||||
|
"Skeleton.vue",
|
||||||
|
"Separator.vue",
|
||||||
|
"Button.vue"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"name": "Sidebar.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Sheet from '@/lib/registry/default/ui/sheet/Sheet.vue'\nimport SheetContent from '@/lib/registry/default/ui/sheet/SheetContent.vue'\nimport { cn } from '@/lib/utils'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}>(), {\n side: 'left',\n variant: 'sidebar',\n collapsible: 'offcanvas',\n})\n\nconst { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n</script>\n\n<template>\n <div\n v-if=\"collapsible === 'none'\"\n :class=\"cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n\n <Sheet v-else-if=\"isMobile\" :open=\"openMobile\" v-bind=\"$attrs\" @update:open=\"setOpenMobile\">\n <SheetContent\n data-sidebar=\"sidebar\"\n data-mobile=\"true\"\n class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarContent.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"content\"\n :class=\"cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarFooter.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"footer\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroup.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group\"\n :class=\"cn('relative flex w-full min-w-0 flex-col p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroupAction.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'radix-vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'radix-vue'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-action\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroupContent.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group-content\"\n :class=\"cn('w-full text-sm', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroupLabel.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'radix-vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'radix-vue'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-label\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarHeader.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"header\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarInput.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Input from '@/lib/registry/default/ui/input/Input.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarInset.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <main\n :class=\"cn(\n 'relative flex min-h-svh flex-1 flex-col bg-background',\n 'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',\n props.class,\n )\"\n >\n <slot />\n </main>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenu.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu\"\n :class=\"cn('flex w-full min-w-0 flex-col gap-1', props.class)\"\n >\n <slot />\n </ul>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuAction.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'radix-vue'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n showOnHover?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-action\"\n :class=\"cn(\n 'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover\n && 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n props.class,\n )\"\n :as=\"as\"\n :as-child=\"asChild\"\n />\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuBadge.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground select-none pointer-events-none',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuButton.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport Tooltip from '@/lib/registry/default/ui/tooltip/Tooltip.vue'\nimport TooltipContent from '@/lib/registry/default/ui/tooltip/TooltipContent.vue'\nimport TooltipTrigger from '@/lib/registry/default/ui/tooltip/TooltipTrigger.vue'\nimport { type Component, computed } from 'vue'\nimport SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue'\nimport { useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps & {\n tooltip?: string | Component\n}>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n\nconst { isMobile, state } = useSidebar()\n\nconst delegatedProps = computed(() => {\n const { tooltip, ...delegated } = props\n return delegated\n})\n</script>\n\n<template>\n <SidebarMenuButtonChild v-if=\"!tooltip\" v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n\n <Tooltip v-else>\n <TooltipTrigger as-child>\n <SidebarMenuButtonChild v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n </TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n :hidden=\"state !== 'collapsed' || isMobile\"\n >\n <template v-if=\"typeof tooltip === 'string'\">\n {{ tooltip }}\n </template>\n <component :is=\"tooltip\" v-else />\n </TooltipContent>\n </Tooltip>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuButtonChild.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'radix-vue'\nimport { type SidebarMenuButtonVariants, sidebarMenuButtonVariants } from '.'\n\nexport interface SidebarMenuButtonProps extends PrimitiveProps {\n variant?: SidebarMenuButtonVariants['variant']\n size?: SidebarMenuButtonVariants['size']\n isActive?: boolean\n class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-button\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(sidebarMenuButtonVariants({ variant, size }), props.class)\"\n :as=\"as\"\n :as-child=\"asChild\"\n v-bind=\"$attrs\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuItem.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n data-sidebar=\"menu-item\"\n :class=\"cn('group/menu-item relative', props.class)\"\n >\n <slot />\n </li>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSkeleton.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport Skeleton from '@/lib/registry/default/ui/skeleton/Skeleton.vue'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSub.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </ul>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSubButton.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'radix-vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'radix-vue'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n size?: 'sm' | 'md'\n isActive?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'a',\n size: 'md',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-sub-button\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSubItem.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\n</script>\n\n<template>\n <li>\n <slot />\n </li>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarProvider.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'radix-vue'\nimport { computed, type HTMLAttributes, type Ref, ref } from 'vue'\nimport { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from './utils'\n\nconst props = withDefaults(defineProps<{\n defaultOpen?: boolean\n open?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n defaultOpen: true,\n open: undefined,\n})\n\nconst emits = defineEmits<{\n 'update:open': [open: boolean]\n}>()\n\nconst isMobile = ref(false) // useIsMobile()\nconst openMobile = ref(false)\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen ?? false,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nfunction setOpen(value: boolean) {\n open.value = value // emits('update:open', value)\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n}\n\nfunction setOpenMobile(value: boolean) {\n openMobile.value = value\n}\n\n// Helper to toggle the sidebar.\nfunction toggleSidebar() {\n return isMobile.value ? setOpenMobile(!open.value) : setOpen(!open.value)\n}\n\nuseEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n toggleSidebar()\n }\n})\n\n// We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n// This makes it easier to style the sidebar with Tailwind classes.\nconst state = computed(() => open.value ? 'expanded' : 'collapsed')\n\nprovideSidebarContext({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n})\n</script>\n\n<template>\n <TooltipProvider :delay-duration=\"0\">\n <div\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n }\"\n :class=\"cn('group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)\"\n >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarRail.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <button\n data-sidebar=\"rail\"\n aria-label=\"Toggle Sidebar\"\n :tabindex=\"-1\"\n title=\"Toggle Sidebar\"\n :class=\"cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n props.class,\n )\"\n @click=\"toggleSidebar\"\n >\n <slot />\n </button>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarSeparator.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Separator from '@/lib/registry/default/ui/separator/Separator.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarTrigger.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Button from '@/lib/registry/default/ui/button/Button.vue'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "index.ts",
|
||||||
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Sidebar } from './Sidebar.vue'\nexport { default as SidebarContent } from './SidebarContent.vue'\nexport { default as SidebarFooter } from './SidebarFooter.vue'\nexport { default as SidebarGroup } from './SidebarGroup.vue'\nexport { default as SidebarGroupAction } from './SidebarGroupAction.vue'\nexport { default as SidebarGroupContent } from './SidebarGroupContent.vue'\nexport { default as SidebarGroupLabel } from './SidebarGroupLabel.vue'\nexport { default as SidebarHeader } from './SidebarHeader.vue'\nexport { default as SidebarInput } from './SidebarInput.vue'\nexport { default as SidebarInset } from './SidebarInset.vue'\nexport { default as SidebarMenu } from './SidebarMenu.vue'\nexport { default as SidebarMenuAction } from './SidebarMenuAction.vue'\nexport { default as SidebarMenuBadge } from './SidebarMenuBadge.vue'\nexport { default as SidebarMenuButton } from './SidebarMenuButton.vue'\nexport { default as SidebarMenuItem } from './SidebarMenuItem.vue'\nexport { default as SidebarMenuSkeleton } from './SidebarMenuSkeleton.vue'\nexport { default as SidebarMenuSub } from './SidebarMenuSub.vue'\nexport { default as SidebarMenuSubButton } from './SidebarMenuSubButton.vue'\nexport { default as SidebarMenuSubItem } from './SidebarMenuSubItem.vue'\nexport { default as SidebarProvider } from './SidebarProvider.vue'\nexport { default as SidebarRail } from './SidebarRail.vue'\nexport { default as SidebarSeparator } from './SidebarSeparator.vue'\nexport { default as SidebarTrigger } from './SidebarTrigger.vue'\n\nexport { useSidebar } from './utils'\n\nexport const sidebarMenuButtonVariants = cva(\n 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type SidebarMenuButtonVariants = VariantProps<typeof sidebarMenuButtonVariants>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "utils.ts",
|
||||||
|
"content": "import type { ComputedRef, Ref } from 'vue'\nimport { createContext } from 'radix-vue'\n\nexport const SIDEBAR_COOKIE_NAME = 'sidebar:state'\nexport const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nexport const SIDEBAR_WIDTH = '16rem'\nexport const SIDEBAR_WIDTH_MOBILE = '18rem'\nexport const SIDEBAR_WIDTH_ICON = '3rem'\nexport const SIDEBAR_KEYBOARD_SHORTCUT = 'b'\n\nexport const [useSidebar, provideSidebarContext] = createContext<{\n state: ComputedRef<'expanded' | 'collapsed'>\n open: Ref<boolean>\n setOpen: (value: boolean) => void\n isMobile: Ref<boolean>\n openMobile: Ref<boolean>\n setOpenMobile: (value: boolean) => void\n toggleSidebar: () => void\n}>('Sidebar')\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DropdownMenuItem.vue",
|
"name": "DropdownMenuItem.vue",
|
||||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'radix-vue'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <DropdownMenuItem\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n"
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'radix-vue'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <DropdownMenuItem\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DropdownMenuLabel.vue",
|
"name": "DropdownMenuLabel.vue",
|
||||||
|
|
|
||||||
125
apps/www/src/public/registry/styles/new-york/sidebar.json
Normal file
125
apps/www/src/public/registry/styles/new-york/sidebar.json
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
{
|
||||||
|
"name": "sidebar",
|
||||||
|
"dependencies": [
|
||||||
|
"@vueuse/core"
|
||||||
|
],
|
||||||
|
"registryDependencies": [
|
||||||
|
"Sheet.vue",
|
||||||
|
"SheetContent.vue",
|
||||||
|
"utils",
|
||||||
|
"Input.vue",
|
||||||
|
"Tooltip.vue",
|
||||||
|
"TooltipContent.vue",
|
||||||
|
"TooltipTrigger.vue",
|
||||||
|
"Skeleton.vue",
|
||||||
|
"Separator.vue",
|
||||||
|
"Button.vue"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"name": "Sidebar.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Sheet from '@/lib/registry/new-york/ui/sheet/Sheet.vue'\nimport SheetContent from '@/lib/registry/new-york/ui/sheet/SheetContent.vue'\nimport { cn } from '@/lib/utils'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}>(), {\n side: 'left',\n variant: 'sidebar',\n collapsible: 'offcanvas',\n})\n\nconst { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n</script>\n\n<template>\n <div\n v-if=\"collapsible === 'none'\"\n :class=\"cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n\n <Sheet v-else-if=\"isMobile\" :open=\"openMobile\" v-bind=\"$attrs\" @update:open=\"setOpenMobile\">\n <SheetContent\n data-sidebar=\"sidebar\"\n data-mobile=\"true\"\n class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarContent.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"content\"\n :class=\"cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarFooter.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"footer\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroup.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group\"\n :class=\"cn('relative flex w-full min-w-0 flex-col p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroupAction.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'radix-vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'radix-vue'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-action\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroupContent.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group-content\"\n :class=\"cn('w-full text-sm', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarGroupLabel.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'radix-vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'radix-vue'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-label\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarHeader.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"header\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarInput.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Input from '@/lib/registry/new-york/ui/input/Input.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarInset.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <main\n :class=\"cn(\n 'relative flex min-h-svh flex-1 flex-col bg-background',\n 'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',\n props.class,\n )\"\n >\n <slot />\n </main>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenu.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu\"\n :class=\"cn('flex w-full min-w-0 flex-col gap-1', props.class)\"\n >\n <slot />\n </ul>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuAction.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'radix-vue'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n showOnHover?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-action\"\n :class=\"cn(\n 'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover\n && 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n props.class,\n )\"\n :as=\"as\"\n :as-child=\"asChild\"\n />\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuBadge.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground select-none pointer-events-none',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuButton.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport Tooltip from '@/lib/registry/new-york/ui/tooltip/Tooltip.vue'\nimport TooltipContent from '@/lib/registry/new-york/ui/tooltip/TooltipContent.vue'\nimport TooltipTrigger from '@/lib/registry/new-york/ui/tooltip/TooltipTrigger.vue'\nimport { type Component, computed } from 'vue'\nimport SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue'\nimport { useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps & {\n tooltip?: string | Component\n}>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n\nconst { isMobile, state } = useSidebar()\n\nconst delegatedProps = computed(() => {\n const { tooltip, ...delegated } = props\n return delegated\n})\n</script>\n\n<template>\n <SidebarMenuButtonChild v-if=\"!tooltip\" v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n\n <Tooltip v-else>\n <TooltipTrigger as-child>\n <SidebarMenuButtonChild v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n </TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n :hidden=\"state !== 'collapsed' || isMobile\"\n >\n <template v-if=\"typeof tooltip === 'string'\">\n {{ tooltip }}\n </template>\n <component :is=\"tooltip\" v-else />\n </TooltipContent>\n </Tooltip>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuButtonChild.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'radix-vue'\nimport { type SidebarMenuButtonVariants, sidebarMenuButtonVariants } from '.'\n\nexport interface SidebarMenuButtonProps extends PrimitiveProps {\n variant?: SidebarMenuButtonVariants['variant']\n size?: SidebarMenuButtonVariants['size']\n isActive?: boolean\n class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-button\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(sidebarMenuButtonVariants({ variant, size }), props.class)\"\n :as=\"as\"\n :as-child=\"asChild\"\n v-bind=\"$attrs\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuItem.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n data-sidebar=\"menu-item\"\n :class=\"cn('group/menu-item relative', props.class)\"\n >\n <slot />\n </li>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSkeleton.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport Skeleton from '@/lib/registry/new-york/ui/skeleton/Skeleton.vue'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSub.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </ul>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSubButton.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'radix-vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'radix-vue'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n size?: 'sm' | 'md'\n isActive?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'a',\n size: 'md',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-sub-button\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarMenuSubItem.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\n</script>\n\n<template>\n <li>\n <slot />\n </li>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarProvider.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'radix-vue'\nimport { computed, type HTMLAttributes, type Ref, ref } from 'vue'\nimport { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from './utils'\n\nconst props = withDefaults(defineProps<{\n defaultOpen?: boolean\n open?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n defaultOpen: true,\n open: undefined,\n})\n\nconst emits = defineEmits<{\n 'update:open': [open: boolean]\n}>()\n\nconst isMobile = ref(false) // useIsMobile()\nconst openMobile = ref(false)\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen ?? false,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nfunction setOpen(value: boolean) {\n open.value = value // emits('update:open', value)\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n}\n\nfunction setOpenMobile(value: boolean) {\n openMobile.value = value\n}\n\n// Helper to toggle the sidebar.\nfunction toggleSidebar() {\n return isMobile.value ? setOpenMobile(!open.value) : setOpen(!open.value)\n}\n\nuseEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n toggleSidebar()\n }\n})\n\n// We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n// This makes it easier to style the sidebar with Tailwind classes.\nconst state = computed(() => open.value ? 'expanded' : 'collapsed')\n\nprovideSidebarContext({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n})\n</script>\n\n<template>\n <TooltipProvider :delay-duration=\"0\">\n <div\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n }\"\n :class=\"cn('group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)\"\n >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarRail.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <button\n data-sidebar=\"rail\"\n aria-label=\"Toggle Sidebar\"\n :tabindex=\"-1\"\n title=\"Toggle Sidebar\"\n :class=\"cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n props.class,\n )\"\n @click=\"toggleSidebar\"\n >\n <slot />\n </button>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarSeparator.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Separator from '@/lib/registry/new-york/ui/separator/Separator.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SidebarTrigger.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Button from '@/lib/registry/new-york/ui/button/Button.vue'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "index.ts",
|
||||||
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Sidebar } from './Sidebar.vue'\nexport { default as SidebarContent } from './SidebarContent.vue'\nexport { default as SidebarFooter } from './SidebarFooter.vue'\nexport { default as SidebarGroup } from './SidebarGroup.vue'\nexport { default as SidebarGroupAction } from './SidebarGroupAction.vue'\nexport { default as SidebarGroupContent } from './SidebarGroupContent.vue'\nexport { default as SidebarGroupLabel } from './SidebarGroupLabel.vue'\nexport { default as SidebarHeader } from './SidebarHeader.vue'\nexport { default as SidebarInput } from './SidebarInput.vue'\nexport { default as SidebarInset } from './SidebarInset.vue'\nexport { default as SidebarMenu } from './SidebarMenu.vue'\nexport { default as SidebarMenuAction } from './SidebarMenuAction.vue'\nexport { default as SidebarMenuBadge } from './SidebarMenuBadge.vue'\nexport { default as SidebarMenuButton } from './SidebarMenuButton.vue'\nexport { default as SidebarMenuItem } from './SidebarMenuItem.vue'\nexport { default as SidebarMenuSkeleton } from './SidebarMenuSkeleton.vue'\nexport { default as SidebarMenuSub } from './SidebarMenuSub.vue'\nexport { default as SidebarMenuSubButton } from './SidebarMenuSubButton.vue'\nexport { default as SidebarMenuSubItem } from './SidebarMenuSubItem.vue'\nexport { default as SidebarProvider } from './SidebarProvider.vue'\nexport { default as SidebarRail } from './SidebarRail.vue'\nexport { default as SidebarSeparator } from './SidebarSeparator.vue'\nexport { default as SidebarTrigger } from './SidebarTrigger.vue'\n\nexport { useSidebar } from './utils'\n\nexport const sidebarMenuButtonVariants = cva(\n 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type SidebarMenuButtonVariants = VariantProps<typeof sidebarMenuButtonVariants>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "utils.ts",
|
||||||
|
"content": "import type { ComputedRef, Ref } from 'vue'\nimport { createContext } from 'radix-vue'\n\nexport const SIDEBAR_COOKIE_NAME = 'sidebar:state'\nexport const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nexport const SIDEBAR_WIDTH = '16rem'\nexport const SIDEBAR_WIDTH_MOBILE = '18rem'\nexport const SIDEBAR_WIDTH_ICON = '3rem'\nexport const SIDEBAR_KEYBOARD_SHORTCUT = 'b'\n\nexport const [useSidebar, provideSidebarContext] = createContext<{\n state: ComputedRef<'expanded' | 'collapsed'>\n open: Ref<boolean>\n setOpen: (value: boolean) => void\n isMobile: Ref<boolean>\n openMobile: Ref<boolean>\n setOpenMobile: (value: boolean) => void\n toggleSidebar: () => void\n}>('Sidebar')\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -80,7 +80,7 @@
|
||||||
"@types/prompts": "^2.4.9",
|
"@types/prompts": "^2.4.9",
|
||||||
"tsup": "^8.3.0",
|
"tsup": "^8.3.0",
|
||||||
"type-fest": "^4.26.1",
|
"type-fest": "^4.26.1",
|
||||||
"typescript": "^5.6.3",
|
"typescript": "catalog:",
|
||||||
"vite-tsconfig-paths": "^5.0.1"
|
"vite-tsconfig-paths": "^5.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user