# View controler (`view-controler`) - SignalOS widget

> Segmented control for switching between view layouts (e.g. grid, list, table), with optional icons and labels per option.

- **Version:** 0.2.4
- **Kind:** widget · **Category:** data-display
- **Install:** `npx shadcn@latest add @signalos/view-controler`
- **Registry dependencies (pulled automatically):** @signalos/tokens, @signalos/utils, @signalos/button, @signalos/tooltip
- **npm dependencies:** lucide-react@^1.7.0, class-variance-authority@^0.7.0
- **Files installed:** `src/components/widgets/view-controler/ViewControler.tsx`, `src/components/widgets/view-controler/ViewControler.types.ts`, `src/components/widgets/view-controler/ViewControler.variants.tsx`

## Access

This is a private registry: pulling source requires a `SIGNALOS_REGISTRY_TOKEN`
(GitHub fine-grained PAT with read access to the signal-widgets repo) and an
`@signalos` entry in components.json `"registries"`. Previews and this document are public.

## Usage

```tsx
import { ViewControler } from "@/components/widgets/view-controler/ViewControler"
```

## Example

```tsx
"use client"

import * as React from "react"
import { Columns2, Grid2x2, List, Table2 } from "lucide-react"

import { ViewControler } from "./ViewControler"

export default function Example() {
  const [value, setValue] = React.useState("grid")

  return (
    <ViewControler
      value={value}
      onChange={setValue}
      items={[
        {
          value: "grid",
          label: "Grid",
          icon: <Grid2x2 className="h-4 w-4" />,
          tooltip: "Grid View",
        },
        {
          value: "list",
          label: "List",
          icon: <List className="h-4 w-4" />,
          tooltip: "List View",
        },
        {
          value: "table",
          label: "Table",
          icon: <Table2 className="h-4 w-4" />,
          tooltip: "Table View",
        },
        {
          value: "split",
          label: "Split",
          icon: <Columns2 className="h-4 w-4" />,
          tooltip: "Split View",
        },
      ]}
    />
  )
}
```

## Props

### `ViewControlerItem`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string` | yes | - | Unique value identifying the view option.  This value is returned when the item is selected.  Examples: - "grid" - "list" - "table" - "kanban" |
| `label` | `ReactNode` | no | - | Text displayed for the view option.  Example: "Grid" |
| `icon` | `ReactNode` | no | - | Optional icon displayed with the label.  Example: <Grid2X2 /> |
| `tooltip` | `string \| undefined` | no | - | Tooltip displayed when hovering over the option.  Example: "Switch to Grid View" |
| `disabled` | `boolean \| undefined` | no | `false` | Whether this view option is disabled.  When true, the user cannot select it. |

### `ViewControlerProps`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string` | yes | - | Currently selected view.  Must match one of the values in `items`. |
| `items` | `ViewControlerItem[]` | yes | - | List of available view options. |
| `onChange` | `(value: string) => void` | yes | - | Callback fired whenever the selected view changes.  Example: ```tsx onChange={(value) => setView(value)} ``` |
| `size` | `"sm" \| "md" \| "xxs" \| "xs" \| null \| undefined` | no | - | Size variant inherited from `viewControlerVariants`.  Available values depend on your component's `viewControlerVariants` definition. |
| `tone` | `"warning" \| "error" \| "primary" \| undefined` | no | - | Tone/style variant inherited from `viewControlerVariants`.  Available values depend on your component's `viewControlerVariants` definition. |
| `className` | `string \| undefined` | no | - | Additional CSS or Tailwind classes. |
| `tooltipDelay` | `number \| undefined` | no | `200` | Delay before showing tooltips.  Value is specified in milliseconds. |
| `variant` | `"default" \| "outline" \| "ghost" \| undefined` | no | - | Test identifier used by automated testing tools.  Typically rendered as: ```html data-testid="view-controller" ``` |
| `data-testid` | `string \| undefined` | no | - | Test identifier rendered as `data-testid` on the root element. |

## Changelog

## 0.2.4

- Derive a `data-testid` on every item from the root one (`${data-testid}-${value}`),
  so a consumer can target an individual segment instead of only the tablist.
- Give icon-only items an accessible name, from `tooltip` when present and the
  item `value` otherwise. Items that render a `label` are untouched — an
  `aria-label` there would override the visible text.

## 0.2.3

- Fix cross-item imports to use canonical @/components paths; add missing signalos.category to manifests.

# view-controler

## 0.2.2

- **Size:** varient added for `xs` and `xxs`
## 0.2.1

- Fixed the `tooltipDelay` JSDoc `@default` from `0` to `200` to match the
  implementation - the catalog's prop tables are generated straight from
  this file, so the documented default was wrong.

## 0.2.0

- **Breaking:** rename the `testId` prop to `data-testid` to match the rest
  of the registry and the DOM attribute name.

## 0.1.2

- Content sync fix to bring source in line with published registry payload.


## 0.1.1

- Added `class-variance-authority` dependency for variant styling.

## 0.1.0

- Initial release.
