Skip to content
txbrendan/ui

View switch

beta

A row of views. The active one slides to the view you pick.

Preview

Showing board

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/view-switch

Use it for

  • Choosing one layout of the same records, like Board, List, and Timeline.
  • Pass options when the views are not those three. Each option needs a value and a label.
  • Hold the value yourself when another part, such as a view morph, must follow it.

Avoid it for

  • A setting that is not a view of the same things. Use Tabs and put a panel under each one.
  • More than a handful of views. The row scrolls, but a menu is easier to scan.

Props

  • options

    The views, in order.

    { value: string; label: string; id?: string; controls?: string }[] · default [{ value: "board", label: "Board" }, { value: "list", label: "List" }, { value: "timeline", label: "Timeline" }]

  • value

    The selected view. Use with onValueChange.

    string

  • defaultValue

    The view selected on first paint, when value is not set. Defaults to the first option.

    string

  • onValueChange

    Called with the view that was just chosen.

    (value: string) => void

  • tone

    Color of the active pill or line.

    "neutral" | "brand" · default "neutral"

  • emphasis

    "solid" puts the active view on a filled pill. "ghost" underlines it.

    "solid" | "ghost" · default "solid"

  • size

    Height, padding, and text size.

    "sm" | "md" | "lg" · default "md"

  • aria-label

    Names the group, like "Layout".

    string · default "View"

  • className

    Classes on the root. Later classes win.

    string

Accessibility

  • The row is a tab list. Each view is a tab. Arrow keys move between them and select the one they reach.
  • Home and End jump to the first and last view.
  • The active view's pill or line slides. Reduced motion jumps there instead.

Examples

Board, list, and timeline

<ViewSwitch value={layout} onValueChange={setLayout} aria-label="Layout" />

Your own views

<ViewSwitch
  aria-label="Layout"
  options={[{ value: "cards", label: "Cards" }, { value: "rows", label: "Rows" }]}
  defaultValue="cards"
/>