{
  "name": "sidebar",
  "type": "registry:ui",
  "dependencies": [
    "reka-ui",
    "@vueuse/core"
  ],
  "registryDependencies": [
    "sheet",
    "input",
    "tooltip",
    "skeleton",
    "separator",
    "button"
  ],
  "files": [
    {
      "path": "ui/sidebar/Sidebar.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SidebarProps } from \".\"\nimport { cn } from \"@/lib/utils\"\nimport { Sheet, SheetContent } from \"@/registry/new-york/ui/sheet\"\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from \"./utils\"\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\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      :side=\"side\"\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 text-sidebar-foreground 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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarGroupAction.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\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      '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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarGroupLabel.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\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,opacity] 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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarInput.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport { Input } from \"@/registry/new-york/ui/input\"\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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarMenuAction.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\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      '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    <slot />\n  </Primitive>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarMenuButton.vue",
      "content": "<script setup lang=\"ts\">\nimport type { Component } from \"vue\"\nimport type { SidebarMenuButtonProps } from \"./SidebarMenuButtonChild.vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"@/registry/new-york/ui/tooltip\"\nimport SidebarMenuButtonChild 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 = reactiveOmit(props, \"tooltip\")\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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarMenuButtonChild.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport type { SidebarMenuButtonVariants } from \".\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\nimport { 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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarMenuSkeleton.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { computed } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport { Skeleton } from \"@/registry/new-york/ui/skeleton\"\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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarMenuSubButton.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { Primitive } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarMenuSubItem.vue",
      "content": "<script setup lang=\"ts\">\n</script>\n\n<template>\n  <li>\n    <slot />\n  </li>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarProvider.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes, Ref } from \"vue\"\nimport { defaultDocument, useEventListener, useMediaQuery, useVModel } from \"@vueuse/core\"\nimport { TooltipProvider } from \"reka-ui\"\nimport { computed, ref } from \"vue\"\nimport { cn } from \"@/lib/utils\"\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: !defaultDocument?.cookie.includes(`${SIDEBAR_COOKIE_NAME}=false`),\n  open: undefined,\n})\n\nconst emits = defineEmits<{\n  \"update:open\": [open: boolean]\n}>()\n\nconst isMobile = useMediaQuery(\"(max-width: 768px)\")\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.value}; 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(!openMobile.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 has-[[data-variant=inset]]:bg-sidebar', props.class)\"\n      v-bind=\"$attrs\"\n    >\n      <slot />\n    </div>\n  </TooltipProvider>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/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-0.5 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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarSeparator.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { cn } from \"@/lib/utils\"\nimport { Separator } from \"@/registry/new-york/ui/separator\"\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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/SidebarTrigger.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from \"vue\"\nimport { PanelLeft } from \"lucide-vue-next\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york/ui/button\"\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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/index.ts",
      "content": "import type { VariantProps } from \"class-variance-authority\"\nimport type { HTMLAttributes } from \"vue\"\nimport { cva } from \"class-variance-authority\"\n\nexport interface SidebarProps {\n  side?: \"left\" | \"right\"\n  variant?: \"sidebar\" | \"floating\" | \"inset\"\n  collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n  class?: HTMLAttributes[\"class\"]\n}\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_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_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",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/sidebar/utils.ts",
      "content": "import type { ComputedRef, Ref } from \"vue\"\nimport { createContext } from \"reka-ui\"\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": "registry:ui",
      "target": ""
    }
  ],
  "tailwind": {
    "config": {
      "theme": {
        "extend": {
          "colors": {
            "sidebar": {
              "DEFAULT": "hsl(var(--sidebar-background))",
              "foreground": "hsl(var(--sidebar-foreground))",
              "primary": "hsl(var(--sidebar-primary))",
              "primary-foreground": "hsl(var(--sidebar-primary-foreground))",
              "accent": "hsl(var(--sidebar-accent))",
              "accent-foreground": "hsl(var(--sidebar-accent-foreground))",
              "border": "hsl(var(--sidebar-border))",
              "ring": "hsl(var(--sidebar-ring))"
            }
          }
        }
      }
    }
  },
  "cssVars": {
    "light": {
      "sidebar-background": "0 0% 98%",
      "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-background": "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%"
    }
  }
}
