defmodule VikWeb.CoreComponents do @moduledoc """ Provides core UI components. Icons are provided by [heroicons](https://heroicons.com). See `icon/1` for usage. """ use Phoenix.Component alias Phoenix.LiveView.JS @doc """ Renders flash notices. ## Examples <.flash kind={:info} flash={@flash} /> <.flash kind={:info} phx-mounted={show("#flash")}>Welcome Back! """ attr :id, :string, doc: "the optional id of flash container" attr :flash, :map, default: %{}, doc: "the map of flash messages to display" attr :title, :string, default: nil attr :kind, :atom, values: [:info, :error], doc: "used for styling and flash lookup" attr :rest, :global, doc: "the arbitrary HTML attributes to add to the flash container" slot :inner_block, doc: "the optional inner block that renders the flash message" def flash(assigns) do assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end) ~H"""
hide("##{@id}")} role="alert" class={["flash", "#{@kind}"]} {@rest} >

{@title}

{msg}

""" end @doc """ Shows the flash group with standard titles and content. ## Examples <.flash_group flash={@flash} /> """ attr :flash, :map, required: true, doc: "the map of flash messages" attr :id, :string, default: "flash-group", doc: "the optional id of flash container" def flash_group(assigns) do ~H"""
<.flash kind={:info} title={"Success!"} flash={@flash} /> <.flash kind={:error} title={"Error!"} flash={@flash} /> <.flash id="client-error" kind={:error} title="We can't find the internet" phx-disconnected={show(".phx-client-error #client-error")} phx-connected={hide("#client-error")} hidden > Attempting to reconnect <.flash id="server-error" kind={:error} title="Something went wrong!" phx-disconnected={show(".phx-server-error #server-error")} phx-connected={hide("#server-error")} hidden > Hang in there while we get back on track
""" end @doc """ Renders a button. ## Examples <.button>Send! <.button phx-click="go" class="action-button">Send! """ attr :type, :string, default: nil attr :class, :string, default: nil attr :rest, :global, include: ~w(disabled form name value) slot :inner_block, required: true def button(assigns) do ~H""" """ end @doc """ Renders an input with label and error messages. A `Phoenix.HTML.FormField` may be passed as argument, which is used to retrieve the input name, id, and values. Otherwise all attributes may be passed explicitly. ## Examples <.input field={@form[:email]} type="email" /> <.input name="my-input" errors={["oh no!"]} /> """ attr :id, :any, default: nil attr :name, :any attr :label, :string, default: nil attr :value, :any attr :type, :string, default: "text", values: ~w(text hidden) attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form, for example: @form[:email]" attr :errors, :list, default: [] attr :rest, :global, include: ~w(accept autocomplete capture cols disabled form list max maxlength min minlength multiple pattern placeholder readonly required rows size step) def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do errors = if Phoenix.Component.used_input?(field), do: field.errors, else: [] assigns |> assign(:errors, errors) |> assign(field: nil, id: assigns.id || field.id) |> assign_new(:name, fn -> field.name end) |> assign_new(:value, fn -> field.value end) |> input() end def input(assigns) do ~H"""
<.label for={@id}>{@label} <.error :for={{msg, _} <- @errors}>{msg}
""" end @doc """ Renders a label. """ attr :for, :string, default: nil slot :inner_block, required: true def label(assigns) do ~H""" """ end @doc """ Generates a generic error message. """ slot :inner_block, required: true def error(assigns) do ~H"""

<.icon name="hero-exclamation-circle-mini" /> {render_slot(@inner_block)}

""" end @doc """ Renders a [Heroicon](https://heroicons.com). Heroicons come in three styles – outline, solid, and mini. By default, the outline style is used, but solid and mini may be applied by using the `-solid` and `-mini` suffix. ## Examples <.icon name="hero-x-mark-solid" /> <.icon name="hero-arrow-path" /> """ attr :name, :string, required: true attr :class, :string, default: nil def icon(%{name: "hero-cloud"} = assigns) do ~H""" """ end def icon(%{name: "hero-server"} = assigns) do ~H""" """ end def icon(%{name: "hero-globe-alt"} = assigns) do ~H""" """ end def icon(%{name: "hero-x-mark-solid"} = assigns) do ~H""" """ end def icon(%{name: "hero-information-circle-mini"} = assigns) do ~H""" """ end def icon(%{name: "hero-exclamation-circle-mini"} = assigns) do ~H""" """ end def icon(%{name: "hero-arrow-path"} = assigns) do ~H""" """ end ## JS Commands @doc """ Same as `Phoenix.LiveView.JS.show/2`. Left here for backwards compatibility. """ def show(js \\ %JS{}, selector) do JS.show(js, to: selector) end @doc """ Same as `Phoenix.LiveView.JS.hide/2`. Left here for backwards compatibility. """ def hide(js \\ %JS{}, selector) do JS.hide(js, to: selector) end end