Change a record's status inside a workflow — task To do → Done, deal stages, content Draft → Published, leave Pending → Approved. The trigger is the status badge itself. Every status has a category with its own icon (shape, not only colour), transitions not allowed from the current status stay visible with the reason, a transition can ask for confirmation and a note, and async saves are optimistic and revert on failure.
- WEB-311Hero block: video background option
- WEB-314Cookie banner copy for Turkish locale
- WEB-318Blog list: author filter
- WEB-302Footer social icons in RTL
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { StatusPicker, type StatusDef } from "@vamos-ui/react";
const statuses: StatusDef[] = [
{ value: "todo", label: "To do", category: "todo" },
{ value: "doing", label: "In progress", category: "active" },
{ value: "done", label: "Done", category: "done" },
];
<StatusPicker statuses={statuses} value={task.status} onValueChange={(v) => save({ status: v })} />Examples
Workflow transitions
transitions lists the allowed next statuses. The others stay visible, disabled, with “Not allowed from Draft” as their description.
A field guide to GDPR consent banners
Last edited by Priya Raman · 12 min ago
Confirm with a note
confirm(next) returns an Alert Dialog config. requireNote asks for a reason; it arrives as meta.note in onValueChange.
Can Yıldız · Annual leave
Dec 22 – Jan 2 · 7 working days
Optimistic save
Return a promise from onValueChange: the badge switches at once with a spinner, then reverts if it rejects. onError is where you toast. color takes user-defined pipeline colours.
Fjord Freight · Fleet tracking
$48,000 ARR · closes Dec 15
Field trigger & states
trigger="field" for forms (name posts a native value). Small, disabled and read-only badges.
API
StatusPicker
| Prop | Type | Default |
|---|---|---|
statusesThe workflow's statuses, in order. | StatusDef[] | — |
valueControlled status. | string | null | — |
defaultValueInitial status (uncontrolled). | string | null | — |
onValueChangeReturn a promise for an optimistic save with revert. | (value, previous, { note }) => void | Promise | — |
transitionsAllowed next statuses per status. | Record<string, string[]> | — |
confirmAsk before a transition (title, description, requireNote, noteLabel, confirmLabel, tone). | (next, current) => false | StatusConfirm | — |
onErrorAfter a failed async save reverted. | (error, attempted) => void | — |
triggerBadge for tables and headers, field for forms. | "badge" | "field" | "badge" |
groupByCategoryGroup options under To do / In progress / Done / Cancelled. | boolean | true above 5 statuses |
fieldLabelUsed in the trigger's name: “Stage: Proposal sent. Change”. | string | "Status" |
sizeBadge / field size. | "sm" | "md" | "md" |
loadingExternal busy state. | boolean | — |
nameHidden native select for form posts. | string | — |
disabled / readOnlyRead-only renders a plain StatusBadge. | boolean | — |
labelsBuilt-in strings (namespace statusPicker), incl. the category headings. | Partial<StatusPickerLabels> | — |
StatusDef
| Prop | Type | Default |
|---|---|---|
value / labelStored value and display text (localise in your app). | string | — |
categoryDefault icon, tone and grouping. | "todo" | "active" | "done" | "cancelled" | — |
toneSemantic colour; default from the category. | "neutral" | "accent" | "success" | "warning" | "danger" | "info" | — |
colorAny CSS colour (user-defined stages). Overrides tone. | string | — |
iconReplace the category icon. | ReactNode | — |
descriptionSecond line in the list. | string | — |
StatusBadge
| Prop | Type | Default |
|---|---|---|
statusRenders a status without a picker (table cells, activity entries). | StatusDef | — |
sizeBadge size. | "sm" | "md" | "md" |