You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to propose a sidebar component. I considered raising this at the Ark or Park level, but the core complexity feels like a good fit for a state machine. Once the primitive exists, the rest of the stack can build on it naturally.
🧱 Problem Statement / Justification
Sidebars are one of the most common UI patterns in web apps, and deceptively hard to get right. The complexity comes from the number of axes they vary on:
Collapse behaviour: off-screen (hidden), or down to a rail with icons + popovers
Layout interaction: does the sidebar push page content, or overlay it?
Scrim / interaction model: does opening the sidebar block the rest of the page, or allow interaction behind it?
Responsive behaviour: sidebars typically collapse by default on small viewports, open as a drawer with a scrim, and behave like a persistent panel on large ones
Persistence: open/closed/collapsed state often needs to survive page navigation
Each of these is manageable in isolation; together they're enough state that most handrolled implementations end up buggy or incomplete at the edges. A good state machine and primitive layer would help to solve that problem for a wide range of apps.
✅ Proposed solution or API
Inspiration
Shadcn's sidebar has a reasonable anatomy, it's been ported to solid and svelte, and supports a lot of different use-cases. It's got a reasonable anatomy, although the naming is slightly different to the Ark/Chakra approach. It's worth noting that it's hand-rolled (no BaseUI primitive backs it), which means the Solid-UI and Svelte ports have re-produced that core logic themselves.
What Zag would own
The state a machine would manage:
open / closed / collapsed (icon-rail) modes and transitions between them
Responsive mode switching (e.g. floating drawer on mobile, persistent panel on desktop)
Keyboard shortcut handling
Persisted state (cookie or localStorage)
The layout concerns (how the sidebar relates to main content, the scrim, the trigger placement) would live above Zag at the Ark/component layer, similar to how dialog handles its backdrop separately from the core machine.
Anatomy (roughly following shadcn's model as a starting point) of what that might look like:
Component
Description
Sidebar.Root
context + state (open/closed/collapsed, persistence, keyboard shortcut)
Sidebar.Panel
the sidebar shell (side, variant, collapsible props)
Sidebar.Trigger
toggle button, usable outside Panel
Sidebar.Header
Sticky top region
Sidebar.Body
Scrollable content region
Sidebar.Footer
Sticky bottom region
Sidebar.Rail
Drag/click-to-resize strip
Sidebar.Section
Labelled group of items
Sidebar.SectionHeader
Section label, can host a Collapsible.Trigger
Sidebar.SectionBody
Section content wrapper
Sidebar.SectionAction
Action button slotted beside the section label
Shadcn also includes some other things that are more for styling (Inset), or can be composed from existing primitives (MenuItem, MenuButton, MenuSub, etc)
↩️ Alternatives
The closest primitives are Drawer for the mobile case and a custom Collapsible for the desktop rail, but they have slightly different a11y semantics, and composing those by hand means reimplementing the responsive mode-switching logic and state persistence every time, which is where most implementations go wrong. There are sidebar implementations in shadcn, and solid-ui, but no headless machine-level primitive that Ark could build on.
This discussion was converted from issue #3122 on May 17, 2026 18:43.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
🚀 Feature request
I'd like to propose a sidebar component. I considered raising this at the Ark or Park level, but the core complexity feels like a good fit for a state machine. Once the primitive exists, the rest of the stack can build on it naturally.
🧱 Problem Statement / Justification
Sidebars are one of the most common UI patterns in web apps, and deceptively hard to get right. The complexity comes from the number of axes they vary on:
Each of these is manageable in isolation; together they're enough state that most handrolled implementations end up buggy or incomplete at the edges. A good state machine and primitive layer would help to solve that problem for a wide range of apps.
✅ Proposed solution or API
Inspiration
Shadcn's sidebar has a reasonable anatomy, it's been ported to solid and svelte, and supports a lot of different use-cases. It's got a reasonable anatomy, although the naming is slightly different to the Ark/Chakra approach. It's worth noting that it's hand-rolled (no BaseUI primitive backs it), which means the Solid-UI and Svelte ports have re-produced that core logic themselves.
What Zag would own
The state a machine would manage:
The layout concerns (how the sidebar relates to main content, the scrim, the trigger placement) would live above Zag at the Ark/component layer, similar to how dialog handles its backdrop separately from the core machine.
Anatomy (roughly following shadcn's model as a starting point) of what that might look like:
Sidebar.RootSidebar.PanelSidebar.TriggerSidebar.HeaderSidebar.BodySidebar.FooterSidebar.RailSidebar.SectionSidebar.SectionHeaderSidebar.SectionBodySidebar.SectionActionShadcn also includes some other things that are more for styling (Inset), or can be composed from existing primitives (MenuItem, MenuButton, MenuSub, etc)
↩️ Alternatives
The closest primitives are Drawer for the mobile case and a custom Collapsible for the desktop rail, but they have slightly different a11y semantics, and composing those by hand means reimplementing the responsive mode-switching logic and state persistence every time, which is where most implementations go wrong. There are sidebar implementations in shadcn, and solid-ui, but no headless machine-level primitive that Ark could build on.
📝 Additional Information
Beta Was this translation helpful? Give feedback.
All reactions