import { Input } from "@/components/ui/input";
export function InputDemo() {
return (
<div className="w-full max-w-sm">
<Input type="email" placeholder="Email" />
</div>
);
}
pnpm dlx shadcn@latest add https://herocn.dev/r/input.jsonimport { Input } from "@/components/ui/input"<Input placeholder="Email" type="email" />Use the variant prop for a softer background on the secondary style.
import { Input } from "@/components/ui/input";
export function InputVariants() {
return (
<div className="flex w-full max-w-sm flex-col gap-3">
<Input placeholder="Default" />
<Input variant="secondary" placeholder="Secondary" />
</div>
);
}
Disabled inputs are non-interactive. Set aria-invalid for error styling (for example when validation fails).
import { Input } from "@/components/ui/input";
export function InputStates() {
return (
<div className="flex w-full max-w-sm flex-col gap-3">
<Input disabled placeholder="Disabled" />
<Input aria-invalid placeholder="Invalid" defaultValue="Invalid value" />
</div>
);
}
Pair Input with Field, FieldLabel, and FieldDescription for accessible labels and helper text.
Choose a unique username for your account.
import {
Field,
FieldDescription,
FieldLabel,
} from "@/components/ui/field";
import { Input } from "@/components/ui/input";
export function InputField() {
return (
<div className="w-full max-w-sm">
<Field>
<FieldLabel htmlFor="input-field-username">Username</FieldLabel>
<Input
id="input-field-username"
type="text"
placeholder="Enter your username"
/>
<FieldDescription>
Choose a unique username for your account.
</FieldDescription>
</Field>
</div>
);
}
Stack multiple fields and actions with FieldGroup.
We'll send updates to this address.
import { Button } from "@/components/ui/button";
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/components/ui/field";
import { Input } from "@/components/ui/input";
export function InputFieldgroup() {
return (
<div className="w-full max-w-sm">
<FieldGroup>
<Field>
<FieldLabel htmlFor="fieldgroup-name">Name</FieldLabel>
<Input id="fieldgroup-name" placeholder="Jordan Lee" />
</Field>
<Field>
<FieldLabel htmlFor="fieldgroup-email">Email</FieldLabel>
<Input
id="fieldgroup-email"
type="email"
placeholder="[email protected]"
/>
<FieldDescription>
We'll send updates to this address.
</FieldDescription>
</Field>
<Field orientation="horizontal">
<Button type="reset" variant="outline">
Reset
</Button>
<Button type="submit">Submit</Button>
</Field>
</FieldGroup>
</div>
);
}
Use a badge in the label row for status or metadata (for example a feature flag).
import { Badge } from "@/components/ui/badge";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
export function InputBadge() {
return (
<div className="w-full max-w-sm">
<Field>
<FieldLabel
htmlFor="input-badge"
className="flex w-full items-center gap-2"
>
Webhook URL
<Badge variant="default" className="ml-auto">
Beta
</Badge>
</FieldLabel>
<Input
id="input-badge"
type="url"
placeholder="https://api.example.com/webhook"
/>
</Field>
</div>
);
}
Prefix or suffix text and icons with InputGroup, InputGroupAddon, and InputGroupInput.
import { InfoIcon } from "lucide-react";
import { Field, FieldLabel } from "@/components/ui/field";
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText,
} from "@/components/ui/input-group";
export function InputInputGroup() {
return (
<div className="w-full max-w-sm">
<Field>
<FieldLabel htmlFor="input-group-url">Website URL</FieldLabel>
<InputGroup>
<InputGroupInput id="input-group-url" placeholder="example.com" />
<InputGroupAddon>
<InputGroupText>https://</InputGroupText>
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<InfoIcon />
</InputGroupAddon>
</InputGroup>
</Field>
</div>
);
}
Place the input beside actions using ButtonGroup.
import { Button } from "@/components/ui/button";
import { ButtonGroup } from "@/components/ui/button-group";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
export function InputButtonGroup() {
return (
<div className="w-full max-w-sm">
<Field>
<FieldLabel htmlFor="input-button-group">Search</FieldLabel>
<ButtonGroup>
<Input
id="input-button-group"
variant="secondary"
placeholder="Type to search..."
/>
<Button variant="tertiary">Search</Button>
</ButtonGroup>
</Field>
</div>
);
}
Use variant="secondary" when placing an Input inside a card or panel surface for a subtler, shadow-free appearance that blends with the surface background.
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Surface } from "@/components/ui/surface";
export function InputInSurface() {
return (
<Surface className="flex w-full max-w-sm flex-col gap-3 rounded-3xl p-6">
<Field>
<FieldLabel htmlFor="input-in-surface-message">
What's your name?
</FieldLabel>
<Input id="input-in-surface-message" variant="secondary" />
</Field>
<Button>Submit</Button>
</Surface>
);
}
لن نشارك بريدك الإلكتروني مع أي شخص.
"use client";
import {
type Translations,
useTranslation,
} from "@/components/language-selector";
import {
Field,
FieldDescription,
FieldLabel,
} from "@/components/ui/field";
import { Input } from "@/components/ui/input";
const translations: Translations = {
en: {
dir: "ltr",
values: {
nameLabel: "Full name",
namePlaceholder: "John Doe",
emailLabel: "Email address",
emailPlaceholder: "[email protected]",
emailDescription: "We'll never share your email with anyone.",
},
},
ar: {
dir: "rtl",
values: {
nameLabel: "الاسم الكامل",
namePlaceholder: "محمد علي",
emailLabel: "البريد الإلكتروني",
emailPlaceholder: "[email protected]",
emailDescription: "لن نشارك بريدك الإلكتروني مع أي شخص.",
},
},
he: {
dir: "rtl",
values: {
nameLabel: "שם מלא",
namePlaceholder: "ישראל ישראלי",
emailLabel: "כתובת דוא״ל",
emailPlaceholder: "[email protected]",
emailDescription: "לעולם לא נשתף את הדוא״ל שלך עם אחרים.",
},
},
};
export function InputRtl() {
const { dir, language, t } = useTranslation(translations, "ar");
return (
<div
className="flex w-full max-w-sm flex-col gap-4"
lang={language}
dir={dir}
>
<Field>
<FieldLabel htmlFor="form-input-rtl-name">{t.nameLabel}</FieldLabel>
<Input
type="text"
id="form-input-rtl-name"
placeholder={t.namePlaceholder}
/>
</Field>
<Field>
<FieldLabel htmlFor="form-input-rtl-email">{t.emailLabel}</FieldLabel>
<Input
type="email"
id="form-input-rtl-email"
placeholder={t.emailPlaceholder}
/>
<FieldDescription>{t.emailDescription}</FieldDescription>
</Field>
</div>
);
}
The Input component accepts all props from a native <input> and @base-ui/react Input plus the following:
| Prop | Type | Default |
|---|---|---|
| variant | "default" | "secondary" | "default" |