Sidebar Menu Flyout
A sidebar row whose entries open in a menu beside it on hover or press, such as Spaces in the collapsed icon rail.
- Status
- Since
0.25.90- Accessibility pattern
- Menu button; Escape returns focus to the row
Last updated
Install
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Sidebar Menu Flyout before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify sidebar-menu-flyoutInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/sidebar-menu-flyoutRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
The same command installs the registry items it composes: @vegastack/dropdown-menu, @vegastack/sidebar.
Usage
import { SidebarMenuFlyout } from "@/components/ui/sidebar-menu-flyout";
<SidebarMenu>
<SidebarMenuFlyout label="Spaces" icon={<LayoutGrid />} railOnly>
{spaces.map((space) => (
<DropdownMenuItem key={space.id} render={<Link href={space.href} />}>
{space.name}
</DropdownMenuItem>
))}
<DropdownMenuSeparator />
<DropdownMenuItem render={<Link href="/spaces/new" />}>
<Plus />
New space
</DropdownMenuItem>
</SidebarMenuFlyout>
</SidebarMenu>;A sidebar row whose entries open beside it rather than under it. In the collapsed icon rail a
nested list — the person's spaces — has no room to show inline, so the row keeps one icon and its
entries open in a menu at its side, headed by the row's label, when the pointer rests on it or it is
pressed. railOnly shows the row in the rail alone, so the expanded sidebar keeps its own inline
group and the phone drawer lists the entries in full.
Scope
- Owns: the row (a
SidebarMenuItemwith aSidebarMenuButtontrigger), opening on hover and press, the menu's place beside the row (under it in the phone drawer), the heading, the rail-only display, and the row's count as on any sidebar row. - Does not own: the entries — they are the host's
DropdownMenuItems, links throughrender. - Compose with:
Sidebar'sSidebarMenu;DropdownMenu's items and separators;AppShell'srailSeparators.
Examples
Spaces in the icon rail
Hover Spaces in the rail, or focus it and press Enter. Expand the sidebar with the header button: the flyout row goes and the inline Spaces group shows instead.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
children* | React.ReactNode | — | The flyout's entries: DropdownMenuItems (links through render={<Link href="…" />}), with
DropdownMenuSeparators between sets ("+ New space" last). |
icon* | React.ReactNode | — | The row's icon — all that shows of it in the icon rail. |
label* | string | — | The row's name: the trigger's label, its tooltip, and the flyout's heading. |
badge | React.ReactNode | — | A count on the row, as on SidebarMenuButton (a dot or a short pill in the rail). |
badgeLabel | string | — | The count's words in the row's name ("3 unread"), as on SidebarMenuButton. |
closeDelay | number | 200 | Milliseconds the flyout stays after the pointer leaves, so it can travel into it. |
delay | number | 100 | Milliseconds the pointer rests on the row before the flyout opens. |
isActive | boolean | false | The row is current — one of its entries is the page on screen. |
railOnly | boolean | false | Show the row only in the collapsed icon rail — for entries the expanded sidebar lists inline (a Spaces group) and the phone drawer lists in full. |
Data attributes and CSS variables on SidebarMenuFlyout
| Attribute | Values |
|---|---|
data-rail-only | "" |
data-slot | "sidebar-menu-flyout" | "sidebar-menu-flyout-content" | "sidebar-menu-flyout-label" | "sidebar-menu-flyout-trigger" |
Accessibility
- The row is a menu button named by its label (and its count, as "Spaces 3 new"); the flyout is a menu, its entries menu items.
- In the collapsed rail the row shows its label as a tooltip on keyboard focus, as every rail row does; the tooltip steps aside while the flyout is open.
- Hover opens the flyout without taking focus. From the keyboard, Enter or Space opens it with the first entry focused, and Escape closes it and returns focus to the row.
| Key | Action |
|---|---|
| Enter / Space | Opens the flyout |
| ↓ / ↑ | Moves between the entries |
| Enter | Follows the entry |
| Escape | Closes the flyout and returns focus to the row |
| Contract | States tested |
|---|---|
| Behaviour | default, open, hover-open, keyboard-open, rail-only, badge, phone-drawer |
| Accessibility | menu-semantics, labeled, focus-return, browser-accessibility-test |
| Visual | default, open, active, collapsed |