Style Reactively
Goal: animate or react to state in an element's inline style without re-rendering — a single CSS property, or a whole style object, driven by a stream.
The style prop accepts the Source vocabulary at any level: a property value can be a stream, and you can spread a stream of style objects. CSS transition composes naturally, because the renderer mutates the existing node in place.
import { h } from "@weftui/core";
import { Schedule, Stream } from "effect";
const AnimatedHue = () => {
const hue = Stream.iterate(0, (h) => (h + 2) % 360).pipe(
Stream.schedule(Schedule.spaced("50 millis")),
);
return h.div(
{
class: "demo-box",
style: {
// one property is reactive; the rest are static
backgroundColor: Stream.map(hue, (h) => `hsl(${h}, 70%, 60%)`),
transition: "background-color 0.05s",
},
},
"Hue",
);
};Three modes
- A single property as a stream — as above: one key's value is a
Stream, the others are static strings. Each stream property is subscribed independently. - A static object — an ordinary
style: { backgroundColor: "#667eea" }with no streams; nothing updates. - A whole style object as a stream — spread a stream that emits complete style objects, merged with static props:
const pulse = Stream.make(1, 0.5).pipe(
Stream.schedule(Schedule.spaced("800 millis")),
Stream.forever,
);
h.div({ style: { ...pulse, transition: "opacity 0.4s ease-in-out" } }, "Pulse");Each emitted object is merged with the static properties on the element.
Notes
- Property names are camelCase (
backgroundColor,boxShadow) — the same keys as the DOMstyleobject. - CSS transitions just work. Because a stream emission patches the DOM node directly (no re-render), the browser applies the
transitionas it would for any style mutation. - Pace with
Schedule.Stream.iterate/Stream.makepaced byStream.schedule(Schedule.spaced(…))and looped withStream.foreveris the idiom for time-based style animation; combine with any Effect timing you like.
See also
- Reactive Primitives — reactive style props and the
Sourcevocabulary - examples/reactive-styles — per-property and whole-object stream styles with CSS transitions