Stack a bar's readings, and stop widgets taking the phone sideways
A bar drew its nested reading on top of the outer one in --chart-5, which measures 2.53:1 against --primary and lost the 3:1 guideline for non-text. The readings now partition the fill end to end, up to three of them, in a token of their own: --primary-nested, the primary hue a few steps deeper, 3.14:1 light and 3.12:1 dark. It cannot also clear 3:1 against --muted — in dark those two are 5.82:1 apart and a colour 3:1 from both would need a 9:1 gap — so a segment is drawn inside a gutter of outer fill rather than ever bordering the track, which is what separates neighbours too, and what caps the count at three. A nested value larger than its outer used to spill onto the track; it is clamped. `inner` still reads as a single binding, so no dashboard needs migrating. On a phone, .widget-grid took its width from the widest thing any widget held — a truncating flex item still offers its whole unwrapped line as a min-content contribution — and a handful of widgets had no floor of their own: the uPlot legend is a table, a fieldset carries min-inline-size: min-content from the UA sheet, and buttons are whitespace-nowrap. Each is capped now. A widget's body scrolls rather than clipping, so long text stops painting over the title. Gauges and bars move between readings instead of jumping, and a segmented control slides one thumb rather than recolouring cells. The gauge arc is drawn whole and revealed by its dash, because `d` cannot be transitioned. UplotChart pushed new readings only when the point count changed, so once a rolling window was full a refetch left the old values on screen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uq8mtNb97A7praJLyeEYgs
This commit is contained in:
@@ -239,11 +239,16 @@ export function UplotChart({
|
||||
}
|
||||
}, [key, ready])
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: rebuilding the joined table is what the point count stands for.
|
||||
// Every render, deliberately. `plots` is rebuilt on every render in both
|
||||
// consumers, so no memo can hit, and any signature short of hashing shares
|
||||
// the blind spot a point count has: once a rolling window is full, a refetch
|
||||
// carrying different readings leaves the count where it was and never fires.
|
||||
// Safe to run this often because `setData` is idempotent and re-ranges the
|
||||
// scales *from the data* — the opposite of the `redraw(false)` below.
|
||||
useEffect(() => {
|
||||
if (!chart.current || plots.length === 0) return
|
||||
chart.current.setData(table(plots))
|
||||
}, [points, key])
|
||||
})
|
||||
|
||||
// The canvas cannot follow a CSS variable, so a theme swap is a redraw. The
|
||||
// paths are geometry and stay as they are — and leaving them alone is what
|
||||
@@ -272,8 +277,10 @@ export function UplotChart({
|
||||
) : null}
|
||||
</div>
|
||||
{/* Kept at the legend's resting height, so the plot does not resize
|
||||
under the pointer the first time a reading arrives. */}
|
||||
<div ref={legend} className="min-h-6 shrink-0" />
|
||||
under the pointer the first time a reading arrives. uPlot mounts a
|
||||
table here and a table cannot lay out below its min-content width, so
|
||||
the labels get their own scroller rather than widening the card. */}
|
||||
<div ref={legend} className="min-h-6 min-w-0 shrink-0 overflow-x-auto" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user