Badge
A compact label for status or metadata.
- Chromium
- Firefox
- WebKit
- WCAG 2.2 AA
Preview
import { Badge } from "@moe-ui/registry/components/ui/badge";
import { Text } from "@moe-ui/registry/components/ui/text";
export default function BadgePreview() {
return (
<Badge>
<Text>Badge</Text>
</Badge>
);
}
export function BadgeSecondaryPreview() {
return (
<Badge variant="secondary">
<Text>Secondary</Text>
</Badge>
);
}
export function BadgeDestructivePreview() {
return (
<Badge variant="destructive">
<Text>Destructive</Text>
</Badge>
);
}
export function BadgeOutlinePreview() {
return (
<Badge variant="outline">
<Text>Outline</Text>
</Badge>
);
}
One command, your source
Installation
pnpm dlx @moe-ui/cli@beta add badgeUsage
The CLI installs editable source into your application. Import the component from your configured UI directory:
import { Badge } from "@/components/ui/badge";Variants and composition
Each additional variant has its own live preview and testable section.
Secondary
import { Badge } from "@moe-ui/registry/components/ui/badge";
import { Text } from "@moe-ui/registry/components/ui/text";
export default function BadgePreview() {
return (
<Badge>
<Text>Badge</Text>
</Badge>
);
}
export function BadgeSecondaryPreview() {
return (
<Badge variant="secondary">
<Text>Secondary</Text>
</Badge>
);
}
export function BadgeDestructivePreview() {
return (
<Badge variant="destructive">
<Text>Destructive</Text>
</Badge>
);
}
export function BadgeOutlinePreview() {
return (
<Badge variant="outline">
<Text>Outline</Text>
</Badge>
);
}
Destructive
import { Badge } from "@moe-ui/registry/components/ui/badge";
import { Text } from "@moe-ui/registry/components/ui/text";
export default function BadgePreview() {
return (
<Badge>
<Text>Badge</Text>
</Badge>
);
}
export function BadgeSecondaryPreview() {
return (
<Badge variant="secondary">
<Text>Secondary</Text>
</Badge>
);
}
export function BadgeDestructivePreview() {
return (
<Badge variant="destructive">
<Text>Destructive</Text>
</Badge>
);
}
export function BadgeOutlinePreview() {
return (
<Badge variant="outline">
<Text>Outline</Text>
</Badge>
);
}
Outline
import { Badge } from "@moe-ui/registry/components/ui/badge";
import { Text } from "@moe-ui/registry/components/ui/text";
export default function BadgePreview() {
return (
<Badge>
<Text>Badge</Text>
</Badge>
);
}
export function BadgeSecondaryPreview() {
return (
<Badge variant="secondary">
<Text>Secondary</Text>
</Badge>
);
}
export function BadgeDestructivePreview() {
return (
<Badge variant="destructive">
<Text>Destructive</Text>
</Badge>
);
}
export function BadgeOutlinePreview() {
return (
<Badge variant="outline">
<Text>Outline</Text>
</Badge>
);
}
Compound parts and variants remain regular source in your project, so you can change them without wrapping a package API.
Public API
The canonical source panel below lists every public export, dependency, and the complete implementation shipped by the registry.
Keyboard and accessibility
Status is not communicated by color alone. Add an accessible label or live-region behavior when the message changes dynamically.
Browser support
This beta is release-tested in Chromium, Firefox, and WebKit in light and dark themes. See the web compatibility matrix for the current gate.
Nothing hiddenCanonical source and public exports3 exports
BadgebadgeTextVariantsbadgeVariants"use client";
import { TextClassContext } from "./text";
import { cn } from "../../lib/utils";
import * as Slot from "@rn-primitives/slot";
import { cva, type VariantProps } from "class-variance-authority";
import { Platform, View, ViewProps } from "react-native";
const badgeVariants = cva(
cn(
"border-border group shrink-0 flex-row items-center justify-center gap-1 overflow-hidden rounded-full border px-2 py-0.5",
Platform.select({
web: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive w-fit whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none [&>svg]:size-3",
}),
),
{
variants: {
variant: {
default: cn(
"bg-primary border-transparent",
Platform.select({ web: "[a&]:hover:bg-primary/90" }),
),
secondary: cn(
"bg-secondary border-transparent",
Platform.select({ web: "[a&]:hover:bg-secondary/90" }),
),
destructive: cn(
"bg-destructive border-transparent",
Platform.select({ web: "[a&]:hover:bg-destructive/90" }),
),
outline: Platform.select({
web: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
}),
},
},
defaultVariants: {
variant: "default",
},
},
);
const badgeTextVariants = cva("text-xs font-medium", {
variants: {
variant: {
default: "text-primary-foreground",
secondary: "text-secondary-foreground",
destructive: "text-white",
outline: "text-foreground",
},
},
defaultVariants: {
variant: "default",
},
});
type BadgeProps = ViewProps &
React.RefAttributes<View> & {
asChild?: boolean;
} & VariantProps<typeof badgeVariants>;
function Badge({ className, variant, asChild, ...props }: BadgeProps) {
const Component = asChild ? Slot.View : View;
return (
<TextClassContext.Provider value={badgeTextVariants({ variant })}>
<Component
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
</TextClassContext.Provider>
);
}
export { Badge, badgeTextVariants, badgeVariants };
export type { BadgeProps };