DSL
Elements, attributes, and children compose through one uniform apply. The Arg union
auto-lifts: String → text, Squawk[String] → reactive text, attr key + Squawk → reactive
attribute, Seq → flattened. Void elements (E.input, E.br) reject children at compile time.
Elements and attrs
{
E.label(
A.className("title"),
A.htmlFor("name"),
"Name",
)
}{
E.div(
E.input(A.`type`("text"), A.placeholder("draft")),
E.br(),
E.span("after break"),
)
}after break
Events
Ev.onClick hands you the typed platform event (dom.PointerEvent). For two-way binding there
is the platform-neutral Events.onInput / Events.onKeyDown with targetValue / key.
Handlers are ZIO effects. Use .sync (Ev.sync.onDragStart { … }) when the body must run on
the dispatch stack (preventDefault, drag-and-drop).
{
for draft <- sq("")
yield E.input(
A.value(draft),
Events.onInput(e => draft.set(e.targetValue.getOrElse(""))),
)
}ARIA
{
E.button(Aria.ariaLabel("Close"), Aria.role("button"), "×")
}