wire(subject, timing, coalesce, dom_opts). The
element-level .event and .prevent_default props are removed, along
with event_immediate() / event_throttle() / event_debounce() —
replaced by the pure timing shapes wire_immediate() /
wire_throttle(ms, leading) / wire_debounce(ms) (with coalesce
hoisted onto wire) and wire_dom_opts(prevent_default, stop_propagation, capture, passive). A bare handler/reactive in a slot
still works as sugar for wire(callable).value/checked binding with an explicit on* handler for the same
event (e.g. value = rv, onInput = ...) is an error; use
value = 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).iridExample() — run a shipped example app (mirroring shiny::runExample(),
source shown alongside via showcase mode by default). Called with no argument
it lists them; missing per-example dependencies are reported up front.
IridWidget() — wrap arbitrary JavaScript libraries (CodeMirror,
Plotly, Leaflet, ...) as reactive irid components. Props are
two-way-capable by default (symmetric with DOM value/checked): a
callable prop reads inbound and accepts write-back when the widget JS
calls setProp(key, value). Genuine notifications flow back via events
(sendEvent). Composes inside When, Each, and Match like any other
irid construct. See inst/examples/codemirror/app.R.
PlotlyOutput() — a plotly component built on IridWidget(). UI state
(axis ranges, drag mode, selection, trace visibility) is exposed as two-way
reactive props; discrete interactions (clicks, hovers, legend) are on*
callbacks. Data changes diff via Plotly.react(), preserving zoom, pan, and
selection. See inst/examples/plotly/app.R.
Per-item (Each) and per-case (Match) reactiveVals are now reclaimed on
unmount, rather than leaking until session end. make_scope feature-detects
shiny#4372's scoped-teardown
API at runtime: on a Shiny that carries it, scope$destroy() reclaims the
per-item / per-case observers and reactiveVals — plus any user
observe() in a component body. Pre-#4372 Shiny (including current CRAN) is
unchanged; no irid change is required at upgrade time.
Auto-bind: value and checked accept 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 explicit
on* handler on the same event, the auto-bind write always lands
first regardless of attribute order. Works on <input>, <textarea>,
<select> for value; checkboxes and radios for checked.
event_immediate() / event_throttle() / event_debounce() no longer
wrap a handler. They return a config used with the element-level
.event prop. 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))
.event takes a single config or a named list keyed by lowercase DOM
event for per-event overrides.
prevent_default moved off the event constructors onto the element as
.prevent_default. Logical scalar broadcasts; named list overrides per
event; unmapped events default to FALSE.
Each() redesigned. The callback receives a per-item callable (mini-
store for records, scalar accessor for atomics) and an optional pos.
Reconciliation moves to by: NULL (default) for positional, \(x) x$id for 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 of Match(). yes /
otherwise must be 0-arg functions returning tag trees; each
activation builds a fresh tree.
Index() removed. Covered by Each(items, fn) with default by = NULL.
reactiveProxy() — callable built from a get reader and optional
set writer for validation, transforms, and read-only views at
component boundaries.reactiveStore() — hierarchical reactive state container. Bare named
lists become navigable sub-nodes; everything else (including
I()-wrapped lists) is a reactiveVal leaf. Branch writes replace
and must list every locked key; node$key(value) is the single-slot
path.innerHTML is now a DOM property, so reactive writes hit the IDL
property directly.<span>
wrapper, so reactive text no longer adds spurious wrappers to the DOM.Initial release.
value directly to a reactiveVal for two-way
binding without update*Input() callbacksreactiveVals for
natural state sharingWhen(), Each(), Index(), Match()Output(), PlotOutput(), TableOutput(), DTOutput()event_immediate(), event_throttle(), event_debounce()iridOutput() / renderIrid(), or build
standalone apps with iridApp()