Input
A single-line text field. It takes part in forms as a native input does.
import '@usezeno/tokens/css';
import '@usezeno/core/web-components';
Examples
Label, placeholder and a start slot
The start slot holds a short prefix or an icon in front of the text.
<zeno-input label="Amount" type="number" value="25">
<span slot="start">$</span>
</zeno-input>
<zeno-input label="Search orders" type="search">
<zeno-icon slot="start" name="search"></zeno-icon>
</zeno-input>
Variants
outlined is the default. ghost has no border and no side padding.
<zeno-input label="Outlined" variant="outlined" value="Ada Lovelace"></zeno-input>
<zeno-input label="Filled" variant="filled" value="Ada Lovelace"></zeno-input>
<zeno-input label="Ghost" variant="ghost" value="Ada Lovelace"></zeno-input>
Sizes
<zeno-input label="Small" size="sm" placeholder="32px high"></zeno-input>
<zeno-input label="Medium" size="md" placeholder="40px high"></zeno-input>
<zeno-input label="Large" size="lg" placeholder="48px high"></zeno-input>
States
An error marks the field invalid and shows the text under it. clearable shows a clear button while the field has a value.
<zeno-input label="Required" required placeholder="Your full name"></zeno-input>
<zeno-input label="Disabled" value="Ada Lovelace" disabled></zeno-input>
<zeno-input label="Read only" value="INV-2041" readonly></zeno-input>
<zeno-input label="With an error" value="ada@example" error="Enter a full email address."></zeno-input>
<zeno-input label="Clearable" value="Quarterly report" clearable></zeno-input>
<zeno-input label="Loading" value="Checking the name" loading></zeno-input>
In a form
The value is sent under name. Enter in a field submits the form, and a required field blocks the submit while it is empty.
<form>
<zeno-input name="email" type="email" label="Email" required></zeno-input>
<zeno-input name="seats" type="number" label="Seats" min="1" max="20" value="2"></zeno-input>
<zeno-button type="submit">Save changes</zeno-button>
<zeno-button type="reset" variant="ghost">Reset</zeno-button>
<p data-result>Nothing submitted yet.</p>
</form>
const form = document.querySelector('form');
form.addEventListener('submit', event => {
event.preventDefault();
const sent = [...new FormData(form)].map(([name, value]) => name + '=' + value);
document.querySelector('[data-result]').textContent = 'Submitted: ' + sent.join('&');
});
Attributes and properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
type | typereflects | InputType | 'text' | |
variant | variantreflects | 'outlined' | 'filled' | 'underlined' | 'outlined' | |
size | sizereflects | 'sm' | 'md' | 'lg' | 'md' | |
placeholder | placeholder | string | ||
pattern | pattern | string | ||
minlength | minlength | number | ||
maxlength | maxlength | number | ||
min | min | number | ||
max | max | number | ||
step | step | number | ||
autocomplete | autocomplete | string | ||
autofocus | autofocusreflects | boolean | false | |
clearable | clearablereflects | boolean | false | |
loading | loadingreflects | boolean | false | |
success | successreflects | boolean | false | |
showPasswordToggle | show-password-togglereflects | boolean | false | |
value | value | FormValue | '' | From FormFieldMixin. |
name | namereflects | string | From FormFieldMixin. | |
required | requiredreflects | boolean | false | From FormFieldMixin. |
disabled | disabledreflects | boolean | false | From FormFieldMixin. |
readonly | readonlyreflects | boolean | false | From FormFieldMixin. |
error | error | string | An error to show, for example one a server returned. From FormFieldMixin. | |
label | label | string | A visible label. An outside <label for> works as well. From FormFieldMixin. | |
hideRequiredIndicator | hide-required-indicator | boolean | false | From FormFieldMixin. |
touched | boolean | false | True once the user has left the control or a submit was refused. From FormFieldMixin. | |
dirty | boolean | false | True once the user has changed the value. From FormFieldMixin. | |
defaultValue | FormValue | '' | The value the control goes back to when its form is reset. From FormFieldMixin. | |
formread only | HTMLFormElement | null | From FormFieldMixin. | ||
labelsread only | NodeList | From FormFieldMixin. | ||
validityread only | ValidityState | From FormFieldMixin. | ||
validationMessageread only | string | From FormFieldMixin. | ||
willValidateread only | boolean | From FormFieldMixin. | ||
isDisabledread only | boolean | True when the element or an ancestor fieldset disables it. From FormFieldMixin. | ||
invalidread only | boolean | True when the control should look invalid. From FormFieldMixin. | ||
testId | string | Test ID for automated testing From ZenoElement. |
Methods
| Method | Description |
|---|---|
focus(options?: FocusOptions): void | Focus the input element From ZenoElement. |
blur(): void | Blur the input element From ZenoElement. |
select(): void | Select all text in the input |
setSelectionRange(start: number, end: number, direction?: 'forward' | 'backward' | 'none'): void | Set selection range |
checkValidity(): boolean | Reports whether the value is valid without showing anything. Use reportValidity() or validate() to show the result as well. From FormFieldMixin. |
reportValidity(): boolean | From FormFieldMixin. |
setCustomValidity(message: string): void | From FormFieldMixin. |
validate(): boolean | Checks validity and shows the result on the control. From FormFieldMixin. |
Events
| Event | Detail | Description |
|---|---|---|
input | { value: FormValue } | The value changed while typing. |
change | { value: FormValue } | The value was committed. |
clear | The clear button was pressed. | |
enter | { value: FormValue } | Enter was pressed. Cancel it to stop the form from submitting. |
password-toggle | { visible: boolean } | The password was shown or hidden. |
Slots
| Slot | Description |
|---|---|
end | An icon or text after the value. |
start | An icon or text before the value. |
CSS parts
| Part |
|---|
clear-button |
end-icon |
error |
input |
label |
loading |
password-toggle |
start-icon |
wrapper |
CSS custom properties
This element documents no custom properties of its own. Style it through its parts and through the tokens it reads.
The element's own source reads no tokens.
Types
type InputType =
| 'text'
| 'email'
| 'password'
| 'number'
| 'tel'
| 'url'
| 'search'
| 'date'
| 'time'
| 'datetime-local'
| 'color'
| 'range';
type FormValue = string | number | boolean | Date | null | undefined;
Accessibility
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the text field. The clear button and the password button are skipped. |
| Enter | Fires enter, then submits the form that holds the input. Cancel the enter event to stop the submit. |
Forms
- With a
name, the element adds its value to the data of the form it is in, and is left out while it is disabled. - It is labelled by its
labelattribute or by a<label for>that points at itsid. - It takes part in validation:
checkValidity(),reportValidity()andsetCustomValidity()work, and an invalid element blocks the submit and matches:invalid. - It follows a
<fieldset disabled>around it and goes back to its first value when the form is reset. - The messages it writes itself, such as “Please fill out this field.”, are in English only.
Notes
- Renders a native
<input>in its shadow root, so typing, selection and the on-screen keyboard for eachtypecome from the browser. - The
labeltext is a real<label>for the input. Withoutlabel, the name comes fromaria-labelon the element or from an outside<label for>, and a click on that outside label focuses the input. - The input always carries
aria-invalid. When an error shows,aria-describedbypoints at the error text. - Focus on the element goes to the inner input, and the required star is hidden from assistive technology.
- Enter is ignored while an input method editor is composing text.
Tests and known gaps
- Tested in a real browser by
button.test.ts,input.test.ts. - Checked with axe-core in the light and the dark theme.
- Has a Storybook story.
38 of the 59 properties, methods, events, slots and parts above have no description in the source
- the property
type - the property
variant - the property
size - the property
placeholder - the property
pattern - the property
minlength - the property
maxlength - the property
min - the property
max - the property
step - the property
autocomplete - the property
autofocus - the property
clearable - the property
loading - the property
success - the property
showPasswordToggle - the property
value - the property
name - the property
required - the property
disabled - the property
readonly - the property
hideRequiredIndicator - the property
form - the property
labels - the property
validity - the property
validationMessage - the property
willValidate - the method
reportValidity() - the method
setCustomValidity() - the part
clear-button - the part
end-icon - the part
error - the part
input - the part
label - the part
loading - the part
password-toggle - the part
start-icon - the part
wrapper
Known gaps:
- The
varianttype listsunderlined, but there is no style for it, so it looks like a plain bordered field. The stylesheet has aghostvariant that the type does not list. - With
show-password-togglethe button to show the password is empty. It uses the icon nameseyeandeye-off, whichzeno-icondoes not have. - The clear button and the password button cannot be reached with the keyboard, and no key clears the field or shows the password.
- The names “Clear input”, “Show password” and “Hide password” are English only and have no property.
loadinghides the typed text and shows a spinner, but the field can still be edited and the input has noaria-busy. The spinner is announced as “Loading”, in English.successonly changes the border colour. Nothing tells assistive technology or people who cannot see the colour.min,maxandstepare numbers. A date or time string fortype="date",timeordatetime-local, andstep="any", becomeNaN.- Content in the
startandendslots cannot be clicked. A button placed there does not work with a pointer. - The
endslot is hidden while the clear button or the password button shows. - The error text is not a live region. An error that appears while the user is elsewhere is not announced.
- There is no help text.
aria-describedbycan only point at the error. - The slots and their padding use left and right. In a right-to-left page the
startslot stays on the left. - The element gives its icons the size
16, whichzeno-icondoes not have, so they render at the default size.