Skip to content

Directives

Tova provides several JSX directives for common UI patterns. Directives are special attributes prefixed with a keyword followed by :.

on: — Event Handlers

Attach DOM event listeners:

tova
<button on:click={fn() count += 1}>Click</button>
<input on:input={fn(e) name = e.target.value} />

See Event Handlers and Event Modifiers for full documentation.

bind: — Two-Way Binding

Create two-way data bindings between form elements and signals:

DirectiveElementSignal Type
bind:value<input>, <textarea>, <select>String/Number
bind:checked<input type="checkbox">Boolean
bind:group<input type="radio/checkbox">String/Array
bind:thisAny elementRef object
tova
state name = ""
state agreed = false

<input bind:value={name} />
<input type="checkbox" bind:checked={agreed} />

See Two-Way Binding for full documentation.

class: — Conditional Classes

Toggle CSS classes based on expressions:

tova
<div class:active={is_active} class:hidden={not visible}>
  Content
</div>

Multiple class: directives merge with any static class attribute.

See Conditional Classes and the Styling guide for dynamic class expressions, match-based variants, and combining approaches.

show — Conditional Display

Toggle element visibility without removing from DOM:

tova
<div show={is_visible}>
  This content is hidden with display:none when is_visible is false
</div>

Unlike if blocks which add/remove elements from the DOM, show keeps the element in the DOM and toggles display: none. Use show when:

  • You want to preserve element state (form inputs, scroll position)
  • Toggling is frequent and you want to avoid re-rendering costs

use: — Actions

Run imperative code when an element is created. Actions are functions that receive the DOM element and an optional parameter:

tova
fn tooltip(el, text) {
  tip = document.createElement("div")
  tip.textContent = text
  tip.className = "tooltip"

  el.addEventListener("mouseenter", fn() {
    document.body.appendChild(tip)
  })
  el.addEventListener("mouseleave", fn() {
    tip.remove()
  })

  // Return lifecycle methods
  {
    update: fn(new_text) { tip.textContent = new_text },
    destroy: fn() { tip.remove() }
  }
}

<button use:tooltip="Hover for help">?</button>

Action Lifecycle

An action function is called with (element, parameter) when the element is created. It can return an object with:

  • update(newValue) — called when a reactive parameter changes
  • destroy() — called when the element is removed from the DOM

Reactive Parameters

When the parameter reads a signal, the action's update method is called whenever the signal changes:

tova
state tip_text = "Initial tooltip"

<button use:tooltip={tip_text}>?</button>

Multiple Actions

Multiple use: directives can be applied to the same element:

tova
<div use:draggable use:resizable={min_size}>
  Draggable and resizable
</div>

transition: — Animations

Apply CSS transitions when elements enter or leave the DOM:

tova
<div transition:fade>Fades in and out</div>
<div transition:slide={{duration: 300}}>Slides</div>

See Transitions for full documentation including directional and custom transitions.

in: / out: — Directional Transitions

Apply different transitions for entering and leaving:

tova
<div in:fade out:slide>
  Fades in, slides out
</div>

See Directional Transitions for full documentation.

Directive Summary

DirectivePurposeExample
on:eventEvent handleron:click={handler}
on:event.modEvent with modifieron:click.stop={handler}
bind:valueTwo-way text bindingbind:value={name}
bind:checkedTwo-way checkbox bindingbind:checked={flag}
bind:groupRadio/checkbox groupbind:group={selected}
bind:thisElement referencebind:this={ref}
class:nameConditional classclass:active={cond}
showToggle visibilityshow={visible}
use:actionElement actionuse:tooltip={text}
transition:nameEnter/leave animationtransition:fade
in:nameEnter-only animationin:fade
out:nameLeave-only animationout:slide

Released under the MIT License.