{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"label","type":"registry:component","title":"Label","description":"The text label tied to a form control, with a required marker that screen readers announce.","categories":["forms"],"dependencies":["@radix-ui/react-direction@1.1.4","@radix-ui/react-label@2.1.15","clsx@^2.1.1","tailwind-merge@^3.7.0"],"registryDependencies":["https://beamline.io/registry/look-prism.json"],"files":[{"path":"beamline/components/label/label.tsx","type":"registry:file","target":"src/ui/beamline/components/label/label.tsx","content":"\"use client\";\n\nimport { useMessages } from \"../../runtime/localization\";\nimport { english as englishMessages } from \"./messages\";\nimport type { ComponentProps } from \"react\";\nimport * as RadixLabel from \"@radix-ui/react-label\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface LabelProps extends ComponentProps<typeof RadixLabel.Root> {\n  /** Shows the marker and announces \"required\". */\n  required?: boolean;\n  /** The control says \"required\" itself (a native required input, a radiogroup with aria-required): the label shows\n   * the marker only, so the control's name stays the label's words and the state is announced once. */\n  requiredOnControl?: boolean;\n}\n\n/** The text label tied to a form control. It dims with a disabled control next to it (peer) or inside it (group). */\nexport function Label({ required = false, requiredOnControl = false, className, children, ...props }: LabelProps) {\n  const i18n = useMessages(\"label\", englishMessages);\n\n  return (\n    <RadixLabel.Root\n      data-slot=\"label\"\n      {...props}\n      className={cn(\n        \"inline-flex items-center gap-[var(--pui-space-1)] text-sm leading-tight font-medium text-ink select-none group-data-[disabled]:opacity-[var(--pui-opacity-disabled)] peer-disabled:opacity-[var(--pui-opacity-disabled)]\",\n        className,\n      )}\n    >\n      {children}\n      {required && (\n        <>\n          <span aria-hidden className=\"text-red\">\n            *\n          </span>\n          {!requiredOnControl && <span className=\"sr-only\">{i18n(\"required\")}</span>}\n        </>\n      )}\n    </RadixLabel.Root>\n  );\n}\n\nexport default Label;\n"},{"path":"beamline/components/label/messages.ts","type":"registry:file","target":"src/ui/beamline/components/label/messages.ts","content":"import type { MessageDefinitions } from \"../../runtime/messages\";\n/** Built-in English copy; stable keys are the public translation API. */\nexport const english = {\n  required: \"required\",\n} satisfies MessageDefinitions;\n"},{"path":"beamline/lib/utils.ts","type":"registry:file","target":"src/ui/beamline/lib/utils.ts","content":"import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/* The type roles (utilities.css) and the 2xs step are sizes, not text colours: without this, tailwind-merge reads\n   `text-overline` as a colour and drops it next to `text-ink-3`. A role and a size step still replace each other.\n   Likewise `font-title` is the look's title weight, not a family: read as a family it dropped `font-display` beside it,\n   and every merged page title lost the look's display face. */\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-weight\": [{ font: [\"title\"] }],\n      \"font-family\": [{ font: [\"display\", \"numeric\", \"figure\"] }],\n      \"font-size\": [\n        {\n          text: [\n            \"2xs\",\n            \"display\",\n            \"title\",\n            \"heading\",\n            \"subheading\",\n            \"body\",\n            \"body-sm\",\n            \"reading\",\n            \"label\",\n            \"caption\",\n            \"overline\",\n            \"numeric\",\n            \"code\",\n          ],\n        },\n      ],\n    },\n  },\n});\n\n/** Merge class names, letting later Tailwind utilities win over earlier ones. */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n\n/** A small seeded random generator (LCG): the same seed gives the same sequence, for stable sample data and jitter. */\nexport function rng(seed = 1) {\n  let s = seed >>> 0 || 1;\n  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 2 ** 32;\n}\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n"}],"docs":"Label is in src/ui/beamline/components/label/label.tsx. The source is in src/ui/beamline (ui/beamline in a project without src/). After Tailwind, import its styles/beamline.css once, then styles/look-prism.css in your app stylesheet (use relative paths). Keep the shared base before all chosen looks. Wrap your app in <UIRoot preset={prism}> with UIRoot from its runtime/appearance and prism from its looks/prism.  shadcn replaces files when asked; use the Beamline managed-source CLI from the start for three-way upgrades that preserve edits.","meta":{"free":true,"version":"0.2.0-rc.42","library":"https://beamline.io/components/label"}}