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.

KQ-2116 · PREVIEW/PALETTE

Up and Down move and flip the preview. Enter opens. Command or Control Enter opens beside.

Recent

Release checklist
Ines Park
basin-survey-map.png
Brand voice

Pages

Onboarding: your first week
Field notes: Basin survey

People

Tomas Reyes
Juno Vale

Files

field-budget-2026.sheet
field-guide-v4.pdf
flipopenCtrl ↵beside10 results

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.