UI/UI
Label
Displays a label element with enhanced styling and accessibility features for form controls.
Usage
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="Enter your email" />
</div>;
Installation
Install following dependencies:
npm install class-variance-authority
pnpm add class-variance-authority
yarn add class-variance-authority
bun add class-variance-authority
Copy and paste the following code into your project.
"use client";
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
{
variants: {
variant: {
default: "text-[hsl(var(--hu-foreground))]",
destructive: "text-[hsl(var(--hu-destructive))]",
muted: "text-[hsl(var(--hu-muted-foreground))]",
},
size: {
default: "text-sm",
sm: "text-xs",
lg: "text-base",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
export interface LabelProps
extends React.LabelHTMLAttributes<HTMLLabelElement>,
VariantProps<typeof labelVariants> {
required?: boolean;
optional?: boolean;
}
const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
(
{ className, variant, size, required, optional, children, ...props },
ref,
) => {
return (
<label
ref={ref}
className={cn(labelVariants({ variant, size, className }))}
{...props}
>
{children}
{required && (
<span
className="text-[hsl(var(--hu-destructive))] ml-1"
aria-label="required"
>
*
</span>
)}
{optional && !required && (
<span className="text-[hsl(var(--hu-muted-foreground))] ml-1 font-normal">
(optional)
</span>
)}
</label>
);
},
);
Label.displayName = "Label";
export { Label, labelVariants };
npx hextaui@latest add label
pnpm dlx hextaui@latest add label
yarn dlx hextaui@latest add label
bun x hextaui@latest add label
Usage
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="Enter your email" />
</div>
Examples
Sizes
<div className="grid w-full items-center gap-1.5">
<Label size="sm" htmlFor="small">Small Label</Label>
<Input id="small" placeholder="Small input" size="sm" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="default">Default Label</Label>
<Input id="default" placeholder="Default input" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label size="lg" htmlFor="large">Large Label</Label>
<Input id="large" placeholder="Large input" size="lg" />
</div>
Variants
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="default-variant">Default Label</Label>
<Input id="default-variant" placeholder="Enter text" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label variant="destructive" htmlFor="error-variant">Error Label</Label>
<Input id="error-variant" placeholder="Enter text" error />
</div>
<div className="grid w-full items-center gap-1.5">
<Label variant="muted" htmlFor="muted-variant">Muted Label</Label>
<Input id="muted-variant" placeholder="Enter text" />
</div>
Required and Optional Labels
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="required-field" required>Required Field</Label>
<Input id="required-field" placeholder="This field is required" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="optional-field" optional>Optional Field</Label>
<Input id="optional-field" placeholder="This field is optional" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="normal-field">Normal Field</Label>
<Input id="normal-field" placeholder="Normal field" />
</div>
With Icons and Complex Inputs
import { Mail, Lock, User } from "lucide-react";
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="email-with-icon" required>Email Address</Label>
<Input
id="email-with-icon"
type="email"
placeholder="Enter your email"
leftIcon={<Mail />}
clearable
/>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="password-with-icon" required>Password</Label>
<Input
id="password-with-icon"
type="password"
placeholder="Enter your password"
leftIcon={<Lock />}
/>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="username-with-icon" optional>Username</Label>
<Input
id="username-with-icon"
type="text"
placeholder="Choose a username"
leftIcon={<User />}
clearable
/>
</div>
Form Layout Examples
<form className="space-y-4">
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="form-email" required>
Email
</Label>
<Input
id="form-email"
type="email"
placeholder="Enter your email"
leftIcon={<Mail />}
clearable
/>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="form-password" required>
Password
</Label>
<Input
id="form-password"
type="password"
placeholder="Enter your password"
leftIcon={<Lock />}
/>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="form-confirm" required>
Confirm Password
</Label>
<Input
id="form-confirm"
type="password"
placeholder="Confirm your password"
leftIcon={<Lock />}
/>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="form-bio" optional>
Bio
</Label>
<Input id="form-bio" placeholder="Tell us about yourself" clearable />
</div>
</form>
Disabled State
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="disabled-input">Disabled Field</Label>
<Input id="disabled-input" placeholder="Disabled input" disabled />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="disabled-required" required>Disabled Required Field</Label>
<Input id="disabled-required" placeholder="Disabled required input" disabled />
</div>
Form Association
The Label component works seamlessly with form controls:
// Proper association using htmlFor
<Label htmlFor="email">Email Address</Label>
<Input id="email" type="email" />
// Required field indication
<Label htmlFor="password" required>Password</Label>
<Input id="password" type="password" />
// Optional field indication
<Label htmlFor="bio" optional>Biography</Label>
<Input id="bio" />
Props
Prop | Type | Default |
---|---|---|
className? | string | undefined |
optional? | boolean | false |
required? | boolean | false |
size? | "default" | "sm" | "lg" | "default" |
variant? | "default" | "destructive" | "muted" | "default" |
Edit on GitHub
Last updated on