{"name":"sidebar","title":"Sidebar","description":"A composable, collapsible side navigation panel built from a provider, a sidebar shell, and header/content/footer/menu parts.","installCommand":"bunx marko-ui add sidebar -y","usageTags":"<SidebarProvider>, <Sidebar>","importSnippet":"import SidebarProvider from \"@/components/ui/sidebar/provider.marko\";\nimport Sidebar from \"@/components/ui/sidebar/sidebar.marko\";\nimport SidebarTrigger from \"@/components/ui/sidebar/trigger.marko\";","usageSnippet":"<SidebarProvider>\n  <@sidebar|{ open, toggle }|>\n    <Sidebar open=open>...</Sidebar>\n  </@sidebar>\n  <@main|{ open, toggle }|>\n    <SidebarTrigger open=open toggle=toggle/>\n  </@main>\n</SidebarProvider>","tags":["Sidebar","SidebarContent","SidebarFooter","SidebarGroup","SidebarGroupAction","SidebarGroupContent","SidebarGroupLabel","SidebarHeader","SidebarInset","SidebarMenu","SidebarMenuAction","SidebarMenuBadge","SidebarMenuButton","SidebarMenuItem","SidebarMenuSkeleton","SidebarMenuSub","SidebarMenuSubButton","SidebarMenuSubItem","SidebarProvider","SidebarRail","SidebarTrigger"],"parts":[],"props":[{"name":"collapsible","type":"'icon' | 'none' | 'offcanvas'","required":false},{"name":"open","type":"boolean","required":false,"description":"Expanded/collapsed state, provided by the provider's"},{"name":"side","type":"'right' | 'left'","required":false},{"name":"variant","type":"'sidebar' | 'floating' | 'inset'","required":false}],"events":[],"keyboard":[],"accessibilityNotes":["Unlike upstream shadcn/ui, this port does not wire up a `cmd+b` / `ctrl+b` keyboard shortcut to toggle the sidebar — call `toggle()` (from the provider's `@sidebar`/`@main` body arguments) from your own key handler if you need one.","`SidebarTrigger` renders a real `<button>` with an `sr-only` \"Toggle Sidebar\" label, so it's reachable and named for screen readers without extra props.","`SidebarRail` is `tabindex=\"-1\"` and carries `aria-label=\"Toggle Sidebar\"` — it's a pointer-only resize/toggle affordance, not part of the tab order; keyboard users should use `SidebarTrigger` instead.","Layout mirrors automatically in RTL: `Sidebar`, `SidebarTrigger`, and `SidebarRail` use logical positioning and `rtl:`-variant classes, so no `dir` prop or separate RTL variant is needed."],"examples":[{"id":"sidebar-demo","title":"Basic","source":"import SidebarProvider from \"@marko-ui/shadcn/ui/sidebar/provider.marko\";\nimport Sidebar from \"@marko-ui/shadcn/ui/sidebar/sidebar.marko\";\nimport SidebarHeader from \"@marko-ui/shadcn/ui/sidebar/header.marko\";\nimport SidebarContent from \"@marko-ui/shadcn/ui/sidebar/content.marko\";\nimport SidebarFooter from \"@marko-ui/shadcn/ui/sidebar/footer.marko\";\nimport SidebarGroup from \"@marko-ui/shadcn/ui/sidebar/group.marko\";\nimport SidebarGroupLabel from \"@marko-ui/shadcn/ui/sidebar/group-label.marko\";\nimport SidebarMenu from \"@marko-ui/shadcn/ui/sidebar/menu.marko\";\nimport SidebarMenuItem from \"@marko-ui/shadcn/ui/sidebar/menu-item.marko\";\nimport SidebarMenuButton from \"@marko-ui/shadcn/ui/sidebar/menu-button.marko\";\nimport SidebarTrigger from \"@marko-ui/shadcn/ui/sidebar/trigger.marko\";\n\nstatic const NAV_ITEMS = [\n  { title: \"Inbox\", href: \"#\", active: true },\n  { title: \"Calendar\", href: \"#\" },\n  { title: \"Search\", href: \"#\" },\n  { title: \"Settings\", href: \"#\" },\n];\n\n<div class=\"h-[420px] w-full overflow-hidden rounded-lg border\">\n  <SidebarProvider width=\"14rem\" class=\"min-h-0 h-full\">\n    <@sidebar|{ open, toggle }|>\n      <Sidebar open=open>\n        <SidebarHeader>\n          <div class=\"flex items-center gap-2 px-2 text-sm font-semibold\">Acme Inc</div>\n        </SidebarHeader>\n        <SidebarContent>\n          <SidebarGroup>\n            <SidebarGroupLabel>Platform</SidebarGroupLabel>\n            <SidebarMenu>\n              <for|item| of=NAV_ITEMS>\n                <SidebarMenuItem>\n                  <SidebarMenuButton href=item.href active=item.active>\n                    ${item.title}\n                  </SidebarMenuButton>\n                </SidebarMenuItem>\n              </for>\n            </SidebarMenu>\n          </SidebarGroup>\n        </SidebarContent>\n        <SidebarFooter>\n          <div class=\"px-2 text-xs text-sidebar-foreground/70\">v1.0.0</div>\n        </SidebarFooter>\n      </Sidebar>\n    </@sidebar>\n    <@main|{ open, toggle }|>\n      <div class=\"flex min-w-0 flex-1 flex-col\">\n        <header class=\"flex h-12 items-center gap-2 border-b px-3\">\n          <SidebarTrigger open=open toggle=toggle/>\n          <span class=\"text-sm text-muted-foreground\">\n            Sidebar is ${open ? \"open\" : \"closed\"}\n          </span>\n        </header>\n        <main class=\"flex-1 overflow-auto p-4 text-sm text-muted-foreground\">\n          Main content area. Click the trigger to collapse the sidebar.\n        </main>\n      </div>\n    </@main>\n  </SidebarProvider>\n</div>","description":"A provider wrapping a sidebar shell (header, content, footer) and a main content area, joined by a trigger."},{"id":"sidebar-controlled","title":"Controlled","source":"import SidebarProvider from \"@marko-ui/shadcn/ui/sidebar/provider.marko\";\nimport Sidebar from \"@marko-ui/shadcn/ui/sidebar/sidebar.marko\";\nimport SidebarHeader from \"@marko-ui/shadcn/ui/sidebar/header.marko\";\nimport SidebarContent from \"@marko-ui/shadcn/ui/sidebar/content.marko\";\nimport SidebarGroup from \"@marko-ui/shadcn/ui/sidebar/group.marko\";\nimport SidebarGroupLabel from \"@marko-ui/shadcn/ui/sidebar/group-label.marko\";\nimport SidebarMenu from \"@marko-ui/shadcn/ui/sidebar/menu.marko\";\nimport SidebarMenuItem from \"@marko-ui/shadcn/ui/sidebar/menu-item.marko\";\nimport SidebarMenuButton from \"@marko-ui/shadcn/ui/sidebar/menu-button.marko\";\nimport SidebarTrigger from \"@marko-ui/shadcn/ui/sidebar/trigger.marko\";\n\n<let/open=true/>\n\n<p class=\"mb-4 text-sm text-muted-foreground\">Open: ${open}</p>\n\n<div class=\"h-[320px] w-full overflow-hidden rounded-lg border\">\n  <SidebarProvider\n    width=\"14rem\"\n    class=\"min-h-0 h-full\"\n    open=open\n    openChange(next) { open = next; }\n  >\n    <@sidebar|{ open }|>\n      <Sidebar open=open>\n        <SidebarHeader>\n          <div class=\"px-2 text-sm font-semibold\">Controlled</div>\n        </SidebarHeader>\n        <SidebarContent>\n          <SidebarGroup>\n            <SidebarGroupLabel>Menu</SidebarGroupLabel>\n            <SidebarMenu>\n              <SidebarMenuItem>\n                <SidebarMenuButton href=\"#\" active>Home</SidebarMenuButton>\n              </SidebarMenuItem>\n              <SidebarMenuItem>\n                <SidebarMenuButton href=\"#\">Profile</SidebarMenuButton>\n              </SidebarMenuItem>\n            </SidebarMenu>\n          </SidebarGroup>\n        </SidebarContent>\n      </Sidebar>\n    </@sidebar>\n    <@main|{ open, toggle }|>\n      <div class=\"flex min-w-0 flex-1 flex-col\">\n        <header class=\"flex h-12 items-center gap-2 border-b px-3\">\n          <SidebarTrigger open=open toggle=toggle/>\n        </header>\n        <main class=\"flex-1 overflow-auto p-4 text-sm text-muted-foreground\">\n          This sidebar's open state is owned by the demo page.\n        </main>\n      </div>\n    </@main>\n  </SidebarProvider>\n</div>\n\n<button\n  type=\"button\"\n  class=\"mt-4 rounded-md border px-3 py-1.5 text-sm hover:bg-accent\"\n  onClick() { open = !open; }\n>\n  Toggle externally\n</button>","description":"SidebarProvider is controlled: pass `open` alongside `openChange` to own the state outside the component, or omit both for uncontrolled behavior (defaults to open)."},{"id":"sidebar-rtl","title":"RTL","source":"import SidebarProvider from \"@marko-ui/shadcn/ui/sidebar/provider.marko\";\nimport Sidebar from \"@marko-ui/shadcn/ui/sidebar/sidebar.marko\";\nimport SidebarHeader from \"@marko-ui/shadcn/ui/sidebar/header.marko\";\nimport SidebarContent from \"@marko-ui/shadcn/ui/sidebar/content.marko\";\nimport SidebarFooter from \"@marko-ui/shadcn/ui/sidebar/footer.marko\";\nimport SidebarGroup from \"@marko-ui/shadcn/ui/sidebar/group.marko\";\nimport SidebarGroupLabel from \"@marko-ui/shadcn/ui/sidebar/group-label.marko\";\nimport SidebarMenu from \"@marko-ui/shadcn/ui/sidebar/menu.marko\";\nimport SidebarMenuItem from \"@marko-ui/shadcn/ui/sidebar/menu-item.marko\";\nimport SidebarMenuButton from \"@marko-ui/shadcn/ui/sidebar/menu-button.marko\";\nimport SidebarTrigger from \"@marko-ui/shadcn/ui/sidebar/trigger.marko\";\n\nstatic const NAV_ITEMS = [\n  { title: \"دخل\", href: \"#\", active: true },\n  { title: \"التقويم\", href: \"#\" },\n  { title: \"بحث\", href: \"#\" },\n  { title: \"الإعدادات\", href: \"#\" },\n];\n\n<div dir=\"rtl\" class=\"h-[420px] w-full overflow-hidden rounded-lg border\">\n  <SidebarProvider width=\"14rem\" class=\"min-h-0 h-full\">\n    <@sidebar|{ open, toggle }|>\n      <Sidebar open=open>\n        <SidebarHeader>\n          <div class=\"flex items-center gap-2 px-2 text-sm font-semibold\">شركة أكمي</div>\n        </SidebarHeader>\n        <SidebarContent>\n          <SidebarGroup>\n            <SidebarGroupLabel>المنصة</SidebarGroupLabel>\n            <SidebarMenu>\n              <for|item| of=NAV_ITEMS>\n                <SidebarMenuItem>\n                  <SidebarMenuButton href=item.href active=item.active>\n                    ${item.title}\n                  </SidebarMenuButton>\n                </SidebarMenuItem>\n              </for>\n            </SidebarMenu>\n          </SidebarGroup>\n        </SidebarContent>\n        <SidebarFooter>\n          <div class=\"px-2 text-xs text-sidebar-foreground/70\">v1.0.0</div>\n        </SidebarFooter>\n      </Sidebar>\n    </@sidebar>\n    <@main|{ open, toggle }|>\n      <div class=\"flex min-w-0 flex-1 flex-col\">\n        <header class=\"flex h-12 items-center gap-2 border-b px-3\">\n          <SidebarTrigger open=open toggle=toggle/>\n          <span class=\"text-sm text-muted-foreground\">\n            الشريط الجانبي ${open ? \"مفتوح\" : \"مغلق\"}\n          </span>\n        </header>\n        <main class=\"flex-1 overflow-auto p-4 text-sm text-muted-foreground\">\n          منطقة المحتوى الرئيسية. انقر على الزر لطي الشريط الجانبي.\n        </main>\n      </div>\n    </@main>\n  </SidebarProvider>\n</div>","description":"Sidebar restyles correctly under `dir=\"rtl\"` — `Sidebar`, `SidebarTrigger`, and `SidebarRail` use logical positioning and `mu-rtl-flip`/`rtl:`-variant classes, so no separate RTL prop is needed."}],"importInstallCommand":"bun add @marko-ui/shadcn marko-zag","body":{},"nativeAttributes":"div","subcomponents":[{"name":"content","props":[],"nativeAttributes":"div"},{"name":"footer","props":[],"nativeAttributes":"div"},{"name":"group-action","props":[],"nativeAttributes":"button"},{"name":"group-content","props":[],"nativeAttributes":"div"},{"name":"group-label","props":[],"nativeAttributes":"div"},{"name":"group","props":[],"nativeAttributes":"div"},{"name":"header","props":[],"nativeAttributes":"div"},{"name":"inset","props":[],"nativeAttributes":"main"},{"name":"menu-action","props":[{"name":"showOnHover","type":"boolean","required":false,"description":"Only reveal the action on hover/focus of its menu item (md and up)."}],"nativeAttributes":"button"},{"name":"menu-badge","props":[],"nativeAttributes":"div"},{"name":"menu-button","props":[{"name":"active","type":"boolean","required":false},{"name":"href","type":"string","required":false,"description":"Renders an <a> instead of a <button> when set (with href passed through rest)."},{"name":"size","type":"'default' | 'sm' | 'lg' | null | undefined","required":false,"default":"default"},{"name":"variant","type":"'default' | 'outline' | null | undefined","required":false,"default":"default"}],"nativeAttributes":"div"},{"name":"menu-item","props":[],"nativeAttributes":"li"},{"name":"menu-skeleton","props":[{"name":"showIcon","type":"boolean","required":false}],"nativeAttributes":"div"},{"name":"menu-sub-button","props":[{"name":"active","type":"boolean","required":false},{"name":"size","type":"'sm' | 'md'","required":false}],"nativeAttributes":"a"},{"name":"menu-sub-item","props":[],"nativeAttributes":"li"},{"name":"menu-sub","props":[],"nativeAttributes":"ul"},{"name":"menu","props":[],"nativeAttributes":"ul"},{"name":"provider","props":[{"name":"open","type":"boolean","required":false,"description":"Controlled open state. Uncontrolled default: true."},{"name":"width","type":"string","required":false,"description":"CSS length for --sidebar-width, default 16rem."},{"name":"widthIcon","type":"string","required":false,"description":"CSS length for --sidebar-width-icon, default 3rem."}],"parts":[{"name":"main","param":"{ open: boolean; toggle: () => void; }","description":"Main content area, rendered next to the sidebar."},{"name":"sidebar","param":"{ open: boolean; toggle: () => void; }","description":"Sidebar panel content (header/content/footer parts)."}],"events":[{"name":"openChange","arg":"boolean"}],"nativeAttributes":"div"},{"name":"rail","props":[{"name":"toggle","type":"() => void","required":false,"description":"Toggles the sidebar, provided by the provider's body args."}],"nativeAttributes":"button"},{"name":"trigger","props":[{"name":"open","type":"boolean","required":false},{"name":"toggle","type":"() => void","required":false}],"nativeAttributes":"button"}],"concepts":"`SidebarProvider` sets the panel width via CSS custom properties: pass `width`/`widthIcon` props (defaulting to `16rem`/`3rem`) rather than editing constants in the source, since this is the import/copy-safe surface. Colors come from the `--sidebar`, `--sidebar-foreground`, `--sidebar-primary`, `--sidebar-primary-foreground`, `--sidebar-accent`, `--sidebar-accent-foreground`, `--sidebar-border`, and `--sidebar-ring` tokens defined per style layer — the same token names upstream uses, though our values are OKLCH (matching this port's token system) rather than upstream's HSL triples, so copy the token block from your chosen style rather than upstream's CSS. Upstream's dedicated \"Styling\" section additionally documents data-attribute styling hooks; this port carries the same ones, verified in source: `Sidebar` sets `data-collapsible` (so `group-data-[collapsible=icon]:hidden` on descendants works the same as upstream), and `SidebarMenuButton` sets `data-active` (so `peer-data-active/menu-button:...` — this port's Tailwind-v4 boolean-attribute selector syntax for upstream's `peer-data-[active=true]/menu-button:...` — works the same way on a sibling `SidebarMenuAction`). RTL is handled through logical-property and `rtl:`-variant classes baked into `Sidebar`/`SidebarTrigger`/`SidebarRail` (`mu-rtl-flip`, `ltr:`/`rtl:` translate classes) — there is no RTL-specific prop, and `dir=\"rtl\"` on a wrapper (or any ancestor) is all that is needed, as the \"RTL\" example below shows."}
