KQ-2116 · PREVIEW/PALETTE
Preview Palette
A command menu whose right half previews the highlighted result on a vertical filmstrip: Up and Down glide the highlight pill down the list and the whole strip the other way on springs.glide in the same moment, so the next card rises into the window while the last tucks behind the top edge and moving down the list feels like flipping through the items themselves. Pages show their first lines, people their card and local time, files a drawn thumbnail; the pane can also be dragged 1:1 or flicked (the release projects to the card it was heading for) or wheeled, a press settles on springs.snap and an end-of-list press gives the strip a velocity kick that leaves and returns. The field is a combobox: Enter opens, Cmd or Ctrl+Enter opens beside, an empty search offers to create, and below 34rem the pane hides and a long press or → peeks it over the list.
Up and Down move and flip the preview. Enter opens. Command or Control Enter opens beside.
Recent
Pages
People
Files
previewing Release checklist · page
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/preview-palette
Props
- previewWidth
- number
- default 50
- Share of the palette the preview pane takes, in percent, where the palette is 34rem or wider.
- listDensity
- "compact" | "cozy" | "roomy"
- default "cozy"
- Row height: one tight line, a comfortable line, or two lines with the path or role.
- accent
- "cobalt" | "plum" | "mint" | "ink" | string
- default "cobalt"
- Highlight, flash, avatars, thumbnails and badges. A name or any CSS colour.
- items
- PreviewPaletteItem[]
- default defaultPreviewPaletteItems
- Everything that can be found: { id, kind, title, group, keywords?, path?, excerpt?, outline?, author?, updated?, role?, team?, handle?, utcOffset?, presence?, presenceNote?, owns?, fileType?, size?, detail? }.
- groups
- PreviewPaletteGroup[]
- default defaultPreviewPaletteGroups
- The groups results list under, in order: { id, label }.
- recent
- string[]
- default defaultPreviewPaletteRecent
- Ids shown under Recent while the field is empty, newest first.
- renderers
- Partial<Record<"page" | "person" | "file", (item, { now }) => ReactNode>>
- default —
- Replace the built-in preview for a kind of result; the card frame stays the palette's.
- query / defaultQuery
- string
- default — / ""
- The search text, controlled or initial.
- onQueryChange
- (query: string) => void
- default —
- Fires with every keystroke's new query.
- highlighted
- string
- default —
- Controlled: the id of the highlighted result ("create" for the create row).
- onHighlight
- (item: PreviewPaletteItem | null) => void
- default —
- The highlight moved, from the key, pointer or drag that moved it, and once on mount; null for the create row.
- onSelect
- (item: PreviewPaletteItem) => void
- default —
- A result was opened: Enter, a click, or a tap on its preview.
- onOpenBeside
- (item: PreviewPaletteItem) => void
- default —
- Cmd or Ctrl+Enter: open the highlighted result beside the current one.
- onCreate
- (query: string) => void
- default —
- The no-results row was chosen, with the query to create from.
- createLabel
- string
- default "Create page"
- The create row's verb.
- pendingIds
- string[]
- default []
- Results whose preview is still loading: their card shows a skeleton.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the results have arrived: skeleton rows while loading, a message with Try again on error.
- onRetry
- () => void
- default —
- Try again after an error.
- now
- number
- default defaultPreviewPaletteNow
- The time relative dates and local times are read from, in ms.
- maxResults
- number
- default 12
- Most results listed for a query.
- peekDelay
- number
- default 380
- How long a press on a row must last to peek its preview where the pane is hidden, in ms.
- placeholder
- string
- default "Search Fernworks…"
- The field's placeholder.
- label
- string
- default "Search the wiki"
- The field's accessible name.
- onDismiss
- () => void
- default —
- Escape on an empty field. Without it Escape is left to the page.
- className
- string
- default —
- Classes for the outer container.
| Prop | Type | Default | Description |
|---|---|---|---|
| previewWidth | number | 50 | Share of the palette the preview pane takes, in percent, where the palette is 34rem or wider. |
| listDensity | "compact" | "cozy" | "roomy" | "cozy" | Row height: one tight line, a comfortable line, or two lines with the path or role. |
| accent | "cobalt" | "plum" | "mint" | "ink" | string | "cobalt" | Highlight, flash, avatars, thumbnails and badges. A name or any CSS colour. |
| items | PreviewPaletteItem[] | defaultPreviewPaletteItems | Everything that can be found: { id, kind, title, group, keywords?, path?, excerpt?, outline?, author?, updated?, role?, team?, handle?, utcOffset?, presence?, presenceNote?, owns?, fileType?, size?, detail? }. |
| groups | PreviewPaletteGroup[] | defaultPreviewPaletteGroups | The groups results list under, in order: { id, label }. |
| recent | string[] | defaultPreviewPaletteRecent | Ids shown under Recent while the field is empty, newest first. |
| renderers | Partial<Record<"page" | "person" | "file", (item, { now }) => ReactNode>> | — | Replace the built-in preview for a kind of result; the card frame stays the palette's. |
| query / defaultQuery | string | — / "" | The search text, controlled or initial. |
| onQueryChange | (query: string) => void | — | Fires with every keystroke's new query. |
| highlighted | string | — | Controlled: the id of the highlighted result ("create" for the create row). |
| onHighlight | (item: PreviewPaletteItem | null) => void | — | The highlight moved, from the key, pointer or drag that moved it, and once on mount; null for the create row. |
| onSelect | (item: PreviewPaletteItem) => void | — | A result was opened: Enter, a click, or a tap on its preview. |
| onOpenBeside | (item: PreviewPaletteItem) => void | — | Cmd or Ctrl+Enter: open the highlighted result beside the current one. |
| onCreate | (query: string) => void | — | The no-results row was chosen, with the query to create from. |
| createLabel | string | "Create page" | The create row's verb. |
| pendingIds | string[] | [] | Results whose preview is still loading: their card shows a skeleton. |
| status | "ready" | "loading" | "error" | "ready" | Whether the results have arrived: skeleton rows while loading, a message with Try again on error. |
| onRetry | () => void | — | Try again after an error. |
| now | number | defaultPreviewPaletteNow | The time relative dates and local times are read from, in ms. |
| maxResults | number | 12 | Most results listed for a query. |
| peekDelay | number | 380 | How long a press on a row must last to peek its preview where the pane is hidden, in ms. |
| placeholder | string | "Search Fernworks…" | The field's placeholder. |
| label | string | "Search the wiki" | The field's accessible name. |
| onDismiss | () => void | — | Escape on an empty field. Without it Escape is left to the page. |
| className | string | — | Classes for the outer container. |