Primitives

Menu — collapsible sidebar

`collapsible` narrows the menu to its icons: names in tooltips, counts on the icons. `collapsedMode="hidden"` folds it away instead.

The button beside the title collapses it.

Gulshan Parking

sessions

Picked from the icons, a branch (Payments) opens the menu with it.

Import#

Everything comes from the package root. The example above uses:

your-component.tsx
import { Menu, MenuGroup, MenuItem, MenuSub, Segmented, type MenuLook } from "@waveinno/ui";

Props#

Read from the source of this version, so they match the code exactly.

<Menu>

src/components/ui/menu.tsx
PropTypeDefaultDescription
variant"soft" | "line" | "raised" | "gradient" | "dark" | "panel" | "rail""soft"
valuestring—The chosen item's `value` (controlled).
defaultValuestring—
onValueChange(value: string) => void—
headingReact.ReactNode—On top of the list: a title, or in the rail, the product mark.
collapsibleboolean—A collapse toggle in the heading row.
collapsedboolean—
defaultCollapsedbooleanfalse
onCollapsedChange(collapsed: boolean) => void—
collapsedMode"icons" | "hidden""icons"`icons`: narrow to the icons. `hidden`: fold away entirely (toggle it from outside).
collapseShortcutbooleanfalse⌘B / Ctrl+B toggles it. Off by default: AppShell already uses ⌘B for its panel.

Also takes Omit<React.HTMLAttributes<HTMLElement>, "defaultValue" | "onChange">.

<MenuGroup>

src/components/ui/menu.tsx
PropTypeDefaultDescription
labelReact.ReactNode—
actionReact.ReactNode—Something small on the label's right: a "+" button, a count.
classNamestring—
childrenrequiredReact.ReactNode—

<MenuItem>

src/components/ui/menu.tsx
PropTypeDefaultDescription
iconReact.ReactNode—
descriptionReact.ReactNode—Second line, muted: what is behind the item. Puts the icon in a tile.
badgeReact.ReactNode—
countnumber | string—A number on the right: unread, pending, items inside.
shortcutstring—
valuestring—Chosen when it matches Menu's `value`; clicking makes it the value.
activeboolean—Mark it chosen yourself, e.g. from the router's pathname. Overrides `value`.
dangerboolean—
asChildboolean—Render your own element (a Next.js Link): `<MenuItem asChild><Link href="/x">Label</Link></MenuItem>`.

Also takes Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "value">.

<MenuSub>

src/components/ui/menu.tsx
PropTypeDefaultDescription
iconReact.ReactNode—
descriptionReact.ReactNode—Second line, muted: what is behind the item. Puts the icon in a tile.
badgeReact.ReactNode—
countnumber | string—A number on the right: unread, pending, items inside.
shortcutstring—
labelrequiredReact.ReactNode—
defaultOpenbooleanfalse
openboolean—
onOpenChange(open: boolean) => void—
disabledboolean—
classNamestring—
childrenrequiredReact.ReactNode—

<Segmented>

src/components/ui/segmented.tsx
PropTypeDefaultDescription
valuerequiredT—
onChangerequired(v: T) => void—
optionsrequiredSegmentedOption<T>[]—
classNamestring—
ariaLabelstring—
variantkeyof typeof TRACK"pill"
sizekeyof typeof SIZES"sm"
fullWidthbooleanfalseStretch to the container, options sharing the width equally.

Install#

If the project does not have the package yet, add it, then follow the setup for Next.js or Vite once.

$ npm install @waveinno/ui