KQ-1637 · BRUSHED/WINDOWS

Brushed Windows

A density ribbon of a month of events above an event list, where dragging across the ribbon cuts a frosted window that follows the pointer 1:1 and you may cut as many as you need, overlapping cuts joining. On release the window's edges settle onto bin boundaries on springs.snap with the drag's velocity, its soft handles swell in on snap, a chip for it pops into the row below, and the list regroups on springs.glide with one heading per window while rows outside every window fold away. Handles resize and the body moves a window 1:1; touch starts a cut with a long press; the ribbon is a slider cursor whose Enter cuts a day, and a focused window moves with the arrows, resizes with Shift and goes with Delete.

KQ-1637 · BRUSHED/WINDOWS

Gaugeworks events

85 of 186 events

Left and Right move the cursor a bin, Page Up and Page Down a day. Enter cuts a one-day window at the cursor. On a window, the arrows move it, Shift with an arrow resizes its end, Alt and Shift its start, and Delete removes it.

Sep 18 12:00 – Sep 19 12:0052 events

  • 12:30Drift above 2%, warnBasin inlet
  • 12:40Temperature rising, warnGauge 7
  • 12:51Sensor offline, alertLine 5
  • 13:06Pressure high, alertWeir pump
  • 13:07Drift above 2%, warnGauge 14

Oct 3 00:00 – Oct 3 18:0033 events

  • 03:09Temperature rising, warnGauge 7
  • 03:25Valve stuck, alertNorth station
  • 03:48Battery low, warnNorth station
  • 04:04Drift above 2%, warnGauge 14
  • 04:23Flow drop, alertGauge 14

2 windows · 85 of 186 events · drag the ribbon to cut another

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/brushed-windows

Props

events
GaugeEvent[]
default defaultGaugeEvents
The events the ribbon counts and the list shows: { id, at, title, source, level: info | warn | alert }.
windows / defaultWindows
{ id?, start, end }[]
default — / defaultGaugeWindows
The cut windows in ms, controlled or initial; ids are assigned when missing.
onWindowsChange
(windows) => void
default —
Fires with every window, in time order and with ids, after a cut, move, resize, merge or removal.
now
number
default defaultGaugeNow
The end of the period in ms; the ribbon shows the days before it. Never read from the clock during render.
days
number
default 30
How many days the ribbon spans.
binSize
number
default 6
Hours per bin, 1 to 24: the ribbon's grain and the step windows snap to and keys move by.
frostLevel
number
default 0.5
How frosted a window's glass is, 0 (clear, tinted) to 1 (deep frost).
accent
string
default "var(--accent-bright)"
Windows, the density inside them, chips and the live count, any CSS colour.
maxWindows
number
default 6
Most windows at once; a cut past it replaces the oldest.
rowsPerWindow
number
default 5
Rows shown under each window's heading before Show all.
longPressMs
number
default 380
How long a touch must hold before it starts a window, so a swipe still scrolls.
status
"ready" | "loading" | "error"
default "ready"
Loading draws a skeleton ribbon and rows; error keeps the ribbon's shape with a Try again.
onRetry
() => void
default —
Try again was pressed after the events failed to load.
title
string
default "Gaugeworks events"
The heading over the ribbon and the surface's accessible name.
height
number
default 520
Height of the surface in px; the list scrolls inside it.
disabled
boolean
default false
No cutting, moving or removing; the surface dims.
className
string
default —
Classes for the outer surface.