Skip to content

HyTextInput ​

Usage examples on this page are written for Lit / plain HTML (<hy-text-input>). The same component ships as HyTextInput in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A versatile single-line text input component with enhanced styling and functionality. Supports multiple input types, validation states, icons, and comprehensive accessibility features. Provides a consistent interface for various text input scenarios with built-in error handling. Offers both block (default) and inline layout options — in inline, label sits on the left of the row, input on the right, and helper/error under the control (col 2–end).

A field or a settings row? ​

A field has its label above it, or beside it with layout="inline" (its helper and messages then sit under the control). A settings row — a setting's name with a line of description at the start and the control at the row's end, as on a preferences page — is a row of your own: a flex row with justify-content: space-between, the name and description as your own text, and the control named with aria-labelledby pointing at the name, with no label, helper-text or layout. Rebuilding a drawn settings page, keep the control at the row's end.

When to use

  • A single line of free text: a name, an email address, a title, a search.
  • A value with a known format people type, with the matching type: email, URL, phone.

Do

  • Size a field to its expected length with chars when the content has one: a postal code, a year.
  • Say the expected format in helper-text, before people type.

When not to use

  • Text that runs over several lines: hy-text-area.
  • One of a few known options: hy-select. A long list: hy-combobox, so people can type to filter.
  • A quantity with bounds or steps: hy-number-input, not type="number".
  • A yes or no answer: hy-checkbox or hy-switch.

Accessibility: your part ​

  • Never use placeholder as the label or for guidance. It disappears as people type.
  • Set autocomplete on a field that asks for the person's own data, such as name, email or phone.

Examples ​

html
<hy-text-input label="Name" placeholder="Enter your name"></hy-text-input>
html
<hy-text-input
  type="email"
  label="Email Address"
  placeholder="user@example.com"
  helper-text="We'll never share your email with anyone"
  required
>
</hy-text-input>

Search with a clear button ​

The × shows while there is a value; Escape clears too. The search icon goes at the start, so the end of the field is the ×'s.

html
<hy-text-input
  type="search"
  aria-label="Search"
  clearable
  clear-label="Clear search"
></hy-text-input>

Password with a show / hide button ​

The host keeps type="password"; only the inner input switches, so forms and password managers still see a password field. The button re-hides the password when the form is submitted or reset.

html
<hy-text-input
  type="password"
  label="Password"
  autocomplete="current-password"
  password-toggle
></hy-text-input>

Inline layout (dense parameter panels) ​

Label on the left, input on the right, helper/error below the row. Set --hy-text-input-label-column-width on a wrapping container so stacked inputs align on the left edge.

html
<style>
  .form {
    --hy-text-input-label-column-width: 8rem;
  }
</style>
<div class="form">
  <hy-text-input layout="inline" label="Name" placeholder="Jane Doe"></hy-text-input>
  <hy-text-input layout="inline" label="Email" placeholder="jane@example.com"></hy-text-input>
</div>

API ​

Properties ​

