{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "accordion",
  "type": "registry:component",
  "title": "Accordion",
  "description": "Reveals related sections on demand. Native details rows with 1px rules.",
  "registryDependencies": [
    "https://vlak.dev/r/vlak-base.json",
    "https://vlak.dev/r/inter.json",
    "https://vlak.dev/r/vlak-lib.json",
    "https://vlak.dev/r/icons.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/accordion.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport { vlak, mq } from \"./tokens.stylex\";\nimport { rs } from \"./rs\";\nimport { Icon } from \"./icons\";\n\nconst AccordionContext = React.createContext<string | undefined>(undefined);\n\nexport interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** One item open at a time, via the platform's own `name` grouping. */\n  exclusive?: boolean;\n}\n\nconst styles = stylex.create({\n  acc: {\n    borderTopWidth: vlak.hairline,\n    borderTopStyle: \"solid\",\n    borderTopColor: vlak.divider,\n  },\n  item: {\n    borderBottomWidth: vlak.hairline,\n    borderBottomStyle: \"solid\",\n    borderBottomColor: vlak.divider,\n  },\n  summary: {\n    listStyle: \"none\",\n    cursor: \"pointer\",\n    display: \"flex\",\n    justifyContent: \"space-between\",\n    alignItems: \"center\",\n    gap: \"0.75rem\",\n    paddingBlock: \"0.875rem\",\n    paddingInline: 0,\n    minHeight: {\n      default: \"1.5rem\",\n      [mq.phone]: vlak.hit,\n    },\n    fontSize: {\n      default: \"0.90625rem\",\n      [mq.phone]: \"1.0625rem\",\n    },\n    fontWeight: 600,\n    letterSpacing: \"-0.01em\",\n    color: vlak.ink,\n    \"::-webkit-details-marker\": {\n      display: \"none\",\n    },\n    outlineWidth: {\n      default: null,\n      \":focus-visible\": 2,\n    },\n    outlineStyle: {\n      default: null,\n      \":focus-visible\": \"solid\",\n    },\n    outlineColor: {\n      default: null,\n      \":focus-visible\": vlak.ink,\n    },\n    outlineOffset: {\n      default: null,\n      \":focus-visible\": 2,\n    },\n  },\n  chevron: {\n    flexShrink: 0,\n    color: vlak.gray,\n    transition: {\n      default: `transform ${vlak.duration} ${vlak.ease}`,\n      [mq.reduce]: \"none\",\n    },\n  },\n  chevronOpen: {\n    transform: \"rotate(180deg)\",\n  },\n  body: {\n    paddingTop: 0,\n    paddingInlineEnd: 0,\n    paddingBottom: {\n      default: \"1rem\",\n      [mq.phone]: \"1.25rem\",\n    },\n    paddingInlineStart: 0,\n    fontSize: {\n      default: \"0.84375rem\",\n      [mq.phone]: \"1rem\",\n    },\n    lineHeight: 1.45,\n    color: vlak.gray,\n  },\n});\n\n/** Native <details> rows on hairlines. */\nexport const Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n  { exclusive, className, style, children, ...props },\n  ref,\n) {\n  const group = React.useId();\n  const sx = rs([\"rs-acc\", className], styles.acc);\n  return (\n    <div ref={ref} {...props} className={sx.className} style={{ ...sx.style, ...style }}>\n      <AccordionContext.Provider value={exclusive ? group : undefined}>\n        {children}\n      </AccordionContext.Provider>\n    </div>\n  );\n});\n\nexport interface AccordionItemProps\n  extends Omit<React.DetailsHTMLAttributes<HTMLDetailsElement>, \"title\"> {\n  title: React.ReactNode;\n  defaultOpen?: boolean;\n}\n\nexport const AccordionItem = React.forwardRef<HTMLDetailsElement, AccordionItemProps>(function AccordionItem({\n  title,\n  defaultOpen,\n  className,\n  style,\n  children,\n  onToggle,\n  open,\n  ...props\n}, ref) {\n  const group = React.useContext(AccordionContext);\n  const [innerOpen, setInnerOpen] = React.useState(!!defaultOpen);\n  const isOpen = open ?? innerOpen;\n  const item = rs([\"rs-acc-item\", className], styles.item);\n  const summary = rs([\"rs-acc-summary\"], styles.summary);\n  const chevron = rs([\"rs-acc-chevron\", isOpen && \"rs-acc-chevron-open\"], styles.chevron, isOpen && styles.chevronOpen);\n  const body = rs([\"rs-acc-body\"], styles.body);\n  return (\n    <details\n      ref={ref}\n      name={group}\n      open={open ?? (defaultOpen || undefined)}\n      onToggle={(e) => {\n        setInnerOpen(e.currentTarget.open);\n        onToggle?.(e);\n      }}\n      {...props}\n      className={item.className}\n      style={{ ...item.style, ...style }}\n    >\n      <summary className={summary.className} style={summary.style}>\n        {title}\n        <Icon name=\"chevron-right\" rotate={90} className={chevron.className} style={chevron.style} />\n      </summary>\n      <div className={body.className} style={body.style}>\n        {children}\n      </div>\n    </details>\n  );\n});\n",
      "type": "registry:component",
      "target": "components/vlak/accordion.tsx"
    },
    {
      "path": "vlak/styles/accordion.css",
      "content": "/* ── accordion: generated from packages/react/src/components/accordion.tsx ── */\n.rs-acc{border-top-width:1px;border-top-style:solid;border-top-color:var(--divider)}\n.rs-acc-item{border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:var(--divider)}\n.rs-acc-summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:0.75rem;padding-block:0.875rem;padding-inline:0;min-height:1.5rem;font-size:0.90625rem;font-weight:600;letter-spacing:-0.01em;color:var(--text)}\n.rs-acc-summary::-webkit-details-marker{display:none}\n.rs-acc-summary:focus-visible{outline-width:2px;outline-style:solid;outline-color:var(--text);outline-offset:2px}\n@media (max-width: 640px){.rs-acc-summary{min-height:var(--hit);font-size:1.0625rem}}\n.rs-acc-chevron{flex-shrink:0;color:var(--text-secondary);transition:transform var(--duration) var(--ease)}\n@media (prefers-reduced-motion: reduce){.rs-acc-chevron{transition:none}}\n.rs-acc-chevron-open{transform:rotate(180deg)}\n.rs-acc-body{padding-top:0;padding-inline-end:0;padding-bottom:1rem;padding-inline-start:0;font-size:0.84375rem;line-height:1.45;color:var(--text-secondary)}\n@media (max-width: 640px){.rs-acc-body{padding-bottom:1.25rem;font-size:1rem}}\n",
      "type": "registry:file",
      "target": "styles/vlak/accordion.css"
    }
  ],
  "meta": {
    "vlak": {
      "category": "content",
      "classes": [
        "rs-acc",
        "rs-acc-item",
        "rs-acc-chevron",
        "rs-acc-body",
        "rs-acc-chevron-open",
        "rs-acc-summary"
      ],
      "snippet": "<div class=\"rs-acc\"><details class=\"rs-acc-item\" name=\"faq\" open><summary>What is Vlak?<svg class=\"rs-acc-chevron\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><g transform=\"rotate(90 8 8)\"><path d=\"M5.5 3.5 L10.5 8 L5.5 12.5\" vector-effect=\"non-scaling-stroke\"/></g></svg></summary><div class=\"rs-acc-body\">A minimal, CSS-first design system.</div></details><details class=\"rs-acc-item\" name=\"faq\"><summary>Does it require Radix?<svg class=\"rs-acc-chevron\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><g transform=\"rotate(90 8 8)\"><path d=\"M5.5 3.5 L10.5 8 L5.5 12.5\" vector-effect=\"non-scaling-stroke\"/></g></svg></summary><div class=\"rs-acc-body\">No. Native elements provide the behavior.</div></details></div>",
      "cssOnly": false,
      "registryDependencies": [
        "vlak-lib",
        "icons"
      ],
      "aliases": [
        "Accordion",
        "Disclosure group",
        "Expansion panel",
        "FAQ"
      ],
      "example": "import { Accordion, AccordionItem } from \"@noorddev/vlak-react\";\n\n<Accordion exclusive>\n  <AccordionItem title=\"What is Vlak?\" defaultOpen>\n    A minimal, CSS-first design system.\n  </AccordionItem>\n  <AccordionItem title=\"Does it require Radix?\">\n    No. Native elements provide the behavior.\n  </AccordionItem>\n</Accordion>",
      "usage": {
        "use": [
          "FAQ and settings sections where headings should stay scannable.",
          "exclusive to keep one item open through the platform's details name grouping."
        ],
        "avoid": [
          "Hiding content most readers need; put it in the flow.",
          "A single item; use Collapsible."
        ]
      },
      "keyboard": [
        {
          "keys": "Tab",
          "does": "Moves to the next summary"
        },
        {
          "keys": "Enter, Space",
          "does": "Opens or closes the item"
        }
      ],
      "a11y": [
        "Each item is a native <details> with a <summary>; the platform exposes the expanded state.",
        "title is the summary text and the accessible name. Controlled with open and onToggle, or uncontrolled with defaultOpen."
      ]
    }
  }
}
