PhiaUi.Components.Input (phia_ui v0.1.17)

Copy Markdown View Source

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)
end

Class 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

phia_input(assigns)

Renders a labeled text input integrated with Phoenix.HTML.FormField.

Produces a <div> containing:

  1. An optional <label> linked via for/id
  2. An optional description <p> in muted foreground
  3. The <input> element with full Tailwind styling and focus ring
  4. 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) - A Phoenix.HTML.FormField struct, typically obtained via @form[:field_name] inside a Phoenix.Component.form/1 block. Provides the input id, name, value, and errors automatically.

  • label (:string) - Text rendered in a <label> element above the input. The label is associated with the input via for/id so clicking it focuses the input. When nil, 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 in text-muted-foreground to 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 via cn/1 so 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 empty
    • phx-debounce — delay (ms) or "blur" before sending phx-change events
    • readonly — prevents editing without disabling form submission
    • disabled — disables the input entirely
    • min / max / step — numeric constraints for type="number" inputs Supports all globals plus: ["autocomplete", "readonly", "disabled", "step", "max", "min", "placeholder", "phx-debounce"].