{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "snackbar", "type": "registry:ui", "title": "Snackbar", "description": "Transient bottom bar with optional action.", "registryDependencies": [ "https://raw.githubusercontent.com/truongnat/rnui/main/registry/dist/nativewind/utils.json", "https://raw.githubusercontent.com/truongnat/rnui/main/registry/dist/nativewind/text.json", "https://raw.githubusercontent.com/truongnat/rnui/main/registry/dist/nativewind/theme.json" ], "files": [ { "path": "registry/shared/ui/snackbar.tsx", "type": "registry:ui", "target": "components/ui/snackbar.tsx", "content": "import { useEffect } from 'react';\nimport { Pressable, View, type ViewProps } from 'react-native';\nimport { Text } from '@/components/ui/text';\nimport { cn } from '@/lib/utils';\n\nexport interface SnackbarProps extends ViewProps {\n open: boolean;\n onDismiss?: () => void;\n /** Auto-dismiss after ms — 0 disables. */\n duration?: number;\n /** Trailing action — e.g. . */\n action?: React.ReactNode;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport function Snackbar({\n open,\n onDismiss,\n duration = 4000,\n action,\n className,\n children,\n ...props\n}: SnackbarProps) {\n useEffect(() => {\n if (!open || duration <= 0) return;\n const t = setTimeout(() => onDismiss?.(), duration);\n return () => clearTimeout(t);\n }, [open, duration, onDismiss]);\n\n if (!open) return null;\n\n return (\n \n \n {typeof children === 'string' ? (\n {children}\n ) : (\n children\n )}\n \n {action}\n \n );\n}\n\nexport function SnackbarAction({\n label,\n onPress,\n className,\n}: {\n label: string;\n onPress?: () => void;\n className?: string;\n}) {\n return (\n \n \n {label}\n \n \n );\n}\n" } ] }