HextaUI

Label

Una etiqueta que sigue a su control: se atenúa cuando está deshabilitado y lo marca como obligatorio u opcional por sí sola.

import { Checkbox } from "@/components/ui/checkbox"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function LabelDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-6">
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-demo-email" indicator="required">
          Email
        </Label>
        <Input
          id="label-demo-email"
          type="email"
          autoComplete="email"
          required
        />
      </div>
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-demo-team" indicator="required">
          Team
        </Label>
        <Input id="label-demo-team" defaultValue="Design systems" disabled />
      </div>
      <Label>
        <Checkbox defaultChecked />
        Send me product updates
      </Label>
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/label.json

Añade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.

import { Label } from "@/components/ui/label"
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" />

Apunta htmlFor al id de un control, o envuelve el control. En ambos casos la etiqueta lo encuentra y sigue su estado. Dentro de un <Field />, usa <FieldLabel />, que conecta el id por ti.

Sigue a su control

La etiqueta se atenúa y muestra un cursor not-allowed mientras su control está deshabilitado, y expone data-required, data-invalid y data-readonly para tus propios estilos. Se mantiene al día cuando el control cambia.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function LabelStates() {
  const [locked, setLocked] = React.useState(true)

  return (
    <div className="flex w-full max-w-sm flex-col gap-3">
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-states-domain">Custom domain</Label>
        <Input
          id="label-states-domain"
          defaultValue="docs.example.com"
          disabled={locked}
        />
      </div>
      <Button
        variant="outline"
        size="sm"
        className="self-start"
        onClick={() => setLocked(!locked)}
      >
        {locked ? "Unlock" : "Lock"}
      </Button>
    </div>
  )
}

Obligatorio y opcional

indicator="optional" marca los controles sin required, e indicator="required" añade un asterisco a los que lo tienen. La marca se oculta a los lectores de pantalla, que ya anuncian los campos obligatorios.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function LabelIndicator() {
  return (
    <div className="grid w-full max-w-sm gap-6">
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-indicator-name" indicator="optional">
          Full name
        </Label>
        <Input id="label-indicator-name" autoComplete="name" required />
      </div>
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-indicator-company" indicator="optional">
          Company
        </Label>
        <Input id="label-indicator-company" autoComplete="organization" />
      </div>
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-indicator-card" indicator="required">
          Card number
        </Label>
        <Input id="label-indicator-card" inputMode="numeric" required />
      </div>
    </div>
  )
}

Checkbox

Envuelve un checkbox para que toda la etiqueta lo active, o coloca la etiqueta a su lado con htmlFor. Un checkbox deshabilitado atenúa su etiqueta en ambos casos.

import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"

export function LabelCheckbox() {
  return (
    <div className="flex flex-col gap-4">
      <Label>
        <Checkbox defaultChecked />
        Email me when someone replies
      </Label>
      <Label>
        <Checkbox disabled />
        Weekly digest (coming soon)
      </Label>
      <div className="flex items-center gap-2">
        <Checkbox id="label-checkbox-terms" />
        <Label htmlFor="label-checkbox-terms">Accept the terms</Label>
      </div>
    </div>
  )
}

Icono

Los iconos dentro de una etiqueta se dimensionan y se atenúan para acompañar al texto.

import { IconLock } from "@tabler/icons-react"

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function LabelIcon() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="label-icon-key">
        <IconLock aria-hidden="true" />
        API key
      </Label>
      <Input id="label-icon-key" defaultValue="sk_live_51H…" readOnly />
    </div>
  )
}

Contenido largo

Las etiquetas largas se ajustan, y las cadenas sin espacios se cortan en lugar de ensanchar el diseño.

import { Checkbox } from "@/components/ui/checkbox"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function LabelLongContent() {
  return (
    <div className="flex w-64 max-w-full flex-col gap-6">
      <div className="flex flex-col gap-2">
        <Label htmlFor="label-long" indicator="optional">
          Where should we send invoices for the international subsidiary
        </Label>
        <Input id="label-long" />
      </div>
      <Label>
        <Checkbox />
        billing-notifications@an-extremely-long-company-domain.example.com
      </Label>
    </div>
  )
}

De derecha a izquierda

Los espacios y el indicador siguen la dirección de lectura.

import { Checkbox } from "@/components/ui/checkbox"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function LabelRtl() {
  return (
    <div dir="rtl" className="flex w-full max-w-sm flex-col gap-6">
      <div className="flex flex-col gap-2">
        <Label
          htmlFor="label-rtl-name"
          indicator="optional"
          optionalText="اختياري"
        >
          الاسم
        </Label>
        <Input id="label-rtl-name" />
      </div>
      <Label>
        <Checkbox defaultChecked />
        تذكرني
      </Label>
    </div>
  )
}
  • Hacer clic en la etiqueta enfoca o activa su control, así que es un objetivo más grande que el control solo.
  • Hacer doble clic en el texto de la etiqueta no lo selecciona. Los dobles clics sobre un control dentro de la etiqueta funcionan como siempre.
  • Todo control necesita un nombre. Cuando no hay etiqueta visible, usa aria-label en el control.

Renderiza un <label> y acepta sus atributos.

PropTipoPredeterminado
htmlForEl id del control. Omítelo cuando la etiqueta envuelve el control.
string–
indicatorMarca la etiqueta a partir del estado obligatorio del control. Desactivado por defecto.
"required" | "optional"–
optionalText
ReactNode"Optional"
render
ReactElement | (props, state) => ReactElement<label>
AtributoDescripción
data-slot="label"Apunta a las etiquetas en CSS.
data-disabledPresente mientras el control está deshabilitado.
data-requiredPresente mientras el control es obligatorio.
data-invalidPresente mientras el control no es válido, después de que el usuario haya interactuado o cuando se define aria-invalid.
data-readonlyPresente mientras el control es de solo lectura.
data-slot="label-indicator"La marca de obligatorio u opcional.

Usado en bloques

Bloques que se construyen sobre Label.