Back to Prisma

Label

apps/eclipse/content/design-system/components/label.mdx

latest10.8 KB
Original Source

import { Label, Input, Button } from "@prisma/eclipse";

Usage

Basic Label

tsx
import { Label, Input } from "@prisma/eclipse";

export function BasicLabel() {
  return (
    <div className="space-y-2">
      <Label htmlFor="email">Email</Label>
      <Input id="email" type="email" placeholder="Enter your email" />
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="space-y-2"> <Label htmlFor="email-basic">Email</Label> <Input id="email-basic" type="email" placeholder="Enter your email" /> </div> </div>

Label with Required Indicator

tsx
import { Label, Input } from "@prisma/eclipse";

export function RequiredLabel() {
  return (
    <div className="space-y-2">
      <Label htmlFor="username">
        Username <span className="text-foreground-error">*</span>
      </Label>
      <Input id="username" placeholder="Enter username" required />
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="space-y-2"> <Label htmlFor="username-req"> Username <span className="text-foreground-error">*</span> </Label> <Input id="username-req" placeholder="Enter username" required /> </div> </div>

Multiple Inputs with Labels

tsx
import { Label, Input } from "@prisma/eclipse";

export function MultipleLabels() {
  return (
    <div className="space-y-4 max-w-md">
      <div className="space-y-2">
        <Label htmlFor="first-name">First Name</Label>
        <Input id="first-name" placeholder="John" />
      </div>
      <div className="space-y-2">
        <Label htmlFor="last-name">Last Name</Label>
        <Input id="last-name" placeholder="Doe" />
      </div>
      <div className="space-y-2">
        <Label htmlFor="email-multi">Email</Label>
        <Input id="email-multi" type="email" placeholder="[email protected]" />
      </div>
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="space-y-4"> <div className="space-y-2"> <Label htmlFor="first-name-live">First Name</Label> <Input id="first-name-live" placeholder="John" /> </div> <div className="space-y-2"> <Label htmlFor="last-name-live">Last Name</Label> <Input id="last-name-live" placeholder="Doe" /> </div> <div className="space-y-2"> <Label htmlFor="email-multi-live">Email</Label> <Input id="email-multi-live" type="email" placeholder="[email protected]" /> </div> </div> </div>

Disabled State

Labels automatically adapt when associated with disabled inputs:

tsx
import { Label, Input } from "@prisma/eclipse";

export function DisabledLabel() {
  return (
    <div className="space-y-4 max-w-md">
      <div className="space-y-2">
        <Label htmlFor="enabled">Enabled Field</Label>
        <Input id="enabled" placeholder="This is enabled" />
      </div>
      <div className="space-y-2">
        <Label htmlFor="disabled">Disabled Field</Label>
        <Input id="disabled" placeholder="This is disabled" disabled />
      </div>
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="space-y-4"> <div className="space-y-2"> <Label htmlFor="enabled-live">Enabled Field</Label> <Input id="enabled-live" placeholder="This is enabled" /> </div> <div className="space-y-2"> <Label htmlFor="disabled-live">Disabled Field</Label> <Input id="disabled-live" placeholder="This is disabled" disabled /> </div> </div> </div>

Label with Helper Text

tsx
import { Label, Input } from "@prisma/eclipse";

export function LabelWithHelper() {
  return (
    <div className="space-y-2 max-w-md">
      <Label htmlFor="password">
        Password
      </Label>
      <Input id="password" type="password" placeholder="Enter password" />
      <span className="text-sm text-foreground-neutral-weak">
        Must be at least 8 characters
      </span>
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="space-y-2"> <Label htmlFor="password-helper"> Password </Label> <Input id="password-helper" type="password" placeholder="Enter password" /> <span className="text-sm text-foreground-neutral-weak block"> Must be at least 8 characters </span> </div> </div>

Inline Layout

tsx
import { Label, Input } from "@prisma/eclipse";

export function InlineLabel() {
  return (
    <div className="flex items-center gap-4 max-w-md">
      <Label htmlFor="search" className="flex-shrink-0">
        Search:
      </Label>
      <Input id="search" placeholder="Type to search..." />
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="flex items-center gap-4"> <Label htmlFor="search-inline" className="flex-shrink-0"> Search: </Label> <Input id="search-inline" placeholder="Type to search..." /> </div> </div>

Grid Layout

tsx
import { Label, Input } from "@prisma/eclipse";

export function GridLabels() {
  return (
    <div className="grid grid-cols-2 gap-4 max-w-md">
      <div className="space-y-2">
        <Label htmlFor="first">First Name</Label>
        <Input id="first" placeholder="John" />
      </div>
      <div className="space-y-2">
        <Label htmlFor="last">Last Name</Label>
        <Input id="last" placeholder="Doe" />
      </div>
    </div>
  );
}

Live Example:

<div className="max-w-md my-4"> <div className="grid grid-cols-2 gap-4"> <div className="space-y-2"> <Label htmlFor="first-grid">First Name</Label> <Input id="first-grid" placeholder="John" /> </div> <div className="space-y-2"> <Label htmlFor="last-grid">Last Name</Label> <Input id="last-grid" placeholder="Doe" /> </div> </div> </div>

Form Example

tsx
import { Label, Input, Button } from "@prisma/eclipse";

export function FormWithLabels() {
  return (
    <form className="space-y-4 max-w-md">
      <div className="space-y-2">
        <Label htmlFor="form-name">
          Name <span className="text-foreground-error">*</span>
        </Label>
        <Input id="form-name" placeholder="Enter your name" required />
      </div>
      
      <div className="space-y-2">
        <Label htmlFor="form-email">
          Email <span className="text-foreground-error">*</span>
        </Label>
        <Input id="form-email" type="email" placeholder="[email protected]" required />
      </div>
      
      <div className="space-y-2">
        <Label htmlFor="form-phone">Phone</Label>
        <Input id="form-phone" type="tel" placeholder="(555) 555-5555" />
      </div>
      
      <Button type="submit">Submit</Button>
    </form>
  );
}

Live Example:

<div className="max-w-md my-4"> <form className="space-y-4"> <div className="space-y-2"> <Label htmlFor="form-name-live"> Name <span className="text-foreground-error">*</span> </Label> <Input id="form-name-live" placeholder="Enter your name" required /> </div>
<div className="space-y-2">
  <Label htmlFor="form-email-live">
    Email <span className="text-foreground-error">*</span>
  </Label>
  <Input id="form-email-live" type="email" placeholder="[email protected]" required />
</div>

<div className="space-y-2">
  <Label htmlFor="form-phone-live">Phone</Label>
  <Input id="form-phone-live" type="tel" placeholder="(555) 555-5555" />
</div>

<Button type="submit">Submit</Button>
</form> </div>

Component Props

Label

  • htmlFor - ID of the associated input element (string, required for accessibility)
  • className - Additional CSS classes (string, optional)
  • children - Label text or content (ReactNode, required)
  • All standard Radix UI Label props

Features

  • ✅ Built on Radix UI for accessibility
  • ✅ Proper association with form inputs via htmlFor
  • ✅ Automatically styled for disabled states
  • ✅ Consistent typography and spacing
  • ✅ Clickable to focus associated input
  • ✅ Screen reader friendly
  • ✅ Supports nested content
  • ✅ Fully typed with TypeScript
  • ✅ Customizable with className prop

Best Practices

  • Always use htmlFor attribute that matches the input's id
  • Keep label text clear, concise, and descriptive
  • Use required indicators (*) for required fields
  • Place labels above inputs for better mobile UX (vertical layout)
  • Don't rely solely on placeholder text - always use labels
  • Use helper text below inputs for additional context
  • Keep labels visible (don't hide them for accessibility)
  • Use sentence case for label text
  • Avoid ending labels with colons unless in inline layouts

Common Use Cases

The Label component is perfect for:

  • Form fields - Labeling all types of form inputs
  • Login forms - Email and password labels
  • Registration - User information fields
  • Settings - Configuration options
  • Search fields - Search input labels
  • Filters - Filter criteria labels
  • Contact forms - Contact information fields
  • Checkout forms - Payment and shipping labels

Accessibility

The Label component follows accessibility best practices:

  • Uses Radix UI's accessible label primitive
  • Properly associates with inputs via htmlFor attribute
  • Clicking label focuses the associated input
  • Screen readers announce the label when input is focused
  • Supports all ARIA attributes
  • Works with assistive technologies
  • Automatically applies disabled styling when associated with disabled inputs
  • Provides semantic meaning to form controls

Styling

The Label component uses design tokens:

  • Font size: text-sm (14px)
  • Font weight: font-medium (500)
  • Line height: leading-none
  • Disabled opacity: peer-disabled:opacity-70
  • Cursor: peer-disabled:cursor-not-allowed on disabled inputs

Customize by passing className:

tsx
<Label htmlFor="custom" className="text-lg font-bold text-blue-600">
  Custom Label
</Label>

Integration with Other Components

Label works seamlessly with:

  • Input - Text inputs, email, password, etc.
  • Field - Use with Field component for complete form fields
  • Checkbox - Label checkbox inputs
  • Radio - Label radio button inputs
  • Select - Label dropdown selections
  • Textarea - Label multi-line text inputs
  • Switch - Label toggle switches

Examples with Other Input Types

With File Input

<div className="max-w-md my-4"> <div className="space-y-2"> <Label htmlFor="file-upload">Upload Document</Label> <Input id="file-upload" type="file" /> </div> </div>

With Date Input

<div className="max-w-md my-4"> <div className="space-y-2"> <Label htmlFor="birth-date">Date of Birth</Label> <Input id="birth-date" type="date" /> </div> </div>

With Number Input

<div className="max-w-md my-4"> <div className="space-y-2"> <Label htmlFor="age">Age</Label> <Input id="age" type="number" min="0" max="120" placeholder="Enter your age" /> </div> </div>