defmodule Corex.TextInput do @moduledoc ~S''' Text input component with Corex design and form field support. ## Examples ### Basic ```heex <.text_input id="name" name="user[name]" class="text-input"> <:label>Name ``` ### With form field ```heex <.text_input field={@form[:name]} class="text-input"> <:label>Name <:error :let={msg}> <.icon name="hero-exclamation-circle" class="icon" /> {msg} ``` ## Styling Use data attributes to target elements: ```css [data-scope="text-input"][data-part="root"] {} [data-scope="text-input"][data-part="label"] {} [data-scope="text-input"][data-part="input"] {} [data-scope="text-input"][data-part="error"] {} ``` Use the class `text-input` on the component for default Corex styling. ''' @doc type: :component use Phoenix.Component attr(:id, :string, required: false) attr(:name, :string, required: false) attr(:value, :any, default: nil) attr(:form, :string, required: false) attr(:errors, :list, default: [], doc: "List of error messages to display") attr(:class, :any, default: nil) attr(:field, Phoenix.HTML.FormField, doc: "A form field struct from the form, e.g. @form[:name]" ) attr(:rest, :global, include: ~w(autocomplete disabled maxlength minlength pattern placeholder readonly required cols list form) ) slot(:label, required: false) slot(:error, required: false) do attr(:class, :string, required: false) end def text_input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do errors = if Phoenix.Component.used_input?(field), do: field.errors, else: [] assigns = assigns |> assign(field: nil) |> assign(:errors, Enum.map(errors, &Corex.Gettext.translate_error(&1))) |> assign_new(:id, fn -> field.id end) |> assign_new(:name, fn -> field.name end) |> assign_new(:value, fn -> field.value end) |> assign_new(:form, fn -> field.form.id end) text_input(assigns) end def text_input(assigns) do assigns = assigns |> assign_new(:id, fn -> "text-input-#{System.unique_integer([:positive])}" end) ~H"""
{render_slot(@error, msg)}
""" end end