PropertyAttributeTypeDefaultDescription
focusedfocusedbooleanfalseWhether the input is currently focused.
disableddisabledbooleanfalseDisables the input, preventing user interaction.
requiredrequiredbooleanfalseMarks the input as required for form validation.
readonlyreadonlybooleanfalseMakes the input read-only, preventing user editing.
errorerrorbooleanfalseWhether the input is in an error state.
warningwarningbooleanfalseWarning state: the value is accepted but worth a second look. Paints the warning color and shows warning-message; never sets aria-invalid and never blocks submission. error wins when both are set.
leadingIconleading-iconstring''Icon name from HyIcon component library to display before the input field, drawn in the field's icon ink. Lit resolves the name (its icon registry); React's leadingIcon takes the icon node instead. A type="search" field draws its own magnifier (the design system picks its side), so it names none here.
trailingIcontrailing-iconstring''Icon name from HyIcon component library to display after the input field, as leading-icon.
sizesize'small' | 'medium' | 'large''medium'The size of the input: 'small', 'medium', or 'large'.
layoutlayout'block' | 'inline''block'Row layout: block (default) stacks label above the input; inline puts label on the left and input on the right. Helper/error always sit under the control (col 2–end), never under the label.
charschars1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 12 | 16 | 20 | 24 | 32 | 48undefinedHow many characters the field holds — the way to make a field narrower than its container. One of 1–8, 10, 12, 16, 20, 24, 32, 48; the width is that many 0 glyphs in the input's own font, plus its padding and icons, so it follows every design system. Never wider than the container. A value outside the set is ignored (dev warning). width wins when both are set.
widthwidthstring | undefinedundefinedA fixed width for the input container, as any CSS width value (e.g. '300px', '20rem', '50%') — for a size the layout dictates rather than the content. Never wider than the container. To size a field to its content, use chars.
labellabelstring''The label text displayed above the input (block layout) or to the left (inline layout).
valuevaluestring''The current value of the input.
placeholderplaceholderstring''Placeholder text displayed when the input is empty.
helperTexthelper-textstring''Helper text displayed below the input to provide additional context.
typetype'text' | 'email' | 'password' | 'tel' | 'url' | 'search' | 'number''text'The input type: 'text', 'email', 'password', 'tel', 'url', 'search', or 'number'.
namenamestring''The name attribute for form submission.
autocompleteautocompletestring''The autocomplete attribute for browser auto-completion.
autofocusautofocusbooleanfalseMarks this input as the auto-focus target. Read by hy-dialog (and other overlay containers) on show to choose which slotted control receives initial focus. Also focuses on first connect when used outside an overlay, matching the native HTML autofocus attribute — but routed through JS so SSR'd HTML doesn't pull focus during hydration.
autoselectautoselectbooleanfalseAfter auto-focus lands, selects the current value so the user can type-to-replace. Pairs with autofocus for rename-style dialogs where the existing name is shown for context but is meant to be overwritten.
errorMessageerror-messagestring''Error message displayed when the input is in an invalid state.
warningMessagewarning-messagestring''Warning message shown under the input (replaces the helper text). Setting it raises warning.
maxlengthmaxlengthnumber | undefined—Maximum number of characters allowed in the input.
minlengthminlengthnumber | undefined—Minimum number of characters required in the input.
patternpatternstring''Regular expression pattern for input validation.
inputmodeinputmodestring''Virtual-keyboard hint forwarded to the inner input (inputmode), e.g. numeric for one-time codes so mobile users get the number pad while the type stays text (leading zeros, no spinner).
clearableclearablebooleanfalseAdds a clear (×) button at the end of the field while it has a value (not when disabled or read-only). A press empties the field, keeps focus in it, and sends input then change with an empty value. The × is not in the tab order: Escape clears from the keyboard — and while the field is empty, Escape passes through, so an enclosing dialog still closes on the next one. Opt-in on every type, type="search" included; the browser's own search × is always hidden.
clearLabelclear-labelstring'Clear'The clear button's accessible name. Name what it clears ("Clear search").
passwordTogglepassword-togglebooleanfalseAdds a show / hide button at the end of a type="password" field. The host keeps type="password" throughout — only the inner input switches to text — so form semantics, autocomplete and password managers never see a type change. Ignored on any other type (dev warning).
passwordVisiblepassword-visiblebooleanfalseWhether the password is shown as plain text (type="password" only). Set it to reveal or hide from code; the show / hide button and a form submit or reset change it too. A submit or reset always hides it, so the browser never records the credential from a text field.
showPasswordLabelshow-password-labelstring'Show password'The show / hide button's accessible name while the password is hidden. The name swaps with the state (GOV.UK, Web Awesome, Carbon), so the button says what a press does. Set it to localize.
hidePasswordLabelhide-password-labelstring'Hide password'The show / hide button's accessible name while the password is shown.
form—HTMLFormElement | null——
validity—ValidityState——
validationMessage—string——

Events ​

EventDetailDescription
input—Fired when the input value changes. Detail:
change—Fired when the input loses focus after a value change. Detail:
focus—Fired when the input receives focus. Detail: none
blur—Fired when the input loses focus. Detail: none
password-visibility-change—Fired when the show / hide button reveals or hides the password, and when a form submit or reset hides it again; not when password-visible is set. Detail: TextInputPasswordVisibilityDetail

