irid (development version)
Breaking changes
- Event and binding dispatch config now rides the slot it configures via a single carrier,
wire(subject, timing, coalesce, dom_opts). The element-level.eventand.prevent_defaultprops are removed, along withevent_immediate()/event_throttle()/event_debounce()— replaced by the pure timing shapeswire_immediate()/wire_throttle(ms, leading)/wire_debounce(ms)(withcoalescehoisted ontowire) andwire_dom_opts(prevent_default, stop_propagation, capture, passive). A bare handler/reactive in a slot still works as sugar forwire(callable). - A DOM event is now bound or handled, never both. Combining a
value/checkedbinding with an expliciton*handler for the same event (e.g.value = rv, onInput = ...) is an error; usevalue = reactiveProxy(get, set)for a synchronous write side-effect, or observe the bound reactive for an async reaction. Two explicit handlers on the same event also error (no composition).
New features
IridWidget()— wrap arbitrary JavaScript libraries (CodeMirror, Plotly, Leaflet, …) as reactive irid components. Props are two-way-capable by default (symmetric with DOMvalue/checked): a callable prop reads inbound and accepts write-back when the widget JS callssetProp(key, value). Genuine notifications flow back viaevents(sendEvent). Composes insideWhen,Each, andMatchlike any other irid construct. Seeexamples/codemirror.R.Per-item (
Each) and per-case (Match)reactiveVals are now reclaimed on unmount, rather than leaking until session end.make_scopefeature-detects shiny#4372’s scoped-teardown API at runtime: on a Shiny that carries it,scope$destroy()reclaims the per-item / per-case observers andreactiveVals — plus any userobserve()in a component body. Pre-#4372 Shiny (including current CRAN) is unchanged; no irid change is required at upgrade time.
irid 0.2.0
Breaking changes
Auto-bind:
valueandcheckedaccept any callable (reactiveVal, store leaf,reactiveProxy, plain function) and two-way bind automatically. Reads populate the IDL property; DOM events write back through the same callable. When auto-bind coexists with an expliciton*handler on the same event, the auto-bind write always lands first regardless of attribute order. Works on<input>,<textarea>,<select>forvalue; checkboxes and radios forchecked.-
event_immediate()/event_throttle()/event_debounce()no longer wrap a handler. They return a config used with the element-level.eventprop. Per-handler timing is gone:# OLD tags$input(value = field, onInput = event_debounce(\(e) field(e$value), ms = 500)) # NEW tags$input(value = field, .event = event_debounce(500)).eventtakes a single config or a named list keyed by lowercase DOM event for per-event overrides. prevent_defaultmoved off the event constructors onto the element as.prevent_default. Logical scalar broadcasts; named list overrides per event; unmapped events default toFALSE.Each()redesigned. The callback receives a per-item callable (mini- store for records, scalar accessor for atomics) and an optionalpos. Reconciliation moves toby:NULL(default) for positional,\(x) x$idfor keyed. In-place value changes update accessors without DOM recreation; keyed reorders move DOM nodes.Match()projects the bound value as a mini-store for the active case’s body (records) or the bare callable (scalars). Active-case change fully tears down the previous case and mounts the new one fresh.When()is a fixed-shape binary specialization ofMatch().yes/otherwisemust be 0-arg functions returning tag trees; each activation builds a fresh tree.Index()removed. Covered byEach(items, fn)with defaultby = NULL.
New features
-
reactiveProxy()— callable built from agetreader and optionalsetwriter for validation, transforms, and read-only views at component boundaries. -
reactiveStore()— hierarchical reactive state container. Bare named lists become navigable sub-nodes; everything else (includingI()-wrapped lists) is areactiveValleaf. Branch writes replace and must list every locked key;node$key(value)is the single-slot path. -
innerHTMLis now a DOM property, so reactive writes hit the IDL property directly.
irid 0.1.0
Initial release.
Features
- Reactive attributes and children — pass functions to any tag attribute or text child for fine-grained DOM updates without re-rendering
- Controlled inputs — bind
valuedirectly to areactiveValfor two-way binding withoutupdate*Input()callbacks - Composable components — plain functions that accept
reactiveVals for natural state sharing - Control flow primitives:
When(),Each(),Index(),Match() - Output bindings:
Output(),PlotOutput(),TableOutput(),DTOutput() - Event handling with
event_immediate(),event_throttle(),event_debounce() - Embed in existing Shiny apps via
iridOutput()/renderIrid(), or build standalone apps withiridApp() - Optimistic updates with sequence-number tracking
