{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "badge",
  "type": "registry:ui",
  "title": "Badge",
  "description": "Compact label for statuses, counts, and tags, with semantic intent colors and subtle/solid styles.",
  "dependencies": [
    "@radix-ui/react-slot",
    "@saasflare/ui",
    "class-variance-authority",
    "motion"
  ],
  "files": [
    {
      "path": "components/ui/badge.tsx",
      "type": "registry:ui",
      "content": "// @toreview\n\"use client\"\n\n/**\n * @fileoverview Saasflare Badge — status indicator with intent support.\n * @module packages/ui/components/ui/badge\n * @layer core\n *\n * Fully owned Saasflare implementation. Does NOT import from ui/.\n * Supports intent system and optional hover animation with reduced-motion.\n *\n * @example\n * import { Badge } from \"@saasflare/ui\";\n *\n * <Badge>Default</Badge>\n * <Badge intent=\"success\" variant=\"soft\">Active</Badge>\n * <Badge intent=\"danger\" variant=\"outline\" size=\"sm\">Error</Badge>\n */\n\nimport * as React from \"react\"\nimport { m } from \"motion/react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as Slot from \"@radix-ui/react-slot\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\nimport { useSaasflareMotion, spring } from \"@saasflare/ui\"\nimport type { Intent } from \"@saasflare/ui\"\n\n/* ── Backward-compat variant mapping ── */\nconst LEGACY_VARIANT_MAP: Record<string, { variant: string; intent?: Intent }> = {\n  default: { variant: \"solid\", intent: \"primary\" },\n  destructive: { variant: \"solid\", intent: \"danger\" },\n  secondary: { variant: \"soft\", intent: \"neutral\" },\n}\n\n/**\n * Badge variant definitions.\n *\n * Axes:\n *   variant — visual treatment: solid, soft, outline\n *   size    — sm, md\n */\nconst badgeVariants = cva(\n  \"inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3\",\n  {\n    variants: {\n      variant: {\n        solid:\n          \"bg-[var(--intent)] text-[var(--intent-fg)] [a&]:hover:brightness-110\",\n        soft:\n          \"bg-[var(--intent)]/15 text-[var(--intent-text)] [a&]:hover:bg-[var(--intent)]/25 dark:bg-[var(--intent)]/20 dark:hover:bg-[var(--intent)]/30\",\n        outline:\n          \"border-[var(--intent-text)]/30 text-[var(--intent-text)] [a&]:hover:bg-[var(--intent-text)]/10\",\n      },\n      size: {\n        sm: \"px-1.5 py-px text-[10px]\",\n        md: \"px-2 py-0.5 text-xs\",\n      },\n    },\n    defaultVariants: {\n      variant: \"solid\",\n      size: \"md\",\n    },\n  }\n)\n\n/** Props for the Saasflare Badge component */\ninterface BadgeProps\n  extends Omit<\n      React.ComponentProps<\"span\">,\n      \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\" | \"onAnimationEnd\" | keyof SaasflareComponentProps\n    >,\n    Omit<VariantProps<typeof badgeVariants>, \"variant\">,\n    SaasflareComponentProps {\n  /** Render as child element (Radix Slot pattern) */\n  asChild?: boolean\n  /** Semantic color intent */\n  intent?: Intent\n  /**\n   * Visual treatment: `\"solid\" | \"soft\" | \"outline\"`.\n   * @remarks `\"default\" | \"destructive\" | \"secondary\"` are deprecated aliases\n   * (mapped to a solid/soft variant + intent via {@link LEGACY_VARIANT_MAP});\n   * prefer `variant` + `intent` instead.\n   */\n  variant?: VariantProps<typeof badgeVariants>[\"variant\"] | \"default\" | \"destructive\" | \"secondary\"\n}\n\n/**\n * Badge for status, labels, and counts with intent-based coloring.\n *\n * @component\n * @layer core\n *\n * @param {string} variant - Visual treatment: \"solid\" | \"soft\" | \"outline\"\n * @param {string} intent - Color intent: \"primary\" | \"neutral\" | \"success\" | \"warning\" | \"danger\" | \"info\"\n * @param {string} size - Badge size: \"sm\" | \"md\"\n * @param {boolean} asChild - Render as child element (Slot pattern)\n *\n * @example\n * <Badge intent=\"success\" variant=\"soft\">Active</Badge>\n *\n * @example\n * <Badge intent=\"danger\" variant=\"outline\" size=\"sm\">Error</Badge>\n *\n * @remarks\n * In `asChild` mode the badge renders via Radix Slot, which cannot receive\n * motion props — the hover-scale animation is intentionally a no-op there.\n */\nfunction Badge({\n  className,\n  variant: variantProp = \"solid\",\n  size = \"md\",\n  intent: intentProp = \"primary\",\n  asChild = false,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: BadgeProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n  const motion = useSaasflareMotion(sf.animated, spring)\n\n  /* ── Backward compat: map legacy variant names ── */\n  let resolvedVariant = variantProp as string\n  let resolvedIntent = intentProp\n\n  const legacy = LEGACY_VARIANT_MAP[variantProp as string]\n  if (legacy) {\n    resolvedVariant = legacy.variant\n    if (legacy.intent) {\n      resolvedIntent = legacy.intent\n    }\n  }\n\n  if (asChild) {\n    return (\n      <Slot.Root\n        {...props}\n        data-slot=\"badge\"\n        data-variant={resolvedVariant}\n        data-intent={resolvedIntent}\n        data-surface={sf.surface}\n        data-radius={sf.radius}\n        data-animated={String(sf.animated)}\n        className={cn(badgeVariants({ variant: resolvedVariant as VariantProps<typeof badgeVariants>[\"variant\"], size }), className)}\n      />\n    )\n  }\n\n  return (\n    <m.span\n      {...props}\n      data-slot=\"badge\"\n      data-variant={resolvedVariant}\n      data-intent={resolvedIntent}\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n      whileHover={motion.disabled ? undefined : { scale: 1.05 }}\n      transition={motion.transition}\n      className={cn(badgeVariants({ variant: resolvedVariant as VariantProps<typeof badgeVariants>[\"variant\"], size }), className)}\n    />\n  )\n}\n\nexport { Badge, badgeVariants, type BadgeProps }\n",
      "target": "components/ui/badge.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/badge.json"
  }
}
