{
  "title": "Model Ability Selector",
  "description": "Compact selector for toggling abilities with icons and custom styles",
  "name": "motion-ai-model-ability-selector",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "button",
    "dropdown-menu",
    "tooltip"
  ],
  "type": "registry:ui",
  "files": [
    {
      "path": "components/paceui/motion/ai-model-ability-selector.tsx",
      "type": "registry:ui",
      "content": "import { type ComponentProps, type ReactNode, useState } from \"react\";\n\nimport { BrainIcon, CodeIcon, EyeIcon, FileSearch2Icon, SpeechIcon, Wand2Icon } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport NumberFlow from \"@number-flow/react\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n    DropdownMenu,\n    DropdownMenuCheckboxItem,\n    DropdownMenuContent,\n    DropdownMenuTrigger,\n} from \"@/components/paceui/motion/dropdown-menu\";\nimport {\n    Tooltip,\n    TooltipContent,\n    TooltipProvider,\n    TooltipTrigger,\n} from \"@/components/paceui/motion/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 ModelAbilitySelectorProps = ComponentProps<\"div\"> & {\n    buttonVariant?: \"ghost\" | \"outline\" | \"default\";\n    maxVisible?: number;\n};\n\nconst spring = { type: \"spring\", stiffness: 500, damping: 35 } as const;\n\nexport const AiModelAbilitySelector = ({\n    className,\n    buttonVariant = \"ghost\",\n    maxVisible = 3,\n    ...props\n}: ModelAbilitySelectorProps) => {\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    const visibleItems = selected.slice(0, maxVisible - 1);\n    const overflowItems = selected.slice(maxVisible - 1);\n    const hasOverflow = selected.length > maxVisible - 1;\n    const singleOverflowIcon = selected.length === maxVisible;\n    const count = selected.length - (maxVisible - 1);\n\n    return (\n        <TooltipProvider>\n            <DropdownMenu>\n                <DropdownMenuTrigger\n                    render={\n                        <div className={cn(\"flex cursor-pointer items-center gap-2\", className)} {...props}>\n                            {selected.length === 0 ? (\n                                <Button\n                                    variant={buttonVariant}\n                                    className=\"cursor-pointer h-8 px-2.5 shadow-none ring-0!\">\n                                    <p className=\"text-muted-foreground px-1\">None</p>\n                                </Button>\n                            ) : null}\n\n                            <motion.div layout transition={spring} className=\"flex items-center\">\n                                <AnimatePresence initial={false}>\n                                    {visibleItems.map((cap) => (\n                                        <motion.span\n                                            key={cap}\n                                            initial={{ width: 0, opacity: 0 }}\n                                            animate={{ width: \"auto\", opacity: 1 }}\n                                            exit={{ width: 0, opacity: 0 }}\n                                            transition={spring}\n                                            className=\"relative\">\n                                            <motion.span\n                                                initial={{ x: -18, opacity: 0 }}\n                                                animate={{ x: 0, opacity: 1 }}\n                                                exit={{ x: 18, opacity: 0 }}\n                                                transition={spring}\n                                                className=\"block pr-1.5\">\n                                                <Tooltip>\n                                                    <TooltipTrigger\n                                                        render={\n                                                            <div className=\"bg-card border shadow-2xs flex size-8 cursor-pointer items-center justify-center rounded-md\">\n                                                                {abilityConfig[cap].icon}\n                                                            </div>\n                                                        }></TooltipTrigger>\n                                                    <TooltipContent>{abilityConfig[cap].text}</TooltipContent>\n                                                </Tooltip>\n                                            </motion.span>\n                                        </motion.span>\n                                    ))}\n\n                                    {hasOverflow && (\n                                        <motion.span\n                                            key=\"overflow\"\n                                            initial={{ width: 0, opacity: 0 }}\n                                            animate={{ width: \"auto\", opacity: 1 }}\n                                            exit={{ width: 0, opacity: 0 }}\n                                            transition={spring}\n                                            className=\"relative\">\n                                            <motion.span\n                                                initial={{ x: -18, opacity: 0 }}\n                                                animate={{ x: 0, opacity: 1 }}\n                                                exit={{ x: 18, opacity: 0 }}\n                                                transition={spring}\n                                                className=\"block pr-1.5\">\n                                                <Tooltip>\n                                                    <TooltipTrigger\n                                                        render={\n                                                            <div className=\"border bg-card shadow-2xs flex h-8 min-w-8 cursor-pointer items-center justify-center rounded-md px-1.5 text-xs font-medium tabular-nums\">\n                                                                {singleOverflowIcon ? (\n                                                                    abilityConfig[overflowItems[0]].icon\n                                                                ) : (\n                                                                    <span className=\"flex items-center\">\n                                                                        +<NumberFlow value={count} />\n                                                                    </span>\n                                                                )}\n                                                            </div>\n                                                        }></TooltipTrigger>\n                                                    <TooltipContent>\n                                                        {singleOverflowIcon\n                                                            ? abilityConfig[overflowItems[0]].text\n                                                            : overflowItems\n                                                                .map((cap) => abilityConfig[cap].text)\n                                                                .join(\", \")}\n                                                    </TooltipContent>\n                                                </Tooltip>\n                                            </motion.span>\n                                        </motion.span>\n                                    )}\n                                </AnimatePresence>\n                            </motion.div>\n                        </div>\n                    }></DropdownMenuTrigger>\n\n                <DropdownMenuContent className=\"w-44 shadow-xs transition-shadow hover:shadow-md\" align=\"start\">\n                    <AnimatePresence mode=\"wait\">\n                        <div className=\"space-y-0.5\">\n                            {abilities.map((ability) => (\n                                <motion.div\n                                    key={ability}\n                                    initial={{ opacity: 0, y: -6 }}\n                                    animate={{ opacity: 1, y: 0 }}\n                                    exit={{ opacity: 0, y: -6 }}\n                                    transition={spring}\n                                    className=\"relative\">\n                                    <DropdownMenuCheckboxItem\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                                </motion.div>\n                            ))}\n                        </div>\n                    </AnimatePresence>\n                </DropdownMenuContent>\n            </DropdownMenu>\n        </TooltipProvider>\n    );\n};\n"
    },
    {
      "path": "components/paceui/motion/dropdown-menu.tsx",
      "type": "registry:ui",
      "content": "import * as React from \"react\";\n\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\";\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\";\nimport { AnimatePresence, type Transition, motion } from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface DropdownMenuHighlightContextType {\n    highlightLayoutId: string;\n    activeItemId: string | null;\n    setActiveItem: (id: string) => void;\n    clearActiveItemWithDelay: () => void;\n}\n\nconst DropdownMenuHighlightContext = React.createContext<DropdownMenuHighlightContextType | null>(null);\n\nexport interface DropdownMenuProps extends MenuPrimitive.Root.Props {}\n\nfunction DropdownMenu({ ...props }: DropdownMenuProps) {\n    return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n    return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n    return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nexport interface DropdownMenuContentProps\n    extends\n        MenuPrimitive.Popup.Props,\n        Pick<MenuPrimitive.Positioner.Props, \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"> {\n    transition?: Transition;\n}\n\nfunction DropdownMenuContent({\n    align = \"start\",\n    alignOffset = 0,\n    side = \"bottom\",\n    sideOffset = 4,\n    transition = { type: \"spring\", stiffness: 380, damping: 26, mass: 0.8 },\n    className,\n    children,\n    ...props\n}: DropdownMenuContentProps) {\n    const parentHighlightContext = React.useContext(DropdownMenuHighlightContext);\n\n    const generatedLayoutId = React.useId();\n    const highlightLayoutId = parentHighlightContext?.highlightLayoutId ?? generatedLayoutId;\n\n    const [localActiveItemId, setLocalActiveItemId] = React.useState<string | null>(null);\n    const timeoutRef = React.useRef<any>(null);\n\n    const setActiveItem =\n        parentHighlightContext?.setActiveItem ??\n        React.useCallback((id: string) => {\n            if (timeoutRef.current) clearTimeout(timeoutRef.current);\n            setLocalActiveItemId(id);\n        }, []);\n\n    const clearActiveItemWithDelay =\n        parentHighlightContext?.clearActiveItemWithDelay ??\n        React.useCallback(() => {\n            if (timeoutRef.current) clearTimeout(timeoutRef.current);\n            timeoutRef.current = setTimeout(() => {\n                setLocalActiveItemId(null);\n            }, 180);\n        }, []);\n\n    const activeItemId = parentHighlightContext ? parentHighlightContext.activeItemId : localActiveItemId;\n\n    const highlightValue: DropdownMenuHighlightContextType = parentHighlightContext ?? {\n        highlightLayoutId,\n        activeItemId,\n        setActiveItem,\n        clearActiveItemWithDelay,\n    };\n\n    return (\n        <MenuPrimitive.Portal keepMounted>\n            <MenuPrimitive.Positioner\n                className=\"isolate z-500 outline-none\"\n                align={align}\n                alignOffset={alignOffset}\n                side={side}\n                sideOffset={sideOffset}>\n                <MenuPrimitive.Popup\n                    data-slot=\"dropdown-menu-content\"\n                    {...props}\n                    render={(popupProps, state) => (\n                        <AnimatePresence initial={false}>\n                            {state.open && (\n                                <motion.div\n                                    {...popupProps}\n                                    key=\"dropdown-menu-content\"\n                                    initial={{\n                                        opacity: 0,\n                                        scale: 0.94,\n                                        y: side === \"bottom\" ? -8 : side === \"top\" ? 8 : 0,\n                                        x: side === \"right\" ? -12 : side === \"left\" ? 12 : 0,\n                                    }}\n                                    animate={{ opacity: 1, scale: 1, y: 0, x: 0 }}\n                                    exit={{\n                                        opacity: 0,\n                                        scale: 0.94,\n                                        y: side === \"bottom\" ? -6 : side === \"top\" ? 6 : 0,\n                                        x: side === \"right\" ? -8 : side === \"left\" ? 8 : 0,\n                                    }}\n                                    transition={transition}\n                                    className={cn(\n                                        \"ring-foreground/10 bg-popover text-popover-foreground z-50 flex max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) flex-col gap-px overflow-x-hidden overflow-y-auto rounded-md p-1 shadow-md ring-1 outline-none\",\n                                        className,\n                                    )}>\n                                    <DropdownMenuHighlightContext.Provider value={highlightValue}>\n                                        <div onPointerLeave={clearActiveItemWithDelay} className=\"flex flex-col gap-px\">\n                                            {children}\n                                        </div>\n                                    </DropdownMenuHighlightContext.Provider>\n                                </motion.div>\n                            )}\n                        </AnimatePresence>\n                    )}\n                />\n            </MenuPrimitive.Positioner>\n        </MenuPrimitive.Portal>\n    );\n}\n\nfunction DropdownMenuGroup({ className, ...props }: MenuPrimitive.Group.Props) {\n    return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" className={cn(\"flex flex-col gap-px\", className)} {...props} />;\n}\n\nfunction DropdownMenuLabel({\n    className,\n    inset,\n    ...props\n}: MenuPrimitive.GroupLabel.Props & {\n    inset?: boolean;\n}) {\n    return (\n        <MenuPrimitive.Group>\n            <MenuPrimitive.GroupLabel\n                data-slot=\"dropdown-menu-label\"\n                data-inset={inset}\n                className={cn(\"text-muted-foreground px-2 py-1.5 text-xs font-medium data-inset:pl-8\", className)}\n                {...props}\n            />\n        </MenuPrimitive.Group>\n    );\n}\n\nexport interface DropdownMenuItemProps extends MenuPrimitive.Item.Props {\n    inset?: boolean;\n    variant?: \"default\" | \"destructive\";\n}\n\nfunction DropdownMenuItem({\n    className,\n    inset,\n    variant = \"default\",\n    children,\n    render: customRender,\n    ...props\n}: DropdownMenuItemProps) {\n    const highlightContext = React.useContext(DropdownMenuHighlightContext);\n    const itemId = React.useId();\n\n    return (\n        <MenuPrimitive.Item\n            data-slot=\"dropdown-menu-item\"\n            data-inset={inset}\n            data-variant={variant}\n            {...props}\n            render={(itemProps, state) => {\n                const isCurrentActive = highlightContext?.activeItemId === itemId;\n\n                const innerContent = (\n                    <>\n                        {isCurrentActive && highlightContext?.highlightLayoutId && (\n                            <motion.div\n                                layoutId={highlightContext.highlightLayoutId}\n                                className={cn(\n                                    \"pointer-events-none absolute inset-0 z-0 rounded-sm\",\n                                    variant === \"destructive\"\n                                        ? \"bg-destructive/10 dark:bg-destructive/20\"\n                                        : \"bg-accent\",\n                                )}\n                                transition={{ type: \"spring\", stiffness: 450, damping: 32 }}\n                            />\n                        )}\n                        <span className=\"relative z-10 flex w-full items-center gap-2\">\n                            {React.isValidElement(customRender) && customRender.props.children\n                                ? customRender.props.children\n                                : children}\n                        </span>\n                    </>\n                );\n\n                const itemClassName = cn(\n                    \"group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n                    (state.highlighted || isCurrentActive) &&\n                        (variant === \"destructive\" ? \"text-destructive\" : \"text-accent-foreground\"),\n                    className,\n                    React.isValidElement(customRender) && (customRender.props as any).className,\n                );\n\n                if (React.isValidElement(customRender)) {\n                    return React.cloneElement(customRender as React.ReactElement<any>, {\n                        ...itemProps,\n                        ...(customRender.props as any),\n                        onPointerEnter: (e: any) => {\n                            itemProps.onPointerEnter?.(e);\n                            (customRender.props as any).onPointerEnter?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        },\n                        onFocus: (e: any) => {\n                            itemProps.onFocus?.(e);\n                            (customRender.props as any).onFocus?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        },\n                        className: itemClassName,\n                        children: innerContent,\n                    });\n                }\n\n                return (\n                    <motion.div\n                        {...itemProps}\n                        onPointerEnter={(e: any) => {\n                            itemProps.onPointerEnter?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        onFocus={(e: any) => {\n                            itemProps.onFocus?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        whileTap={{ scale: 0.98 }}\n                        transition={{ type: \"spring\", stiffness: 400, damping: 25 }}\n                        className={itemClassName}>\n                        {innerContent}\n                    </motion.div>\n                );\n            }}\n        />\n    );\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n    return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nexport interface DropdownMenuSubTriggerProps extends MenuPrimitive.SubmenuTrigger.Props {\n    inset?: boolean;\n}\n\nfunction DropdownMenuSubTrigger({ className, inset, children, ...props }: DropdownMenuSubTriggerProps) {\n    const highlightContext = React.useContext(DropdownMenuHighlightContext);\n    const itemId = React.useId();\n\n    return (\n        <MenuPrimitive.SubmenuTrigger\n            data-slot=\"dropdown-menu-sub-trigger\"\n            data-inset={inset}\n            {...props}\n            render={(triggerProps, state) => {\n                const isCurrentActive = highlightContext?.activeItemId === itemId;\n\n                return (\n                    <motion.div\n                        {...triggerProps}\n                        onPointerEnter={(e: any) => {\n                            triggerProps.onPointerEnter?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        onFocus={(e: any) => {\n                            triggerProps.onFocus?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        whileTap={{ scale: 0.98 }}\n                        transition={{ type: \"spring\", stiffness: 400, damping: 25 }}\n                        className={cn(\n                            \"group/dropdown-menu-sub-trigger relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n                            (state.highlighted || state.open || isCurrentActive) && \"text-accent-foreground\",\n                            className,\n                        )}>\n                        {isCurrentActive && highlightContext?.highlightLayoutId ? (\n                            <motion.div\n                                layoutId={highlightContext.highlightLayoutId}\n                                className=\"bg-accent pointer-events-none absolute inset-0 z-0 rounded-sm\"\n                                transition={{ type: \"spring\", stiffness: 450, damping: 32 }}\n                            />\n                        ) : state.open ? (\n                            <div className=\"bg-accent/60 pointer-events-none absolute inset-0 z-0 rounded-sm\" />\n                        ) : null}\n                        <span className=\"relative z-10 flex w-full items-center gap-2\">{children}</span>\n                        <ChevronRightIcon className=\"relative z-10 ml-auto\" />\n                    </motion.div>\n                );\n            }}\n        />\n    );\n}\n\nfunction DropdownMenuSubContent({\n    align = \"start\",\n    alignOffset = -3,\n    side = \"right\",\n    sideOffset = 4,\n    className,\n    ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n    return (\n        <DropdownMenuContent\n            data-slot=\"dropdown-menu-sub-content\"\n            className={cn(\"w-auto min-w-[120px] shadow-lg\", className)}\n            align={align}\n            alignOffset={alignOffset}\n            side={side}\n            sideOffset={sideOffset}\n            {...props}\n        />\n    );\n}\n\nexport interface DropdownMenuCheckboxItemProps extends MenuPrimitive.CheckboxItem.Props {}\n\nfunction DropdownMenuCheckboxItem({ className, children, checked, ...props }: DropdownMenuCheckboxItemProps) {\n    const highlightContext = React.useContext(DropdownMenuHighlightContext);\n    const itemId = React.useId();\n\n    return (\n        <MenuPrimitive.CheckboxItem\n            data-slot=\"dropdown-menu-checkbox-item\"\n            className={cn(\n                \"group/dropdown-menu-checkbox-item relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n                className,\n            )}\n            checked={checked}\n            {...props}\n            render={(itemProps, state) => {\n                const isCurrentActive = highlightContext?.activeItemId === itemId;\n\n                return (\n                    <motion.div\n                        {...itemProps}\n                        onPointerEnter={(e: any) => {\n                            itemProps.onPointerEnter?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        onFocus={(e: any) => {\n                            itemProps.onFocus?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        whileTap={{ scale: 0.98 }}\n                        transition={{ type: \"spring\", stiffness: 400, damping: 25 }}\n                        className={cn(\n                            \"group/dropdown-menu-checkbox-item relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n                            (state.highlighted || isCurrentActive) && \"text-accent-foreground\",\n                            className,\n                        )}>\n                        {isCurrentActive && highlightContext?.highlightLayoutId && (\n                            <motion.div\n                                layoutId={highlightContext.highlightLayoutId}\n                                className=\"bg-accent pointer-events-none absolute inset-0 z-0 rounded-sm\"\n                                transition={{ type: \"spring\", stiffness: 450, damping: 32 }}\n                            />\n                        )}\n                        <span className=\"relative z-10 flex items-center gap-2\">{children}</span>\n                        <span\n                            className=\"pointer-events-none absolute right-2 z-10 flex items-center justify-center\"\n                            data-slot=\"dropdown-menu-checkbox-item-indicator\">\n                            <MenuPrimitive.CheckboxItemIndicator>\n                                <motion.span\n                                    initial={{ scale: 0, opacity: 0 }}\n                                    animate={{ scale: 1, opacity: 1 }}\n                                    exit={{ scale: 0, opacity: 0 }}\n                                    transition={{ type: \"spring\", stiffness: 400, damping: 22 }}\n                                    className=\"flex items-center justify-center\">\n                                    <CheckIcon />\n                                </motion.span>\n                            </MenuPrimitive.CheckboxItemIndicator>\n                        </span>\n                    </motion.div>\n                );\n            }}\n        />\n    );\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n    return <MenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nexport interface DropdownMenuRadioItemProps extends MenuPrimitive.RadioItem.Props {}\n\nfunction DropdownMenuRadioItem({ className, children, ...props }: DropdownMenuRadioItemProps) {\n    const highlightContext = React.useContext(DropdownMenuHighlightContext);\n    const itemId = React.useId();\n\n    return (\n        <MenuPrimitive.RadioItem\n            data-slot=\"dropdown-menu-radio-item\"\n            className={cn(\n                \"group/dropdown-menu-radio-item relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n                className,\n            )}\n            {...props}\n            render={(itemProps, state) => {\n                const isCurrentActive = highlightContext?.activeItemId === itemId;\n\n                return (\n                    <motion.div\n                        {...itemProps}\n                        onPointerEnter={(e: any) => {\n                            itemProps.onPointerEnter?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        onFocus={(e: any) => {\n                            itemProps.onFocus?.(e);\n                            highlightContext?.setActiveItem(itemId);\n                        }}\n                        whileTap={{ scale: 0.98 }}\n                        transition={{ type: \"spring\", stiffness: 400, damping: 25 }}\n                        className={cn(\n                            \"group/dropdown-menu-radio-item relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n                            (state.highlighted || isCurrentActive) && \"text-accent-foreground\",\n                            className,\n                        )}>\n                        {isCurrentActive && highlightContext?.highlightLayoutId && (\n                            <motion.div\n                                layoutId={highlightContext.highlightLayoutId}\n                                className=\"bg-accent pointer-events-none absolute inset-0 z-0 rounded-sm\"\n                                transition={{ type: \"spring\", stiffness: 450, damping: 32 }}\n                            />\n                        )}\n                        <span className=\"relative z-10 flex items-center gap-2\">{children}</span>\n                        <span\n                            className=\"pointer-events-none absolute right-2 z-10 flex items-center justify-center\"\n                            data-slot=\"dropdown-menu-radio-item-indicator\">\n                            <MenuPrimitive.RadioItemIndicator>\n                                <motion.span\n                                    initial={{ scale: 0, opacity: 0 }}\n                                    animate={{ scale: 1, opacity: 1 }}\n                                    exit={{ scale: 0, opacity: 0 }}\n                                    transition={{ type: \"spring\", stiffness: 400, damping: 22 }}\n                                    className=\"flex items-center justify-center\">\n                                    <CheckIcon />\n                                </motion.span>\n                            </MenuPrimitive.RadioItemIndicator>\n                        </span>\n                    </motion.div>\n                );\n            }}\n        />\n    );\n}\n\nfunction DropdownMenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {\n    return (\n        <MenuPrimitive.Separator\n            data-slot=\"dropdown-menu-separator\"\n            className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n            {...props}\n        />\n    );\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n    return (\n        <span\n            data-slot=\"dropdown-menu-shortcut\"\n            className={cn(\n                \"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest\",\n                className,\n            )}\n            {...props}\n        />\n    );\n}\n\nexport {\n    DropdownMenu,\n    DropdownMenuPortal,\n    DropdownMenuTrigger,\n    DropdownMenuContent,\n    DropdownMenuGroup,\n    DropdownMenuLabel,\n    DropdownMenuItem,\n    DropdownMenuCheckboxItem,\n    DropdownMenuRadioGroup,\n    DropdownMenuRadioItem,\n    DropdownMenuSeparator,\n    DropdownMenuShortcut,\n    DropdownMenuSub,\n    DropdownMenuSubTrigger,\n    DropdownMenuSubContent,\n};\n"
    },
    {
      "path": "components/paceui/motion/tooltip.tsx",
      "type": "registry:ui",
      "content": "import * as React from \"react\";\n\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\nimport { AnimatePresence, type Transition, motion } from \"motion/react\";\nimport { createPortal } from \"react-dom\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface TooltipItemData {\n    content: React.ReactNode;\n    side?: TooltipPrimitive.Positioner.Props[\"side\"];\n    sideOffset?: TooltipPrimitive.Positioner.Props[\"sideOffset\"];\n    align?: TooltipPrimitive.Positioner.Props[\"align\"];\n    alignOffset?: TooltipPrimitive.Positioner.Props[\"alignOffset\"];\n    className?: string | ((state: any) => string | undefined);\n    showArrow?: boolean;\n}\n\ninterface TooltipProviderContextValue {\n    activeId: string | null;\n    openTooltip: (id: string, element: HTMLElement, data?: TooltipItemData | null) => void;\n    closeTooltip: (id: string) => void;\n    updateTooltipData: (id: string, data: TooltipItemData) => void;\n}\n\nconst TooltipProviderContext = React.createContext<TooltipProviderContextValue | null>(null);\n\nconst TooltipItemContext = React.createContext<{\n    id: string;\n    triggerRef: React.RefObject<HTMLElement | null>;\n    dataRef: React.RefObject<TooltipItemData>;\n} | null>(null);\n\nexport interface TooltipProviderProps extends TooltipPrimitive.Provider.Props {\n    transition?: Transition;\n}\n\nconst contentVariants = {\n    initial: (offset: { x: number; y: number }) => {\n        if (offset.x === 0 && offset.y === 0) {\n            return {\n                opacity: 0,\n                scale: 0.96,\n                filter: \"blur(4px)\",\n                x: 0,\n                y: 4,\n            };\n        }\n        return {\n            opacity: 0,\n            filter: \"blur(4px)\",\n            x: offset.x,\n            y: offset.y,\n            scale: 0.96,\n        };\n    },\n    animate: {\n        opacity: 1,\n        filter: \"blur(0px)\",\n        x: 0,\n        y: 0,\n        scale: 1,\n    },\n    exit: (offset: { x: number; y: number }) => {\n        if (offset.x === 0 && offset.y === 0) {\n            return {\n                opacity: 0,\n                scale: 0.96,\n                filter: \"blur(4px)\",\n                x: 0,\n                y: -4,\n            };\n        }\n        return {\n            opacity: 0,\n            filter: \"blur(4px)\",\n            x: -offset.x * 0.6,\n            y: -offset.y * 0.6,\n            scale: 0.96,\n        };\n    },\n};\n\nfunction TooltipProvider({\n    delay = 0,\n    closeDelay = 150,\n    transition = { type: \"spring\", stiffness: 420, damping: 28, mass: 0.7 },\n    children,\n    ...props\n}: TooltipProviderProps) {\n    const [activeId, setActiveId] = React.useState<string | null>(null);\n    const [activeRect, setActiveRect] = React.useState<DOMRect | null>(null);\n    const [activeData, setActiveData] = React.useState<TooltipItemData | null>(null);\n    const [offset, setOffset] = React.useState<{ x: number; y: number }>({ x: 0, y: 0 });\n    const [isMounted, setIsMounted] = React.useState(false);\n\n    const itemsDataRef = React.useRef<Map<string, TooltipItemData>>(new Map());\n    const triggerElementsRef = React.useRef<Map<string, HTMLElement>>(new Map());\n    const activeRectRef = React.useRef<DOMRect | null>(null);\n    const closeTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n    const openTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n\n    React.useEffect(() => {\n        setIsMounted(true);\n    }, []);\n\n    const updatePosition = React.useCallback(() => {\n        if (!activeId) return;\n        const el = triggerElementsRef.current.get(activeId);\n        if (el) {\n            const rect = el.getBoundingClientRect();\n            setActiveRect(rect);\n            activeRectRef.current = rect;\n        }\n    }, [activeId]);\n\n    React.useEffect(() => {\n        if (!activeId) return;\n        window.addEventListener(\"scroll\", updatePosition, true);\n        window.addEventListener(\"resize\", updatePosition);\n        return () => {\n            window.removeEventListener(\"scroll\", updatePosition, true);\n            window.removeEventListener(\"resize\", updatePosition);\n        };\n    }, [activeId, updatePosition]);\n\n    const openTooltip = React.useCallback(\n        (id: string, element: HTMLElement, directData?: TooltipItemData | null) => {\n            if (closeTimeoutRef.current) {\n                clearTimeout(closeTimeoutRef.current);\n                closeTimeoutRef.current = null;\n            }\n\n            triggerElementsRef.current.set(id, element);\n            if (directData) {\n                itemsDataRef.current.set(id, directData);\n            }\n\n            const data = directData || itemsDataRef.current.get(id) || null;\n            const isAlreadyOpen = Boolean(activeId);\n            const newRect = element.getBoundingClientRect();\n\n            if (isAlreadyOpen && activeRectRef.current) {\n                const prevCenterX = activeRectRef.current.left + activeRectRef.current.width / 2;\n                const prevCenterY = activeRectRef.current.top + activeRectRef.current.height / 2;\n                const newCenterX = newRect.left + newRect.width / 2;\n                const newCenterY = newRect.top + newRect.height / 2;\n\n                const dx = prevCenterX - newCenterX;\n                const dy = prevCenterY - newCenterY;\n\n                const clampedX = Math.max(Math.min(dx, 80), -80);\n                const clampedY = Math.max(Math.min(dy, 40), -40);\n                setOffset({ x: clampedX, y: clampedY });\n            } else {\n                setOffset({ x: 0, y: 0 });\n            }\n\n            activeRectRef.current = newRect;\n\n            if (isAlreadyOpen || delay <= 0) {\n                setActiveId(id);\n                setActiveRect(newRect);\n                if (data) setActiveData(data);\n            } else {\n                if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);\n                openTimeoutRef.current = setTimeout(() => {\n                    setActiveId(id);\n                    const rect = element.getBoundingClientRect();\n                    setActiveRect(rect);\n                    activeRectRef.current = rect;\n                    const latestData = itemsDataRef.current.get(id) || directData || null;\n                    if (latestData) setActiveData(latestData);\n                }, delay);\n            }\n        },\n        [activeId, delay],\n    );\n\n    const closeTooltip = React.useCallback(\n        (id: string) => {\n            if (openTimeoutRef.current) {\n                clearTimeout(openTimeoutRef.current);\n                openTimeoutRef.current = null;\n            }\n\n            if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);\n            closeTimeoutRef.current = setTimeout(() => {\n                setActiveId((current) => {\n                    if (current === id) {\n                        setActiveRect(null);\n                        activeRectRef.current = null;\n                        setActiveData(null);\n                        setOffset({ x: 0, y: 0 });\n                        return null;\n                    }\n                    return current;\n                });\n            }, closeDelay);\n        },\n        [closeDelay],\n    );\n\n    const updateTooltipData = React.useCallback((id: string, data: TooltipItemData) => {\n        itemsDataRef.current.set(id, data);\n    }, []);\n\n    const side = activeData?.side ?? \"top\";\n    const sideOffset = typeof activeData?.sideOffset === \"number\" ? activeData.sideOffset : 6;\n    const align = activeData?.align ?? \"center\";\n    const alignOffset = typeof activeData?.alignOffset === \"number\" ? activeData.alignOffset : 0;\n\n    let targetX = 0;\n    let targetY = 0;\n    let translateX = \"-50%\";\n    let translateY = \"-100%\";\n\n    if (activeRect) {\n        if (side === \"top\") {\n            targetX =\n                align === \"start\"\n                    ? activeRect.left + alignOffset\n                    : align === \"end\"\n                      ? activeRect.right + alignOffset\n                      : activeRect.left + activeRect.width / 2 + alignOffset;\n            targetY = activeRect.top - sideOffset;\n            translateX = align === \"start\" ? \"0%\" : align === \"end\" ? \"-100%\" : \"-50%\";\n            translateY = \"-100%\";\n        } else if (side === \"bottom\") {\n            targetX =\n                align === \"start\"\n                    ? activeRect.left + alignOffset\n                    : align === \"end\"\n                      ? activeRect.right + alignOffset\n                      : activeRect.left + activeRect.width / 2 + alignOffset;\n            targetY = activeRect.bottom + sideOffset;\n            translateX = align === \"start\" ? \"0%\" : align === \"end\" ? \"-100%\" : \"-50%\";\n            translateY = \"0%\";\n        } else if (side === \"left\") {\n            targetX = activeRect.left - sideOffset;\n            targetY =\n                align === \"start\"\n                    ? activeRect.top + alignOffset\n                    : align === \"end\"\n                      ? activeRect.bottom + alignOffset\n                      : activeRect.top + activeRect.height / 2 + alignOffset;\n            translateX = \"-100%\";\n            translateY = align === \"start\" ? \"0%\" : align === \"end\" ? \"-100%\" : \"-50%\";\n        } else if (side === \"right\") {\n            targetX = activeRect.right + sideOffset;\n            targetY =\n                align === \"start\"\n                    ? activeRect.top + alignOffset\n                    : align === \"end\"\n                      ? activeRect.bottom + alignOffset\n                      : activeRect.top + activeRect.height / 2 + alignOffset;\n            translateX = \"0%\";\n            translateY = align === \"start\" ? \"0%\" : align === \"end\" ? \"-100%\" : \"-50%\";\n        }\n    }\n\n    return (\n        <TooltipProviderContext.Provider\n            value={{\n                activeId,\n                openTooltip,\n                closeTooltip,\n                updateTooltipData,\n            }}>\n            <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" delay={delay} {...props}>\n                {children}\n            </TooltipPrimitive.Provider>\n            {isMounted &&\n                createPortal(\n                    <AnimatePresence>\n                        {activeId && activeRect && activeData && activeData.content && (\n                            <motion.div\n                                key=\"shared-tooltip-wrapper\"\n                                initial={{\n                                    opacity: 0,\n                                    scale: 0.94,\n                                    filter: \"blur(4px)\",\n                                    x: targetX,\n                                    y: targetY,\n                                }}\n                                animate={{\n                                    opacity: 1,\n                                    scale: 1,\n                                    filter: \"blur(0px)\",\n                                    x: targetX,\n                                    y: targetY,\n                                }}\n                                exit={{\n                                    opacity: 0,\n                                    scale: 0.94,\n                                    filter: \"blur(4px)\",\n                                }}\n                                transition={transition}\n                                style={{\n                                    position: \"fixed\",\n                                    left: 0,\n                                    top: 0,\n                                    pointerEvents: \"none\",\n                                    zIndex: 99999,\n                                }}>\n                                <div\n                                    style={{\n                                        transform: `translate(${translateX}, ${translateY})`,\n                                    }}>\n                                    <motion.div\n                                        layout\n                                        transition={transition}\n                                        className={cn(\n                                            \"bg-foreground text-background relative w-fit max-w-xs rounded-md px-3 py-1.5 text-xs shadow-md select-none\",\n                                            activeData.className,\n                                        )}>\n                                        <div className=\"relative flex items-center justify-center overflow-hidden\">\n                                            <AnimatePresence mode=\"popLayout\" custom={offset} initial={false}>\n                                                <motion.div\n                                                    key={activeId}\n                                                    custom={offset}\n                                                    variants={contentVariants}\n                                                    initial=\"initial\"\n                                                    animate=\"animate\"\n                                                    exit=\"exit\"\n                                                    transition={transition}\n                                                    className=\"flex items-center gap-1.5 whitespace-nowrap\">\n                                                    {activeData.content}\n                                                </motion.div>\n                                            </AnimatePresence>\n                                        </div>\n                                        {activeData.showArrow !== false && (\n                                            <div\n                                                className={cn(\n                                                    \"bg-foreground pointer-events-none absolute size-2 rotate-45 rounded-[1px]\",\n                                                    side === \"top\" && \"-bottom-1 left-1/2 -translate-x-1/2\",\n                                                    side === \"bottom\" && \"-top-1 left-1/2 -translate-x-1/2\",\n                                                    side === \"left\" && \"top-1/2 -right-1 -translate-y-1/2\",\n                                                    side === \"right\" && \"top-1/2 -left-1 -translate-y-1/2\",\n                                                )}\n                                            />\n                                        )}\n                                    </motion.div>\n                                </div>\n                            </motion.div>\n                        )}\n                    </AnimatePresence>,\n                    document.body,\n                )}\n        </TooltipProviderContext.Provider>\n    );\n}\n\nexport interface TooltipProps extends TooltipPrimitive.Root.Props {\n    id?: string;\n}\n\nfunction Tooltip({ id: propId, children, ...props }: TooltipProps) {\n    const parentProvider = React.useContext(TooltipProviderContext);\n    const generatedId = React.useId();\n    const id = propId ?? generatedId;\n    const triggerRef = React.useRef<HTMLElement | null>(null);\n    const dataRef = React.useRef<TooltipItemData>({ content: null });\n\n    if (!parentProvider) {\n        return (\n            <TooltipProvider>\n                <TooltipItemContext.Provider value={{ id, triggerRef, dataRef }}>\n                    <TooltipPrimitive.Root data-slot=\"tooltip\" {...props}>\n                        {children}\n                    </TooltipPrimitive.Root>\n                </TooltipItemContext.Provider>\n            </TooltipProvider>\n        );\n    }\n\n    return (\n        <TooltipItemContext.Provider value={{ id, triggerRef, dataRef }}>\n            <TooltipPrimitive.Root data-slot=\"tooltip\" {...props}>\n                {children}\n            </TooltipPrimitive.Root>\n        </TooltipItemContext.Provider>\n    );\n}\n\nexport interface TooltipTriggerProps extends TooltipPrimitive.Trigger.Props {}\n\nfunction TooltipTrigger({\n    className,\n    onMouseEnter,\n    onMouseLeave,\n    onPointerEnter,\n    onPointerLeave,\n    onFocus,\n    onBlur,\n    ...props\n}: TooltipTriggerProps) {\n    const itemContext = React.useContext(TooltipItemContext);\n    const providerContext = React.useContext(TooltipProviderContext);\n    const localRef = React.useRef<HTMLElement | null>(null);\n\n    const handleOpen = (e: any) => {\n        if (itemContext && providerContext) {\n            const el = (e.currentTarget || itemContext.triggerRef.current || localRef.current) as HTMLElement;\n            if (el) {\n                providerContext.openTooltip(itemContext.id, el, itemContext.dataRef.current);\n            }\n        }\n    };\n\n    const handleClose = () => {\n        if (itemContext && providerContext) {\n            providerContext.closeTooltip(itemContext.id);\n        }\n    };\n\n    return (\n        <TooltipPrimitive.Trigger\n            data-slot=\"tooltip-trigger\"\n            ref={(node: any) => {\n                localRef.current = node;\n                if (itemContext) {\n                    itemContext.triggerRef.current = node;\n                }\n            }}\n            onMouseEnter={(e: any) => {\n                onMouseEnter?.(e);\n                handleOpen(e);\n            }}\n            onMouseLeave={(e: any) => {\n                onMouseLeave?.(e);\n                handleClose();\n            }}\n            onPointerEnter={(e: any) => {\n                onPointerEnter?.(e);\n                handleOpen(e);\n            }}\n            onPointerLeave={(e: any) => {\n                onPointerLeave?.(e);\n                handleClose();\n            }}\n            onFocus={(e: any) => {\n                onFocus?.(e);\n                handleOpen(e);\n            }}\n            onBlur={(e: any) => {\n                onBlur?.(e);\n                handleClose();\n            }}\n            className={className}\n            {...props}\n        />\n    );\n}\n\nexport interface TooltipContentProps\n    extends\n        TooltipPrimitive.Popup.Props,\n        Pick<TooltipPrimitive.Positioner.Props, \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"> {\n    transition?: Transition;\n    showArrow?: boolean;\n}\n\nfunction TooltipContent({\n    className,\n    side = \"top\",\n    sideOffset = 6,\n    align = \"center\",\n    alignOffset = 0,\n    showArrow = true,\n    children,\n    ...props\n}: TooltipContentProps) {\n    const itemContext = React.useContext(TooltipItemContext);\n    const providerContext = React.useContext(TooltipProviderContext);\n\n    const data: TooltipItemData = {\n        content: children,\n        side,\n        sideOffset,\n        align,\n        alignOffset,\n        className,\n        showArrow,\n    };\n\n    if (itemContext) {\n        itemContext.dataRef.current = data;\n    }\n\n    React.useEffect(() => {\n        if (itemContext && providerContext) {\n            providerContext.updateTooltipData(itemContext.id, data);\n        }\n    }, [itemContext, providerContext, children, side, sideOffset, align, alignOffset, className, showArrow]);\n\n    if (providerContext) {\n        return null;\n    }\n\n    return (\n        <TooltipPrimitive.Portal>\n            <TooltipPrimitive.Positioner\n                align={align}\n                alignOffset={alignOffset}\n                side={side}\n                sideOffset={sideOffset}\n                className=\"isolate z-50\">\n                <TooltipPrimitive.Popup\n                    data-slot=\"tooltip-content\"\n                    className={cn(\n                        \"data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 bg-foreground text-background z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md px-3 py-1.5 text-xs shadow-md\",\n                        className,\n                    )}\n                    {...props}>\n                    {children}\n                    {showArrow && (\n                        <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] data-[side=bottom]:top-1 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n                    )}\n                </TooltipPrimitive.Popup>\n            </TooltipPrimitive.Positioner>\n        </TooltipPrimitive.Portal>\n    );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n"
    }
  ],
  "mcp": {
    "description": "Provides refined UI interactions and accessible controls. Compact selector for toggling abilities with icons and custom styles Configurable props include: ComponentProps<typeof Button> & {; buttonVariant?: \"ghost\" | \"outline\" | \"default\";; maxVisible?: number;. Relies on motion, button, dropdown-menu, tooltip. Optimal for building reusable interface elements and user input flows.",
    "tags": [
      "component",
      "motion",
      "animation"
    ]
  }
}