KQ-1128 · ROLL/SEARCH
Roll Search
A search that lives as a round lens at the right end of its slot: pressed, or with / typed anywhere on the page, the lens rolls to the left end like a wheel on the snap spring while the field unrolls behind it like a strip of carpet, one motion value driving the pill's width, the lens's place and its turn, so the wheel never slips and always lands upright. Results drop in below on snap in a cascade, in a panel whose height is measured and glides, with the query lit in each; Escape rolls it back up on glide. The input is a real combobox: arrows move through the results, Enter picks one, Escape rolls it up and returns focus to the lens.
Gaugeworks Docs
docs · press / to search
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/roll-search
Props
- items
- { id: string; label: string; meta?: string; keywords?: readonly string[] }[]
- default —
- What is searched: the label and meta are shown and lit, keywords only searched.
- label
- string
- default —
- What is being searched, as "Search docs": the lens button's name and the input's visible label, which heads the results panel.
- placeholder
- string
- default "Search"
- The input's placeholder.
- value / defaultValue
- string
- default ""
- The query. Controlled or uncontrolled.
- onValueChange
- (query: string) => void
- default —
- Fires with the new query on every edit, and with "" when the search rolls up.
- open / defaultOpen
- boolean
- default false
- Whether the field is rolled open. Controlled or uncontrolled; a host change rolls it silently.
- onOpenChange
- (open: boolean) => void
- default —
- Fires from the press, key or blur that opened or closed it.
- onSelect
- (item: RollSearchItem) => void
- default —
- Enter, or a press on a result. The search then rolls up and focus returns to the lens.
- filter
- (item: RollSearchItem, query: string) => boolean
- default —
- Whether an item answers a query. Defaults to every word of the query appearing in its label, meta or keywords.
- limit
- number
- default 4
- The most results shown at once; the panel says "4 of 9" when there are more.
- shortcut
- string | null
- default "/"
- The key that opens it from anywhere on the page, shown as a small key cap beside the lens; null for none. It never fires while typing in a field, with a modifier, during composition, or behind a dialog.
- width
- number
- default 320
- How far the field unrolls, in px, 200 to 400. It shrinks to fit a narrower box.
- roll
- boolean
- default true
- The lens turns as it travels, like a wheel, rocking slightly against the end; off, it slides.
- results
- "list" | "cards"
- default "list"
- Compact rows with a page glyph and the meta at the end, or small cards in two columns.
- highlight
- boolean
- default true
- Light every occurrence of the query's words in each result.
- sound
- boolean
- default false
- Play a whir while the lens rolls, its gain and pitch following the lens's speed (a swish when it slides), and a tick as each arriving result lands. Nothing plays, and no audio context exists, unless this is on.
- disabled
- boolean
- default false
- Disables the lens, the input and the shortcut.
- className
- string
- default —
- Merged onto the root's classes.
| Prop | Type | Default | Description |
|---|---|---|---|
| items | { id: string; label: string; meta?: string; keywords?: readonly string[] }[] | — | What is searched: the label and meta are shown and lit, keywords only searched. |
| label | string | — | What is being searched, as "Search docs": the lens button's name and the input's visible label, which heads the results panel. |
| placeholder | string | "Search" | The input's placeholder. |
| value / defaultValue | string | "" | The query. Controlled or uncontrolled. |
| onValueChange | (query: string) => void | — | Fires with the new query on every edit, and with "" when the search rolls up. |
| open / defaultOpen | boolean | false | Whether the field is rolled open. Controlled or uncontrolled; a host change rolls it silently. |
| onOpenChange | (open: boolean) => void | — | Fires from the press, key or blur that opened or closed it. |
| onSelect | (item: RollSearchItem) => void | — | Enter, or a press on a result. The search then rolls up and focus returns to the lens. |
| filter | (item: RollSearchItem, query: string) => boolean | — | Whether an item answers a query. Defaults to every word of the query appearing in its label, meta or keywords. |
| limit | number | 4 | The most results shown at once; the panel says "4 of 9" when there are more. |
| shortcut | string | null | "/" | The key that opens it from anywhere on the page, shown as a small key cap beside the lens; null for none. It never fires while typing in a field, with a modifier, during composition, or behind a dialog. |
| width | number | 320 | How far the field unrolls, in px, 200 to 400. It shrinks to fit a narrower box. |
| roll | boolean | true | The lens turns as it travels, like a wheel, rocking slightly against the end; off, it slides. |
| results | "list" | "cards" | "list" | Compact rows with a page glyph and the meta at the end, or small cards in two columns. |
| highlight | boolean | true | Light every occurrence of the query's words in each result. |
| sound | boolean | false | Play a whir while the lens rolls, its gain and pitch following the lens's speed (a swish when it slides), and a tick as each arriving result lands. Nothing plays, and no audio context exists, unless this is on. |
| disabled | boolean | false | Disables the lens, the input and the shortcut. |
| className | string | — | Merged onto the root's classes. |