Use Input for short text, email, password, or file entry. It wraps Base UI Input and preserves ordinary input props. Use Textarea for multi-line text and Input Group for attached units or actions.
Live preview
import { Input } from "@/components/ui/input";
export default function InputDemo() {
return (
<div className="grid w-full max-w-sm gap-2">
<label htmlFor="invite-email" className="text-sm font-heading leading-none select-none">
Invite by email
</label>
<Input
id="invite-email"
name="email"
type="email"
autoComplete="email"
placeholder="name@example.com"
aria-describedby="invite-email-help"
/>
<p id="invite-email-help" className="text-sm text-foreground/70">
An invitation is sent only after the form is submitted.
</p>
</div>
);
}
#Installation
Complete the base setup. For manual installation:
First time? Install the shared base once.
npx shadcn@latest add https://neobrutal-ui.andongmin.com/r/input.jsonnpm install @base-ui/react@^1.8.0Create components/ui/input.tsx:
"use client";
import { Input as InputPrimitive } from "@base-ui/react/input";
import * 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(
"flex h-10 w-full rounded-base border-2 border-input bg-secondary-background selection:bg-main selection:text-main-foreground px-3 py-2 text-sm font-base text-foreground file:border-0 file:bg-transparent file:text-sm file:font-heading placeholder:text-foreground/50 focus-visible:border-ring focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...props}
/>
);
}
export { Input };
#Usage
import { Input } from "@/components/ui/input";
export default function EmailField() {
return (
<div className="grid w-full max-w-sm gap-2">
<label htmlFor="email">Email address</label>
<Input
id="email"
name="email"
type="email"
autoComplete="email"
required
aria-describedby="email-help"
/>
<p id="email-help" className="text-sm">
Used only for workspace invitations.
</p>
</div>
);
}#API reference
| Prop | Purpose | Default |
|---|---|---|
type | Native type such as text, email, password, file | text |
value / onChange | Controlled value and native event | Uncontrolled |
defaultValue | Initial uncontrolled value | — |
id / name | Label association and form key | — |
disabled / required / readOnly | Native constraints | false |
aria-invalid / aria-describedby | Invalid state and supporting text | Unset |
#Accessibility
Provide a visible label or justified accessible name. A placeholder is not a label. Match autocomplete and input mode to the task. Do not control the value of a file input. Associate validation feedback with the field and validate submitted data on the server.
#Examples
The File and With label examples additionally use Label. Install it before copying their Code:
npx shadcn@latest add https://neobrutal-ui.andongmin.com/r/label.json#File
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export default function InputFileDemo() {
return (
<div className="grid w-full max-w-64 items-center gap-1.5">
<Label htmlFor="picture">Picture</Label>
<Input id="picture" type="file" />
</div>
);
}
#Disabled
import { Input } from "@/components/ui/input";
export default function InputDisabledDemo() {
return (
<Input className="max-w-[200px]" type="email" placeholder="Email" aria-label="Email" disabled />
);
}
#With label
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export default function InputWithLabelDemo() {
return (
<div className="grid max-w-[200px] items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Email" />
</div>
);
}
#With button
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
export default function InputWithButtonDemo() {
return (
<div className="flex w-full max-w-sm items-center space-x-2">
<Input type="email" placeholder="Email" aria-label="Email" />
<Button variant="noShadow" type="submit">
Subscribe
</Button>
</div>
);
}