labb 0.5.0 is out

Events & bindings

Connect labb inputs and page events to signals with bind and Datastar data attributes.

After declaring a signal, connect it to the page with bind and data- attributes. labb forwards Datastar’s attributes to its components. The examples on this page run in the browser without a request to Django.

This example binds an input, reads a signal with data-text, changes it with data-on:click, and responds with data-show.

Hello,

<c-lbr.signals $open="false" $name="" />

<div class="flex flex-col gap-4 w-full md:w-96">

    <c-lb.input placeholder="Type your name" bind="$name" />
    <p class="text-sm">
        Hello, <span class="font-semibold" data-text="$name || 'stranger'"></span>
    </p>

    <c-lb.button btnStyle="soft" data-on:click="$open = !$open">
        <span data-text="$open ? 'Hide details' : 'Show details'"></span>
    </c-lb.button>

    <c-lb.alert variant="info" alertStyle="soft" data-show="$open">
        <span>These details are shown and hidden entirely in the browser.</span>
    </c-lb.alert>

</div>

Bind an input

The bind prop keeps a signal in sync with what the user types or selects.

<c-lbr.signals $filters.q="" />

<c-lb.input type="search" bind="$filters.q" placeholder="Search" />

filters.q now holds the search text. bind works with input, textarea, select, checkbox, toggle, and range. When you use a typed schema, bind through the field descriptor.

<c-lb.input type="search" :bind=signals.fields.q />

Responding to events

Use data-on:<event> for a short expression that runs on an event. Read and update signals with $.

<c-lbr.signals $open="false" />

<c-lb.button data-on:click="$open = !$open">Toggle</c-lb.button>

<div data-show="$open">Now you can see me.</div>

Inside a data-on expression, the event is evt and the element is el. Write both without $, which is reserved for signals.

Add a timing modifier with __.

<c-lb.input data-on:input__debounce.300ms="..." />
<div data-on:mousemove__throttle.50ms="$mx = evt.clientX"></div>

The data- attributes

These attributes cover most local interface changes. They work on any element after a c-lbr. component or reactive $ prop loads the runtime.

Attribute Does
data-show="$open" Shows or hides the element.
data-text="$label" Sets the element's text content.
data-class="{'active': $open}" Toggles classes. A key may hold several space-separated classes.
data-attr:href="$url" Sets any attribute reactively. data-attr:style, data-attr:disabled, and so on.

Use them for local toggles, tabs, and dropdowns. Use a server action when Django needs to own the change.

The search box, step two

Continuing the signals example, the input now binds to filters.q, a handler sets status, and Clear appears only when needed.

filters.q = ""
status = ""
<c-lbr.signals $filters.q="" $status="idle" />

<div class="flex flex-col gap-3 w-full max-w-sm">
    <c-lb.input
        type="search"
        bind="$filters.q"
        placeholder="Search customers"
        data-on:input="$status = $filters.q ? 'searching' : 'idle'"
    />

    <div class="rounded-lg bg-base-200/50 p-3 font-mono text-xs">
        filters.q = "<span data-text="$filters.q"></span>"<br>
        status = "<span data-text="$status"></span>"
    </div>

    <c-lb.button
        btnStyle="ghost"
        size="sm"
        class="self-start"
        data-show="$filters.q"
        data-on:click="$filters.q = ''; $status = 'idle'"
    >Clear</c-lb.button>
</div>

The example still runs entirely in the browser. Continue to Reactive props to let the signal drive the result badge.