Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Simple Groups Sidebar Block for Ark UI

A company handbook in a fixed-height window whose muted sidebar has four groups of pages and a density toggle: Roomy, Default and Compact set the size of the rows and the gaps, and the rail prints the measured row height.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let people tune a long menu to their screen with this simple groups sidebar for React with Ark UI. A window framed by a hairline with a plus mark on each corner holds a Sidebar in the theme's muted tone, with four labelled groups of handbook pages: Welcome, Policies, Benefits and Tools. One control sits in the rail, a Toggle Group named Density. Roomy, Default and Compact set the size of every menu button (lg, default, sm) and the gaps between rows and between groups, so the same fourteen links read three ways, and a quiet readout beside the toggle prints the height of the first row, measured in the page so the number is true in every style. Folded to icons, the rail shows each page's icon with a Tooltip; on a phone it is a sheet with the toggle inside it. The page shows the chosen handbook page: a sentence, three key points, its owner and its last review. It's built from Sidebar, Toggle Group, Badge, Avatar and Guides, with a CSS entrance only. For handbooks, docs, settings and any menu whose readers want it tighter or looser.

FAQ

How does the toggle change the rows?

Each density is one entry in MODES: the catalog size for the menu buttons, a gap class for each group's menu and a padding class for each group. The toggle sets one value in state and every row and group reads it, so nothing is measured to make the change. The sizes are the Sidebar's own, which is why the three densities follow whatever style the project uses.

Where does the row height number come from?

A small RowReadout finds the first row in its own copy of the rail after each change and prints its rendered height. A style with taller rows prints its own number, and on a phone the readout sits in the sheet and measures the sheet's copy. The rows turn their height transition off, so the measurement is taken after the change and not part-way through it.

Do the groups fold?

No, and that is on purpose: this block is about how a long menu is spaced, not folded. Each group's label names its menu with aria-labelledby, so a screen reader hears "Policies" before the four pages. For groups that open and close, see the collapsible groups sidebar.

What happens when the sidebar folds to icons?

The labels and the density toggle go, since the toggle has no icon form, and every page shows its icon with a tooltip at the icon rail's own size whatever the density says. Unfolding brings the toggle back with the density you chose.

What stays in the page, and how do I connect it?

Everything. The fourteen pages are typed in GROUPS with their text, owner and review date, and the density is held only in the block's state: the block sets persist={false} and shortcut={false}, so it writes no cookie and leaves Ctrl and Command with B to the page it sits on. To remember a density, keep it where your app keeps preferences and pass it in as the starting value. The pages are links to # whose handler shows the page instead of navigating. They're SidebarMenuButtons with asChild around an a element. Point them 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 density toggle is inside it, so you see the rows change as you press. Choosing a page closes the sheet and puts focus back on the button, and the status line under the page says which page opened or which density is on.