shadcn.io is not affiliated with official shadcn/ui
Sub-Menus Sidebar Block for React
A recipe manager in a fixed-height window whose floating sidebar has sections with sub-menus, a switch between One at a time and Keep open, and arrow keys that open a sub-menu toward the end of the line and close it toward the start.
Installation
Overview
Decide how a menu's sub-menus behave with this sub-menus sidebar for React with Base UI. A window framed by a hairline with a plus mark on each corner holds a floating Sidebar of five meal sections, Breakfast, Lunch, Dinner, Baking and Drinks, each with a sub-menu of collections: Dinner holds Pasta, Curries and Roasts. A Segment Group over the menu sets the mode. In One at a time, opening a section closes the others, like an accordion; in Keep open, any number can stay open, with a count of how many. On a section's row the arrow toward the end of the line opens its sub-menu and the one toward the start closes it, so the menu works from the keyboard the way a tree does; from a collection the start arrow closes the section and returns to its row. The page lists the chosen collection's recipes with their times and servings. It's built from Sidebar, Collapsible, Segment Group, Badge and Guides, with a CSS entrance only. Folded to icons the rail keeps the five section icons, and pressing one unfolds it; below the medium breakpoint it is a sheet. For recipes, settings, help and any menu where the right behaviour is a choice.
FAQ
What do the two modes do?
In One at a time, afterToggle returns a list of just the section you opened, so the others close, and the status line says which: "Opened Baking. Dinner closed. 1 open." In Keep open it adds the section to the list instead. Switching to One at a time with several open keeps only the section that holds the current page, or the first open one if none does, and says what it closed. Switching to Keep open changes nothing until you open another.
How do the arrow keys work?
With focus on a section's row, the arrow toward the end of the line opens its sub-menu, and the one toward the start closes it. With focus on a collection, the start arrow closes its section and puts focus back on the section's row. In a right-to-left layout the two arrows swap, because the block reads the direction from the element. The keys are caught for the whole rail in the capture phase, because React Aria's buttons stop a key before it bubbles, and they obey the mode: in One at a time, opening with the arrow closes the others too. Enter and Space still toggle a row.
Where does the count come from?
It is the length of the list of open sections, shown under the mode switch and spoken in the status line after every change. It is never typed, so it cannot disagree with what is open.
What happens when the sidebar folds to icons?
The menu button or the rail along the edge folds it to the five section icons with tooltips, and the sub-menus and the mode switch are hidden. Pressing a section icon unfolds the rail and opens that section. The provider is set with persist={false} and shortcut={false}, so the block writes no cookie and leaves Ctrl and Command with B to the page it sits on.
What stays in the page, and how do I connect it?
Everything. The fifteen collections and their recipes are typed in SECTIONS at the top of the file, and choosing one swaps the list in the block's own state; nothing is saved. The collections are links to # whose handler shows the list instead of navigating. Each section row is a SidebarMenuButton that flips its own sub-menu: it carries its own aria-expanded and a press handler, onClick, over a controlled Collapsible, rather than being the Collapsible's trigger, because a row's tooltip and a trigger would both claim the button's id. Point the links at your routes and mark the current one with isActive and aria-current.
How does it work on a phone?
Below the medium breakpoint the sidebar is a sheet that the menu button in the top bar opens from the start edge, the right in a right-to-left layout. The mode switch and the sub-menus are inside it, and choosing a collection closes the sheet and puts focus back on the button. The status line under the page says what opened and how many sections are open.
Related
- Pro
Collapsible Items Sidebar
Folds and treesA design system's docs in a fixed-height window whose sidebar rows are split: a label that opens a section's overview and a separate chevron that opens its sub-menu, with a count of pages on each row.
- Pro
Collapsible Groups Sidebar
Folds and treesA framework's docs in a fixed-height window whose slim sidebar has five groups that fold from their labels, with Expand all and Collapse all, a count of open groups and a dot on a folded group that holds the current page.
- Pro
Floating Variant Sidebar
VariantsA CSS toolkit's docs in a fixed-height window with a floating sidebar: a rounded card inset from the window over a tinted shell, five collapsing sections of pages, and a switch to the flush rail for comparison.
- Pro
Nested Collapsible Sidebar
Folds and treesA help centre in a fixed-height window whose wide sidebar folds three levels deep, categories that hold topics that hold articles, with a Reveal active button that opens only the folds above the open article.
- Pro
Documentation Tree Sidebar
Folds and treesA docs host in a fixed-height window whose sidebar is a numbered outline that opens the folds above the page you choose, an Auto-collapse switch that closes the rest, a breadcrumb over the page and Previous and Next buttons in the top bar.
- Pro
Multi-Level Menu Sidebar
Folds and treesA grocery app in a fixed-height window whose inset sidebar drills down one level at a time, panel by panel up to four levels deep, with a back button, Escape and a breadcrumb that all go up.