Text field and select
Native inputs and selects with their label above, help and errors below. The edge of the box is the focus ring: 1 px at rest, 2 px while focused, red when something is wrong.
- Native HTML
- 2.2 KB gzipped · script and styles
@orbex/sonar-components/field
Examples
In pallets. Up to 120 per order.
Choose a date from May 12 on: earlier days are closed.
Code
import { TextField } from '@orbex/sonar-components/field'
import type { ComponentProps } from 'react'
import searchSymbol from '@material-symbols/svg-400/rounded/search.svg?raw'
/* Material Symbols Rounded, weight 400, as icon components (Foundations › Icons) */
const symbol = (svg: string) => {
const path = svg.match(/ d="([^"]+)"/)?.[1]
return (props: ComponentProps<'svg'>) => (
<svg viewBox="0 -960 960 960" fill="currentColor" aria-hidden="true" focusable="false" {...props}>
<path d={path} />
</svg>
)
}
const SearchIcon = symbol(searchSymbol)
export default function TextFields() {
return (
<>
<TextField label="Product" placeholder="Name or code" />
<TextField label="Quantity" type="number" inputMode="numeric" defaultValue="40" description="In pallets. Up to 120 per order." />
<TextField label="Delivery date" defaultValue="May 3" error="Choose a date from May 12 on: earlier days are closed." />
<TextField label="Search orders" type="search" icon={<SearchIcon />} placeholder="Order, product or carrier" />
<TextField label="Account" defaultValue="Northwind Foods" disabled />
</>
)
}
Code
import { SelectField } from '@orbex/sonar-components/field'
export default function Select() {
return (
<>
<SelectField label="Warehouse" defaultValue="north">
<option value="north">North · Valencia</option>
<option value="south">South · Seville</option>
<option value="central">Central · Madrid</option>
</SelectField>
<SelectField label="Carrier" size="small" defaultValue="">
<option value="" disabled>
Choose a carrier
</option>
<option>Iberia Freight</option>
<option>Atlas Logistics</option>
</SelectField>
</>
)
}
Sizes, variants and states
Usage
- The label is always visible. A placeholder is an example of what to type, never the label.
- An error says what is wrong and how to fix it, in one sentence. Show it when the field is left or the form is sent, not while typing.
- The select is the platform’s own list: the best picker on phones, and complete keyboard and screen reader support everywhere. For searching a long list, a combobox comes later.
- On touch screens fields grow to 48 px and their text to 16 px, below which iOS zooms in when a field is focused.
Do and don’t
Accessibility
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the field. |
| Arrow keys, Space, Enter | Open and move through a select’s options, with the platform’s own picker. |
Roles and attributes
| Element or attribute | What it gives |
|---|---|
<label for> |
Names the input or select. |
aria-describedby |
Points at the help and then the error, so both are read after the name. |
aria-invalid |
Set while there is an error. |
| Icon | aria-hidden. |
Notes
- The label is a
<label for>; help and error are tied to the control witharia-describedby, in that order. - An error sets
aria-invalidand is marked by an icon and by words, not by color alone. - Placeholder text reads at the tertiary level, 5.6:1 on cards.
Use it
Each component is its own entry point with its own stylesheet, so an app loads only what it uses. The tokens and the cascade layers are set once for the app: see Installation.
import { TextField, SelectField } from '@orbex/sonar-components/field'
import '@orbex/sonar-components/field.css'
API
TextField
A native text input with its label, help and error. Any input type that takes text: text, search, email, number…
| Prop | Type | Default |
|---|---|---|
label
Required
The field’s name, always visible above it. Placeholders are examples, never labels. |
ReactNode
|
— |
description
Help shown under the field and read after the label. |
ReactNode
|
— |
error
What is wrong and how to fix it. When present, the field is marked invalid. |
ReactNode
|
— |
size
Height of the field: medium (48 px) in forms, small (36 px) inside rows and panels, such as a quantity in a list. |
'small' | 'medium'
|
'medium' |
icon
Icon at the start of the control, such as a search glass. |
ReactNode
|
— |
suffix
A unit after the value, inside the field, such as plt; it is read after the value. |
ReactNode
|
— |
Also takes every attribute of the native <input>
, except size, and a ref to it.
SelectField
A native select with its label, help and error. The list is the platform’s own: the best picker on phones and full keyboard and screen reader support everywhere.
| Prop | Type | Default |
|---|---|---|
label
Required
The field’s name, always visible above it. Placeholders are examples, never labels. |
ReactNode
|
— |
description
Help shown under the field and read after the label. |
ReactNode
|
— |
error
What is wrong and how to fix it. When present, the field is marked invalid. |
ReactNode
|
— |
size
Height of the field: medium (48 px) in forms, small (36 px) inside rows and panels, such as a quantity in a list. |
'small' | 'medium'
|
'medium' |
icon
Icon at the start of the control, such as a search glass. |
ReactNode
|
— |
children
Required
The |
ReactNode
|
— |
Also takes every attribute of the native <select>
, except size, and a ref to it.