Text input
On this page
Use this component when you want to collect textual or numerical data from a user that is not more than a single line.
Examples
Default
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-basic-label" for="example-input-basic-input">
Example input
</label>
<input type="text" id="example-input-basic-input" name="example-input-basic" aria-required="true" aria-invalid="false" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-basic",
label: "Example input",
type: :text
))%>
With hint text
Use hint text for help that’s relevant to the majority of users, based on the needs of your service.
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-with-hint-label" for="example-input-with-hint-input">
Example input with hint
</label>
<p class="cads-form-field__hint" id="example-input-with-hint-hint" data-testid="hint-message">This is the hint for the input</p>
<input type="text" id="example-input-with-hint-input" name="example-input-with-hint" aria-required="true" aria-invalid="false" aria-describedby="example-input-with-hint-hint" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-with-hint",
label: "Example input with hint",
type: :text,
options: {
hint: "This is the hint for the input"
}
))%>
Optional
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-optional-label" for="example-input-optional-input">
Example input
<span class="cads-form-field__optional">(optional)</span>
</label>
<input type="text" id="example-input-optional-input" name="example-input-optional" aria-required="false" aria-invalid="false" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-optional",
label: "Example input",
type: :text,
options: {
optional: true
}
))%>
Fixed widths
Help users understand the purpose of the input by making the input size appropriate for the content it’s intended for.
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-fixed-width-two_chars-label" for="example-input-fixed-width-two_chars-input">
Example input
</label>
<p class="cads-form-field__hint" id="example-input-fixed-width-two_chars-hint" data-testid="hint-message">This input is two_chars wide</p>
<input type="text" id="example-input-fixed-width-two_chars-input" name="example-input-fixed-width-two_chars" aria-required="true" aria-invalid="false" aria-describedby="example-input-fixed-width-two_chars-hint" class="cads-input cads-input--two-chars">
</div>
</div>
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-fixed-width-four_chars-label" for="example-input-fixed-width-four_chars-input">
Example input
</label>
<p class="cads-form-field__hint" id="example-input-fixed-width-four_chars-hint" data-testid="hint-message">This input is four_chars wide</p>
<input type="text" id="example-input-fixed-width-four_chars-input" name="example-input-fixed-width-four_chars" aria-required="true" aria-invalid="false" aria-describedby="example-input-fixed-width-four_chars-hint" class="cads-input cads-input--four-chars">
</div>
</div>
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-fixed-width-eight_chars-label" for="example-input-fixed-width-eight_chars-input">
Example input
</label>
<p class="cads-form-field__hint" id="example-input-fixed-width-eight_chars-hint" data-testid="hint-message">This input is eight_chars wide</p>
<input type="text" id="example-input-fixed-width-eight_chars-input" name="example-input-fixed-width-eight_chars" aria-required="true" aria-invalid="false" aria-describedby="example-input-fixed-width-eight_chars-hint" class="cads-input cads-input--eight-chars">
</div>
</div>
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-fixed-width-sixteen_chars-label" for="example-input-fixed-width-sixteen_chars-input">
Example input
</label>
<p class="cads-form-field__hint" id="example-input-fixed-width-sixteen_chars-hint" data-testid="hint-message">This input is sixteen_chars wide</p>
<input type="text" id="example-input-fixed-width-sixteen_chars-input" name="example-input-fixed-width-sixteen_chars" aria-required="true" aria-invalid="false" aria-describedby="example-input-fixed-width-sixteen_chars-hint" class="cads-input cads-input--sixteen-chars">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
width: :two_chars,
name: "example-input-fixed-width-two_chars",
label: "Example input", type: :text,
options: { hint: "This input is two_chars wide" }
)) %>
<%= render(CitizensAdviceComponents::TextInput.new(
width: :four_chars,
name: "example-input-fixed-width-four_chars",
label: "Example input", type: :text,
options: { hint: "This input is four_chars wide" }
)) %>
<%= render(CitizensAdviceComponents::TextInput.new(
width: :eight_chars,
name: "example-input-fixed-width-eight_chars",
label: "Example input", type: :text,
options: { hint: "This input is eight_chars wide" }
)) %>
<%= render(CitizensAdviceComponents::TextInput.new(
width: :sixteen_chars,
name: "example-input-fixed-width-sixteen_chars",
label: "Example input", type: :text,
options: { hint: "This input is sixteen_chars wide" }
)) %>
With error message
Error messages are used to highlight where users need to change information. They’re used together with an error summary
<div class="cads-form-field cads-form-field--has-error">
<div class="cads-form-field__error-marker"></div>
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-error-label" for="example-input-error-input">
Email address
</label>
<p class="cads-form-field__error-message" id="example-input-error-error" data-testid="error-message">
Enter a valid email address, like name@example.com
</p>
<input type="text" id="example-input-error-input" name="example-input-error" aria-required="true" aria-invalid="true" aria-describedby="example-input-error-error" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-error",
label: "Email address",
type: :text,
options: {
error_message: "Enter a valid email address, like name@example.com"
}
))%>
With value
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-value-label" for="example-input-value-input">
Example input
</label>
<input type="text" id="example-input-value-input" name="example-input-value" value="Lorem ipsum" aria-required="true" aria-invalid="false" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-value",
label: "Example input",
type: :text,
options: { value: "Lorem ipsum" }
))%>
With custom type
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="example-input-password-label" for="example-input-password-input">
Example input
</label>
<p class="cads-form-field__hint" id="example-input-password-hint" data-testid="hint-message">This input has type 'password'</p>
<input type="password" id="example-input-password-input" name="example-input-password" value="It's a secret" aria-required="true" aria-invalid="false" aria-describedby="example-input-password-hint" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-password",
label: "Example input",
type: :password,
options: {
value: "It's a secret",
hint: "This input has type 'password'"
}
))%>
With custom id
By default the id is based on the name
. This can be customised by passing an id
argument.
<div class="cads-form-field">
<div class="cads-form-field__content">
<label class="cads-form-field__label" id="test-id-label" for="test-id-input">
Example input
</label>
<input type="text" id="test-id-input" name="example-input-basic[test]" aria-required="true" aria-invalid="false" class="cads-input">
</div>
</div>
<%= render(CitizensAdviceComponents::TextInput.new(
name: "example-input-basic[test]",
id: "test-id",
label: "Example input",
type: :text
))%>
Implementation
You must always have a label
associated with the input element.
Use the correct input type
so the purpose of each input field can be determined.
When collecting information about a user, use the autocomplete
attribute to help users complete forms more quickly.
Read more about input purpose at WCAG 2.1.
The following needs more research:
- The effects of
type=number
andinputmode=numeric
on assistive technologies? - Should we be able to group text inputs into fieldsets? Eg when capturing addresses?
Using with Rails
If you are using the citizens_advice_components
gem, you can call the component from within a template using:
<%= render(CitizensAdviceComponents::TextInput.new(
name: "my-input",
label: "My input",
type: :text,
width: :sixteen_chars,
options: {
hint: "Hint text",
error_message: "Error message",
optional: true,
value: "Input value",
additional_attributes: {
"data-test-id": "test"
}
}
))%>
Component arguments
Argument | Description |
---|---|
Argument
name
|
Description Required, field name |
Argument
id
|
Description
Optional, allows customising the id. By default the id is autogenerated based on the name
|
Argument
label
|
Description Required, the text for the label associated with the input |
Argument
type
|
Description
Required, one of: :email , :hidden , :number , :password , :search , :tel , :text , :url
|
Argument
width
|
Description
Optional, one of: :two_char , :four_char , :eight_char , :sixteen_char
|
Argument
options
|
Description Optional, a hash with one or more of the following values: |
Argument
options[:hint]
|
Description → Optional, hint text for the input |
Argument
options[:error_message]
|
Description → Optional, an error message for the input |
Argument
options[:optional]
|
Description → Optional, boolean indicating the field is optional (i.e. not required) |
Argument
options[:value]
|
Description → Optional, the value of the input |
Argument
options[:additional_attributes]
|
Description
→ Optional, a hash of additional attributes rendered onto the input, eg { autocomplete: "name" }
|
Additional type values
If you need access to inputs with additional type values, eg file or color, you can use the base Input
view component instead. The interface is the same except you may not specify a width parameter.
Questions and contributions
All design system discussions take place in the #design-system Slack channel. For current issues, roadmap and other info see the Github project board and related issues.