TextField

A field for entering text, on one line or several.

StableSince 1.0.0
On this page

Import

import {
  SearchField,
  Textarea,
  TextField,
} from '@envsemble/envui';

Usage

<TextField label="Project name" name="project" defaultValue="Launch" />
<TextField label="Owner" name="owner" value={owner} onValueChange={setOwner} />
<SearchField label="Search members" value={query} onValueChange={setQuery} />
<Textarea label="Notes" name="notes" sizing="content" rows={3} />

A TextField is a native <input> with its label, description and error. Give it a name for its form, and leave it uncontrolled, with defaultValue, or control it with value and onValueChange, which receives the string as people type.

Errors

error marks the field invalid, sets aria-invalid and shows under the description. Check on blur and on submit, and clear it as soon as the value fits.

Variants and sizes

<TextField size="lg" label="Owner" name="owner" />
<TextField variant="ghost" label="Find projects" visibleLabel={false} startIcon={<IconSearch />} />
<TextField size="sm" label="Filter" visibleLabel={false} placeholder="Filter" name="filter" />

variant is outline, the default, or ghost, as on Textarea. size is sm, md or lg; without it, a field takes its container's. visibleLabel={false} keeps the label for assistive technology only; sm is for a field with its label hidden, as Sizes says.

Prefix, suffix, icon and end action

prefix and suffix are short text in line with the value, not part of it, and forms don't submit them. startIcon is decorative. endAction holds a control, such as an IconButton, which takes the ghost variant where it sets none; name an icon-only one with aria-label.

Values the browser can help with

Set type, autoComplete and inputMode to fit the value, such as type="email" with autoComplete="email". Use readOnly for a value people can see and copy but not change: a disabled field can't be focused, copied or submitted.

SearchField and Textarea

SearchField takes value and onValueChange, or defaultValue; its label shows only with showLabel. Textarea keeps its height and scrolls with sizing="fixed", the default, or grows with its text with sizing="content"; rows sets its height, or the lines it starts at.

Composition

TextField, SearchField and Textarea are built from Field's parts: the root, env-field with env-text-field, the control and its contents, then the description and the error, env-field-error. The suffix is env-text-field-suffix, and a Textarea's resize edge env-textarea-resize-handle. Build a field of your own from the same parts, as Build your own field shows.

A field fills its container's width, so set the width on the container, or on the field through style. Put fields in a native <form>, in a Column or a Grid: the inputs are native, so submission, reset and autofill work, and ref reaches the input for a form library.

Customize

className and style reach the field's root, and ref and the other native props the input. CSS may target the part classes and their state attributes, such as data-invalid on the control, listed under Part names below.

Accessibility

You provide

  • A label for every field, or aria-label.
  • An aria-label on an icon-only endAction.
  • Validation, the error text, and focus on the first invalid field.
  • An announcement of results when a search filters as people type.
  • The clear and resize labels and the search placeholder in the application's language, through EnvUIProvider's messages.

envUI provides

  • Native <input> and <textarea>, so autofill, validation, submission and reset work.
  • A <label> tied to the control, kept for assistive technology when hidden.
  • The description and error as the control's description, and aria-invalid.
  • SearchField's clear button, named Clear search.
  • Textarea's resize edge as a separator named Resize text area.
  • 1 rem text on touch screens, so focusing a field doesn't zoom the page.

Props

TextField

A labelled single-line text input: a native input with a floating label, a description and an error, at the control height in an outline or ghost look, with an optional start icon, end action, prefix and suffix.

PropTypeDescription
ref
Ref<HTMLInputElement>
The native input, so that a form library can register it and focus it.
className
string
The field's class, on its root element, beside env-field and env-text-field.
style
CSSProperties
Styles of the field's root element, such as its width in a row.
onValueChange
(value: string) => void
Receives the value as people type, after the native onChange.
label
ReactNode
The field's visible name, such as Project name; it also names the control for assistive technology.
description
ReactNode
Lasting guidance under the field, such as a format or a limit, linked to the control as its description.
error
ReactNode
A message under the field that says how to correct the value. While it is set, the control is invalid (aria-invalid) and the message joins its description, after the description.
variantDefault 'outline'
'outline''ghost'
The field's look: outline, a thin border its label floats into, or ghost, a faint fill, for a search at the top of a sidebar or a list.
startIcon
ReactNode
A decorative icon at the start of the field, such as Search or Mail.
endAction
ReactNode
A control at the end of the field, such as an IconButton that reveals or copies the value; name it with aria-label. A button that sets no variant takes ghost here.
visibleLabelDefault true
boolean
The label shows in the field, where it rests while the field is empty and floats into the outline while the field is in use or has a value. false hides it, for a field whose purpose is clear without it, such as a search in a toolbar: the label still names the field for assistive technology, and a placeholder gives the visible guidance.
size
'sm''md''lg'
The control height, sm, md or lg; without it, the container's, and else md. sm is for a field with its label hidden.
prefix
ReactNode
Short, non-interactive text before the value, such as the start of an address. It is not part of the value; it shows once the field has focus or a value and is read after the label.
suffix
ReactNode
Short, non-interactive text after the value, such as a unit. It is not part of the value; it shows once the field has focus or a value and is read after the label.

