KQ-2117 · BATCH/PALETTE
Batch Palette
A command menu that gathers several items before choosing what to do with them: Space or Enter picks the highlighted ticket and a copy of its key flies from the row to the tray, landing as a chip on springs.snap with one crisp overshoot, while removed chips leave on the exit ease and the rest close up on springs.glide. Tab moves to the actions and the chips glide out of the tray in a cascade to fan over the highlighted action like a hand of cards, following it from row to row on springs.glide, with the tickets the action would skip or cannot take struck through so you see exactly what it will touch. Running reports a partial failure through onRunAction's { failed }: those chips glide home tinted while the rest sink into the action, and Shift+Tab, Backspace and Escape step back, drop the last chip and clear.
Up and Down move, Space or Enter picks, Tab moves to the actions, Backspace removes the last pick.
Open
In progress
Closed
3 picked · picking tickets
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/batch-palette
Props
- chipStyle
- "pill" | "tag" | "stub"
- default "pill"
- How a picked item is drawn in the tray and the fan: a rounded accent pill, a square tag with a status notch, or a ticket stub with punched sides.
- fanSpread
- number
- default 6
- Degrees between neighbouring chips when they fan out over an action; 0 is a neat stack.
- accent
- "cobalt" | "plum" | "mint" | "ink" | string
- default "cobalt"
- Highlight, chips and checks. A name or any CSS colour.
- items
- BatchItem[]
- default defaultBatchItems
- Everything that can be picked: { id, key, title, status, priority?, assignee?, updated?, keywords? }.
- actions
- BatchAction[]
- default defaultBatchActions
- What can be done: { id, label, icon, appliesTo?, unsupportedReason?, min?, max?, past?, tone?, keywords? }.
- selection / defaultSelection
- string[]
- default — / []
- Ids of the picked items in the order they were picked, controlled or initial.
- onSelectionChange
- (ids: string[]) => void
- default —
- Fires with the new pick from the key, click or run that changed it.
- onRunAction
- (action, items) => void | BatchRunResult | Promise<void | BatchRunResult>
- default —
- Run an action on the supported picked items; return or resolve { failed: [{ id, reason }] } for a partial failure.
- onClearSelection
- () => void
- default —
- The tray's Clear was pressed.
- phase / defaultPhase
- "items" | "actions"
- default — / "items"
- Which list is showing, controlled or initial.
- onPhaseChange
- (phase: "items" | "actions") => void
- default —
- Fires from the Tab, click or run that switched lists.
- maxFan
- number
- default 6
- Most chips fanned over an action; the rest are counted.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the items have arrived: skeleton rows while loading, a message with Try again on error.
- onRetry
- () => void
- default —
- Try again after an error.
- now
- number
- default defaultBatchNow
- The time ages are read from, in ms.
- itemNoun
- [string, string]
- default ["ticket", "tickets"]
- What one item and many are called, in names, counts and summaries.
- placeholder
- string
- default "Find tickets…"
- The field's placeholder while picking.
- label
- string
- default "Batch actions"
- The palette's accessible name.
- onDismiss
- () => void
- default —
- Escape on an empty field while picking. Without it Escape is left to the page.
- className
- string
- default —
- Classes for the outer container.
| Prop | Type | Default | Description |
|---|---|---|---|
| chipStyle | "pill" | "tag" | "stub" | "pill" | How a picked item is drawn in the tray and the fan: a rounded accent pill, a square tag with a status notch, or a ticket stub with punched sides. |
| fanSpread | number | 6 | Degrees between neighbouring chips when they fan out over an action; 0 is a neat stack. |
| accent | "cobalt" | "plum" | "mint" | "ink" | string | "cobalt" | Highlight, chips and checks. A name or any CSS colour. |
| items | BatchItem[] | defaultBatchItems | Everything that can be picked: { id, key, title, status, priority?, assignee?, updated?, keywords? }. |
| actions | BatchAction[] | defaultBatchActions | What can be done: { id, label, icon, appliesTo?, unsupportedReason?, min?, max?, past?, tone?, keywords? }. |
| selection / defaultSelection | string[] | — / [] | Ids of the picked items in the order they were picked, controlled or initial. |
| onSelectionChange | (ids: string[]) => void | — | Fires with the new pick from the key, click or run that changed it. |
| onRunAction | (action, items) => void | BatchRunResult | Promise<void | BatchRunResult> | — | Run an action on the supported picked items; return or resolve { failed: [{ id, reason }] } for a partial failure. |
| onClearSelection | () => void | — | The tray's Clear was pressed. |
| phase / defaultPhase | "items" | "actions" | — / "items" | Which list is showing, controlled or initial. |
| onPhaseChange | (phase: "items" | "actions") => void | — | Fires from the Tab, click or run that switched lists. |
| maxFan | number | 6 | Most chips fanned over an action; the rest are counted. |
| status | "ready" | "loading" | "error" | "ready" | Whether the items have arrived: skeleton rows while loading, a message with Try again on error. |
| onRetry | () => void | — | Try again after an error. |
| now | number | defaultBatchNow | The time ages are read from, in ms. |
| itemNoun | [string, string] | ["ticket", "tickets"] | What one item and many are called, in names, counts and summaries. |
| placeholder | string | "Find tickets…" | The field's placeholder while picking. |
| label | string | "Batch actions" | The palette's accessible name. |
| onDismiss | () => void | — | Escape on an empty field while picking. Without it Escape is left to the page. |
| className | string | — | Classes for the outer container. |