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.

KQ-2117 · BATCH/PALETTE
GW-1042GW-1048GW-1047
3

Up and Down move, Space or Enter picks, Tab moves to the actions, Backspace removes the last pick.

Open

GW-1042Gauge readings drift after firmware 4.2
GW-1043Export to CSV drops the unit column
GW-1047Dashboard tiles flicker on resize
GW-1048Sensor offline banner never clears
GW-1051Celsius and Fahrenheit toggle for reports
GW-1054Mobile app signs out every hour

In progress

GW-1045Calibration reminders sent twice
GW-1053Alert thresholds reset on save

Closed

GW-1050Readings drift after update (duplicate)
GW-1056Typo in the onboarding checklist
␣pick⇥actions10 tickets

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.