Skip to content
UI

Input

A single-line text field for typing a value, such as a name, a domain, an IP range or a search query.

@zenoxai/ui/components/inputBase UI Markdown
<Input
  type="search"
  placeholder="Search alerts"
  aria-label="Search alerts"
  className="max-w-xs"
/>

Usage

import { Input } from "@zenoxai/ui/components/input"

<Input type="email" placeholder="soc@acme.com" />

Input renders a native <input> and accepts all of its attributes: type, value, defaultValue, onChange, name, required, pattern, autoComplete. It is 32px tall (size="default") and fills the width of its container; constrain it with a width class or the layout around it. The size prop sets the height, so the native size attribute (a width in characters) is not available.

Pick a more specific control when the value has a shape:

Value Use
A number with a range or a step Number Input
One option from a fixed list Select
One option from a long, searchable list Combobox
A one-time code Input OTP
Several lines of text Textarea
An icon, a prefix or a button inside Input Group

A type="search" field shows no browser clear button: each browser draws its own, and they do not match the rest of the interface. When a search field needs a clear action, build it with an Input Group and a clear button, as in its first example.

Examples

With a label

Wrap the input in a Field with a FieldLabel and, when the value needs explaining, a FieldDescription. A placeholder is an example value, never the label: it disappears as soon as the user types.

Receives the weekly vulnerability report.

<Field className="max-w-sm">
  <FieldLabel htmlFor="report-recipient">Report recipient</FieldLabel>
  <Input
    id="report-recipient"
    type="email"
    placeholder="soc@acme.com"
    aria-describedby="report-recipient-description"
  />
  <FieldDescription id="report-recipient-description">
    Receives the weekly vulnerability report.
  </FieldDescription>
</Field>

Sizes

size="sm" (28px) fits toolbars and filter bars, default (32px) is the form size and lg (36px) suits a search field on an empty state. The sizes match the heights of Button, Select, Number Input and Input Group, so a field and the button next to it line up.

<div className="flex w-full max-w-xs flex-col gap-3">
  <Input size="sm" placeholder="Filter assets" aria-label="Filter assets" />
  <Input placeholder="Search alerts" aria-label="Search alerts" />
  <Input
    size="lg"
    placeholder="Search domains"
    aria-label="Search domains"
  />
</div>

Invalid

Set aria-invalid on the input and data-invalid on the Field, and put the message in a FieldError linked through aria-describedby.

<Field data-invalid className="max-w-sm">
  <FieldLabel htmlFor="allowed-ip">Allowed IP range</FieldLabel>
  <Input
    id="allowed-ip"
    defaultValue="10.0.0.0/33"
    aria-invalid
    aria-describedby="allowed-ip-error"
  />
  <FieldError id="allowed-ip-error">
    Enter a CIDR range with a prefix from 0 to 32.
  </FieldError>
</Field>

Read-only and disabled

Use readOnly for a value the user can see, select and copy but not change, such as an ID. Use disabled for a value that does not apply right now; it is skipped by keyboard focus and not submitted with the form. A disabled field is dimmed to 50%, like every disabled control. Set data-disabled on the Field to dim the label too.

<div className="grid w-full max-w-sm gap-4">
  <Field>
    <FieldLabel htmlFor="tenant-id">Tenant ID</FieldLabel>
    <Input id="tenant-id" defaultValue="tnt_8f3k2m9q" readOnly />
  </Field>
  <Field data-disabled>
    <FieldLabel htmlFor="sso-domain">SSO domain</FieldLabel>
    <Input id="sso-domain" defaultValue="acme.okta.com" disabled />
  </Field>
</div>

File

type="file" styles the native file button to match the input. Restrict the file types with accept.

A CSV file with one hostname or IP per row.

<Field className="max-w-sm">
  <FieldLabel htmlFor="asset-import">Asset inventory</FieldLabel>
  <Input id="asset-import" type="file" accept=".csv" />
  <FieldDescription>
    A CSV file with one hostname or IP per row.
  </FieldDescription>
</Field>

Accessibility

  • Every input needs a name: a FieldLabel with htmlFor, or aria-label when the purpose is clear from the layout, as in a search box above a table.
  • Set type (email, url, search, tel) and autoComplete so mobile keyboards and password managers offer the right input.
  • The text is 16px below the md breakpoint so iOS does not zoom into the field on focus, and the 12.5px body size from md up.

API reference

Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.

Input

Input is a single-line text field. For several lines use Textarea; for a number with steppers, NumberInput; for icons, text or buttons attached to the field, InputGroup.

PropTypeDefault
size"default" | "sm" | "lg"

Height: `sm` 28px, `default` 32px, `lg` 36px, the heights of the Button sizes of the same names. Replaces the native `size` attribute (a width in characters); set the width with a class instead.

default