KQ-1634 · SIEVE/STACK
Sieve Stack
Active filters stacked as layers above a work-order table, each applied to what survived the layers above it, so every bar shows exactly what its filter costs: the rows it lets through as a solid fill, the rows it removes as a shaded band, bare track for what earlier layers took. Switching a layer off collapses its band and the returning rows pour back down the stack, every layer beneath widening on springs.glide a stagger after the one above while the table admits them in a cascade; the switch thumb snaps on springs.snap. A grip drags a layer 1:1 with its neighbours sliding aside on glide and the release settling with the throw's velocity, and Alt+Arrow moves a layer from any of its controls while Delete removes it.
Work orders
9 of 64 pass
- Not done−23 · 36%41
- East crews' sites−18 · 44%23
- Priority high or urgent−13 · 57%10
- Due within 14 days−1 · 10%9
9 of 64 pass · not done costs 23
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/sieve-stack
Props
- filters / defaultFilters
- SieveFilter[]
- default — / defaultSieveFilters
- The filters in the order they are applied, controlled or initial: { id, label, field, op, value, active? } with op is, not, in, gte, lte or within (days from now).
- onFiltersChange
- (filters) => void
- default —
- Fires with every filter after a switch, reorder or removal.
- rows
- SieveRow[]
- default defaultSieveRows
- The records the stack sieves: { id, ...fields }.
- columns
- SieveColumn[]
- default defaultSieveColumns
- The table's columns: { id, header, kind?: code | text | tag | due, hideBelow?: none | sm | md | lg, sub? }.
- onToggle
- (id, active, filters) => void
- default —
- Fires from the switch or key that turned a layer on or off.
- onReorder
- (ids, filters) => void
- default —
- Fires from the drop or Alt+Arrow that moved a layer, with the new order.
- onRemove
- (id, filters) => void
- default —
- Fires from the button or Delete key that removed a layer.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the rows have arrived; the stack keeps its shape in every state.
- onRetry
- () => void
- default —
- Try again was pressed after the rows failed to load.
- bandStyle
- "hatch" | "tint" | "dashed"
- default "hatch"
- How the rows a layer removes are drawn: diagonal hatching, a flat wash, or a dashed outline.
- density
- "compact" | "cozy" | "roomy"
- default "cozy"
- Layer height (36, 44 or 52px; shorter on phones) and table row padding.
- palette
- "ink" | "cobalt" | "ember" | "moss"
- default "cobalt"
- The hue of the surviving fill and the removed band; ember and moss are fixed-lightness pigments so they read the same in both themes.
- pourStagger
- number
- default 70
- Delay per layer, ms, as returning rows pour down the stack.
- now
- number
- default defaultSieveNow
- Today in ms, for due dates and the within operator.
- title
- string
- default "Work orders"
- The heading over the stack and the surface's accessible name.
- itemLabel
- { one: string; other: string }
- default { one: "work order", other: "work orders" }
- What one row is called, in counts and announcements.
- height
- number
- default 520
- Height of the surface in px; the table scrolls inside it under a sticky header.
- disabled
- boolean
- default false
- No switching, moving or removing; the surface dims.
- className
- string
- default —
- Classes for the outer surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| filters / defaultFilters | SieveFilter[] | — / defaultSieveFilters | The filters in the order they are applied, controlled or initial: { id, label, field, op, value, active? } with op is, not, in, gte, lte or within (days from now). |
| onFiltersChange | (filters) => void | — | Fires with every filter after a switch, reorder or removal. |
| rows | SieveRow[] | defaultSieveRows | The records the stack sieves: { id, ...fields }. |
| columns | SieveColumn[] | defaultSieveColumns | The table's columns: { id, header, kind?: code | text | tag | due, hideBelow?: none | sm | md | lg, sub? }. |
| onToggle | (id, active, filters) => void | — | Fires from the switch or key that turned a layer on or off. |
| onReorder | (ids, filters) => void | — | Fires from the drop or Alt+Arrow that moved a layer, with the new order. |
| onRemove | (id, filters) => void | — | Fires from the button or Delete key that removed a layer. |
| status | "ready" | "loading" | "error" | "ready" | Whether the rows have arrived; the stack keeps its shape in every state. |
| onRetry | () => void | — | Try again was pressed after the rows failed to load. |
| bandStyle | "hatch" | "tint" | "dashed" | "hatch" | How the rows a layer removes are drawn: diagonal hatching, a flat wash, or a dashed outline. |
| density | "compact" | "cozy" | "roomy" | "cozy" | Layer height (36, 44 or 52px; shorter on phones) and table row padding. |
| palette | "ink" | "cobalt" | "ember" | "moss" | "cobalt" | The hue of the surviving fill and the removed band; ember and moss are fixed-lightness pigments so they read the same in both themes. |
| pourStagger | number | 70 | Delay per layer, ms, as returning rows pour down the stack. |
| now | number | defaultSieveNow | Today in ms, for due dates and the within operator. |
| title | string | "Work orders" | The heading over the stack and the surface's accessible name. |
| itemLabel | { one: string; other: string } | { one: "work order", other: "work orders" } | What one row is called, in counts and announcements. |
| height | number | 520 | Height of the surface in px; the table scrolls inside it under a sticky header. |
| disabled | boolean | false | No switching, moving or removing; the surface dims. |
| className | string | — | Classes for the outer surface. |