feat(11-04): create GroupBadge component

- Built-in variant: Badge secondary, no dismiss, hover:bg-accent/30
- Custom variant: Badge outline, X dismiss button with spinner, hover:bg-accent/50
- Tooltip on both variants showing name · built-in · N skills or name · N skills
- text-sm font-semibold typography per UI-SPEC (no font-bold or font-medium)
This commit is contained in:
Mikkel Georgsen 2026-04-01 03:35:45 +02:00 committed by Nexus Dev
parent bd38700876
commit bc89b58a06

View file

@ -0,0 +1,82 @@
import { X, Loader2 } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
type GroupBadgeProps = {
name: string;
isBuiltin: boolean;
skillCount?: number;
description?: string | null;
onRemove?: () => void;
removing?: boolean;
};
export function GroupBadge({
name,
isBuiltin,
skillCount,
description: _description,
onRemove,
removing = false,
}: GroupBadgeProps) {
const tooltipText = isBuiltin
? `${name} · built-in${skillCount != null ? ` · ${skillCount} skills` : ""}`
: `${name}${skillCount != null ? ` · ${skillCount} skills` : ""}`;
if (isBuiltin) {
return (
<Tooltip>
<TooltipTrigger asChild>
<Badge
variant="secondary"
className={cn(
"cursor-default select-none text-sm font-semibold",
"hover:bg-accent/30",
"focus-visible:ring-ring focus-visible:ring-[3px]",
)}
>
{name}
</Badge>
</TooltipTrigger>
<TooltipContent side="top">{tooltipText}</TooltipContent>
</Tooltip>
);
}
return (
<Tooltip>
<TooltipTrigger asChild>
<Badge
variant="outline"
className={cn(
"cursor-default select-none gap-1 text-sm font-semibold",
"hover:bg-accent/50",
"focus-visible:ring-ring focus-visible:ring-[3px]",
)}
>
{name}
{onRemove && (
<button
type="button"
aria-label={`Remove ${name}`}
disabled={removing}
onClick={(e) => {
e.stopPropagation();
onRemove();
}}
className="ml-0.5 rounded-full p-0.5 transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50"
>
{removing ? (
<Loader2 className="h-3 w-3 animate-spin" />
) : (
<X className="h-3 w-3" />
)}
</button>
)}
</Badge>
</TooltipTrigger>
<TooltipContent side="top">{tooltipText}</TooltipContent>
</Tooltip>
);
}