{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-notification-bell-carbon", "type": "registry:component", "title": "Native Notification Bell", "description": "Animated notification bell with badge and ringing effect.", "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-carbon/src/components/native/native-notification-bell-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion, type Variants } from \"framer-motion\";\nimport { Bell } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\nexport interface NativeNotificationBellProps {\n /**\n * Number of notifications to display.\n * Default: 0\n */\n count?: number;\n /**\n * Whether to show the notification badge.\n * Automatically true if count > 0.\n */\n showBadge?: boolean;\n /**\n * Callback when the bell is clicked.\n */\n onClick?: () => void;\n /**\n * Callback when the bell rings (on mount if has notifications).\n */\n onRing?: () => void;\n /**\n * Custom icon to replace the bell.\n */\n icon?: React.ReactNode;\n /**\n * Size variant.\n * Default: 'md'\n */\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nconst sizeClasses = {\n sm: \"h-8 w-8\",\n md: \"h-10 w-10\",\n lg: \"h-12 w-12\",\n};\n\nconst iconSizeClasses = {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-6 w-6\",\n};\n\nconst badgeSizeClasses = {\n sm: \"h-4 w-4 text-[10px]\",\n md: \"h-5 w-5 text-xs\",\n lg: \"h-6 w-6 text-sm\",\n};\n\nconst ringVariants: Variants = {\n idle: { rotate: 0 },\n ringing: {\n rotate: [0, -15, 15, -10, 10, -5, 5, 0],\n transition: {\n duration: 0.6,\n ease: \"easeInOut\",\n },\n },\n};\n\nexport function NativeNotificationBell({\n count = 0,\n showBadge,\n onClick,\n onRing,\n icon,\n size = \"md\",\n className,\n}: NativeNotificationBellProps) {\n const shouldReduceMotion = useReducedMotion();\n const [isRinging, setIsRinging] = useState(false);\n const hasNotifications = count > 0 || showBadge;\n\n useEffect(() => {\n if (hasNotifications && !shouldReduceMotion) {\n setIsRinging(true);\n const timer = setTimeout(() => setIsRinging(false), 600);\n onRing?.();\n return () => clearTimeout(timer);\n }\n }, [hasNotifications, shouldReduceMotion, onRing]);\n\n const displayCount = count > 99 ? \"99+\" : count > 9 ? \"9+\" : count;\n\n return (\n
\n 0 ? `, ${count} unread` : \"\"}`}\n >\n {icon ?? }\n {hasNotifications && (\n \n {count > 0 ? displayCount : \"\"}\n \n )}\n \n
\n );\n}\n", "type": "registry:component", "target": "components/uitripled/native-notification-bell-carbon.tsx" } ] }