Back to Heroui

Input

apps/docs/content/docs/react/components/(forms)/input.mdx

3.0.34.1 KB
Original Source

Import

tsx
import { Input } from '@heroui/react';
<Callout> For validation, labels, and error messages, see **[TextField](/docs/components/text-field)**. </Callout>

Usage

<ComponentPreview name="input-basic" />

Input Types

<ComponentPreview name="input-types" />

Controlled

<ComponentPreview name="input-controlled" />

Full Width

<ComponentPreview name="input-full-width" />

Variants

The Input component supports two visual variants:

  • primary (default) - Standard styling with shadow, suitable for most use cases
  • secondary - Lower emphasis variant without shadow, suitable for use in Surface components
<ComponentPreview name="input-variants" />

In Surface

When used inside a Surface component, use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.

<ComponentPreview name="input-on-surface" /> <RelatedComponents component="input" />

Styling

Passing Tailwind CSS classes

tsx
import {Input, Label} from '@heroui/react';

function CustomInput() {
  return (
    <div className="flex flex-col gap-2">
      <Label htmlFor="custom-input">Project name</Label>
      <Input
        id="custom-input"
        className="rounded-xl border border-border/70 bgsurface px-4 py-2 text-sm shadow-sm focus-visible:border-primary"
        placeholder="New web app"
      />
    </div>
  );
}

Customizing the component classes

The base class .input powers every instance. Override it once with @layer components.

css
@layer components {
  .input {
    @apply rounded-lg border border-border bgsurface px-4 py-2 text-sm shadow-sm transition-colors;

    &:hover,
    &[data-hovered="true"] {
      @apply bg-surface-secondary border-border/80;
    }

    &:focus-visible,
    &[data-focus-visible="true"] {
      @apply border-primary ring-2 ring-primary/20;
    }

    &[data-invalid="true"] {
      @apply border-danger bg-danger-50/10 text-danger;
    }
  }
}

CSS Classes

  • .input – Native input element styling

Interactive States

  • Hover: :hover or [data-hovered="true"]
  • Focus Visible: :focus-visible or [data-focus-visible="true"]
  • Invalid: [data-invalid="true"] (also syncs with aria-invalid)
  • Disabled: :disabled or [aria-disabled="true"]
  • Read Only: [aria-readonly="true"]

API Reference

Input Props

Input accepts all standard HTML <input> attributes plus the following:

PropTypeDefaultDescription
classNamestring-Tailwind classes merged with the component styles.
typestring"text"Input type (text, email, password, number, etc.).
valuestring-Controlled value.
defaultValuestring-Uncontrolled initial value.
onChange(event: React.ChangeEvent<HTMLInputElement>) => void-Change handler.
placeholderstring-Placeholder text.
disabledbooleanfalseDisables the input.
readOnlybooleanfalseMakes the input read-only.
requiredbooleanfalseMarks the input as required.
namestring-Name for form submission.
autoCompletestring-Autocomplete hint for the browser.
maxLengthnumber-Maximum number of characters.
minLengthnumber-Minimum number of characters.
patternstring-Regex pattern for validation.
minnumber | string-Minimum value (for number/date inputs).
maxnumber | string-Maximum value (for number/date inputs).
stepnumber | string-Stepping interval (for number inputs).
fullWidthbooleanfalseWhether the input should take full width of its container
variant"primary" | "secondary""primary"Visual variant of the component. primary is the default style with shadow. secondary is a lower emphasis variant without shadow, suitable for use in surfaces.

For validation props like isInvalid, isRequired, and error handling, use TextField with Input as a child component.