Input
A recessed text well. Focus brightens the floor of the well; invalid state deepens the recess and inks the text in danger.
@emboss/input
Installation
pnpm dlx shadcn@latest add @emboss/inputUsage
import { Input } from "@/components/ui/input";
export function Example() {
return <Input placeholder="Serial number" />;
}Examples
Invalid
Invalid state is carried by depth, color, and the aria-invalid attribute together.
Show codeHide code
import { Input } from "@/components/ui/input";
export default function InputInvalid() {
return (
<div className="flex w-full max-w-64 flex-col gap-1.5">
<Input
aria-label="Serial number"
aria-invalid
aria-describedby="serial-error"
defaultValue="EM-1?0"
/>
<p id="serial-error" className="text-sm text-danger">
Serial numbers contain only letters, digits, and dashes.
</p>
</div>
);
}Disabled
Show codeHide code
import { Input } from "@/components/ui/input";
export default function InputDisabled() {
return (
<div className="w-full max-w-64">
<Input aria-label="Serial number" disabled defaultValue="EM-100" />
</div>
);
}API reference
Input
Extends the native input element and composes with Base UI Field for label and message wiring.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "md" | Control height of the well. |
| defaultValue / value / onChange | string / string / ChangeEventHandler | — | Standard controlled and uncontrolled usage. |
Source
View source — input.tsxHide source — input.tsx
"use client";
import { Input as BaseInput } from "@base-ui/react/input";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const inputVariants = cva(
"w-full min-w-0 rounded-sm bg-well text-ink shadow-deboss-1 focus-ring transition-[background-color,box-shadow] duration-(--duration-release) ease-(--ease-release) selection:bg-accent selection:text-accent-fg placeholder:text-ink-faint focus-visible:bg-surface-1 disabled:pointer-events-none disabled:opacity-50 aria-invalid:text-danger aria-invalid:shadow-deboss-2 aria-invalid:placeholder:text-danger/60",
{
variants: {
size: {
sm: "h-(--control-sm) px-2.5 text-sm",
md: "h-(--control-md) px-3 text-sm",
lg: "h-(--control-lg) px-3.5 text-base",
},
},
defaultVariants: {
size: "md",
},
},
);
export type InputProps = Omit<React.ComponentProps<typeof BaseInput>, "size"> &
VariantProps<typeof inputVariants>;
/**
* A recessed text well. Focus brightens the floor of the well and powers the
* focus ring; invalid state deepens the recess and inks the text in danger.
* Composes with Base UI Field for label and message wiring.
*
* @example
* <Input placeholder="Serial number" />
*/
function Input({ className, size, ...props }: InputProps) {
return (
<BaseInput
data-slot="input"
className={cn(inputVariants({ size }), className)}
{...props}
/>
);
}
export { Input };