KQ-618 · MERCHANT/LOCK
Merchant Lock
A card's spending rules, one row per merchant category. Locking a row closes the hasp on flick, dims the row on a colour tween and strikes its amount, so the state is carried by shape and text rather than tone alone; the allowed figure below sums every open category and rolls its digits to the new total on snap. The header control sweeps every row at once, staggered by cascade so a wall of locks closes in sequence.
KQ-618 · MERCHANT/LOCK
Where this card can spend
- Groceries
- Fuel
- Streaming
- Travel
- Dining
- Cash withdrawal
Alloweda month$706 a month2 of 6 locked
$706 a month allowed across 4 of 6 categories.
Allowed $706 a month · 2 of 6 categories locked
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/merchant-lock
Props
- categories
- MerchantCategory[]
- default six seeded rows
- The rows to draw: id, label, amount and an optional drawn glyph.
- locked / defaultLocked
- string[]
- default []
- Controlled or initial ids of the locked categories.
- onLockedChange
- (locked: string[], changed: { id: string; locked: boolean }) => void
- default —
- Fires from the click or key that toggled a lock; the id is "*" for the header sweep.
- format
- (value: number) => string
- default Intl.NumberFormat USD
- Formats every amount; the list never invents a currency.
- period
- string
- default "a month"
- Suffix on the row amounts and on the total.
- label
- string
- default "Where this card can spend"
- Visible heading, also the list's accessible name.
- showLockAll
- boolean
- default true
- Renders the header control that locks or opens every row.
- disabled
- boolean
- default false
- Locks the rules themselves; every switch goes inert.
| Prop | Type | Default | Description |
|---|---|---|---|
| categories | MerchantCategory[] | six seeded rows | The rows to draw: id, label, amount and an optional drawn glyph. |
| locked / defaultLocked | string[] | [] | Controlled or initial ids of the locked categories. |
| onLockedChange | (locked: string[], changed: { id: string; locked: boolean }) => void | — | Fires from the click or key that toggled a lock; the id is "*" for the header sweep. |
| format | (value: number) => string | Intl.NumberFormat USD | Formats every amount; the list never invents a currency. |
| period | string | "a month" | Suffix on the row amounts and on the total. |
| label | string | "Where this card can spend" | Visible heading, also the list's accessible name. |
| showLockAll | boolean | true | Renders the header control that locks or opens every row. |
| disabled | boolean | false | Locks the rules themselves; every switch goes inert. |