Hold what a control sent until the engine confirms it
An input widget published over HTTP and read the result back over the socket, so between the two it drew the pre-publish value — a slider handle let go of visibly snapped back. usePublish now holds the sent value until the echo matches, the publish is refused, or 3 s pass, and every input widget (button, switch, slider, input, dropdown) draws that instead of the live value. A publish in flight pulses a primary ring over the tile: an absolutely positioned, inert overlay, so nothing resizes or shifts. A refusal drops the hold and toasts, naming the message. Success stays silent. The slider also draws its own scale — min, max and a few labelled stops that land on steps — replacing the unlabelled datalist marks that dropped out past fifty steps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018tULRZJUkZsw7rMJ3h4xvu
This commit is contained in:
@@ -72,12 +72,41 @@
|
||||
height: calc(var(--h) * 5rem + (var(--h) - 1) * 0.75rem);
|
||||
}
|
||||
|
||||
/*
|
||||
* A publish in flight, drawn as a ring just inside the tile's own edge.
|
||||
*
|
||||
* An overlay rather than anything the widget owns: it takes no layout box and
|
||||
* no clicks, so a control being used never resizes its tile or moves what sits
|
||||
* around it. Full opacity at rest, so a panel that asks for no motion still
|
||||
* gets the ring — the animation only breathes it.
|
||||
*/
|
||||
.widget-transmit {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: inset 0 0 0 2px var(--primary);
|
||||
}
|
||||
|
||||
/*
|
||||
* Motion. A value settling is a neutral state change; a selection indicator
|
||||
* moving is emphasized (Material). `<MotionConfig reducedMotion="user">` only
|
||||
* covers `motion/react`, so CSS asks for itself.
|
||||
*/
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
/* One beat per second, which reads as "on its way" from across a room
|
||||
without becoming the loudest thing in a browser tab. */
|
||||
.widget-transmit {
|
||||
animation: widget-transmit var(--duration-pulse) var(--ease-standard)
|
||||
infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes widget-transmit {
|
||||
from {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
/* The arc is the full 240 degrees and the dash hides the rest of it, so the
|
||||
reading changes by animating one number rather than re-pathing. */
|
||||
.widget-gauge-arc {
|
||||
|
||||
Reference in New Issue
Block a user