Cookbook / Counter

Counter

display

Minimal reactive counter — prop-backed count with increment/decrement/reset actions.

id
aihu-counter
since
0.5.0
file
aihu-counter.aihu
propactionon:clickinterpolation

Run it

live · runnable

The real, compiled aihu-counter.aihu component, hydrated as an island right here — fully interactive.

Source

aihu-counter.aihu
governedaihu-counter.aihuaihu961 B
// counter — prop count + action increment/decrement/reset

@state {
  let count = prop({ default: 0 })

  const increment = action(() => { count++ })
  const decrement = action(() => { count-- })
  const reset = action(() => { count = 0 })
}

@template {
  <section class="counter">
    <output class="count">{count}</output>
    <div class="controls">
      <button on:click={decrement} class="btn">−</button>
      <button on:click={reset} class="btn btn-ghost">Reset</button>
      <button on:click={increment} class="btn">+</button>
    </div>
  </section>
}

@style {
  .counter { display: grid; gap: 0.75rem; padding: 1.5rem; max-width: 14rem; }
  .count { font-size: 2.5rem; font-variant-numeric: tabular-nums; text-align: center; display: block; }
  .controls { display: flex; gap: 0.5rem; }
  .btn { flex: 1; padding: 0.5rem; cursor: pointer; border: 1px solid var(--border, #ccc); border-radius: 4px; }
  .btn-ghost { background: transparent; }
}

Requires

concerns
stateevents

Anti-patterns

  • Do not reach for state() when the value is part of the component's public surface — prop() makes it host-settable and attribute-visible.

Related recipes