Fluxon.Components.Input (Fluxon v2.0.0)
Provides <.input>
and <.input_group>
components for flexible text input fields.
This module offers a versatile <.input>
component for various text entry needs,
including standard text fields, search bars, and specialized inputs like password
or email fields. It supports multiple size variants, integration with Phoenix forms,
and a system for adding prefix and suffix content both inside and outside the
input field.
It also includes an <.input_group>
component to visually group multiple related
inputs or controls together.
Basic Usage
Render simple input fields by providing a name
. A label
is recommended for accessibility.
<.input name="username" label="Username" placeholder="Enter username..." />
<.input name="password" type="password" label="Password" />
<.input name="email" type="email" label="Email" />
Size Variants
The component offers five size variants (xs
, sm
, md
, lg
, xl
) using the size
attribute.
The default size is md
.
<.input name="input_xs" size="xs" placeholder="Extra Small" />
<.input name="input_sm" size="sm" placeholder="Small" />
<.input name="input_md" size="md" placeholder="Medium (Default)" />
<.input name="input_lg" size="lg" placeholder="Large" />
<.input name="input_xl" size="xl" placeholder="Extra Large" />
Labels, Helper Text & Descriptions
Use label
, sublabel
, description
, and help_text
attributes to provide context
and guidance for the input field.
<.input
name="full_example_md"
label="Email Address"
sublabel="(required)"
description="We'll send a confirmation link here."
size="md"
help_text="We never share your email."
placeholder="you@example.com"
/>
Form Integration
The input component offers two ways to handle form data: using the field
attribute for Phoenix form integration
or using the name
attribute for standalone inputs. Each approach has its own benefits and use cases.
Using with Phoenix Forms (Recommended)
When working with Phoenix forms, use the field
attribute to bind the input to a form field:
<.form :let={f} for={@form}>
<.input field={f[:email]} type="email" label="Email" />
<.input field={f[:password]} type="password" label="Password" />
</.form>
Using the field
attribute provides several advantages:
- Automatic value handling from the form data
- Built-in error handling and validation messages
- Proper form submission with correct field names
- Integration with changesets for data validation
- Automatic ID generation for accessibility
- Proper handling of nested form data
The component will automatically:
- Set the input's name based on the form structure
- Display the current value from the form data
- Show validation errors when present
- Handle nested form data with proper input naming
Using Standalone Inputs
For simpler cases or when not using Phoenix forms, use the name
attribute:
<.input name="search" placeholder="Search..." />
<.input name="email" type="email" value={@email} errors={@errors} />
When using standalone inputs:
- You must provide the
name
attribute - Values must be managed manually via the
value
attribute - Errors must be passed explicitly via the
errors
attribute - Form submission handling needs to be implemented manually
- Nested data requires manual name formatting (e.g.,
user[email]
)
When to Use Each Approach
Use the field
attribute when:
- Working with changesets and data validation
- Handling complex form data structures
- Need automatic error handling
- Building CRUD interfaces
Use the name
attribute when:
- Building simple search inputs
- Creating standalone filters
- Handling one-off form controls
- Need more direct control over the input behavior
Input States (Disabled, Readonly, Errors)
Control input interactivity and feedback using boolean attributes and the errors
list.
# Disabled input (cannot be focused or edited)
<.input name="disabled_input" value="Cannot change" disabled />
# Readonly input (can be focused but not edited)
<.input name="readonly_input" value="Readonly value" readonly />
# Input with errors (displays error messages below)
<.input name="error_input" value="invalid@" errors={["Must be a valid email."]} />
# Disabled via fieldset
<fieldset disabled>
<.input name="fieldset_disabled" value="Inherits disabled state" />
</fieldset>
Input Types
Supports standard HTML input types via the type
attribute.
<.input type="date" name="date_input" label="Appointment Date" />
<.input type="time" name="time_input" label="Start Time" />
<.input type="number" name="count" label="Quantity" min="1" max="10" />
<.input type="search" name="site_search" placeholder="Search site..." />
Inner Affixes
Use the :inner_prefix
and :inner_suffix
slots to add content inside the input's border.
Useful for icons, text hints, or small controls like password visibility toggles.
# Email input with icon prefix
<.input name="email_icon" placeholder="user@example.com">
<:inner_prefix>
<.icon name="hero-at-symbol" class="icon" />
</:inner_prefix>
</.input>
# Password with visibility toggle suffix
<.input name="password_toggle" type="password" value="secretpassword">
<:inner_suffix>
<.button variant="tertiary" size="icon-sm" title="Show password">
<.icon name="hero-eye" class="icon" />
</.button>
</:inner_suffix>
</.input>
# URL input with static text prefix
<.input name="url_prefix" placeholder="yourdomain.com">
<:inner_prefix class="pointer-events-none text-tertiary">https://www.</:inner_prefix>
</.input>
# Input with loading indicator suffix
<.input name="search_loading" placeholder="Searching..." disabled>
<:inner_suffix>
<.loading variant="ring-bg" />
</:inner_suffix>
</.input>
Outer Affixes
Use the :outer_prefix
and :outer_suffix
slots to add content outside the input's border.
Ideal for buttons, select dropdowns, or static text labels that shouldn't be part of the input value.
# Invite email with send button suffix
<.input name="invite_user" placeholder="user@example.com">
<:inner_prefix>
<.icon name="hero-at-symbol" class="icon" />
</:inner_prefix>
<:outer_suffix>
<.button variant="solid" color="primary">
<.icon name="hero-paper-airplane" class="icon" /> Invite
</.button>
</:outer_suffix>
</.input>
# Currency input with dropdown prefix and button suffix
<.input name="currency_amount" placeholder="100.00">
<:inner_prefix>$</:inner_prefix>
<:outer_prefix>
<select class="h-full w-full rounded-l-lg border-none focus:ring-0 px-2">
<option value="USD">USD</option>
<option value="CAD">CAD</option>
</select>
</:outer_prefix>
<:outer_suffix>
<.button variant="soft" color="primary">Check Balance</.button>
</:outer_suffix>
</.input>
# Website URL input with fixed prefix and suffix
<.input name="website_full_url" placeholder="mysite">
<:outer_prefix class="px-2 text-tertiary">https://</:outer_prefix>
<:outer_suffix class="px-2 text-tertiary">.example.com</:outer_suffix>
</.input>
# Weight input with unit suffix
<.input name="weight_input" type="number" placeholder="50">
<:outer_suffix class="px-2 text-tertiary">kg</:outer_suffix>
</.input>
Button Size Matching
When using buttons within
outer_prefix
orouter_suffix
slots, ensure the button'ssize
matches the input'ssize
for proper alignment. For example, if the input issize="lg"
, use a button withsize="lg"
as well.
Input Groups
Use the <.input_group>
component to visually combine multiple inputs or related
controls (like buttons or selects) into a single, seamless unit. It automatically
adjusts borders and rounding for elements placed within its default slot.
# Grouping first and last name inputs
<.input_group label="Full Name">
<.input name="first_name" placeholder="First Name" />
<.input name="last_name" placeholder="Last Name" />
</.input_group>
# Grouping inputs with a separator element
<.input_group label="Price Range">
<.input name="min_price" placeholder="Min price">
<:inner_prefix>$</:inner_prefix>
</.input>
<div class="shrink-0 bg-emphasis border-y border-base shadow-xs self-stretch flex items-center justify-center px-2 text-foreground-softest">
to
</div>
<.input name="max_price" placeholder="Max price">
<:inner_prefix>$</:inner_prefix>
</.input>
</.input_group>
# Grouping an input with action buttons
<.input_group>
<.input name="grouped_action_1" placeholder="Action 1...">
<:outer_prefix>
<.button variant="soft" color="primary">Go</.button>
</:outer_prefix>
</.input>
<.input name="grouped_action_2" placeholder="Action 2...">
<:outer_suffix>
<.button variant="solid" color="primary">Submit</.button>
</:outer_suffix>
</.input>
</.input_group>
# Grouping payment card details
<.input_group>
<.input name="card_number" placeholder="Card Number">
<:inner_prefix><.icon name="hero-credit-card" class="icon" /></:inner_prefix>
</.input>
<.input name="expiry" placeholder="MM / YY" size="sm" class="w-24" />
<.input name="cvc" placeholder="CVC" size="sm" class="w-20" />
</.input_group>
# Grouping inputs of different sizes (maintains alignment)
<.input_group>
<.input name="group_lg_1" size="lg" placeholder="Username" />
<.input name="group_lg_2" size="lg" placeholder="Code">
<:outer_suffix>
<.button variant="soft" color="primary" size="lg">Verify</.button>
</:outer_suffix>
</.input>
</.input_group>
Summary
Components
Renders a flexible input field with support for various types, sizes, affixes, and form integration.
Renders a set of input elements to visually group them together.
Components
Renders a flexible input field with support for various types, sizes, affixes, and form integration.
This component handles the rendering of the <input>
element itself, along with its surrounding
label, help text, error messages, and any provided prefix/suffix content via slots.
Attributes
id
(:any
) - Sets the HTMLid
attribute for the input element. Defaults tonil
, in which case an ID is automatically generated if needed (e.g., when alabel
is provided or when used with afield
). If integrating with aPhoenix.HTML.Form
via thefield
attribute, the ID is derived from the field.Defaults to
nil
.label
(:string
) - The text content for the input's<label>
. The label is associated with the input via thefor
attribute, using the input'sid
.Defaults to
nil
.sublabel
(:string
) - Optional text displayed inline next to the mainlabel
. Useful for short hints like "Optional". Defaults tonil
.help_text
(:string
) - Optional descriptive text displayed below the input field to provide guidance or clarification. Defaults tonil
.description
(:string
) - Optional text displayed below thelabel
but above the input field. Suitable for more detailed explanations about the input's purpose.Defaults to
nil
.class
(:any
) - Additional CSS classes to apply directly to the input's wrapping<label data-part="field">
element. Allows for custom styling or layout adjustments of the core input container.Defaults to
nil
.size
(:string
) - Defines the visual size (height, padding, font size) of the input field. Available options are:"xs"
,"sm"
,"md"
(default),"lg"
,"xl"
.Defaults to
"md"
.disabled
(:boolean
) - Iftrue
, disables the input field, preventing user interaction and applying disabled styles. Defaults tofalse
.field
(Phoenix.HTML.FormField
) - APhoenix.HTML.FormField
struct, typically obtained from a form binding (e.g.,f[:email]
). When provided, the input'sname
,id
,value
, anderrors
are automatically derived from this struct, simplifying form integration.value
(:any
) - The value attribute for the input element. This is required when not using thefield
attribute and you need to control the input's value. Iffield
is provided, this attribute is ignored in favor offield.value
.name
(:any
) - The name attribute for the input element. Required when not using thefield
attribute. Iffield
is provided, this attribute is ignored in favor offield.name
.errors
(:list
) - A list of error messages (strings) to display below the input. If thefield
attribute is used, errors are automatically extracted fromfield.errors
. This attribute is useful for displaying errors for standalone inputs.Defaults to
[]
.type
(:string
) - Sets thetype
attribute of the HTML<input>
element (e.g.,"text"
,"password"
,"email"
). Defaults to"text"
.Defaults to
"text"
.Global attributes are accepted. Passes any additional HTML attributes supported by the
<input>
element (e.g.,placeholder
,required
,maxlength
). Supports all globals plus:["accept", "autocomplete", "capture", "cols", "form", "list", "max", "maxlength", "min", "minlength", "pattern", "placeholder", "readonly", "required", "rows", "size", "step"]
.
Slots
inner_prefix
- Content placed inside the input field's border, before the text entry area. Ideal for icons or short textual prefixes (e.g., '$', 'https://'). Can be used multiple times.Accepts attributes:class
(:any
) - CSS classes for styling the inner prefix container.
outer_prefix
- Content placed outside and before the input field. Useful for buttons, dropdowns, or other interactive elements associated with the input's start. Can be used multiple times.Accepts attributes:class
(:any
) - CSS classes for styling the outer prefix container.
inner_suffix
- Content placed inside the input field's border, after the text entry area. Suitable for icons, clear buttons, or password visibility toggles. Can be used multiple times.Accepts attributes:class
(:any
) - CSS classes for styling the inner suffix container.
outer_suffix
- Content placed outside and after the input field. Useful for action buttons (e.g., 'Send', 'Search') or other controls related to the input's end. Can be used multiple times.Accepts attributes:class
(:any
) - CSS classes for styling the outer suffix container.
Renders a set of input elements to visually group them together.
This component adjusts the styling (borders, rounding) of its direct <.input>
children to make them appear as a single, connected unit. It also provides attributes
for adding a label, description, and help text for the group as a whole.
Size Consistency
All inputs within the group should have the same
size
attribute value (e.g., all"lg"
or all"md"
). Using inputs with different sizes will break the visual cohesion and border connections between elements.
Examples
<.input_group label="Login Credentials">
<.input name="email" placeholder="Email" size="lg" />
<.input name="password" type="password" placeholder="Password" size="lg" />
</.input_group>
Attributes
class
(:any
) - Additional CSS classes applied to the outermostdiv
wrapping the input group elements (thediv
withdata-part="input-group"
). Allows for custom layout or spacing of the group itself, distinct from the label/help text container.Defaults to
nil
.label
(:string
) - The primary label text displayed above the entire input group. Defaults tonil
.sublabel
(:string
) - Optional text displayed inline next to the group's mainlabel
. Defaults tonil
.description
(:string
) - Optional descriptive text displayed below the grouplabel
but above the grouped input elements. Defaults tonil
.help_text
(:string
) - Optional help text displayed below the grouped input elements. Defaults tonil
.
Slots
inner_block
(required) - The content of the input group, typically one or more<.input>
,<.select>
, or<.button>
components that should be visually joined together.