Help Menu
The sidebar-footer Help item — What's new with an unread dot, Docs, Keyboard shortcuts, support and the version, in one menu.
- Status
- Since
0.25.89- Accessibility pattern
- menu button; unread in the name; rail tooltip
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 Help Menu before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify help-menuInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/help-menuRun 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/notification-bell, @vegastack/sidebar.
Usage
"use client";
import Link from "next/link";
import { HelpMenu } from "@/components/ui/help-menu";
import { SidebarFooter, SidebarMenu } from "@/components/ui/sidebar";
export function AppSidebarFooter({ unread, openShortcuts }: Props) {
return (
<SidebarFooter>
<SidebarMenu>
<HelpMenu
whatsNewUnread={unread}
version="v1.8.21"
linkRender={<Link href="" />}
links={{
whatsNew: { href: "/docs/whats-new" },
docs: { href: "/docs" },
shortcuts: { onSelect: openShortcuts },
support: { href: "mailto:support@example.com", external: true },
}}
/>
</SidebarMenu>
</SidebarFooter>
);
}Learning the product is one job — what changed, how something works, which keys do what, who to ask — so it gets one item, at the foot of the sidebar. A dot on "Docs" does not say "something changed"; here What's new carries the dot, and so does the Help item itself until it is read.
Scope
- Owns: the trigger (label, icon, unread dot, rail tooltip), the four entries in a fixed order, their icons and default labels, the shortcut hint and the version line.
- Does not own: routing — link entries render through
linkRender— the unread state, which the host computes, or the shortcuts overlay, which an action entry opens (ShortcutOverlay). - Compose with:
SidebarFooterandSidebarMenu; extraDropdownMenuItems go in as children, after Contact support.
Examples
In the sidebar
Every entry is optional and is either a link (href, rendered through linkRender, external
for a new tab) or an action (onSelect). Omit an entry and it is not shown. whatsNewUnread
puts the dot on What's new and on the trigger, and adds "(new updates)" to both names.
In the collapsed rail
In an icon-collapsed sidebar the item is the help icon with a "Help" tooltip, and the unread dot moves onto the icon's corner.
API Reference
HelpMenu
| Prop | Type | Default | Description |
|---|---|---|---|
align | "center" | "end" | "start" | "start" | The menu's alignment along that side. |
children | React.ReactNode | — | Extra entries (DropdownMenuItems), after Contact support and before the version. |
className | string | — | Classes for the sidebar item. |
label | string | "Help" | The trigger's text, and its tooltip in the collapsed rail. |
linkRender | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | <a /> | The element each link entry renders as — your router's link (<Link />). The entry's
href, classes and children are merged into it. |
links | { whatsNew?: HelpMenuLink; docs?: HelpMenuLink; shortcuts?: HelpMenuLink; support?: HelpMenuLink; } | {} | The entries, in this order: What's new · Docs · Keyboard shortcuts · Contact support. An omitted entry is not shown. |
shortcutsHint | React.ReactNode | "?" | The keys shown beside Keyboard shortcuts. |
side | "bottom" | "left" | "right" | "top" | "top" | Where the menu opens beside the trigger. |
unreadLabel | string | "new updates" | What the unread dot means, spoken after the trigger's and What's new's names. |
version | React.ReactNode | — | The build version line at the foot of the menu ("v1.8.21"). Omitted, no line. |
whatsNewUnread | boolean | false | Something new to read: What's new and the trigger carry the unread dot, and both say
unreadLabel to assistive technology. |
Data attributes and CSS variables on HelpMenu
| Attribute | Values |
|---|---|
data-entry | mirrors a prop or state value |
data-slot | "help-menu" | "help-menu-content" | "help-menu-dot" | "help-menu-item" | "help-menu-trigger" | "help-menu-version" |
Each entry:
| Prop | Type | Default | Description |
|---|---|---|---|
external | boolean | false | Open the link in a new tab (target="_blank" rel="noopener"). |
href | string | — | Where the entry goes. Rendered through linkRender, else a plain <a>. |
label | string | — | The entry's text; each entry has an English default. |
onSelect | (() => void) | — | Run instead of following a link — open the shortcuts overlay, a support chat. |
Accessibility
- The trigger is a menu button named by its label; while there is something new its name is "Help (new updates)", and What's new says the same — the dot itself is decorative.
- In the collapsed rail the trigger keeps its name and shows it as a tooltip.
- The version line is a menu label, not an item, so the arrow keys skip it.
| Key | Action |
|---|---|
| Enter / Space | Opens the menu |
| ↑ / ↓ | Moves between the entries |
| Escape | Closes the menu, focus returns |
| Contract | States tested |
|---|---|
| Behaviour | default, open, link-entry, action-entry, unread, collapsed-rail, version |
| Accessibility | menu-semantics, labeled, unread-announced, browser-accessibility-test |
| Visual | default, open, unread, collapsed |