Components
A vertical form with labeled inputs where each field label has an info icon that reveals validation hints in a tooltip on hover.

import { InfoIcon } from "lucide-react";
import { Input } from "@/components/ui/v-tooltip-13-utils/input";
import { Label } from "@/components/ui/v-tooltip-13-utils/label";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/v-tooltip-13-utils/tooltip";
type Field = {
id: string;
label: string;
placeholder: string;
hint: string;
defaultOpen?: boolean;
};
const fields: Field[] = [
{
hint: "3–20 characters, letters, numbers, and underscores only.",
id: "username",
label: "Username",
placeholder: "john_doe",
defaultOpen: true,
},
{
hint: "Must be 8+ chars with at least one uppercase letter and one number.",
id: "password",
label: "Password",
placeholder: "••••••••",
},
{
hint: "We only use this for account recovery — no marketing emails.",
id: "email",
label: "Email",
placeholder: "you@example.com",
},
];
function Pattern() {
return (
<div className="w-full max-w-sm space-y-4">
<TooltipProvider>
{fields.map(({ id, label, placeholder, hint, defaultOpen }) => (
<div className="space-y-1.5" key={id}>
<div className="flex items-center gap-1.5">
<Label htmlFor={id}>{label}</Label>
<Tooltip defaultOpen={defaultOpen}>
<TooltipTrigger
aria-label={`${label} format requirements`}
className="inline-flex cursor-default text-muted-foreground hover:text-foreground"
>
<InfoIcon className="size-3.5" />
</TooltipTrigger>
<TooltipContent className="max-w-52">{hint}</TooltipContent>
</Tooltip>
</div>
<Input id={id} placeholder={placeholder} />
</div>
))}
</TooltipProvider>
</div>
);
}
export default function Default() {
return (
<div className="flex min-h-[400px] w-full items-center justify-center p-6">
<Pattern />
</div>
);
}
Part of Cnippet — browse the full library on 21st.dev.