Style picker
A grid of style presets with your own thumbnails. One style or several with a cap, an optional None tile, and grid keyboard movement by column and row.
On this page
Photo styles with a None tile. Arrow keys move through the grid by column and row.
Installation
Usage
import { StylePicker } from "@/components/ui/chatcn/style-picker"
const styles = [
{ id: "film", label: "Film grain", thumbnail: "/styles/film.jpg" },
{ id: "mono", label: "Monochrome", thumbnail: "/styles/mono.jpg" },
]
<StylePicker styles={styles} value={value} onValueChange={setValue} noneOption />The value is always an array of ids, so switching to multiple never changes its type. An empty array means no style, and checks the None tile when there is one. Thumbnails can be any image, or a render node for swatches, canvases or anything drawn.
Examples
Multiple with a cap
Multiple selection with a cap: at the limit the rest wait until one is removed.
States
Loading, empty with an action, render-slot swatches, long labels, a disabled preset and disabled.
Props
| Prop | Type | Notes |
|---|---|---|
styles | StylePreset[] | { id, label, description?, thumbnail?, render?, disabled? } |
value, defaultValue, onValueChange | string[] | Selected ids |
multiple | boolean | Several at once. Default false |
max | number | With multiple, the most that can be selected |
noneOption | boolean | string | Adds a None tile first. A string renames it |
columns | number | Fixed columns. Defaults to as many 96 px columns as fit |
loading, loadingCount | boolean, number | Skeleton tiles in the final layout |
empty | ReactNode | Shown when styles is empty |
disabled | boolean | |
label | string | Names the group. Default "Style" |
Keyboard
| Key | Action |
|---|---|
Tab | Move into the grid. It is one tab stop |
ArrowLeft, ArrowRight | Previous or next tile |
ArrowUp, ArrowDown | Same column, previous or next row |
Home, End | Start or end of the row. With Ctrl, the first or last tile |
Space, Enter | Toggle the focused tile. Single select also follows the arrows |
Accessibility
- Single select is a radio group, multiple is a group of checkboxes. Each tile is named by its label and description.
- At the cap, unselected tiles become
aria-disabledand a polite line says 3 of 3 selected. Remove one to pick another. - Selection shows as an accent ring with a gap and a check badge, never color alone. In forced colors the ring uses the system highlight.
Motion
- Tiles press to 0.98. The ring fades in 150 ms and the check swaps in with the kit's blur crossfade.
- Thumbnails fade in over 200 ms as they load. Moving with the keyboard is instant. Skeletons are static.