{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "badge", "type": "registry:ui", "title": "Badge", "description": "Tone-tinted pill label on the semantic color scales, for status and classification at a glance.", "categories": [ "display" ], "dependencies": [ "class-variance-authority" ], "registryDependencies": [ "https://whiskeyjack.net/r/utils.json" ], "files": [ { "path": "components/ui/badge.tsx", "type": "registry:ui", "target": "components/ui/badge.tsx", "content": "import * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\nconst badgeVariants = cva(\n 'inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2.5 py-1 text-xs font-medium',\n {\n variants: {\n tone: {\n neutral: '',\n success: '',\n info: '',\n warning: '',\n error: '',\n orange: '',\n yellow: '',\n },\n strong: {\n true: '',\n false: '',\n },\n },\n /* The tone recipes live here because `strong` swaps the whole recipe:\n soft = -100 bg / -700 text (dark: 30% -900 mix / -400), strong = one\n step deeper on every channel, for the top tier of a classification\n scale (e.g. a blood-pressure crisis). */\n compoundVariants: [\n {\n tone: 'neutral',\n strong: false,\n className:\n 'bg-[var(--color-surface-muted-light)] dark:bg-[var(--color-surface-muted-dark)] text-[var(--color-text-secondary-light)] dark:text-[var(--color-text-secondary-dark)]',\n },\n {\n tone: 'neutral',\n strong: true,\n className:\n 'bg-[var(--color-warm-200)] text-[var(--color-text-primary-light)] dark:bg-[var(--color-neutral-700)] dark:text-[var(--color-text-primary-dark)]',\n },\n {\n tone: 'success',\n strong: false,\n className:\n 'bg-[var(--color-success-100)] text-[var(--color-success-700)] dark:bg-[color-mix(in_srgb,var(--color-success-900)_30%,transparent)] dark:text-[var(--color-success-400)]',\n },\n {\n tone: 'success',\n strong: true,\n className:\n 'bg-[var(--color-success-200)] text-[var(--color-success-800)] dark:bg-[color-mix(in_srgb,var(--color-success-900)_50%,transparent)] dark:text-[var(--color-success-300)]',\n },\n {\n tone: 'info',\n strong: false,\n className:\n 'bg-[var(--color-info-100)] text-[var(--color-info-700)] dark:bg-[color-mix(in_srgb,var(--color-info-900)_30%,transparent)] dark:text-[var(--color-info-400)]',\n },\n {\n tone: 'info',\n strong: true,\n className:\n 'bg-[var(--color-info-200)] text-[var(--color-info-800)] dark:bg-[color-mix(in_srgb,var(--color-info-900)_50%,transparent)] dark:text-[var(--color-info-300)]',\n },\n {\n tone: 'warning',\n strong: false,\n className:\n 'bg-[var(--color-warning-100)] text-[var(--color-warning-700)] dark:bg-[color-mix(in_srgb,var(--color-warning-900)_30%,transparent)] dark:text-[var(--color-warning-400)]',\n },\n {\n tone: 'warning',\n strong: true,\n className:\n 'bg-[var(--color-warning-200)] text-[var(--color-warning-800)] dark:bg-[color-mix(in_srgb,var(--color-warning-900)_50%,transparent)] dark:text-[var(--color-warning-300)]',\n },\n {\n tone: 'error',\n strong: false,\n className:\n 'bg-[var(--color-error-100)] text-[var(--color-error-700)] dark:bg-[color-mix(in_srgb,var(--color-error-900)_30%,transparent)] dark:text-[var(--color-error-400)]',\n },\n {\n tone: 'error',\n strong: true,\n className:\n 'bg-[var(--color-error-200)] text-[var(--color-error-800)] dark:bg-[color-mix(in_srgb,var(--color-error-900)_50%,transparent)] dark:text-[var(--color-error-300)]',\n },\n {\n tone: 'orange',\n strong: false,\n className:\n 'bg-[var(--color-orange-100)] text-[var(--color-orange-700)] dark:bg-[color-mix(in_srgb,var(--color-orange-900)_30%,transparent)] dark:text-[var(--color-orange-400)]',\n },\n {\n tone: 'orange',\n strong: true,\n className:\n 'bg-[var(--color-orange-200)] text-[var(--color-orange-800)] dark:bg-[color-mix(in_srgb,var(--color-orange-900)_50%,transparent)] dark:text-[var(--color-orange-300)]',\n },\n {\n tone: 'yellow',\n strong: false,\n className:\n 'bg-[var(--color-yellow-100)] text-[var(--color-yellow-700)] dark:bg-[color-mix(in_srgb,var(--color-yellow-900)_30%,transparent)] dark:text-[var(--color-yellow-400)]',\n },\n {\n tone: 'yellow',\n strong: true,\n className:\n 'bg-[var(--color-yellow-200)] text-[var(--color-yellow-800)] dark:bg-[color-mix(in_srgb,var(--color-yellow-900)_50%,transparent)] dark:text-[var(--color-yellow-300)]',\n },\n ],\n defaultVariants: {\n tone: 'neutral',\n strong: false,\n },\n },\n)\n\nexport interface BadgeProps\n extends React.HTMLAttributes,\n VariantProps {}\n\n/**\n * Tone-tinted pill label on the semantic color scales – the smallest member\n * of the tone family (Notice is the in-flow box, Toast the floating pill).\n * For classifications and statuses read at a glance: a blood-pressure\n * category, a roadmap state, a sync status. `strong` deepens the tint one\n * step for the top tier of a scale (crisis / very-high readings).\n *\n * Non-interactive and i18n-agnostic: pass translated text as children. The\n * tint never carries meaning alone – the label IS the information, the tone\n * reinforces it.\n */\nconst Badge = React.forwardRef(\n ({ tone, strong, className, ...props }, ref) => (\n \n ),\n)\nBadge.displayName = 'Badge'\n\nexport { Badge, badgeVariants }\n" } ], "docs": "Badge is the smallest tone surface: a static pill for a status or classification, with `strong` for the top tier of a scale. The label carries the meaning and the tone reinforces it, so it reads without relying on color alone. Use this instead of hand-rolling a tinted pill. Non-interactive and i18n-agnostic.", "meta": { "group": "display", "related": [ "notice", "toast" ], "exports": [ "Badge", "badgeVariants" ], "siteSlug": "badge" } }