{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sidebar",
  "type": "registry:component",
  "title": "Sidebar",
  "description": "Holds persistent navigation in a 204px rail with a head, body, and foot.",
  "registryDependencies": [
    "https://vlak.dev/r/vlak-base.json",
    "https://vlak.dev/r/inter.json",
    "https://vlak.dev/r/vlak-lib.json"
  ],
  "dependencies": [
    "@stylexjs/stylex"
  ],
  "devDependencies": [
    "@stylexjs/babel-plugin"
  ],
  "docs": "Vlak leaves are StyleX. Compile them with @stylexjs/babel-plugin (Vite: @stylexjs/unplugin, Next: @stylexjs/nextjs-plugin). If you would rather not run a compiler, import @noorddev/vlak-react instead: it ships precompiled with one stylesheet.",
  "files": [
    {
      "path": "vlak/sidebar.tsx",
      "content": "import * as React from \"react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport { vlak, mq } from \"./tokens.stylex\";\nimport { rs } from \"./rs\";\n\nexport interface SidebarProps extends React.HTMLAttributes<HTMLElement> {}\n\nconst styles = stylex.create({\n  sidebar: {\n    boxSizing: \"border-box\",\n    width: {\n      default: 204,\n      [mq.phone]: \"100%\",\n    },\n    minHeight: 204,\n    display: \"flex\",\n    flexDirection: \"column\",\n    borderWidth: vlak.hairline,\n    borderStyle: \"solid\",\n    borderColor: vlak.divider,\n    backgroundColor: vlak.paper,\n    borderRadius: 0,\n  },\n  head: {\n    boxSizing: \"border-box\",\n    paddingBlock: \"1rem\",\n    paddingInline: \"1.25rem\",\n    fontSize: {\n      default: \"0.8125rem\",\n      [mq.phone]: vlak.controlFs,\n    },\n    fontWeight: 600,\n    letterSpacing: \"-0.01em\",\n    color: vlak.ink,\n    borderBottomWidth: vlak.hairline,\n    borderBottomStyle: \"solid\",\n    borderBottomColor: vlak.divider,\n    minHeight: {\n      default: null,\n      [mq.phone]: vlak.hit,\n    },\n    display: {\n      default: null,\n      [mq.phone]: \"flex\",\n    },\n    alignItems: {\n      default: null,\n      [mq.phone]: \"center\",\n    },\n  },\n  nav: {\n    display: \"flex\",\n    flexDirection: \"column\",\n    paddingTop: \"0.5rem\",\n    paddingInlineEnd: 0,\n    paddingBottom: \"2rem\",\n    paddingInlineStart: 0,\n    flexGrow: 1,\n    flexShrink: 1,\n    flexBasis: 0,\n  },\n  item: {\n    boxSizing: \"border-box\",\n    transition: {\n      default: vlak.transition,\n      [mq.reduce]: \"none\",\n    },\n    display: {\n      default: \"flex\",\n      [mq.phone]: \"flex\",\n    },\n    alignItems: {\n      default: \"center\",\n      [mq.phone]: \"center\",\n    },\n    minHeight: {\n      default: vlak.hit,\n      [mq.phone]: vlak.hit,\n    },\n    paddingTop: {\n      default: \"0.5rem\",\n      [mq.phone]: \"0.75rem\",\n    },\n    paddingInlineEnd: \"1.25rem\",\n    paddingBottom: {\n      default: \"0.5rem\",\n      [mq.phone]: \"0.75rem\",\n      \":last-child\": \"2rem\",\n    },\n    paddingInlineStart: \"1.25rem\",\n    fontSize: {\n      default: \"0.8125rem\",\n      [mq.phone]: vlak.controlFs,\n    },\n    fontWeight: 500,\n    letterSpacing: \"-0.01em\",\n    color: {\n      default: vlak.gray,\n      \":link\": vlak.gray,\n      \":visited\": vlak.gray,\n      \":hover\": { default: null, [mq.hover]: vlak.ink },\n      '[aria-current=\"page\"]': vlak.ink,\n    },\n    textDecoration: \"none\",\n  },\n  label: {\n    paddingTop: \"1rem\",\n    paddingInlineEnd: \"1.25rem\",\n    paddingBottom: {\n      default: \"0.25rem\",\n      [mq.phone]: \"0.5rem\",\n    },\n    paddingInlineStart: \"1.25rem\",\n    fontSize: {\n      default: \"0.75rem\",\n      [mq.phone]: vlak.controlLabel,\n    },\n    fontWeight: 600,\n    letterSpacing: \"-0.01em\",\n    color: vlak.gray,\n  },\n  foot: {\n    boxSizing: \"border-box\",\n    paddingTop: \"0.75rem\",\n    paddingInlineEnd: \"1.25rem\",\n    paddingBottom: \"0.75rem\",\n    paddingInlineStart: \"1.25rem\",\n    borderTopWidth: vlak.hairline,\n    borderTopStyle: \"solid\",\n    borderTopColor: vlak.divider,\n    fontSize: {\n      default: \"0.75rem\",\n      [mq.phone]: \"0.875rem\",\n    },\n    fontWeight: 500,\n    letterSpacing: \"-0.01em\",\n    color: vlak.gray,\n    minHeight: {\n      default: null,\n      [mq.phone]: vlak.hit,\n    },\n    display: {\n      default: null,\n      [mq.phone]: \"flex\",\n    },\n    alignItems: {\n      default: null,\n      [mq.phone]: \"center\",\n    },\n  },\n});\n\n/** One 204 module rail. Flush items, hairline edge. */\nexport const Sidebar = React.forwardRef<HTMLElement, SidebarProps>(function Sidebar(\n  { className, style, ...props },\n  ref,\n) {\n  const sx = rs([\"rs-sidebar\", className], styles.sidebar);\n  return <aside ref={ref} {...props} className={sx.className} style={{ ...sx.style, ...style }} />;\n});\n\nexport const SidebarHead = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(function SidebarHead(\n  { className, style, ...props },\n  ref,\n) {\n  const sx = rs([\"rs-sidebar-head\", className], styles.head);\n  return <div ref={ref} {...props} className={sx.className} style={{ ...sx.style, ...style }} />;\n});\n\nexport interface SidebarNavProps extends React.HTMLAttributes<HTMLElement> {\n  /** Landmark name; pages carry several navs. */\n  \"aria-label\"?: string;\n}\n\nexport const SidebarNav = React.forwardRef<HTMLElement, SidebarNavProps>(function SidebarNav(\n  { className, style, \"aria-label\": ariaLabel = \"Sidebar\", ...props },\n  ref,\n) {\n  const sx = rs([\"rs-sidebar-nav\", className], styles.nav);\n  return (\n    <nav\n      ref={ref}\n      aria-label={props[\"aria-labelledby\"] ? undefined : ariaLabel}\n      {...props}\n      className={sx.className}\n      style={{ ...sx.style, ...style }}\n    />\n  );\n});\n\nexport interface SidebarItemProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n  current?: boolean;\n}\n\nexport const SidebarItem = React.forwardRef<HTMLAnchorElement, SidebarItemProps>(function SidebarItem(\n  { current, className, style, ...props },\n  ref,\n) {\n  const sx = rs([\"rs-sidebar-item\", className], styles.item);\n  return (\n    <a\n      ref={ref}\n      aria-current={current ? \"page\" : undefined}\n      {...props}\n      className={sx.className}\n      style={{ ...sx.style, ...style }}\n    />\n  );\n});\n\nexport const SidebarLabel = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(function SidebarLabel(\n  { className, style, ...props },\n  ref,\n) {\n  const sx = rs([\"rs-sidebar-label\", className], styles.label);\n  return <p ref={ref} {...props} className={sx.className} style={{ ...sx.style, ...style }} />;\n});\n\nexport const SidebarFoot = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(function SidebarFoot(\n  { className, style, ...props },\n  ref,\n) {\n  const sx = rs([\"rs-sidebar-foot\", className], styles.foot);\n  return <div ref={ref} {...props} className={sx.className} style={{ ...sx.style, ...style }} />;\n});\n",
      "type": "registry:component",
      "target": "components/vlak/sidebar.tsx"
    },
    {
      "path": "vlak/styles/sidebar.css",
      "content": "/* ── sidebar: generated from packages/react/src/components/sidebar.tsx ── */\n.rs-sidebar{box-sizing:border-box;width:204px;min-height:204px;display:flex;flex-direction:column;border-width:1px;border-style:solid;border-color:var(--divider);background-color:var(--bg);border-radius:0}\n@media (max-width: 640px){.rs-sidebar{width:100%}}\n.rs-sidebar-head{box-sizing:border-box;padding-block:1rem;padding-inline:1.25rem;font-size:0.8125rem;font-weight:600;letter-spacing:-0.01em;color:var(--text);border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:var(--divider)}\n@media (max-width: 640px){.rs-sidebar-head{font-size:var(--control-fs);min-height:var(--hit);display:flex;align-items:center}}\n.rs-sidebar-nav{display:flex;flex-direction:column;padding-top:0.5rem;padding-inline-end:0;padding-bottom:2rem;padding-inline-start:0;flex-grow:1;flex-shrink:1;flex-basis:0}\n.rs-sidebar-item{box-sizing:border-box;transition:var(--transition);display:flex;align-items:center;min-height:var(--hit);padding-top:0.5rem;padding-inline-end:1.25rem;padding-bottom:0.5rem;padding-inline-start:1.25rem;font-size:0.8125rem;font-weight:500;letter-spacing:-0.01em;color:var(--text-secondary);text-decoration:none}\n.rs-sidebar-item:last-child{padding-bottom:2rem}\n.rs-sidebar-item:link{color:var(--text-secondary)}\n.rs-sidebar-item:visited{color:var(--text-secondary)}\n.rs-sidebar-item[aria-current=\"page\"]{color:var(--text)}\n@media (prefers-reduced-motion: reduce){.rs-sidebar-item{transition:none}}\n@media (max-width: 640px){.rs-sidebar-item{display:flex;align-items:center;min-height:var(--hit);padding-top:0.75rem;padding-bottom:0.75rem;font-size:var(--control-fs)}}\n@media (hover: hover) and (pointer: fine){.rs-sidebar-item:hover{color:var(--text)}}\n.rs-sidebar-label{padding-top:1rem;padding-inline-end:1.25rem;padding-bottom:0.25rem;padding-inline-start:1.25rem;font-size:0.75rem;font-weight:600;letter-spacing:-0.01em;color:var(--text-secondary)}\n@media (max-width: 640px){.rs-sidebar-label{padding-bottom:0.5rem;font-size:var(--control-label)}}\n.rs-sidebar-foot{box-sizing:border-box;padding-top:0.75rem;padding-inline-end:1.25rem;padding-bottom:0.75rem;padding-inline-start:1.25rem;border-top-width:1px;border-top-style:solid;border-top-color:var(--divider);font-size:0.75rem;font-weight:500;letter-spacing:-0.01em;color:var(--text-secondary)}\n@media (max-width: 640px){.rs-sidebar-foot{font-size:0.875rem;min-height:var(--hit);display:flex;align-items:center}}\n",
      "type": "registry:file",
      "target": "styles/vlak/sidebar.css"
    }
  ],
  "meta": {
    "vlak": {
      "category": "navigation",
      "classes": [
        "rs-sidebar",
        "rs-sidebar-head",
        "rs-sidebar-nav",
        "rs-sidebar-item",
        "rs-sidebar-label",
        "rs-sidebar-foot"
      ],
      "snippet": "<aside class=\"rs-sidebar\"><div class=\"rs-sidebar-head\">Vlak</div><nav class=\"rs-sidebar-nav\"><p class=\"rs-sidebar-label\">Go to</p><a class=\"rs-sidebar-item\" aria-current=\"page\">Overview</a><a class=\"rs-sidebar-item\" href=\"#\">Docs</a><a class=\"rs-sidebar-item\" href=\"#\">Components</a></nav><div class=\"rs-sidebar-foot\">0.3</div></aside>",
      "cssOnly": false,
      "registryDependencies": [
        "vlak-lib"
      ],
      "aliases": [
        "Sidebar",
        "Side nav",
        "Rail",
        "Navigation drawer"
      ],
      "example": "import { Sidebar, SidebarFoot, SidebarHead, SidebarItem, SidebarLabel, SidebarNav } from \"@noorddev/vlak-react\";\n\n<Sidebar>\n  <SidebarHead>Vlak</SidebarHead>\n  <SidebarNav aria-label=\"Sidebar\">\n    <SidebarLabel>Go to</SidebarLabel>\n    <SidebarItem href=\"/\" current>Overview</SidebarItem>\n    <SidebarItem href=\"/docs\">Docs</SidebarItem>\n    <SidebarItem href=\"/components\">Components</SidebarItem>\n  </SidebarNav>\n  <SidebarFoot>0.3</SidebarFoot>\n</Sidebar>",
      "usage": {
        "use": [
          "A 204px rail for app or docs navigation with a head, groups of links, and a foot.",
          "SidebarLabel to name each group of items."
        ],
        "avoid": [
          "Marketing sites; use NavigationMenu.",
          "Collapsing it on desktop; the rail is the layout."
        ]
      },
      "keyboard": [
        {
          "keys": "Tab",
          "does": "Moves between the items"
        },
        {
          "keys": "Enter",
          "does": "Follows the link"
        }
      ],
      "a11y": [
        "Sidebar is an <aside>; SidebarNav is a <nav> named by aria-label (\"Sidebar\" by default).",
        "SidebarItem is an <a>; current sets aria-current=\"page\"."
      ]
    }
  }
}
