astwerk

Attribute bindings

Everything a value can do to an element: x.Attr, x.Class, x.Disabled and x.Style. Each one owns its property — use the buttons to change the signals and watch each element update on its own, nothing else re-renders.

templ.guide

a toggled class

styled text

How it works

State

templ
var BURL    = x.NewSignal("https://templ.guide")
var BActive = x.NewSignal(true)
var BBusy   = x.NewSignal(false)
var BColour = x.NewSignal("#4f7cff")

One signal per property the demo touches: the link target, the class, the disabled flag and the colour.

The elements

templ
<p>@x.El("a", x.Attr("href", BURL)) { templ.guide }</p>
<p>@x.El("span", x.Class("on", BActive)) { a toggled class }</p>
<p>@x.El("button", x.Disabled(BBusy)) { save }</p>
<p>@x.El("span", x.Style("color", BColour)) { styled text }</p>

Each binding owns one property of one element. x.Attr sets a string attribute and removes it when empty; x.Class toggles one class; x.Disabled toggles the boolean attribute — present or absent, not true or false; x.Style sets one CSS property through style.setProperty.

The buttons

templ
<div class="counter-row">
	@x.El("button", x.On("click", BActive.Set(x.Not(BActive)))) {
		toggle class
	}
	@x.El("button", x.On("click", BBusy.Set(x.Not(BBusy)))) {
		toggle disabled
	}
	@x.El("button", x.On("click", BColour.Set(x.Lit("#ff4f7c")))) {
		recolour
	}
	@x.El("button", x.On("click", BURL.Set(x.Lit("https://pkg.go.dev/github.com/LukasDerBaum42/astwerk")))) {
		retarget link
	}
</div>

Each button writes its signal with an action built from combinators: x.Not toggles, x.Lit stores a constant. Because each binding owns its property, changing one signal updates exactly that element's property — nothing else re-renders.

Full source
templ
var BURL    = x.NewSignal("https://templ.guide")
var BActive = x.NewSignal(true)
var BBusy   = x.NewSignal(false)
var BColour = x.NewSignal("#4f7cff")

templ XBindingsDemo() {
	<div class="demo">
		<p>@x.El("a", x.Attr("href", BURL)) { templ.guide }</p>
		<p>@x.El("span", x.Class("on", BActive)) { a toggled class }</p>
		<p>@x.El("button", x.Disabled(BBusy)) { save }</p>
		<p>@x.El("span", x.Style("color", BColour)) { styled text }</p>
		<div class="counter-row">
			@x.El("button", x.On("click", BActive.Set(x.Not(BActive)))) {
				toggle class
			}
			@x.El("button", x.On("click", BBusy.Set(x.Not(BBusy)))) {
				toggle disabled
			}
			@x.El("button", x.On("click", BColour.Set(x.Lit("#ff4f7c")))) {
				recolour
			}
			@x.El("button", x.On("click", BURL.Set(x.Lit("https://pkg.go.dev/github.com/LukasDerBaum42/astwerk")))) {
				retarget link
			}
		</div>
	</div>
}

// On the page: @x.Document(XBindingsDemo())
How the static value renders

Every binding renders its current value into the HTML at build time — the page reads correctly with JavaScript disabled — and subscribes to the signal for updates.