defmodule Web.CoreComponents do @moduledoc """ Provides core UI components. """ use Phoenix.Component alias Phoenix.HTML.FormField attr :id, :any, default: nil attr :name, :any attr :label, :string, default: nil attr :value, :any attr :class, :string, default: nil attr :type, :string, default: "text", values: ~w[text password textarea datetime-local checkbox] attr :field, FormField attr :errors, :list, default: [] attr :rest, :global, include: ~w[disabled form pattern placeholder readonly required] def input(%{field: %FormField{} = field} = assigns) do errors = if Phoenix.Component.used_input?(field) do field.errors else [] end assigns |> assign( field: nil, id: assigns.id || field.id, errors: Enum.map(errors, &translate_error/1) ) |> assign_new(:name, fn -> field.name end) |> assign_new(:value, fn -> field.value end) |> input() end def input(%{type: "checkbox"} = assigns) do ~H"""
<.icon name="hero-exclamation-circle-mini" class="h-5 w-5 flex-none" /> {render_slot(@inner_block)}
""" end attr :name, :string, required: true attr :class, :string, default: nil def icon(%{name: "hero-" <> _} = assigns) do ~H""" """ end def translate_error({msg, opts}) do Enum.reduce(opts, msg, fn {key, value}, acc -> String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end) end) end def translate_errors(errors, field) when is_list(errors) do for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts}) end attr :type, :string, default: "button", values: ~w[button submit] attr :rest, :global slot :inner_block, required: true def button(assigns) do ~H""" """ end attr :format, :string, required: true attr :value, :any, default: nil attr :formatter, :atom, default: :default attr :timezone, :string, default: "America/New_York" attr :global, :global def timex(%{value: nil} = assigns) do ~H""" """ end def timex(%{value: value, timezone: timezone} = assigns) do assigns = assign_new(assigns, :local_value, fn -> case value do %DateTime{} = datetime -> datetime %NaiveDateTime{} = naive -> naive |> DateTime.from_naive!("Etc/UTC") |> DateTime.shift_zone!(timezone) end end) ~H""" """ end defp timex_formatter(formatter) do Module.concat(Timex.Format.DateTime.Formatters, :string.titlecase("#{formatter}")) end @doc """ Renders markdown content as HTML. ## Examples <.markdown content={@post.body} /> """ attr :content, :string, required: true attr :class, :string, default: "" def markdown(assigns) do ~H"""{col[:label]} | <% end %>
---|
{render_slot(col, item)} | <% end %>