Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Custom Width Sidebar Block for React

A hosting platform's settings console in a fixed-height window where the sidebar's width is the control: four presets set its CSS variable, and a measured count shows how many of ten long labels get cut at each.

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

Give long labels the room they need with this custom width sidebar for React with Base UI. A window framed by a hairline with a plus mark on each corner holds the Sidebar, whose width is one CSS variable, --sidebar-width, on its provider. A Segment Group in the top bar (a native Select below the large breakpoint) sets it to Narrow, Default, Wide or Roomy, 14, 16, 19 or 22rem, with a short transition that stops under reduced motion. Ten settings pages with long labels such as "Webhook configuration and signing keys" fill the rail, and the width decides how many of them are cut with an ellipsis. That count is measured in the browser, not typed: the page lists it for every preset, marks the current one, and the status line repeats it. It's built from Sidebar, Segment Group, Native Select, Avatar and Guides, with a CSS entrance only. For consoles, settings and admin screens whose navigation has long names.

FAQ

How do I set the width?

Give the provider a style with --sidebar-width set to any length, as this block does from its selected preset (style={{ "--sidebar-width": "19rem" }}, typed as CSSProperties). The sidebar, the gap it leaves in the layout and its mobile counterpart all read the variable, so nothing else changes. The folded width is a second variable, --sidebar-width-icon, 3rem by default. The window itself stays 36rem high on phones and 46rem from the medium breakpoint whatever the width.

How is the number of cut labels measured?

The page keeps hidden copies of the ten labels at each preset's width, laid out like the rail's rows, and counts the ones whose text is wider than the box they truncate in (their scroll width against their client width). It measures once the page has loaded, again when the fonts finish loading and again when the current label changes weight, so the counts are right in whatever font your theme uses. Because the copies are independent of the real rail, the numbers stay right while the rail is folded to icons or, on a phone, not on screen at all.

Why doesn't the preset change the phone's sidebar?

Below the medium breakpoint the sidebar is a sheet from the start edge, and it has its own width, 18rem, set on the sheet and not on the provider. The preset therefore applies from 768 px up, and the page says so. On a phone the select still changes the measured counts and the status line, so you can see what a width would do on a larger screen. To size the sheet too, override --sidebar-width on the sheet's own element in the catalog.

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

Everything. The ten settings pages and their sentences are typed in PAGES, the width lives in the block's own state, and nothing is saved. The pages are links to # whose handler shows the page instead of navigating. They're SidebarMenuButtons with render set to an a element. Point them at your routes and mark the current one with isActive.

Why is there no drag handle on the rail?

The catalog's rail on Ark can be dragged to resize the sidebar, and it writes the same --sidebar-width variable on the provider that the presets set, so the two would fight over one value. This block leaves the rail out and keeps the menu button, which still folds the sidebar to its icons. The other bases' rail only toggles, but the block keeps the same markup on all of them.

Is it accessible?

The sidebar is a navigation landmark named after the product, with its two groups named by their labels and the open page marked as the current page. A cut label keeps its full name for screen readers and shows in full in a tooltip when the rail is folded. The width control is a labeled group of four options with arrow keys, or a labeled native select on smaller screens, and one polite status line reports the width and the measured count after each change.

  • Pro

    Controlled State Sidebar

    State and theming

    A layout playground in a fixed-height window with a controlled sidebar: Open, Close, Toggle, a switch and Ctrl or Command with B all drive the provider, and every onOpenChange call is logged with where it came from.

  • Pro

    A reading app in a fixed-height window whose sidebar slides fully out of view, so the article's line length grows from 62 to 78 characters; the trigger, the edge rail and Ctrl or Command with B bring it back.

  • Pro

    A team file manager in a fixed-height window with its sidebar on the end side: choose a file in the list and the sidebar shows its details, a Copy path button and a Close button, and on a phone it opens as a sheet.

  • Pro

    A mail client in a fixed-height window: mailboxes and labels whose counts follow the mail you file, a searchable message list beside the open message, and Compose for a local draft.

  • Pro

    Scrollable Content Sidebar

    Headers and sections

    An all-in-one workspace in a fixed-height window whose wide sidebar scrolls six groups of pages under sticky group labels, with a line that says which group is at the top and a Jump to select that scrolls to one.

  • Pro

    A note-taking app in a fixed-height window whose narrow rail keeps a caption under every icon, with a pill on the open destination, a dot on Inbox while it holds unopened notes and Alerts and Settings pinned at the foot.