Skip to content
Component installs need the registry setup
VegaStack Design

Display Menu

The toolbar's Display tool — layout and sort once folded in, row height, group by, columns, the Show switches and Reset, on one surface.

Status
stable
Since
0.25.100
Accessibility pattern
named tool with state; labelled switches and drill-ins

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 Display Menu before installation. Retain the digest printed by this command.

pnpm exec vegastack-design verify display-menu

Install with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.

pnpm dlx shadcn@4.21.0 add @vegastack/display-menu

Run 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/button, @vegastack/list-toolbar, @vegastack/sortable-list, @vegastack/switch, @vegastack/toggle-group.

Usage

import { DisplayMenu } from "@/components/ui/display-menu";

<ListToolbar
  display={
    <DisplayMenu
      rowHeight={{
        value: density,
        options: [
          { value: "compact", label: "Compact" },
          { value: "comfortable", label: "Comfortable" },
        ],
        onValueChange: setDensity,
      }}
      columns={{ items: columns, onToggle: toggleColumn, onShowAll: showAll }}
      toggles={[
        {
          id: "subtasks",
          label: "Show subtasks",
          checked: subtasks,
          onCheckedChange: setSubtasks,
        },
        {
          id: "closed",
          label: "Show closed",
          checked: closed,
          onCheckedChange: setClosed,
        },
      ]}
      isDefault={isDefault}
      onReset={reset}
    />
  }
/>;

Display says how rows look and which lifecycle states are included. It is named Display, not View, so it is never confused with a table's saved views. Its sections appear only when filled, always in this order:

  1. Layout — once the toolbar has folded Layout in (or when you pass layout): labelled options.
  2. Sort by — once the toolbar has folded Sort in: one row with the order's summary that drills into the same sort content.
  3. Rows — Row height (text-labelled options: "Compact · Comfortable", "Short · Medium · Tall"), Group by (a GroupByPicker), and Columns or Fields ("5 of 7 ›", drilling into an eye per column, reorderable when onReorder is set; a long list scrolls inside the menu).
  4. Show — one switch per lifecycle state the page supports: Show subtasks, Show closed, Show archived, Show disabled, Show empty groups. One rule everywhere: a state hidden by default is included from here, never from a default filter chip.
  5. Reset — "Reset to default" (or resetLabel, "Reset to saved view" on a table), shown only while isDefault is false. The tool carries a dot then too.

It is one surface: no filled rows, no control tracks, no card inside it. Every row is 32px from the 8px inset, sections divided by a hairline. A drill-in replaces the page in place with a ‹ back header; a reopen always starts on the main page. On a phone it is a bottom sheet.

Actions on the view (Rename, Delete, Save view, Export) never live here: they go in the view tab's own ⋯ or the toolbar's ListToolbarMenu.

Examples

A table's display

Group by with a GroupByPicker, three row heights, "Show empty groups" and "Reset to saved view".

API Reference

PropTypeDefaultDescription
columnsDisplayMenuColumns—The columns (or a table's fields): a row that drills into show/hide and order.
groupByReact.ReactNode—Group by — a GroupByPicker (or a Select).
isDefaultbooleantrueWhether the display is the page's default. false puts a dot on the tool and shows Reset.
labelsPartial<DisplayMenuLabels>EnglishThe component's words.
layoutListToolbarLayout<ListToolbarLayoutValue>—Layout, as a section with labelled options. The toolbar fills it once Layout folds into Display; pass it yourself to always show it.
onReset(() => void)—Put everything back. Shown only while isDefault is false.
resetLabelstring"Reset to default"The reset action's text ("Reset to saved view" on a table).
rowHeightDisplayMenuRowHeight<string>—Row height, as text-labelled options.
togglesreadonly DisplayMenuToggle[][]The "Show …" switches the page supports, in order.

Data attributes and CSS variables on DisplayMenu

AttributeValues
data-slot"display-menu-columns" | "display-menu-columns-list" | "display-menu-content" | "display-menu-group-by" | "display-menu-layout" | "display-menu-reset" | "display-menu-row-height" | "display-menu-rows" | "display-menu-show" | "display-menu-sort" | "display-menu-trigger"

Columns

PropTypeDefaultDescription
items*readonly DisplayMenuColumn[]—The columns, in order.
onToggle*(id: string, visible: boolean) => void—Show or hide one.
onReorder((from: number, to: number) => void)—Move one (from index → to index). Omitted, the columns do not reorder.
onShowAll(() => void)—Show every column (the drill-in's "Show all").
titlestring"Columns"The row's and the drill-in's title.

Toggle

PropTypeDefaultDescription
checked*boolean—Whether it is on.
id*string—Stable id.
label*string—The switch's text ("Show archived").
onCheckedChange*(checked: boolean) => void—Called with the next state.
disabledbooleanfalseShown but not available.

Accessibility

  • The tool is named "Display" ("Display, changed" with its dot) and opens a surface named Display.
  • Row height and Layout are groups of toggle buttons labelled by their row; each Show row is a switch labelled by its text.
  • Drill-in rows are buttons that carry their summary; the drill-in's back button is named "Back".
  • Each column's eye is a toggle button ("Hide Due" / "Show Due") with aria-pressed.
KeyAction
TabMove through the rows' controls
Space / EnterToggle a switch, pick an option, drill in
EscClose the surface
ContractStates tested
Behaviourdefault, open, changed, folded
Accessibilitylabeled, browser-accessibility-test
Visualdefault, hover

Do / Don't

Do
Put every 'Show …' inclusion switch here and pass isDefault so the tool's dot and Reset tell the truth.
Don't
Hide lifecycle states behind a default filter chip, or put destructive view actions under Display.

On this page