{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"label","type":"registry:ui","title":"Label","description":"Form label with a required asterisk, optional tag and hint text that lights up while its control has focus.","dependencies":[],"registryDependencies":["utils"],"files":[{"path":"registry/ui/label.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { useEffect, useState, type LabelHTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n  /** Show a required marker. Also set `required` on the control so assistive tech announces it. */\n  required?: boolean;\n  /** Show an \"Optional\" tag on the right instead. */\n  optional?: boolean;\n  /** Helper text under the label. Gets id `${htmlFor}-hint` for the control's aria-describedby. */\n  hint?: ReactNode;\n  disabled?: boolean;\n}\n\nexport function Label({ required = false, optional = false, hint, disabled = false, htmlFor, className, children, ...props }: LabelProps) {\n  const [focused, setFocused] = useState(false);\n\n  // Light up while the labelled control has focus.\n  useEffect(() => {\n    const el = htmlFor ? document.getElementById(htmlFor) : null;\n    if (!el) return;\n    const on = () => setFocused(true);\n    const off = () => setFocused(false);\n    el.addEventListener(\"focus\", on);\n    el.addEventListener(\"blur\", off);\n    return () => {\n      el.removeEventListener(\"focus\", on);\n      el.removeEventListener(\"blur\", off);\n    };\n  }, [htmlFor]);\n\n  return (\n    <div data-focused={focused || undefined} data-disabled={disabled || undefined} className=\"group/label grid gap-1 data-disabled:opacity-50\">\n      <div className=\"flex items-baseline justify-between gap-3\">\n        <label\n          {...props}\n          htmlFor={htmlFor}\n          className={cn(\n            \"inline-flex items-baseline gap-1 text-sm font-medium leading-none text-foreground/85 transition-colors duration-200 select-none\",\n            \"group-data-focused/label:text-foreground group-data-disabled/label:cursor-not-allowed\",\n            className,\n          )}\n        >\n          {children}\n          {required && (\n            <span\n              aria-hidden\n              className=\"inline-block text-destructive transition-[scale,rotate] duration-300 ease-[cubic-bezier(.3,1.6,.5,1)] group-data-focused/label:scale-125 group-data-focused/label:rotate-[72deg] motion-reduce:transition-none\"\n            >\n              *\n            </span>\n          )}\n        </label>\n        {optional && !required && <span className=\"text-xs text-muted-foreground\">Optional</span>}\n      </div>\n      {hint && (\n        <p\n          id={htmlFor ? `${htmlFor}-hint` : undefined}\n          className=\"text-xs leading-snug text-muted-foreground transition-colors duration-200 group-data-focused/label:text-foreground/70\"\n        >\n          {hint}\n        </p>\n      )}\n    </div>\n  );\n}\n"}]}