Radiant0.3.0-rc.5

@bindTo

@bindTo patches attributes, boolean attributes, DOM properties, or text on nodes that already exist. Use it on authored light-DOM hosts and catalog shells where the parent (or a view helper) owns the markup.

It does not create nodes, move children, or attach event listeners. For those jobs use composition helpers, @onEvent, and @onUpdated.

Usage

import { RadiantElement, bindTo, customElement, prop } from '@ecopages/radiant';
 
@customElement('rui-dialog')
export class RuiDialog extends RadiantElement {
	@prop({ type: Boolean, reflect: true, defaultValue: false })
	@bindTo({ ref: 'root', bool: 'hidden', invert: true })
	open = false;
}

Omit ref / selector to patch the host element itself (this on RadiantElement, this.element on RadiantController).

One value, several writes

Pass an array to fan one field out to several DOM facts:

@prop({ type: Boolean, defaultValue: false })
@bindTo([
	{ selector: '[data-disclosure-trigger]', attr: 'aria-expanded' },
	{ selector: '[data-disclosure-panel]', attr: 'data-state', map: (open) => (open ? 'open' : 'closed') },
])
open = false;

Parameters

Each target sets exactly one of attr, bool, prop, or text. ref and selector are mutually exclusive. A target that violates that throws when the decorator is applied.

ParameterTypeRequiredDescription
refstringNodata-ref of a descendant. Omit both ref and selector to patch the host.
selectorstringNoCSS selector of a descendant.
attrstringOne write kindsetAttribute / removeAttribute (null/undefined removes).
boolstringOne write kindtoggleAttribute from a boolean value.
propstringOne write kindDOM property write (input.value, meter.value).
texttrueOne write kindtextContent.
inverttrueNoNegate the value before writing (openhidden).
map(value: T) => unknownNoTransform the value before writing. T is the decorated field; do not annotate the parameter.

Missing descendants are skipped. A field that is not @prop, @state, or @signal is skipped too. The first paint runs after attribute catch-up (and the initial render() / hydrate() when the host owns a view), so parent-authored data-ref nodes are visible.

A target with no write kind is a type error. Two write kinds, or both ref and selector, still typecheck — excess-property checking against the union treats a key on any member as known — and throw TypeError when the decorator is applied.

What not to put on @bindTo

JobUse
Click, keydown, Escape@onEvent
Focus trap, timers, joined aria-describedby@onUpdated
Host-owned JSX leavesthis.$ inside render()
Replaceable title / icon / chromeView helpers and {children ?? default}

Unrelated fields stay on separate @bindTo declarations. Branching (if (this.animated)) stays in a method.

Learn More