Mask Input
v0.0.10
mix mishka.ui.gen.headless mask_input
Overview of the Phoenix and LiveView Headless Mask Input Component
The Mishka Chelekom Headless Mask Input is a Phoenix function component that renders one text input and formats what the user types to a pattern, such as a phone number or a date. The MaskInput JS hook re-masks the value on every keystroke, before the LiveView phx-change handler reads it, so the server always receives the masked text. The component ships no styling. Its classes come from class.
The pattern is the mask attribute. 9 accepts a digit, a a letter and * a letter or a digit. Every other character is a literal that the hook inserts for the user. Typed characters that do not fit the next slot are skipped, and a literal appears as soon as the group before it is complete.
Base UI Mask Input example - phone number (Phoenix headless)
Base UI Mask Input example - phone number (Phoenix headless)
<.mask_input
id="baseui-mask-input"
mask="(999) 999-9999"
placeholder="(___) ___-____"
inputmode="numeric"
class="w-72 rounded-lg border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-900 outline-none focus:ring-2 focus:ring-neutral-400 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
/>Mask patterns
(999) 999-9999for a phone number99/99/9999for a date99/99for a card expiryaaa-9999for three letters, a dash and four digits
Clearing the field gives an empty string, with no leftover literals. Characters beyond the end of the mask are dropped.
Attributes
id and mask are required. name is the form field name, value the current text, placeholder the hint shown while the field is empty, and disabled turns the field off. inputmode sets the on-screen keyboard, for example "numeric" for a digit-only mask. The global attributes accept form, maxlength, minlength, readonly, required and any phx-* binding.
Pass value already masked, for example from @form[:phone].value. When the server patches the input, the hook applies the mask to the new value again.
<.form for={@form} id="contact-form" phx-change="validate" phx-submit="save">
<.mask_input
id="contact-phone"
name={@form[:phone].name}
value={@form[:phone].value}
mask="(999) 999-9999"
inputmode="numeric"
required
class="w-72 rounded-lg border border-neutral-300 px-3 py-2 text-sm"
/>
</.form>Accessibility
The element is a native text input with autocomplete="off", so labels, required and validation messages behave as usual. The component renders no label. Wrap it in a <label> or point a <label for> at its id. Use inputmode="numeric" for digit-only patterns so phones open a number pad.
Attributes
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
id
|
string
| — | — | Yes | Unique id (carries the MaskInput hook) |
name
|
string
| — | — | No | Form field name |
value
|
string
| — | — | No | Current value (already masked) |
mask
|
string
| — | — | Yes | Mask pattern: 9=digit, a=letter, *=alnum, others literal |
placeholder
|
string
| — | — | No | Placeholder |
inputmode
|
string
| — | — | No | Hint for on-screen keyboards, e.g. "numeric" |
disabled
|
boolean
|
false
| — | No | Disable input |
class
|
any
| — | — | No | Extra classes |
rest
|
global
| — | — | No | Any input/global attrs, e.g. phx-change, required |
Options
Each option takes one or more of its values, separated by commas.
| Option | Values |
|---|---|
--type
|
mask_input
|
--module
| A module name of your own |
What it generates
mix mishka.ui.gen.headless mask_input