Text Input
Text input components are used to collect text-based data from the user. It should be used for single-line text input fields such as text, email, password, number, tel, and url fields.
<TextInput label="Label" name="example-1" placeholder="Placeholder" class="max-w-xs"/>
<div class="field-group max-w-xs" data-layout="FieldGroup" data-component="TextInput"> <label for="example-1" id="label-example-1"> <span class="field-label">Label</span> </label> <input type="text" id="example-1" name="input-example-1" placeholder="Placeholder" aria-labelledby="label-example-1" ></div>
API Reference
This component inherits from the Field Group component.
This component is based on the <input>
element and can take in any additional HTML attributes through the use of the inputProps
property. The following are the custom props that can be passed to the component.
Prop | Type | Default |
---|---|---|
name * | string | — |
label * | string | — |
labelHidden | boolean | false |
sublabel | string | — |
instructions | string | — |
placeholder | string | — |
disabled | boolean | false |
required | boolean | "long" | false |
type | "text" | "email" | "password" | "number" | "tel" | "url" | "text" |
inputProps | HTMLAttributes<input> | — |
errorMessages | string[] | — |
Accessibility
The <TextInput>
component is designed with accessibility in mind and extends much of the accessibility features from the <Field Group>
component. The following are some of the field specific accessibility features that are included in the component and worth considering:
- The
aria-labelledby
attribute is used to associate thelabel
andinstructions
elements with the input field. This is an important consideration specifically for the instructions so that they are read out by screen readers when the field is focused, rather than after the input field.
Examples
Required
Use the required
prop to mark a field as required. You can also use the required
prop to mark a field as required and include explicit “required” text by passing the value "long"
.
<TextInput label="Label" name="example-2" required placeholder="Placeholder"/><TextInput label="Label" name="example-3" required="long" placeholder="Placeholder"/>
<div class="field-group" data-required="" data-layout="FieldGroup" data-component="TextInput"> <label for="example-2" id="label-example-2"> <span class="field-label">Label</span> </label> <input type="text" id="example-2" name="input-example-2" placeholder="Placeholder" required="" aria-labelledby="label-example-2"></div><div class="field-group" data-required="long" data-layout="FieldGroup" data-component="TextInput"> <label for="example-3" id="label-example-3"> <span class="field-label">Label</span> </label> <input type="text" id="example-3" name="input-example-3" placeholder="Placeholder" required="" aria-labelledby="label-example-3"></div>
Disabled
Use the disabled
prop to disable the input field.
<TextInput label="Label" name="example-4" placeholder="Placeholder" disabled/>
<div class="field-group" data-layout="FieldGroup" data-component="TextInput"> <label for="example-4" id="label-example-4"> <span class="field-label">Label</span> </label> <input type="text" id="example-4" name="input-example-4" placeholder="Placeholder" disabled aria-labelledby="label-example-4" /></div>
With Helper Text
Use the sublabel
and instructions
props to add helper text to the input field.
<TextInput label="Label" name="example-5" sublabel="Sublabel lorem ipsum dolor sit amet." instructions="Instructions lorem ipsum dolor." placeholder="Placeholder"/>
<div class="field-group" data-layout="FieldGroup" data-component="TextInput"> <label for="example-5" id="label-example-5"> <span class="field-label">Label</span> <span class="field-sublabel">Sublabel lorem ipsum dolor sit amet.</span> </label> <input type="text" id="example-5" name="input-example-5" placeholder="Placeholder" aria-labelledby="label-example-5 instructions-example-5" > <span class="field-instructions" id="instructions-example-5" > Instructions lorem ipsum dolor. </span></div>
With Errors
Use the errorMessages
prop to display error messages below the input field.
- Error message 1
- Error message 2
<TextInput label="Label" name="example-6" errorMessages={['Error message 1', 'Error message 2']} placeholder="Placeholder"/>
<div class="field-group" data-state="error" data-layout="FieldGroup" data-component="TextInput"> <label for="example-6" id="label-example-6"> <span class="field-label">Label</span> </label> <input type="text" id="example-6" name="input-example-6" placeholder="Placeholder" aria-labelledby="label-example-6" > <ul class="field-errors"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="absolute left-0 top-2 size-16 shrink-0"><line x1="12" y1="9" x2="12" y2="13"></line><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg> <li>Error message 1</li> <li>Error message 2</li> </ul></div>
With Hidden Label
Use the labelHidden
prop to visually hide the label. When hidden, the label will still be available to screen readers.
<TextInput label="Label" name="example-7" labelHidden placeholder="Placeholder"/>
<div class="field-group" data-layout="FieldGroup" data-component="TextInput"> <label for="example-7" id="label-example-7"> <span class="field-label sr-only">Label</span> </label> <input type="text" id="example-7" name="input-example-7" placeholder="Placeholder" aria-labelledby="label-example-7" ></div>
Astro Component
It’s recommended that an element like this is made as a reusable component. In this case, we have put together the following Astro component to serve as a blueprint for how you could possibly set up a text input component, and what properties to consider.
---import type { ComponentProps, HTMLAttributes } from 'astro/types'import FieldGroup from '@/components/forms/FieldGroup.astro'
interface Props extends ComponentProps<typeof FieldGroup> { /** Placeholder text for the input field */ placeholder?: string /** Whether the input field is disabled or not */ disabled?: boolean /** Type of input field */ type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' /** Additional props to pass into the input field */ inputProps?: HTMLAttributes<'input'>}
const { placeholder, type = 'text', disabled = false, inputProps, ...fieldGroupProps} = Astro.props---
<FieldGroup data-component="TextInput" {...fieldGroupProps}> <input type={type} id={fieldGroupProps.name} name={`input-${fieldGroupProps.name}`} placeholder={placeholder} disabled={disabled} required={fieldGroupProps.required === true || fieldGroupProps.required === 'long'} aria-labelledby={`label-${fieldGroupProps.name}${ fieldGroupProps.instructions ? ` instructions-${fieldGroupProps.name}` : '' }`} {...inputProps} /></FieldGroup>