Skip to content
Brew

Example — Live search

A classic Brew flow: type in a search box, wait a short debounce, and re-render a filtered list without a full page reload.

package app.brew
import org.konaframework.brew.Component
import org.konaframework.brew.Computed
class Search : Component() {
var query = ""
@Computed
fun results(): List<String> =
BEANS.filter { query.isBlank() || it.contains(query.trim(), ignoreCase = true) }
override fun template() = """
<div class="card">
<h2>Search beans</h2>
<input
type="search"
wire:model.live.debounce.300ms="query"
placeholder="Try 'kona'"
>
<ul>
@foreach(results as bean)
<li wire:key="{{ bean }}">{{ bean }}</li>
@endforeach
</ul>
<p wire:loading wire:target="query">Searching…</p>
</div>
""".trimIndent()
companion object {
val BEANS = listOf(
"Kona Extra Fancy",
"Kona Peaberry",
"Ethiopia Yirgacheffe",
"Colombia Supremo",
"Sumatra Mandheling",
)
}
}
  1. wire:model.live.debounce.300ms updates query on the server 300ms after typing stops.
  2. @Computed results() recalculates on each request from current state.
  3. wire:key on each <li> keeps the morph stable when the list shrinks or grows.
  4. Optional wire:loading + wire:target="query" shows feedback during the round-trip.

Embed with <brew:search /> on any Crema page that already loads @brewScripts.

Brew.test("search")
.set("query", "kona")
.assertSee("Kona Extra Fancy")
.assertSee("Kona Peaberry")
.assertDontSee("Colombia Supremo")