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.

KQ-1634 · SIEVE/STACK

Work orders

9 of 64 pass

  • Not done41
  • East crews' sites23
  • Priority high or urgent10
  • Due within 14 days9
9 work orders that pass every filter
OrderAssetDue
WO-2243Clarifier driveNorth Weir4d late
WO-2364Flow meter 7Basin Eastin 1d
WO-2601Clarifier driveNorth Weirin 3d
WO-2609Intake pump 2Basin Eastin 4d
WO-2644Chlorine doserBasin Eastin 7d
WO-2383Intake pump 2North Weirin 10d
WO-2391Clarifier driveNorth Weirin 12d
WO-2566Settling tank BNorth Weirin 12d
WO-2399Intake pump 2North Weirin 13d

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.