{
    "name": "ai-modal-ability-selector",
    "title": "Modal Ability Selector",
    "description": "Compact selector for toggling abilities with icons and custom styles",
    "type": "registry:ui",
    "dependencies": ["gsap", "@gsap/react"],
    "registryDependencies": ["@paceui-gsap/swap", "button", "dropdown-menu", "tooltip"],
    "files": [
        {
            "path": "components/gsap/ai-modal-ability-selector.tsx",
            "type": "registry:ui",
            "target": "~/components/gsap/ai-modal-ability-selector.tsx",
            "content": "import { ComponentProps, ReactNode, useEffect, useState } from \"react\";\n\nimport { BrainIcon, CodeIcon, EyeIcon, FileSearch2Icon, SpeechIcon, Wand2Icon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport { Swap } from \"@/components/gsap/swap\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n    DropdownMenu,\n    DropdownMenuCheckboxItem,\n    DropdownMenuContent,\n    DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@/components/ui/tooltip\";\n\nconst abilities = [\"vision\", \"thinking\", \"code\", \"speech\", \"search\", \"creativity\"] as const;\n\ntype AbilityType = (typeof abilities)[number];\n\nconst abilityConfig: Record<AbilityType, { color: string; text: string; icon: ReactNode }> = {\n    thinking: {\n        color: \"bg-purple-500/10 hover:bg-purple-500/20 text-purple-500\",\n        text: \"Thinking\",\n        icon: <BrainIcon className=\"size-4.5\" />,\n    },\n    code: {\n        color: \"bg-cyan-500/10 hover:bg-cyan-500/20 text-cyan-500\",\n        text: \"Code\",\n        icon: <CodeIcon className=\"size-4.5\" />,\n    },\n    vision: {\n        color: \"bg-green-500/10 hover:bg-green-500/20 text-green-500\",\n        text: \"Vision\",\n        icon: <EyeIcon className=\"size-4.5\" />,\n    },\n    creativity: {\n        color: \"bg-orange-500/10 hover:bg-orange-500/20 text-orange-500\",\n        text: \"Creativity\",\n        icon: <Wand2Icon className=\"size-4.5\" />,\n    },\n    search: {\n        color: \"bg-teal-500/10 hover:bg-teal-500/20 text-teal-500\",\n        text: \"Search\",\n        icon: <FileSearch2Icon className=\"size-4.5\" />,\n    },\n    speech: {\n        color: \"bg-pink-500/10 hover:bg-pink-500/20 text-pink-500\",\n        text: \"Speech\",\n        icon: <SpeechIcon className=\"size-4.5\" />,\n    },\n};\n\ntype ModalAbilitySelectorProps = ComponentProps<typeof Button> & {\n    buttonVariant?: \"ghost\" | \"outline\" | \"default\";\n    maxVisible?: number;\n};\n\nexport const AiModalAbilitySelector = ({\n    className,\n    buttonVariant = \"ghost\",\n    maxVisible = 3,\n    ...props\n}: ModalAbilitySelectorProps) => {\n    const [selected, setSelected] = useState<AbilityType[]>([\"code\", \"search\"]);\n\n    const toggleAbility = (ability: AbilityType) => {\n        setSelected((prev) => (prev.includes(ability) ? prev.filter((c) => c !== ability) : [...prev, ability]));\n    };\n\n    useEffect(() => setSelected((s) => [...s]), [maxVisible]);\n\n    return (\n        <TooltipProvider>\n            <DropdownMenu>\n                <DropdownMenuTrigger\n                    render={\n                        <Button\n                            variant={buttonVariant}\n                            {...props}\n                            className={cn(\"cursor-pointer px-2 shadow-none ring-0!\", className)}>\n                            <Swap state={selected} effects={[\"blur\", \"opacity\"]}>\n                                {(current) =>\n                                    current.length === 0 ? (\n                                        <p className=\"text-muted-foreground\">None</p>\n                                    ) : (\n                                        <div className=\"flex items-center gap-1.5\">\n                                            {current.slice(0, maxVisible - 1).map((cap) => (\n                                                <Tooltip key={cap}>\n                                                    <TooltipTrigger\n                                                        render={\n                                                            <div className=\"bg-card rounded p-1 shadow\">\n                                                                {abilityConfig[cap].icon}\n                                                            </div>\n                                                        }></TooltipTrigger>\n                                                    <TooltipContent>{abilityConfig[cap].text}</TooltipContent>\n                                                </Tooltip>\n                                            ))}\n                                            {current.length > maxVisible - 1 && (\n                                                <Tooltip>\n                                                    <TooltipTrigger\n                                                        render={\n                                                            <div className=\"bg-card flex size-6 items-center justify-center rounded text-xs font-medium shadow\">\n                                                                {current.length === maxVisible\n                                                                    ? abilityConfig[current[maxVisible - 1]].icon\n                                                                    : `+${current.length - (maxVisible - 1)}`}\n                                                            </div>\n                                                        }></TooltipTrigger>\n                                                    <TooltipContent>\n                                                        {current.length === maxVisible\n                                                            ? abilityConfig[current[maxVisible - 1]].text\n                                                            : current\n                                                                  .slice(maxVisible - 1)\n                                                                  .map((cap) => abilityConfig[cap].text)\n                                                                  .join(\", \")}\n                                                    </TooltipContent>\n                                                </Tooltip>\n                                            )}\n                                        </div>\n                                    )\n                                }\n                            </Swap>\n                        </Button>\n                    }></DropdownMenuTrigger>\n\n                <DropdownMenuContent className=\"w-44 shadow-xs transition-all hover:shadow-md\" align=\"start\">\n                    <div className=\"space-y-0.5\">\n                        {abilities.map((ability) => (\n                            <DropdownMenuCheckboxItem\n                                key={ability}\n                                className=\"cursor-pointer gap-2\"\n                                checked={selected.includes(ability)}\n                                onCheckedChange={() => toggleAbility(ability)}>\n                                {abilityConfig[ability].icon}\n                                {abilityConfig[ability].text}\n                            </DropdownMenuCheckboxItem>\n                        ))}\n                    </div>\n                </DropdownMenuContent>\n            </DropdownMenu>\n        </TooltipProvider>\n    );\n};\n"
        }
    ]
}
