{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"badge","type":"registry:ui","title":"Badge","description":"A small label for statuses, counts and categories.","dependencies":["radix-ui"],"registryDependencies":["https://dashral.com/r/utils.json"],"files":[{"path":"registry/dashral/badge.tsx","type":"registry:file","target":"components/dashral/badge.tsx","content":"import * as React from \"react\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\n\ntype BadgeVariant = \"solid\" | \"soft\" | \"outline\"\ntype BadgeColor = \"primary\" | \"neutral\" | \"info\" | \"success\" | \"warning\" | \"destructive\" | \"highlight\"\n\nconst defaultColors: Record<BadgeVariant, BadgeColor> = { solid: \"primary\", soft: \"primary\", outline: \"neutral\" }\n\n// Every class is written out in full so Tailwind finds it.\nconst tones: Record<BadgeVariant, Record<BadgeColor, string>> = {\n  solid: {\n    primary: \"border-transparent bg-primary text-primary-foreground\",\n    neutral: \"border-transparent bg-secondary text-secondary-foreground\",\n    info: \"border-transparent bg-info text-info-foreground\",\n    success: \"border-transparent bg-success text-success-foreground\",\n    warning: \"border-transparent bg-warning text-warning-foreground\",\n    destructive: \"border-transparent bg-destructive text-destructive-foreground\",\n    highlight: \"border-transparent bg-highlight text-highlight-foreground\",\n  },\n  soft: {\n    primary: \"border-transparent bg-primary/12 text-primary-text\",\n    neutral: \"border-transparent bg-foreground/6 text-foreground\",\n    info: \"border-transparent bg-info/12 text-info-text\",\n    success: \"border-transparent bg-success/12 text-success-text\",\n    warning: \"border-transparent bg-warning/18 text-warning-text\",\n    destructive: \"border-transparent bg-destructive/12 text-destructive-text\",\n    highlight: \"border-transparent bg-highlight/12 text-highlight-text\",\n  },\n  outline: {\n    primary: \"border-primary/40 text-primary-text\",\n    neutral: \"text-foreground\",\n    info: \"border-info/40 text-info-text\",\n    success: \"border-success/40 text-success-text\",\n    warning: \"border-warning/50 text-warning-text\",\n    destructive: \"border-destructive/40 text-destructive-text\",\n    highlight: \"border-highlight/40 text-highlight-text\",\n  },\n}\n\n/** The status dot, in the color's fill (on a solid badge it takes the text color instead). */\nconst dots: Record<BadgeColor, string> = {\n  primary: \"bg-primary\",\n  neutral: \"bg-muted-foreground\",\n  info: \"bg-info\",\n  success: \"bg-success\",\n  warning: \"bg-warning\",\n  destructive: \"bg-destructive\",\n  highlight: \"bg-highlight\",\n}\n\ntype BadgeStyleProps = {\n  /** How much it stands out: solid, soft or outline. */\n  variant?: BadgeVariant | null\n  /** Its color. Solid and soft default to primary, outline to neutral. */\n  color?: BadgeColor | null\n  className?: string\n}\n\n/** The variant and color a badge ends up with. */\nfunction resolve(variant: BadgeStyleProps[\"variant\"], color: BadgeStyleProps[\"color\"]): [BadgeVariant, BadgeColor] {\n  const kind = variant ?? \"solid\"\n  return [kind, color ?? defaultColors[kind]]\n}\n\n/** The classes for a badge, for an element that should look like one. */\nfunction badgeVariants({ variant, color, className }: BadgeStyleProps = {}) {\n  const [kind, tone] = resolve(variant, color)\n  return cn(\n    \"inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden whitespace-nowrap rounded-md border px-2 py-0.5 text-xs font-medium transition-colors [&>svg]:pointer-events-none [&>svg]:size-3\",\n    tones[kind][tone],\n    className\n  )\n}\n\n/** A short label: variant says how much it stands out, color what it means. `dot` adds a status dot in front. */\nfunction Badge({\n  className,\n  variant,\n  color,\n  dot = false,\n  asChild = false,\n  children,\n  ...props\n}: Omit<React.ComponentProps<\"span\">, \"color\"> &\n  Omit<BadgeStyleProps, \"className\"> & {\n    /** A small dot before the label, as in \"● Active\". */\n    dot?: boolean\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"span\"\n  const [kind, tone] = resolve(variant, color)\n\n  return (\n    <Comp data-slot=\"badge\" className={badgeVariants({ variant, color, className })} {...props}>\n      {dot && (\n        <span\n          aria-hidden\n          data-slot=\"badge-dot\"\n          className={cn(\"size-1.5 shrink-0 rounded-full\", kind === \"solid\" ? \"bg-current\" : dots[tone])}\n        />\n      )}\n      <Slot.Slottable>{children}</Slot.Slottable>\n    </Comp>\n  )\n}\n\nexport { Badge, badgeVariants, type BadgeVariant, type BadgeColor }\n"}],"cssVars":{"theme":{"color-primary-text":"var(--primary-text, var(--primary))","color-destructive-foreground":"var(--destructive-foreground)","color-destructive-text":"var(--destructive-text)","color-info":"var(--info)","color-info-foreground":"var(--info-foreground)","color-info-text":"var(--info-text)","color-success":"var(--success)","color-success-foreground":"var(--success-foreground)","color-success-text":"var(--success-text)","color-warning":"var(--warning)","color-warning-foreground":"var(--warning-foreground)","color-warning-text":"var(--warning-text)","color-highlight":"var(--highlight)","color-highlight-foreground":"var(--highlight-foreground)","color-highlight-text":"var(--highlight-text)"},"light":{"destructive-foreground":"oklch(0.985 0 0)","destructive-text":"#bd2800","info":"oklch(0.5 0.134 242.749)","info-foreground":"oklch(0.985 0 0)","info-text":"oklch(0.443 0.11 240.79)","success":"oklch(0.508 0.118 165.612)","success-foreground":"oklch(0.985 0 0)","success-text":"oklch(0.432 0.095 166.913)","warning":"#f59200","warning-foreground":"oklch(0.3 0.07 60)","warning-text":"#964e00","highlight":"#b8008c","highlight-foreground":"oklch(0.985 0 0)","highlight-text":"#a3007b"},"dark":{"destructive-foreground":"oklch(0.2 0 0)","destructive-text":"#ff8a5c","info":"oklch(0.685 0.169 237.323)","info-foreground":"oklch(0.2 0 0)","info-text":"oklch(0.746 0.16 232.661)","success":"oklch(0.696 0.17 162.48)","success-foreground":"oklch(0.2 0.04 160)","success-text":"oklch(0.765 0.177 163.223)","warning":"#f59200","warning-foreground":"oklch(0.25 0.06 60)","warning-text":"#ffba42","highlight":"#ff2ecf","highlight-foreground":"oklch(0.2 0 0)","highlight-text":"#ff75df"}}}