Form-aware text input component integrating with Phoenix.HTML.FormField.
phia_input/1 renders a labeled <input> element with optional description
text and inline validation error messages sourced directly from the Ecto
changeset. It is the building block for text-based form fields in PhiaUI.
When to use
Use phia_input/1 whenever you need a single-line text, email, password,
number, or URL input that is bound to an Ecto changeset field. For multi-line
text, use phia_textarea/1 instead. For select dropdowns, use phia_select/1.
Basic usage
<.form for={@form} phx-submit="save" phx-change="validate">
<.phia_input field={@form[:email]} label="Email address" />
<.phia_input field={@form[:password]} type="password" label="Password" />
<.button type="submit">Sign in</.button>
</.form>With description and debounce
The :description attribute renders helper text below the label. Combine with
phx-debounce to avoid validating on every keystroke:
<.phia_input
field={@form[:username]}
label="Username"
description="3–20 characters. Letters, numbers, and underscores only."
phx-debounce="blur"
/>Number input with constraints
<.phia_input
field={@form[:age]}
type="number"
label="Age"
min="18"
max="120"
placeholder="Your age"
/>File input
<.phia_input field={@form[:avatar]} type="file" label="Profile picture" />Read-only / disabled
<.phia_input field={@form[:email]} label="Email" readonly />
<.phia_input field={@form[:plan]} label="Plan" disabled />Error handling
Errors are read directly from field.errors — a list of {msg, opts} tuples
produced by Ecto's changeset validation. They are interpolated via the built-in
translate_error/1 which substitutes %{key} placeholders from opts.
For Gettext-aware translations, translate the errors before passing the field
or replace translate_error/1 after ejection:
# After `mix phia.eject Input`, customise lib/my_app_web/components/input.ex:
defp translate_error({msg, opts}) do
Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
endClass customisation
Pass :class to merge additional Tailwind classes into the input via cn/1.
The last-wins merge strategy means your classes override the defaults:
<.phia_input field={@form[:code]} label="Code" class="font-mono tracking-widest" />
Summary
Functions
Renders a labeled text input integrated with Phoenix.HTML.FormField.
Functions
Renders a labeled text input integrated with Phoenix.HTML.FormField.
Produces a <div> containing:
- An optional
<label>linked viafor/id - An optional description
<p>in muted foreground - The
<input>element with full Tailwind styling and focus ring - One
<p class="text-destructive">per changeset error
The input ID, name, and value are derived from the field struct automatically.
When field.errors is non-empty, the input gains a destructive border and focus
ring to give an immediate visual error signal alongside the error text below.
Examples
<%!-- Minimal — label from the field struct --%>
<.phia_input field={@form[:email]} label="Email" />
<%!-- With placeholder and debounce --%>
<.phia_input
field={@form[:email]}
label="Email"
placeholder="you@example.com"
phx-debounce="blur"
/>
<%!-- Password field --%>
<.phia_input field={@form[:password]} type="password" label="Password" />
<%!-- Number with range constraints --%>
<.phia_input field={@form[:quantity]} type="number" label="Quantity" min="1" max="99" />
<%!-- Custom class override --%>
<.phia_input field={@form[:code]} label="Invite code" class="uppercase font-mono" />Attributes
field(Phoenix.HTML.FormField) (required) - APhoenix.HTML.FormFieldstruct, typically obtained via@form[:field_name]inside aPhoenix.Component.form/1block. Provides the inputid,name,value, anderrorsautomatically.label(:string) - Text rendered in a<label>element above the input. The label is associated with the input viafor/idso clicking it focuses the input. Whennil, no label element is rendered — useful when the label is provided externally.Defaults to
nil.description(:string) - Helper text rendered below the label but above the input. Use it to explain format requirements, constraints, or privacy notes. Rendered intext-muted-foregroundto visually separate it from the label.Defaults to
nil.type(:string) - HTML<input>type attribute. Common values:"text"(default),"email","password","number","url","tel","search","file","date". The component passes this value unchanged to the native element.Defaults to
"text".class(:string) - Additional Tailwind CSS classes applied to the<input>element. Merged viacn/1so conflicting utilities are resolved by last-wins. Example:class="font-mono"to render a monospace code input.Defaults to
nil.Global attributes are accepted. Additional HTML attributes forwarded directly to the
<input>element. Commonly used attributes include:autocomplete— browser autocomplete hint (e.g."email","new-password")placeholder— ghost text shown when the field is emptyphx-debounce— delay (ms) or"blur"before sendingphx-changeeventsreadonly— prevents editing without disabling form submissiondisabled— disables the input entirelymin/max/step— numeric constraints fortype="number"inputs Supports all globals plus:["autocomplete", "readonly", "disabled", "step", "max", "min", "placeholder", "phx-debounce"].