{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-morphing-button-carbon", "type": "registry:component", "title": "Native Morphing Button", "description": "Floating action button that morphs into a menu of actions.", "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-carbon/src/components/native/native-morphing-button-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n AnimatePresence,\n LayoutGroup,\n motion,\n Transition,\n useReducedMotion,\n} from \"framer-motion\";\nimport { Plus, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface MorphingButtonAction {\n /**\n * Display label for the action.\n */\n label: string;\n /**\n * Icon to display alongside the label.\n */\n icon: React.ReactNode;\n /**\n * Callback when action is clicked.\n */\n onClick: () => void;\n}\n\nexport interface NativeMorphingButtonProps {\n /**\n * Array of actions to display in the expanded menu.\n */\n actions: MorphingButtonAction[];\n /**\n * Position of the FAB.\n * Default: 'bottom-right'\n */\n position?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n /**\n * Whether to use fixed positioning.\n * Default: false (relative to container)\n */\n fixed?: boolean;\n /**\n * Custom icon when collapsed.\n */\n icon?: React.ReactNode;\n /**\n * Custom close icon when expanded.\n */\n closeIcon?: React.ReactNode;\n className?: string;\n}\n\nconst positionClasses = {\n \"bottom-right\": \"bottom-4 right-4\",\n \"bottom-left\": \"bottom-4 left-4\",\n \"top-right\": \"top-4 right-4\",\n \"top-left\": \"top-4 left-4\",\n};\n\nconst springTransition: Transition = {\n type: \"spring\",\n stiffness: 300,\n damping: 30,\n};\nconst reducedTransition: Transition = { duration: 0.1 };\n\nexport function NativeMorphingButton({\n actions,\n position = \"bottom-right\",\n fixed = false,\n icon,\n closeIcon,\n className,\n}: NativeMorphingButtonProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const shouldReduceMotion = useReducedMotion();\n\n const transition = shouldReduceMotion ? reducedTransition : springTransition;\n\n return (\n