rapidUI

Input

Text input with consistent sizing, focus and invalid states.

Installation

pnpm dlx shadcn@latest add https://rdf.dev.360online.com/r/input.json

Installs to @/components/ui/input.

Manual installation

Install the dependencies:

pnpm add @base-ui/react@^1.8.0

Copy the source into your project:

components/ui/input.tsx
import { Input as InputPrimitive } from '@base-ui/react/input'
import type * as React from 'react'
import { cn } from '@/lib/utils'

function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
	return (
		<InputPrimitive
			type={type}
			data-slot="input"
			className={cn(
				'h-10 w-full min-w-0 rounded-lg border border-input bg-background px-3 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground hover:border-primary/90 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40',
				type !== 'file' &&
					'read-only:cursor-default read-only:border-dashed read-only:bg-muted/50 read-only:hover:border-input',
				className,
			)}
			{...props}
		/>
	)
}

export { Input }

A styled native HTML input element. It accepts every standard input attribute and has built-in styles for focus, disabled, invalid (aria-invalid) and file states. Icons, loading indicators and buttons (such as a password visibility toggle) are composed with InputGroup.

Features

  • Plain native input — all HTML input attributes and types are supported
  • Focus ring, disabled and aria-invalid error styling out of the box
  • Styled type="file" inputs
  • Dark mode support
  • Compose icons, text and buttons with InputGroup

Usage

import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'

<div className="grid w-full max-w-sm items-center gap-1.5">
  <Label htmlFor="case-number">Case number</Label>
  <Input id="case-number" placeholder="2026-04812" />
</div>

// Invalid state
<Input aria-invalid defaultValue="not-an-email" />

With an icon or a button, use InputGroup:

import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group'

<InputGroup>
  <InputGroupAddon>
    <MailIcon />
  </InputGroupAddon>
  <InputGroupInput type="email" placeholder="name@example.se" />
</InputGroup>

Examples

Default

An input paired with a FieldLabel.

With Description

A FieldDescription below the input explains what the value is used for.

Address

Several inputs in a FieldSet, with autoComplete hints so browsers can fill in the address.

With Button

An input and a button side by side.

Disabled

Readonly

Read-only inputs get a dashed border and a muted background.

Invalid

Set aria-invalid to show the destructive border and ring, and point aria-describedby at the error message.

File Input

With Validation

Client-side validation of a case number that toggles aria-invalid once the value is complete.

With Icon

An icon composed with InputGroup.

Loading

A Spinner composed with InputGroup, for example while address suggestions load.

Password

A password visibility toggle composed with InputGroup and InputGroupButton.

Props

Input accepts all native input props (React.ComponentProps<'input'>), including className. It has no custom props.

Accessibility

  • Uses the native HTML input element
  • Pair with a Label via htmlFor / id
  • Use aria-invalid and aria-describedby to announce errors
  • Clear focus indicators and keyboard support

Best Practices

  1. Use the appropriate type (text, email, password, etc.) for validation and mobile keyboards.
  2. Always use a label; placeholders are supplementary only.
  3. Mark invalid fields with aria-invalid and show a clear error message.
  4. Use InputGroup instead of absolutely positioned elements for icons and buttons.
  • Input Group
  • Textarea
  • Label
  • Field
  • Form