{{ $route.name }}
diff --git a/app/router.ts b/app/router.ts
index c3dede5..afa6f05 100644
--- a/app/router.ts
+++ b/app/router.ts
@@ -22,6 +22,7 @@ import {
Select,
Separator,
Sheet,
+ Sidebar,
Skeleton,
Slider,
Table,
@@ -228,6 +229,15 @@ const routes = [
shadcn: true,
},
},
+ {
+ path: '/components/sidebar',
+ name: 'Sidebar',
+ component: Sidebar,
+ meta: {
+ layout: ComponentLayout,
+ shadcn: true,
+ },
+ },
{
path: '/components/skeleton',
name: 'Skeleton',
@@ -298,7 +308,7 @@ const routes = [
const router = createRouter({
history: createWebHistory(),
- linkActiveClass: '!font-medium underline',
+ linkActiveClass: '',
routes,
})
diff --git a/app/views/components/Sidebar.vue b/app/views/components/Sidebar.vue
new file mode 100644
index 0000000..732497d
--- /dev/null
+++ b/app/views/components/Sidebar.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+ Projects
+
+
+
+
+
+
+
+ {{ project.name }}
+
+
+
+
+
+
+
+
+
+
+ Edit Project
+
+
+ Delete Project
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/index.ts b/app/views/index.ts
index 749a22d..ee072f4 100644
--- a/app/views/index.ts
+++ b/app/views/index.ts
@@ -20,6 +20,7 @@ export { default as RangeCalendar } from './components/RangeCalendar.vue'
export { default as Select } from './components/Select.vue'
export { default as Separator } from './components/Separator.vue'
export { default as Sheet } from './components/Sheet.vue'
+export { default as Sidebar} from './components/Sidebar.vue'
export { default as Skeleton } from './components/Skeleton.vue'
export { default as Slider } from './components/Slider.vue'
export { default as Table } from './components/Table.vue'
diff --git a/package-lock.json b/package-lock.json
index 2542b92..d2239ba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1693,6 +1693,7 @@
"version": "10.11.1",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz",
"integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==",
+ "license": "MIT",
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.11.1",
diff --git a/src/components/sidebar/Sidebar.vue b/src/components/sidebar/Sidebar.vue
new file mode 100644
index 0000000..31e13fd
--- /dev/null
+++ b/src/components/sidebar/Sidebar.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarContent.vue b/src/components/sidebar/SidebarContent.vue
new file mode 100644
index 0000000..926dd30
--- /dev/null
+++ b/src/components/sidebar/SidebarContent.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarFooter.vue b/src/components/sidebar/SidebarFooter.vue
new file mode 100644
index 0000000..c99a399
--- /dev/null
+++ b/src/components/sidebar/SidebarFooter.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarGroup.vue b/src/components/sidebar/SidebarGroup.vue
new file mode 100644
index 0000000..66d307b
--- /dev/null
+++ b/src/components/sidebar/SidebarGroup.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarGroupAction.vue b/src/components/sidebar/SidebarGroupAction.vue
new file mode 100644
index 0000000..c1a8587
--- /dev/null
+++ b/src/components/sidebar/SidebarGroupAction.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarGroupContent.vue b/src/components/sidebar/SidebarGroupContent.vue
new file mode 100644
index 0000000..966ce13
--- /dev/null
+++ b/src/components/sidebar/SidebarGroupContent.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarGroupLabel.vue b/src/components/sidebar/SidebarGroupLabel.vue
new file mode 100644
index 0000000..4f42cf3
--- /dev/null
+++ b/src/components/sidebar/SidebarGroupLabel.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarHeader.vue b/src/components/sidebar/SidebarHeader.vue
new file mode 100644
index 0000000..64d7d29
--- /dev/null
+++ b/src/components/sidebar/SidebarHeader.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarInput.vue b/src/components/sidebar/SidebarInput.vue
new file mode 100644
index 0000000..ea12427
--- /dev/null
+++ b/src/components/sidebar/SidebarInput.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarInset.vue b/src/components/sidebar/SidebarInset.vue
new file mode 100644
index 0000000..b3b4809
--- /dev/null
+++ b/src/components/sidebar/SidebarInset.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenu.vue b/src/components/sidebar/SidebarMenu.vue
new file mode 100644
index 0000000..48be487
--- /dev/null
+++ b/src/components/sidebar/SidebarMenu.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuAction.vue b/src/components/sidebar/SidebarMenuAction.vue
new file mode 100644
index 0000000..d51b3cb
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuAction.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuBadge.vue b/src/components/sidebar/SidebarMenuBadge.vue
new file mode 100644
index 0000000..e15993c
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuBadge.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuButton.vue b/src/components/sidebar/SidebarMenuButton.vue
new file mode 100644
index 0000000..abb4e64
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuButton.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tooltip }}
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuButtonChild.vue b/src/components/sidebar/SidebarMenuButtonChild.vue
new file mode 100644
index 0000000..a0efa1f
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuButtonChild.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuItem.vue b/src/components/sidebar/SidebarMenuItem.vue
new file mode 100644
index 0000000..bfb97e0
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuItem.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuSkeleton.vue b/src/components/sidebar/SidebarMenuSkeleton.vue
new file mode 100644
index 0000000..4421169
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuSkeleton.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuSub.vue b/src/components/sidebar/SidebarMenuSub.vue
new file mode 100644
index 0000000..e7e6ccc
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuSub.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuSubButton.vue b/src/components/sidebar/SidebarMenuSubButton.vue
new file mode 100644
index 0000000..b3d82d9
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuSubButton.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarMenuSubItem.vue b/src/components/sidebar/SidebarMenuSubItem.vue
new file mode 100644
index 0000000..fbc3fbf
--- /dev/null
+++ b/src/components/sidebar/SidebarMenuSubItem.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarProvider.vue b/src/components/sidebar/SidebarProvider.vue
new file mode 100644
index 0000000..91ef802
--- /dev/null
+++ b/src/components/sidebar/SidebarProvider.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarRail.vue b/src/components/sidebar/SidebarRail.vue
new file mode 100644
index 0000000..2fe25d7
--- /dev/null
+++ b/src/components/sidebar/SidebarRail.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarSeparator.vue b/src/components/sidebar/SidebarSeparator.vue
new file mode 100644
index 0000000..b957a21
--- /dev/null
+++ b/src/components/sidebar/SidebarSeparator.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/src/components/sidebar/SidebarTrigger.vue b/src/components/sidebar/SidebarTrigger.vue
new file mode 100644
index 0000000..7175d14
--- /dev/null
+++ b/src/components/sidebar/SidebarTrigger.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/src/components/sidebar/index.ts b/src/components/sidebar/index.ts
new file mode 100644
index 0000000..b137821
--- /dev/null
+++ b/src/components/sidebar/index.ts
@@ -0,0 +1,51 @@
+import { cva, type VariantProps } from 'class-variance-authority'
+
+export { default as Sidebar } from './Sidebar.vue'
+export { default as SidebarContent } from './SidebarContent.vue'
+export { default as SidebarFooter } from './SidebarFooter.vue'
+export { default as SidebarGroup } from './SidebarGroup.vue'
+export { default as SidebarGroupAction } from './SidebarGroupAction.vue'
+export { default as SidebarGroupContent } from './SidebarGroupContent.vue'
+export { default as SidebarGroupLabel } from './SidebarGroupLabel.vue'
+export { default as SidebarHeader } from './SidebarHeader.vue'
+export { default as SidebarInput } from './SidebarInput.vue'
+export { default as SidebarInset } from './SidebarInset.vue'
+export { default as SidebarMenu } from './SidebarMenu.vue'
+export { default as SidebarMenuAction } from './SidebarMenuAction.vue'
+export { default as SidebarMenuBadge } from './SidebarMenuBadge.vue'
+export { default as SidebarMenuButton } from './SidebarMenuButton.vue'
+export { default as SidebarMenuItem } from './SidebarMenuItem.vue'
+export { default as SidebarMenuSkeleton } from './SidebarMenuSkeleton.vue'
+export { default as SidebarMenuSub } from './SidebarMenuSub.vue'
+export { default as SidebarMenuSubButton } from './SidebarMenuSubButton.vue'
+export { default as SidebarMenuSubItem } from './SidebarMenuSubItem.vue'
+export { default as SidebarProvider } from './SidebarProvider.vue'
+export { default as SidebarRail } from './SidebarRail.vue'
+export { default as SidebarSeparator } from './SidebarSeparator.vue'
+export { default as SidebarTrigger } from './SidebarTrigger.vue'
+
+export { useSidebar } from './utils'
+
+export const sidebarMenuButtonVariants = cva(
+ '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',
+ {
+ variants: {
+ variant: {
+ default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
+ outline:
+ '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))]',
+ },
+ size: {
+ default: 'h-8 text-sm',
+ sm: 'h-7 text-xs',
+ lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',
+ },
+ },
+ defaultVariants: {
+ variant: 'default',
+ size: 'default',
+ },
+ },
+)
+
+export type SidebarMenuButtonVariants = VariantProps
diff --git a/src/components/sidebar/utils.ts b/src/components/sidebar/utils.ts
new file mode 100644
index 0000000..3ded66c
--- /dev/null
+++ b/src/components/sidebar/utils.ts
@@ -0,0 +1,19 @@
+import type { ComputedRef, Ref } from 'vue'
+import { createContext } from 'radix-vue'
+
+export const SIDEBAR_COOKIE_NAME = 'sidebar:state'
+export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
+export const SIDEBAR_WIDTH = '16rem'
+export const SIDEBAR_WIDTH_MOBILE = '18rem'
+export const SIDEBAR_WIDTH_ICON = '3rem'
+export const SIDEBAR_KEYBOARD_SHORTCUT = 'b'
+
+export const [useSidebar, provideSidebarContext] = createContext<{
+ state: ComputedRef<'expanded' | 'collapsed'>
+ open: Ref
+ setOpen: (value: boolean) => void
+ isMobile: Ref
+ openMobile: Ref
+ setOpenMobile: (value: boolean) => void
+ toggleSidebar: () => void
+}>('Sidebar')
diff --git a/src/index.ts b/src/index.ts
index c1e254f..7561be9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -18,6 +18,7 @@ export * from '@/components/range-calendar'
export * from '@/components/select'
export * from '@/components/separator'
export * from '@/components/sheet'
+export * from '@/components/sidebar'
export * from '@/components/skeleton'
export * from '@/components/slider'
export * from '@/components/table'
diff --git a/src/presets/preset.ts b/src/presets/preset.ts
index db2da4a..caf2652 100644
--- a/src/presets/preset.ts
+++ b/src/presets/preset.ts
@@ -62,6 +62,11 @@ export default {
border: 'hsl(var(--card-border))',
foreground: 'hsl(var(--card-foreground))',
},
+
+ sidebar: {
+ DEFAULT: 'hsl(var(--sidebar))',
+ foreground: 'hsl(var(--sidebar-foreground))',
+ },
},
borderRadius: {
xl: 'calc(var(--radius) + 4px)',
diff --git a/src/presets/slate.css b/src/presets/slate.css
index 2322c3b..585789b 100644
--- a/src/presets/slate.css
+++ b/src/presets/slate.css
@@ -39,9 +39,27 @@
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
+
+ --sidebar: 0 0% 100%; /* white */
+ --sidebar-foreground: 240 5.3% 26.1%;
+ --sidebar-primary: 240 5.9% 10%;
+ --sidebar-primary-foreground: 0 0% 98%;
+ --sidebar-accent: 240 4.8% 95.9%;
+ --sidebar-accent-foreground: 240 5.9% 10%;
+ --sidebar-border: 220 13% 91%;
+ --sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
+ --sidebar: 240 5.9% 10%;
+ --sidebar-foreground: 240 4.8% 95.9%;
+ --sidebar-primary: 224.3 76.3% 48%;
+ --sidebar-primary-foreground: 0 0% 100%;
+ --sidebar-accent: 240 3.7% 15.9%;
+ --sidebar-accent-foreground: 240 4.8% 95.9%;
+ --sidebar-border: 240 3.7% 15.9%;
+ --sidebar-ring: 217.2 91.2% 59.8%;
+
--background: 229 84% 5%; /* slate-950 */
--foreground: 214 32% 91%;