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"""
"""
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"""
"""
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