Badge
A shadcn-style badge component built with Ark UI primitives.
import { Badge } from "@/components/ui/badge";
const BadgeDemo = () => <Badge>Default</Badge>;
export default BadgeDemo;
Installation
npx shadcn@latest add @ark-cn/badgeInstall the dependency required by this primitive:
npm install @ark-ui/react class-variance-authorityCopy the component source into your app:
TSXcomponents/ui/badge.tsx
"use client";
import { ark } from "@ark-ui/react/factory";
import { cva, type VariantProps } from "class-variance-authority";
import type { ComponentProps } from "react";
import { cn } from "@/lib/utils";
export const badgeVariants = cva(
"relative inline-flex shrink-0 items-center justify-center gap-1 whitespace-nowrap rounded-sm border border-transparent font-medium outline-none transition-shadow focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-3.5 sm:[&_svg:not([class*='size-'])]:size-3 [&_svg]:pointer-events-none [&_svg]:shrink-0 [button&,a&]:cursor-pointer [button&,a&]:pointer-coarse:after:absolute [button&,a&]:pointer-coarse:after:size-full [button&,a&]:pointer-coarse:after:min-h-11 [button&,a&]:pointer-coarse:after:min-w-11",
{
defaultVariants: {
size: "default",
variant: "default",
},
variants: {
size: {
default:
"h-5.5 min-w-5.5 px-[calc(--spacing(1)-1px)] text-sm sm:h-4.5 sm:min-w-4.5 sm:text-xs",
lg: "h-6.5 min-w-6.5 px-[calc(--spacing(1.5)-1px)] text-base sm:h-5.5 sm:min-w-5.5 sm:text-sm",
sm: "h-5 min-w-5 rounded-lg px-[calc(--spacing(1)-1px)] text-xs sm:h-4 sm:min-w-4 sm:text-[.625rem]",
},
variant: {
default:
"bg-primary text-primary-foreground [button&,a&]:hover:bg-primary/90",
destructive:
"bg-destructive text-white [button&,a&]:hover:bg-destructive/90",
error:
"bg-destructive/8 text-destructive-foreground dark:bg-destructive/16",
info: "bg-info/8 text-info-foreground dark:bg-info/16",
outline:
"border-input bg-background text-foreground dark:bg-input/32 [button&,a&]:hover:bg-accent/50 dark:[button&,a&]:hover:bg-input/48",
secondary:
"bg-secondary text-secondary-foreground [button&,a&]:hover:bg-secondary/90",
success: "bg-success/8 text-success-foreground dark:bg-success/16",
warning: "bg-warning/8 text-warning-foreground dark:bg-warning/16",
},
},
},
);
export interface BadgeProps extends ComponentProps<typeof ark.span> {
variant?: VariantProps<typeof badgeVariants>["variant"];
size?: VariantProps<typeof badgeVariants>["size"];
}
export const Badge = ({ className, variant, size, ...props }: BadgeProps) => {
return (
<ark.span
className={cn(badgeVariants({ className, size, variant }))}
{...props}
/>
);
};
Add the following CSS to your stylesheet (e.g. styles.css):
@theme inline {
--color-destructive-foreground: var(--destructive-foreground);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
}
:root {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-700);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-700);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-700);
}
.dark {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-400);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-400);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-400);
}Update import aliases to match your project setup.
Usage
import * as Badge from "@/components/ui/badge"Read exported parts in src/components/ui/badge.tsx and compose the primitive according to the Ark UI pattern for this component.
Examples
Default
import { Badge } from "@/components/ui/badge";
const BadgeDemo = () => <Badge>Default</Badge>;
export default BadgeDemo;
Outline
import { Badge } from "@/components/ui/badge";
const BadgeOutlineDemo = () => <Badge variant="outline">Outline</Badge>;
export default BadgeOutlineDemo;
Secondary
import { Badge } from "@/components/ui/badge";
const BadgeSecondaryDemo = () => <Badge variant="secondary">Secondary</Badge>;
export default BadgeSecondaryDemo;
Destructive
import { Badge } from "@/components/ui/badge";
const BadgeDestructiveDemo = () => (
<Badge variant="destructive">Destructive</Badge>
);
export default BadgeDestructiveDemo;
Info
import { Badge } from "@/components/ui/badge";
const BadgeInfoDemo = () => <Badge variant="info">Info</Badge>;
export default BadgeInfoDemo;
Success
import { Badge } from "@/components/ui/badge";
const BadgeSuccessDemo = () => <Badge variant="success">Success</Badge>;
export default BadgeSuccessDemo;
Warning
import { Badge } from "@/components/ui/badge";
const BadgeWarningDemo = () => <Badge variant="warning">Warning</Badge>;
export default BadgeWarningDemo;
Error
import { Badge } from "@/components/ui/badge";
const BadgeErrorDemo = () => <Badge variant="error">Error</Badge>;
export default BadgeErrorDemo;
Small
import { Badge } from "@/components/ui/badge";
const BadgeSmallDemo = () => <Badge size="sm">Small</Badge>;
export default BadgeSmallDemo;
Large
import { Badge } from "@/components/ui/badge";
const BadgeLargeDemo = () => <Badge size="lg">Large</Badge>;
export default BadgeLargeDemo;
With Icon
import { CheckCircle2Icon } from "lucide-react";
import { Badge } from "@/components/ui/badge";
const BadgeWithIconDemo = () => (
<Badge variant="success">
<CheckCircle2Icon />
With Icon
</Badge>
);
export default BadgeWithIconDemo;
With Link
With Count
import { InfoIcon } from "lucide-react";
import { Badge } from "@/components/ui/badge";
const BadgeWithCountDemo = () => (
<Badge variant="info">
<InfoIcon />
Notifications
<span className="rounded bg-background/70 px-1 text-[0.65rem]">12</span>
</Badge>
);
export default BadgeWithCountDemo;
API reference
This component is an ark-cn composition. All props and DOM behavior are defined by Ark unless you see an ark-cn-only row below.
Badge
| Prop | Type | Description |
|---|---|---|
| variant? | "default" | "secondary" | "destructive" | "outline" | "info" | "success" | "warning" | Semantic color preset. |
| size? | "default" | "sm" | "lg" | Density/size preset. |