CSS Parts ​

PartDescription
baseThe text input's base wrapper element
labelThe label element
containerThe input container element
inputThe native input element
leading-iconThe leading icon container
search-iconThe magnifier box of a search field
trailing-iconThe trailing icon container
clear-buttonThe clear (×) button
password-toggleThe show / hide password button
helper-textThe helper text element
error-messageThe error message element
warning-messageThe warning message element
message-iconThe icon starting the error or warning message

CSS Custom Properties ​

The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.

PropertyDefaultDescription
--hy-text-input-background-surface-basevar(--hy-background-surface-base)Background color at rest
--hy-text-input-border-subtle-restvar(--hy-border-subtle-rest)Border color at rest
--hy-text-input-border-brand-restvar(--hy-border-brand-rest)Focused edge color, any focus method.
--hy-text-input-border-default-hovervar(--hy-border-default-hover)Border color on hover
--hy-text-input-border-danger-restvar(--hy-border-danger-rest)Border color for error state
--hy-text-input-border-warning-restvar(--hy-border-warning-rest)Border color for warning state
--hy-text-input-border-default-disabledvar(--hy-border-default-disabled)Border color when disabled — the same disabled edge as every other field (binding rules C7 / F1)
--hy-text-input-foreground-warning-restvar(--hy-foreground-warning-rest)Warning message text and icon color
--hy-text-input-gap-layout-2xsvar(--hy-gap-layout-2xs)Gap between the message icon and its text
--hy-text-input-stroke-smvar(--hy-stroke-sm)Border width
--hy-text-input-radius-form-mdvar(--hy-radius-form-md)Border radius
--hy-text-input-padding-layout-lgvar(--hy-padding-layout-lg)Horizontal padding
--hy-text-input-padding-form-smvar(--hy-padding-form-sm)Vertical padding for small size
--hy-text-input-padding-form-mdvar(--hy-padding-form-md)Vertical padding for medium size
--hy-text-input-padding-form-lgvar(--hy-padding-form-lg)Vertical padding for large size
--hy-text-input-gap-form-smvar(--hy-gap-form-sm)Gap between input elements
--hy-text-input-gap-form-mdvar(--hy-gap-form-md)Gap between container sections
--hy-text-input-clear-button-foreground-subtle-restvar(--hy-foreground-subtle-rest)Clear button glyph color
--hy-text-input-clear-button-foreground-default-restvar(--hy-foreground-default-rest)Clear button glyph color on hover
--hy-text-input-clear-button-radius-form-smvar(--hy-radius-form-sm)Clear button corner
--hy-text-input-password-toggle-foreground-subtle-restvar(--hy-foreground-subtle-rest)Show / hide button glyph color
--hy-text-input-password-toggle-foreground-default-restvar(--hy-foreground-default-rest)Show / hide button glyph color on hover
--hy-text-input-password-toggle-foreground-default-disabledvar(--hy-foreground-default-disabled)Show / hide button glyph color when the input is disabled
--hy-text-input-foreground-icon-default-disabledvar(--hy-foreground-icon-default-disabled)The leading / trailing icon's color when the input is disabled
--hy-text-input-password-toggle-radius-form-smvar(--hy-radius-form-sm)Show / hide button corner (its focus ring follows it)
--hy-text-input-label-column-width—Width of the label column in layout="inline" mode. No default — set on a wrapping container so stacked inputs align.
--hy-text-input-search-icon-placementstartThe side a type="search" field draws its magnifier on: start (the default) or end, after the clear and reveal buttons. A design system's setting; the instance names no glyph.
--hy-text-input-control-height-smvar(--hy-control-height-sm)Outer height for small size variant. Per-component override in the form-control height contract.
--hy-text-input-control-height-mdvar(--hy-control-height-md)Outer height for medium size variant.
--hy-text-input-control-height-lgvar(--hy-control-height-lg)Outer height for large size variant.

Methods ​

focus() ​

Sets focus on the input.

blur() ​

Removes focus from the input.

select() ​

Selects all text in the input.

Built with Lit. Documented with VitePress.