{
  "name": "badge",
  "type": "registry:ui",
  "description": "Small status pill that hugs its label",
  "files": [
    {
      "path": "ui/badge.tsx",
      "type": "registry:ui",
      "content": "import { fv, type VariantProps } from \"@facet-ui/react-variants\";\nimport { getPassthroughProps, type PassthroughProps, React } from \"@lattice-ui/react-runtime\";\nimport { TextSlot } from \"~/lib/text\";\nimport { cn } from \"~/lib/utils\";\n\n// `border border-transparent` on the base is shadcn's, and it is load-bearing\n// here for a different reason than there. shadcn needs it so an outlined badge\n// is not a pixel larger than a filled one; a Roblox `UIStroke` is drawn on the\n// border and changes no size at all. What it does do is split the stroke in two:\n// this line sets its *thickness*, and `outline`'s `border-border` sets only its\n// *colour*. Drop the base token and the outline variant colours a stroke that\n// was never created.\nexport const badgeVariants = fv(\n  \"flex-row items-center justify-center gap-1 size-fit overflow-hidden rounded-full border border-transparent px-2 py-0.5\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary\",\n        secondary: \"bg-secondary\",\n        destructive: \"bg-destructive\",\n        outline: \"border-border\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  },\n);\n\n// Nothing inherits, so the text colour lives here rather than on the badge.\n// `whitespace-nowrap` is the base's, restated: Roblox wraps nothing by default,\n// but `TextSlot` is where the token has to land to reach a `TextLabel`.\nexport const badgeLabelVariants = fv(\"whitespace-nowrap text-xs font-medium\", {\n  variants: {\n    variant: {\n      default: \"text-primary-foreground\",\n      secondary: \"text-secondary-foreground\",\n      // shadcn writes a literal `text-white` here, and this is the one place\n      // this pass does not follow it. Tailwind v4's theme dropped\n      // `--destructive-foreground`, so white is what shadcn has left; Facet's\n      // theme still defines the role, and it resolves to the same near-white.\n      // Naming the role keeps a retheme a config edit, which is the rule a\n      // literal colour would break. See AGENTS.md, \"Layer boundaries\".\n      destructive: \"text-destructive-foreground\",\n      outline: \"text-foreground\",\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n});\n\nexport type BadgeProps = VariantProps<typeof badgeVariants> & {\n  Text?: string;\n  children?: React.ReactNode;\n} & PassthroughProps<Frame>;\n\nconst OWN_PROPS = [\"variant\", \"className\", \"Text\", \"children\"] as const;\n\nconst NEUTRAL_PROPS = {\n  BackgroundTransparency: 1,\n  BorderSizePixel: 0,\n};\n\nexport function Badge(props: BadgeProps) {\n  const passthrough = getPassthroughProps<Frame>(props, OWN_PROPS);\n\n  return (\n    <frame\n      className={cn(badgeVariants({ variant: props.variant, className: props.className }))}\n      {...NEUTRAL_PROPS}\n      {...passthrough}\n    >\n      <TextSlot Text={props.Text} className={badgeLabelVariants({ variant: props.variant })}>\n        {props.children}\n      </TextSlot>\n    </frame>\n  );\n}\n"
    }
  ],
  "registryDependencies": [
    "utils",
    "text"
  ],
  "dependencies": [
    "@facet-ui/react-variants@^0.1.1",
    "@lattice-ui/react-runtime@^0.8.0"
  ],
  "tokens": [
    "primary",
    "primary-foreground",
    "secondary",
    "secondary-foreground",
    "destructive",
    "destructive-foreground",
    "border",
    "foreground"
  ]
}
