defmodule MusicLibraryWeb.SearchComponents do @moduledoc """ Universal search modal and related components. """ use MusicLibraryWeb, :html import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1, record_cover: 1] alias MusicLibrary.Records.Record @doc """ Renders a search result item for records. ## Examples <.search_result_record record={record} /> """ attr :record, :map, required: true attr :type, :atom, required: true, values: [:collection, :wishlist] attr :rest, :global, include: ~w(phx-click phx-value-id) def search_result_record(assigns) do ~H"""
<.record_cover record={@record} class="w-12 h-12 rounded-md aspect-square object-cover" />

{@record.title}

{Record.artist_names(@record)}

{format_label(@record.format)} · {type_label(@record.type)} · {Record.format_release_date( @record.release_date )}

""" end @doc """ Renders a search result item for artists. ## Examples <.search_result_artist artist={artist} /> """ attr :artist, :map, required: true attr :rest, :global, include: ~w(phx-click phx-value-id) def search_result_artist(assigns) do ~H"""
{@artist.name} ~p"/images/cover-not-found.png" <> "';"} />

{@artist.name}

{@artist.disambiguation}

""" end @doc """ Renders a search result group with a title and items. ## Examples <.search_result_group title="Collection" count={3} total_count={10}> <.search_result_record :for={record <- @records} record={record} /> <:actions> """ attr :title, :string, required: true attr :count, :integer, required: true attr :total_count, :integer, default: nil attr :class, :string, default: "" slot :inner_block, required: true slot :actions, doc: "Actions like 'view all' buttons" def search_result_group(assigns) do ~H"""

{@title} @count}> {gettext("(%{count} of %{total})", count: @count, total: @total_count)} ({@count})

{render_slot(@inner_block)}
{render_slot(action)}
""" end @doc """ Renders a view all results button. ## Examples <.view_all_button count={25} target="collection" /> """ attr :count, :integer, required: true attr :target, :string, required: true attr :rest, :global, include: ~w(phx-click phx-value-query) def view_all_button(assigns) do ~H""" """ end @doc """ Renders keyboard shortcut hints. ## Examples <.results_footer /> """ attr :total_results, :integer, default: 0 def results_footer(assigns) do ~H"""
Esc {gettext("Close")}
0} class="text-zinc-500 dark:text-zinc-400"> {ngettext("1 result", "%{count} results", @total_results)}
""" end @doc """ Renders an empty search state. ## Examples <.empty_state /> """ def empty_state(assigns) do ~H"""
<.icon name="hero-magnifying-glass" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />

Cmd/Ctrl+K {gettext("to open this search")}

""" end @doc """ Renders a no results state. ## Examples <.no_results query="radiohead" /> """ attr :query, :string, required: true def no_results(assigns) do ~H"""
<.icon name="hero-face-frown" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />

{gettext("No results found for '%{query}'", query: @query)}

""" end end