Also accepts the native props of <input>, such as ref, className and aria-* attributes.

SearchField

A search input with a search icon and, while it has a query, a clear button; Esc also clears. Its label is hidden by default, so it sits beside buttons with a placeholder.

PropTypeDescription
labelrequired
string
The field's accessible name, such as Search members. It shows as a floating label only with showLabel; otherwise a placeholder gives the visible guidance.
showLabelDefault false
boolean
Show the label in the field, as TextField does. A search field leaves it out, so that it sits in a toolbar with a placeholder such as Search.
value
string
The query of a controlled field; update it from onValueChange.
defaultValueDefault ''
string
The query an uncontrolled field starts with, and that a form reset restores.
onValueChange
(value: string) => void
Receives the next query as people type, and an empty string when the clear button or Esc clears it.
clearLabelDefault 'Clear search', or EnvUIProvider's messages.searchField.clear
string
The accessible name and tooltip of the clear button.
placeholderDefault 'Search' while the label is hidden, or EnvUIProvider's messages.searchField.placeholder
string
The visible guidance while the field is empty, such as Search members. With the label hidden it shows Search unless it is set.
style
CSSProperties
Styles of the field's root element, such as its width in a row.
ref
Ref<HTMLInputElement>
The native input, so that a form library can register it and focus it.
className
string
The field's class, on its root element, beside env-field and env-text-field.
prefix
ReactNode
Short, non-interactive text before the value, such as the start of an address. It is not part of the value; it shows once the field has focus or a value and is read after the label.
description
ReactNode
Lasting guidance under the field, such as a format or a limit, linked to the control as its description.
size
'sm''md''lg'
The control height, sm, md or lg; without it, the container's, and else md. sm is for a field with its label hidden.
variantDefault 'outline'
'outline''ghost'
The field's look: outline, a thin border its label floats into, or ghost, a faint fill, for a search at the top of a sidebar or a list.
error
ReactNode
A message under the field that says how to correct the value. While it is set, the control is invalid (aria-invalid) and the message joins its description, after the description.
suffix
ReactNode
Short, non-interactive text after the value, such as a unit. It is not part of the value; it shows once the field has focus or a value and is read after the label.

Also accepts the native props of <input>, such as ref, className and aria-* attributes.

Textarea

A labelled text area for text over several lines: a native textarea in the text field's frame, at a fixed height that scrolls and resizes from its bottom edge, or growing with its content.

PropTypeDescription
ref
Ref<HTMLTextAreaElement>
The native text area, so that a form library can register it and focus it.
className
string
The field's class, on its root element, beside env-field, env-text-field and env-textarea.
style
CSSProperties
Styles of the field's root element, such as its width in a row.
variantDefault 'outline'
'outline''ghost'
The field's look, as TextField's: outline or ghost. A text area is always tall, with its label resting at the top.
onValueChange
(value: string) => void
Receives the text as people type, after the native onChange.
sizingDefault 'fixed'
'fixed''content'
How the height follows the text: fixed keeps its height, scrolls and resizes from the bottom edge, by dragging it or with the arrow keys; content grows and shrinks with the text.
rows
number
The lines the field shows: with fixed sizing, its height in rows, which resizes down to them or to 7.5 rem, whichever is less; with content sizing, the lines it starts at and shrinks back to. Without rows, both start at 7.5 rem.
label
ReactNode
The field's visible name, such as Project name; it also names the control for assistive technology.
description
ReactNode
Lasting guidance under the field, such as a format or a limit, linked to the control as its description.
error
ReactNode
A message under the field that says how to correct the value. While it is set, the control is invalid (aria-invalid) and the message joins its description, after the description.

Also accepts the native props of <textarea>, such as ref, className and aria-* attributes.

Part names

Each part's class and state attributes are public and versioned, for an application's CSS to style.

TextField

