{"name":"collapsible","title":"Collapsible","description":"An interactive component which expands/collapses a panel.","installCommand":"bunx marko-ui add collapsible -y","usageTags":"<Collapsible>","importSnippet":"import Collapsible from \"@/components/ui/collapsible/collapsible.marko\";","usageSnippet":"<Collapsible>\n  <@trigger|triggerProps|>\n    <button ...triggerProps>Can I use this in my project?</button>\n  </@trigger>\n  Yes. Free to use for personal and commercial projects. No attribution\n  required.\n</Collapsible>","tags":["Collapsible"],"parts":[{"name":"trigger","param":"Record<string, unknown>"}],"props":[{"name":"collapsedHeight","type":"string | number | undefined","required":false,"description":"The height of the content when collapsed."},{"name":"collapsedWidth","type":"string | number | undefined","required":false,"description":"The width of the content when collapsed."},{"name":"defaultOpen","type":"boolean | undefined","required":false,"description":"The initial open state of the collapsible when rendered.\nUse when you don't need to control the open state of the collapsible."},{"name":"dir","type":"'ltr' | 'rtl' | undefined","required":false,"default":"ltr","description":"The document's text/writing direction."},{"name":"disabled","type":"boolean | undefined","required":false,"description":"Whether the collapsible is disabled."},{"name":"getRootNode","type":"(() => ShadowRoot | Document | Node) | undefined","required":false,"description":"A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron."},{"name":"ids","type":"ElementIds | undefined","required":false,"description":"The ids of the elements in the collapsible. Useful for composition."},{"name":"onExitComplete","type":"VoidFunction | undefined","required":false,"description":"The callback invoked when the exit animation completes."},{"name":"open","type":"boolean | undefined","required":false,"description":"The controlled open state of the collapsible."}],"events":[{"name":"onOpenChange","arg":"OpenChangeDetails","description":"The callback invoked when the open state changes."},{"name":"openChange","arg":"boolean"}],"keyboard":[{"keys":"Space / Enter","description":"Toggles the panel open or closed when the trigger is focused."}],"accessibilityNotes":["The trigger owns `aria-expanded`, reflecting the panel's open state, and `aria-controls`, pointing at the content region's id.","The content region is present in the DOM at all times; its visibility (and, when animated, height) is driven by `data-state=\"open\"|\"closed\"` rather than removing/re-adding the subtree, so assistive tech never loses its place in the document.","A `disabled` Collapsible marks its trigger `data-disabled` (style off `data-[disabled]:` selectors, not `disabled:`) and ignores clicks on it. The machine never sets a native `disabled` attribute, so the trigger stays focusable and keyboard-activatable unless you also disable the element you render as the trigger yourself."],"examples":[{"id":"collapsible-demo","title":"Basic","source":"import Collapsible from \"@marko-ui/shadcn/ui/collapsible/collapsible.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<let/open=false/>\n\n<Collapsible class=\"flex w-[350px] flex-col gap-2\" open=open openChange(next) { open = next; }>\n  <@trigger|triggerProps|>\n    <div class=\"flex items-center justify-between gap-4 px-4\">\n      <h3 class=\"text-sm font-semibold\">@peduarte starred 3 repositories</h3>\n      <Button\n        type=\"button\"\n        ...triggerProps\n        variant=\"ghost\"\n        size=\"icon\"\n        class=\"size-8\"\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          stroke-width=\"2\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n          class=`size-4 transition-transform ${open ? \"rotate-180\" : \"\"}`\n        >\n          <path d=\"m7 15 5 5 5-5\"/>\n          <path d=\"m7 9 5-5 5 5\"/>\n        </svg>\n        <span class=\"sr-only\">Toggle</span>\n      </Button>\n    </div>\n  </@trigger>\n  <div class=\"rounded-md border px-4 py-2 font-mono text-sm\">\n    @marko-ui/collapsible\n  </div>\n  <div class=\"flex flex-col gap-2\">\n    <div class=\"rounded-md border px-4 py-2 font-mono text-sm\">\n      @marko-ui/shadcn\n    </div>\n    <div class=\"rounded-md border px-4 py-2 font-mono text-sm\">\n      @zag-js/collapsible\n    </div>\n  </div>\n</Collapsible>","description":"A trigger toggles the panel's open state; the chevron icon rotates to reflect it."},{"id":"collapsible-basic","title":"Product Details","source":"import Collapsible from \"@marko-ui/shadcn/ui/collapsible/collapsible.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Card from \"@marko-ui/shadcn/ui/card/card.marko\";\nimport CardContent from \"@marko-ui/shadcn/ui/card/content.marko\";\n\n<Card class=\"mx-auto w-full max-w-sm\">\n  <Collapsible class=\"rounded-md data-[state=open]:bg-muted\">\n    <@trigger|triggerProps|>\n      <Button ...triggerProps type=\"button\" variant=\"ghost\" class=\"group w-full\">\n        Product details\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          stroke-width=\"2\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n          class=\"ml-auto size-4 transition-transform group-data-[state=open]:rotate-180\"\n        >\n          <path d=\"m6 9 6 6 6-6\"/>\n        </svg>\n      </Button>\n    </@trigger>\n    <div class=\"flex flex-col items-start gap-2 p-2.5 pt-0 text-sm\">\n      <div>\n        This panel can be expanded or collapsed to reveal additional\n        content.\n      </div>\n      <Button type=\"button\" size=\"xs\">Learn More</Button>\n    </div>\n  </Collapsible>\n</Card>","description":"A ghost-button trigger inside a card reveals a short description and a call-to-action button."},{"id":"collapsible-settings","title":"Settings Panel","source":"import Collapsible from \"@marko-ui/shadcn/ui/collapsible/collapsible.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<Collapsible class=\"w-72 rounded-md border p-3 space-y-2\">\n  <@trigger|triggerProps|>\n    <Button type=\"button\" ...triggerProps variant=\"ghost\" class=\"w-full justify-between\">\n      Advanced settings\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        class=\"size-4\"\n      >\n        <path d=\"m6 9 6 6 6-6\"/>\n      </svg>\n    </Button>\n  </@trigger>\n  <div class=\"flex flex-col gap-3 px-2 pt-1 text-sm\">\n    <label class=\"flex items-center justify-between gap-2\">\n      Enable notifications\n      <input type=\"checkbox\" class=\"size-4\"/>\n    </label>\n    <label class=\"flex items-center justify-between gap-2\">\n      Auto-update\n      <input type=\"checkbox\" class=\"size-4\" checked/>\n    </label>\n  </div>\n</Collapsible>","description":"Use a trigger button to reveal additional settings."},{"id":"collapsible-file-tree","title":"File Tree","source":"import Card from \"@marko-ui/shadcn/ui/card/card.marko\";\nimport CardHeader from \"@marko-ui/shadcn/ui/card/header.marko\";\nimport CardContent from \"@marko-ui/shadcn/ui/card/content.marko\";\nimport Tabs from \"@marko-ui/shadcn/ui/tabs/tabs.marko\";\nimport CollapsibleFileTreeItem, {\n  type FileTreeItem,\n} from \"./lib/collapsible-file-tree-item.marko\";\n\nstatic const fileTree: FileTreeItem[] = [\n  {\n    name: \"components\",\n    items: [\n      {\n        name: \"ui\",\n        items: [\n          { name: \"button.marko\" },\n          { name: \"card.marko\" },\n          { name: \"dialog.marko\" },\n          { name: \"input.marko\" },\n          { name: \"select.marko\" },\n          { name: \"table.marko\" },\n        ],\n      },\n      { name: \"login-form.marko\" },\n      { name: \"register-form.marko\" },\n    ],\n  },\n  {\n    name: \"lib\",\n    items: [\n      { name: \"utils.ts\" },\n      { name: \"cn.ts\" },\n      { name: \"api.ts\" },\n    ],\n  },\n  {\n    name: \"hooks\",\n    items: [\n      { name: \"use-media-query.ts\" },\n      { name: \"use-debounce.ts\" },\n      { name: \"use-local-storage.ts\" },\n    ],\n  },\n  {\n    name: \"types\",\n    items: [{ name: \"index.d.ts\" }, { name: \"api.d.ts\" }],\n  },\n  {\n    name: \"public\",\n    items: [\n      { name: \"favicon.ico\" },\n      { name: \"logo.svg\" },\n      { name: \"images\" },\n    ],\n  },\n  { name: \"app.marko\" },\n  { name: \"layout.marko\" },\n  { name: \"globals.css\" },\n  { name: \"package.json\" },\n  { name: \"tsconfig.json\" },\n  { name: \"README.md\" },\n  { name: \".gitignore\" },\n];\n\n<Card class=\"mx-auto w-full max-w-[16rem] gap-2\" size=\"sm\">\n  <CardHeader>\n\n    <Tabs class=\"w-full\">\n      <@trigger value=\"explorer\">Explorer</@trigger>\n      <@trigger value=\"settings\">Outline</@trigger>\n      <@panel value=\"explorer\"/>\n      <@panel value=\"settings\"/>\n    </Tabs>\n  </CardHeader>\n  <CardContent>\n    <div class=\"flex flex-col gap-1\">\n      <for|item| of=fileTree>\n        <CollapsibleFileTreeItem item=item/>\n      </for>\n    </div>\n  </CardContent>\n</Card>","description":"Use nested collapsibles to build a file tree. Each folder recurses into its own Collapsible; files render as plain link-styled buttons."},{"id":"collapsible-rtl","title":"RTL","source":"import Collapsible from \"@marko-ui/shadcn/ui/collapsible/collapsible.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<let/open=false/>\n\n<Collapsible\n  class=\"flex w-[350px] flex-col gap-2\"\n  open=open\n  openChange(next) { open = next; }\n  dir=\"rtl\"\n>\n  <@trigger|triggerProps|>\n    <div class=\"flex items-center justify-between gap-4 px-4\">\n      <h3 class=\"text-sm font-semibold\">الطلب #4189</h3>\n      <Button\n        type=\"button\"\n        ...triggerProps\n        variant=\"ghost\"\n        size=\"icon\"\n        class=\"size-8\"\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          stroke-width=\"2\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n          class=`size-4 transition-transform ${open ? \"rotate-180\" : \"\"}`\n        >\n          <path d=\"m7 15 5 5 5-5\"/>\n          <path d=\"m7 9 5-5 5 5\"/>\n        </svg>\n        <span class=\"sr-only\">تبديل التفاصيل</span>\n      </Button>\n    </div>\n  </@trigger>\n  <div class=\"flex items-center justify-between rounded-md border px-4 py-2 text-sm\">\n    <span class=\"text-muted-foreground\">الحالة</span>\n    <span class=\"font-medium\">تم الشحن</span>\n  </div>\n  <div class=\"flex flex-col gap-2\">\n    <div class=\"rounded-md border px-4 py-2 text-sm\">\n      <p class=\"font-medium\">عنوان الشحن</p>\n      <p class=\"text-muted-foreground\">100 Market St, San Francisco</p>\n    </div>\n    <div class=\"rounded-md border px-4 py-2 text-sm\">\n      <p class=\"font-medium\">العناصر</p>\n      <p class=\"text-muted-foreground\">2x سماعات الاستوديو</p>\n    </div>\n  </div>\n</Collapsible>","description":"Collapsible restyles correctly under `dir=\"rtl\"` with no component changes — its layout uses logical Tailwind flex utilities rather than hard-coded physical margins."},{"id":"collapsible-disabled","title":"Disabled","source":"import Collapsible from \"@marko-ui/shadcn/ui/collapsible/collapsible.marko\";\n\n<Collapsible class=\"w-72 space-y-2\" disabled>\n  <@trigger|triggerProps|>\n    <button type=\"button\"\n      ...triggerProps\n      aria-disabled=\"true\"\n      class=\"flex w-full items-center justify-between text-sm font-semibold data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\"\n    >\n      This trigger is disabled\n    </button>\n  </@trigger>\n  <p class=\"rounded-md border px-4 py-3 text-sm text-muted-foreground\">\n    You should never see this content toggle.\n  </p>\n</Collapsible>","description":"A disabled collapsible marks its trigger `data-disabled` and ignores clicks on it."},{"id":"collapsible-controlled","title":"Controlled","source":"import Collapsible from \"@marko-ui/shadcn/ui/collapsible/collapsible.marko\";\n\n<let/open=false/>\n\n<div class=\"w-72 space-y-3\">\n  <p class=\"text-sm text-muted-foreground\">\n    State: <strong>${open ? \"open\" : \"closed\"}</strong>\n  </p>\n  <Collapsible\n    class=\"space-y-2\"\n    open=open\n    openChange(next) { open = next; }\n  >\n    <@trigger|triggerProps|>\n      <button type=\"button\"\n        ...triggerProps\n        class=\"flex w-full items-center justify-between text-sm font-semibold\"\n      >\n        Controlled from the parent\n      </button>\n    </@trigger>\n    <p class=\"rounded-md border px-4 py-3 text-sm text-muted-foreground\">\n      This panel's open state is owned by the parent and toggled with the button below.\n    </p>\n  </Collapsible>\n  <button\n    type=\"button\"\n    class=\"rounded-md border px-3 py-1.5 text-sm hover:bg-accent\"\n    onClick() { open = !open; }\n  >\n    Toggle externally\n  </button>\n</div>","description":"Zag machines are controlled: an `open` prop without a change handler never moves. Pair it with `openChange`.","essential":true}],"importInstallCommand":"bun add @marko-ui/shadcn marko-zag","body":{},"nativeAttributes":"div","composition":"Collapsible renders its own trigger/content anatomy internally — there are\nno separate CollapsibleTrigger/CollapsibleContent tags to compose.\n\n```text\nCollapsible\n├── <@trigger|triggerProps|>...</@trigger>  (optional; spread triggerProps onto your own element)\n└── body content                             (the collapsible panel itself)\n```\n\nThe `<@trigger>` attribute tag is a render-prop-style slot: it receives\n`triggerProps` (the machine's `getTriggerProps()` plus a `data-slot`) and\nyou spread them onto whatever element you render as the trigger — a\n`<Button>`, a plain `<button>`, or anything else. Everything else placed\ndirectly in the tag's body becomes the collapsible content region, wrapped\nin the machine's `getContentProps()` internally."}
