{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-profile-notch-shadcnui", "type": "registry:component", "title": "Native Profile Notch", "description": "A dynamic expanding notch component for displaying user profiles with smooth spring animations.", "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-shadcn/src/components/native/native-profile-notch-shadcnui.tsx", "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion, MotionConfig } from \"framer-motion\";\nimport { ChevronRight, X } from \"lucide-react\";\nimport { useEffect, useId, useRef, useState } from \"react\";\n\nexport interface NativeProfileNotchProps {\n /**\n * Url of the user image\n */\n imageSrc: string;\n /**\n * Name of the user\n */\n name: string;\n /**\n * Handle or role of the user\n */\n username: string;\n /**\n * Custom content to show in expanded state\n */\n children?: React.ReactNode;\n /**\n * Size of the notch\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Class name for the container\n */\n className?: string;\n /**\n * Variant of the notch.\n * \"default\": expands and pushes content.\n * \"overlay\": expands over content (absolute positioning).\n * @default \"default\"\n */\n variant?: \"default\" | \"overlay\";\n}\n\nexport function NativeProfileNotch({\n imageSrc,\n name,\n username,\n children,\n size = \"md\",\n className,\n variant = \"default\",\n}: NativeProfileNotchProps) {\n const [isOpen, setIsOpen] = useState(false);\n const uid = useId();\n const notchRef = useRef(null);\n const closeButtonRef = useRef(null);\n const wasOpen = useRef(false);\n\n // Move focus into the panel on open, back to the notch on close.\n useEffect(() => {\n if (isOpen) {\n wasOpen.current = true;\n closeButtonRef.current?.focus();\n } else if (wasOpen.current) {\n notchRef.current?.focus();\n }\n }, [isOpen]);\n\n return (\n \n \n !isOpen && setIsOpen(true)}\n onKeyDown={(e) => {\n if (!isOpen && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n setIsOpen(true);\n }\n if (isOpen && e.key === \"Escape\") {\n setIsOpen(false);\n }\n }}\n >\n \n {!isOpen ? (\n \n
\n \n \n \n {name.slice(0, 2).toUpperCase()}\n \n \n
\n \n {name}\n \n \n @{username}\n \n
\n \n
\n \n ) : (\n \n {/* Close Button */}\n {\n e.stopPropagation();\n setIsOpen(false);\n }}\n className=\"absolute top-4 right-4 p-1 rounded-full bg-muted/50 hover:bg-muted transition-colors z-10 outline-none focus-visible:ring-2 focus-visible:ring-ring after:absolute after:-inset-2\"\n aria-label=\"Close profile\"\n >\n \n \n\n {/* Scrollable Content */}\n
\n {/* Profile Header */}\n
\n \n \n \n\n \n {name}\n \n\n \n @{username}\n \n
\n\n {/* Custom Content */}\n \n {children}\n \n\n {/* Bottom Action */}\n \n {\n e.stopPropagation();\n }}\n >\n View Full Profile\n \n \n
\n \n )}\n
\n \n
\n \n );\n}\n", "type": "registry:component", "target": "components/uitripled/native-profile-notch-shadcnui.tsx" } ] }