env-text-field
The text field.
env-text-field-border
The border over the well's edge, which a floated label opens behind it.
env-text-field-control
The well around the input and its adornments.
env-text-field-end
The buttons at the end of the well.
env-text-field-input
The input.
env-text-field-label
The label.
env-text-field-prefix
Fixed text before the input.
env-text-field-start
The icon at the start of the well.
env-text-field-suffix
Fixed text after the input.
data-disabled
Any value, or present on env-text-field-control
data-end-action
Present on env-text-field-control
data-invalid
Any value, or present on env-text-field-control
data-label-floating
Present on env-text-field-control
data-label-hidden
Present
data-popup-open
Present on env-text-field-control
data-prefix
Present on env-text-field-control
data-rows
Present on env-text-field-input
data-size
lg · md · sm
data-sizing
content · fixed on env-text-field-input
data-start-icon
Present on env-text-field-control
data-suffix
Present on env-text-field-control
data-tall
Present
data-variant
ghost · outline on env-text-field-control

Textarea

env-textarea
The text area's root, beside env-field and env-text-field.
env-textarea-resize-handle
The handle on the text area's bottom edge, which resizes it.
data-resizing
Any value, or present on env-textarea-resize-handle

Color properties

Each sets a color of one instance, through style or CSS; its hover, focus and press follow it. They are public and versioned.

TextField

--env-text-field-container
The well behind the entered text.
--env-text-field-content
The entered text.
--env-text-field-outline
The edge at rest, which darkens toward the text under the pointer.
--env-text-field-indicator
The edge while pressed and focused, the caret and the floating label while focused.

Textarea

--env-text-field-container
The well behind the entered text.
--env-text-field-content
The entered text.
--env-text-field-outline
The edge at rest, which darkens toward the text under the pointer.
--env-text-field-indicator
The edge while pressed and focused, the caret and the floating label while focused.

Strings

EnvUIProvider's messages overrides each, and a component's own label prop wins over it.

messages.searchField.clear
"Clear search" The clear button's name.
messages.searchField.placeholder
"Search" The placeholder of a field whose label is hidden, where it gives none of its own.
messages.textarea.resize
"Resize text area" The resize edge's name.
messages.textarea.resizeDescription
"Drag the bottom edge, or use Up and Down arrows to resize. Home restores the minimum height." How to use the resize edge.

Changelog

1.0.0

showLabel is visibleLabel, named after the label that visibleLabel={false} hides. SearchField keeps showLabel, which shows its label where it is hidden by default.

hint is description, and the variants are outline, floating and ghost: outlined is outline and quiet is ghost, and plain is gone, for the default outline. className and style style the field's root rather than the input; ref and the other native props still reach the input. TextField and Textarea take onValueChange. The frame is Field's parts, and the classes follow: env-text-input is env-text-field-input, env-text-field-well env-text-field-control, env-form-field env-field and env-field-hint env-field-description. A button in endAction takes the ghost variant where it sets none. Textarea's resize edge is a separator, and its labels and the clear label come from EnvUIProvider's messages. Textarea's resize edge, env-textarea-resize-edge, is env-textarea-resize-handle, as every resize handle is named.

Input is TextField, with the same props, behaviour and look; the page is text-field.

1.0.0-prerelease.6

The edge and the label change color in --env-motion-duration-fast with --env-motion-ease-enter, as every color under the pointer does; the label still floats and the notch still opens over --env-motion-duration-medium.

Colors under the pointer and while pressed change with --env-motion-ease-enter, rather than easing in slowly, so hover and press show from the first frame.

The outline's notch closes at the pace the floated label settles, so the edge never crosses it.

A SearchField with its label hidden and no placeholder shows Search, messages.searchField.placeholder, rather than an empty field with only its icon.

Textarea's resize grip is two short diagonal lines in its end corner, rather than a bar in the middle that read as a sheet's handle.

A Textarea whose text runs past its rows clips that text at its padding, rather than showing the next line under the bottom border.

The floating variant is gone: a field on its own or in a long form on a page takes outline, the default, with size="lg". An outline field takes a text area's rounded corners rather than round ends, and so does a ghost field. A small field with a visible label takes the medium height, so its floated label and its value each have room, and says so in the console while developing: sm is for a field with its label hidden. A ghost field shows a faint fill at rest, fainter when it is read-only or disabled, so a labelled one no longer reads as a label and its value, and its label floats inside the fill, within the field's height, rather than across its top edge. A focused ghost field keeps its placeholder, as an outline one does. A disabled field no longer fades as a whole: its label, value and icons take --env-color-fg-disabled and its outline the muted border, so it stays readable, also in dark.

1.0.0-prerelease.2

The underline variant, which plain became in the earlier prereleases, is gone from TextField, SearchField and Textarea, for the default outline. Outline and floating fields have no fill of their own.