Skip to main content

Input

A text input field for collecting user data.

Usage

import { Input } from '@easy-ui-react/easy-ui-react'

export function Example() {
const [value, setValue] = useState('')
return <Input value={value} onValueChange={setValue} placeholder="Type here..." />
}
Live Editor
<Input color="primary" placeholder="Type here..." />
Result
Loading...

Variants

VariantDescription
borderedFull border, transparent background (default)
fadedFull border, tinted background
flatTinted background, no border
underlinedBottom border only, no radius
Live Editor
<Input variant="bordered" placeholder="Bordered" />
Result
Loading...

Colors

  • default
  • primary
  • secondary
  • success
  • warning
  • error

Variant affects colors. Have a look to Storybook to see how the component is rendering depending on the variant.

Live Editor
<Input color="primary" placeholder="Primary" />
Result
Loading...

Sizes

  • sm
  • md
  • lg
Live Editor
<Input size="sm" placeholder="Small" />
Result
Loading...

Radius

  • none
  • sm
  • md
  • lg
  • full
Live Editor
<Input radius="sm" placeholder="Rounded" />
Result
Loading...

sm, md and lg map to --easyui-radius-* CSS variables, see the theming guide.

The underlined variant always uses rounded-none regardless of the radius prop.

Content

Add an icon (or any node) before/after the input with startContent / endContent. By default, they sit inside the bordered box. Set startContentPlacement / endContentPlacement to outside to render them outside the input area.

Live Editor
<Input
  startContent={<Search size={16} />}
  endContent={<Mail size={16} />}
  placeholder="Search..."
/>
Result
Loading...

Number

With type="number", Input replaces the browser's default spinner arrows with a styled stepper. It stays a native number field: min, max and step still apply, and the value is clamped natively when you increment or decrement.

Live Editor
<Input type="number" label="Quantity" defaultValue={3} min={0} max={10} placeholder="0" />
Result
Loading...

When a bound is reached, the matching chevron is disabled.

Live Editor
<Input type="number" label="Reached max" defaultValue={10} min={0} max={10} />
Result
Loading...

Set showStepper={false} to hide the stepper entirely while keeping a number field (the value is still editable by typing).

Live Editor
<Input type="number" showStepper={false} defaultValue={3} />
Result
Loading...

The stepper zone has its own slots (stepper, incrementButton, decrementButton), so it can be restyled without touching endContent. See Slots.

States

Loading

Set isLoading to show a spinner and disable the input.

Live Editor
<Input isLoading placeholder="Loading..." />
Result
Loading...

Disabled

Live Editor
<Input isDisabled placeholder="Disabled" />
Result
Loading...

Read only

Live Editor
<Input isReadOnly value="Read-only value" />
Result
Loading...

Full width

Live Editor
<Input isFullWidth placeholder="Full width" />
Result
Loading...

Label & description

Live Editor
<Input
  label="Email address"
  description="We will never share your email."
  placeholder="you@example.com"
/>
Result
Loading...

Use descriptionPlacement to render the description below the label instead of below the input:

Live Editor
<Input
  label="Email address"
  description="We will never share your email."
  descriptionPlacement="label"
  placeholder="you@example.com"
/>
Result
Loading...

Required

Add isRequired to mark the field as required — an asterisk appears next to the label.

Live Editor
<Input label="Email" isRequired placeholder="you@example.com" />
Result
Loading...

Error

Pass an error string to show a message below the input. This is the externally controlled error channel: use it for errors the field cannot produce on its own (a server-side response, an async check, a cross-field rule). It always takes precedence over the field's own validation (isRequired, validations), so a non-empty error is always the message shown.

Live Editor
<Input label="Email" error="Invalid email address." placeholder="you@example.com" />
Result
Loading...

Validation

Use the validations prop to define an array of validators. Each validator is a function (value: string) => string | null that returns null if valid, or an error message string if invalid. Validation runs on blur.

Live Editor
<Input
  label="Email"
  placeholder="you@example.com"
  validations={[
    v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v) ? null : 'Invalid email address'
  ]}
/>
Result
Loading...

Multiple validators run in order; the first failure's message is shown.

The error prop (external) always takes precedence over a validations error.

Slots

Customize individual parts via classNames:

SlotDescription
baseRoot <div> wrapping the whole field
labelThe <label> element
inputWrapperThe visual bordered/background box
inputThe native <input> element
startContentWrapper around startContent
endContentWrapper around endContent
spinnerThe loading spinner
stepperWrapper around the number stepper buttons
incrementButtonThe increment (up) button of the number stepper
decrementButtonThe decrement (down) button of the number stepper
descriptionThe helper text element
errorThe error message element
Live Editor
<Input
  classNames={{ inputWrapper: 'shadow-md', input: 'font-mono' }}
  placeholder="Custom slots"
/>
Result
Loading...

These slots can also be styled globally for every Input in your app, see the global configuration guide.

Props

PropTypeDefaultDescription
variant'bordered' | 'faded' | 'flat' | 'underlined''bordered'Visual style
color'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error''default'Focus color
size'sm' | 'md' | 'lg''md'Input size
radius'none' | 'sm' | 'md' | 'lg' | 'full''md'Corner radius
isDisabledbooleanfalseDisables the input
isLoadingbooleanfalseShows a spinner and disables the input
isRequiredbooleanfalseMarks the field as required
isRequiredMessagestring-Message shown when a required field is left empty
isReadOnlybooleanfalseMakes the input read-only
isFullWidthbooleanfalseMakes the input take the full available width
showStepperbooleantrueShows the stepper buttons when type="number"
labelstring-Label rendered above the input
descriptionstring-Helper text
descriptionPlacement'label' | 'element''element'Render description below the label or below the input
errorstring-Externally controlled error, takes precedence over local validation
validationsArray<(value: string) => string | null>-Validators run on blur
onValueChange(value: string) => void-Shorthand for onChange returning just the value
startContentReactNode-Content rendered before the input text
endContentReactNode-Content rendered after the input text
startContentPlacement'inside' | 'outside''inside'Where startContent is rendered
endContentPlacement'inside' | 'outside''inside'Where endContent is rendered
classNamestring-Class applied to the root element
classNamesPartial<Record<InputSlots, string>>-Per-slot class overrides

Input also accepts every native <input> attribute (value, defaultValue, placeholder, type, name, autoComplete, etc.) and forwards ref to the underlying <input> element.

Storybook

Open in Storybook → and see more combinations.