Write on the margins of the internet. Powered by the AT Protocol.
margin.at
extension
web
atproto
comments
1import React from "react";
2import { clsx } from "clsx";
3
4type BadgeVariant = "default" | "primary" | "success" | "warning" | "danger";
5
6interface BadgeProps {
7 children: React.ReactNode;
8 variant?: BadgeVariant;
9 className?: string;
10}
11
12const variants: Record<BadgeVariant, string> = {
13 default:
14 "bg-surface-100 dark:bg-surface-800 text-surface-600 dark:text-surface-400",
15 primary:
16 "bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300",
17 success:
18 "bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300",
19 warning:
20 "bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-300",
21 danger: "bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300",
22};
23
24export default function Badge({
25 children,
26 variant = "default",
27 className,
28}: BadgeProps) {
29 return (
30 <span
31 className={clsx(
32 "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium",
33 variants[variant],
34 className,
35 )}
36 >
37 {children}
38 </span>
39 );
40}
41
42interface CountBadgeProps {
43 count: number;
44 max?: number;
45 className?: string;
46}
47
48export function CountBadge({ count, max = 99, className }: CountBadgeProps) {
49 if (count <= 0) return null;
50
51 return (
52 <span
53 className={clsx(
54 "inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1.5",
55 "text-[10px] font-bold rounded-full bg-primary-600 text-white",
56 className,
57 )}
58 >
59 {count > max ? `${max}+` : count}
60 </span>
61 );
62}