"""
end
attr :item, :string, required: true
def item(assigns) do
~H"""
{@item}
"""
end
@impl StarView
def handle_event("search", %{"query" => query} = signals, conn) do
conn
|> signal(:results, get_items(query))
|> maybe_patch_list(signals)
end
def handle_event("reset", signals, conn) do
conn
|> signal(:query, "")
|> signal(:results, @items)
|> maybe_patch_list(signals)
end
defp get_items(""), do: @items
defp get_items(query) do
search_query = String.trim(String.downcase(query))
Enum.filter(@items, &String.contains?(&1 |> String.downcase(), search_query))
end
# We use this to make the response as light as possible
# Compared to LiveView which does this automatically with change tracking
defp maybe_patch_list(%{assigns: %{results: x}} = conn, %{"results" => x}), do: conn
defp maybe_patch_list(conn, _signals), do: patch_element(conn, &item_list/1)
# JS helpers - for optimistic updates
defp starts_with?(item) do
"#{item}.trim().toLowerCase().startsWith($query.trim().toLowerCase())"
end
defp query_results(condition) do
"$results.filter(x => #{starts_with?("x")}).length #{condition}"
end
end