@mehul214/react-native-flash-toast 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/FlashMessageManager.ts","../src/icons.tsx","../src/styles.ts","../src/utils/safeArea.ts","../src/FlashMessage.tsx","../src/FlashMessageProvider.tsx","../src/index.ts"],"names":["styles","StyleSheet","Platform","jsx","View","Text","jsxs"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { FlashMessageOptions, FlashMessageRef } from './types';\n\nclass FlashMessageManager {\n private defaultInstance: FlashMessageRef | null = null;\n private instances: Map<string, FlashMessageRef> = new Map();\n private pendingQueue: FlashMessageOptions[] = [];\n\n public register(ref: FlashMessageRef, id: string = 'default'): void {\n this.instances.set(id, ref);\n if (!this.defaultInstance || id === 'default') {\n this.defaultInstance = ref;\n }\n\n // Flush any pending messages that arrived before mount\n if (this.pendingQueue.length > 0) {\n const next = this.pendingQueue.shift();\n if (next) {\n ref.showMessage(next);\n }\n }\n }\n\n public unregister(id: string = 'default'): void {\n this.instances.delete(id);\n if (this.defaultInstance === this.instances.get(id)) {\n this.defaultInstance = this.instances.values().next().value || null;\n }\n }\n\n public showMessage(options: FlashMessageOptions, targetId?: string): void {\n const target = targetId ? this.instances.get(targetId) : this.defaultInstance;\n\n if (target) {\n target.showMessage(options);\n } else {\n // Buffer if component hasn't mounted yet\n this.pendingQueue.push(options);\n }\n }\n\n public hideMessage(targetId?: string): void {\n const target = targetId ? this.instances.get(targetId) : this.defaultInstance;\n if (target) {\n target.hideMessage();\n }\n }\n}\n\nexport const flashManager = new FlashMessageManager();\n\n/**\n * Imperative helper to trigger a flash message from anywhere in the app\n * (services, Zustand, Redux, API handlers, navigation screens).\n */\nexport function showMessage(options: FlashMessageOptions): void {\n flashManager.showMessage(options);\n}\n\n/**\n * Imperative helper to dismiss the currently displayed flash message.\n */\nexport function hideMessage(): void {\n flashManager.hideMessage();\n}\n\n/**\n * Modern alias for showMessage\n */\nexport const flash = showMessage;\nexport const dismissFlash = hideMessage;\n\n","import React from 'react';\nimport { View, Text, StyleSheet } from 'react-native';\nimport type { FlashMessageType } from './types';\n\ninterface BuiltInIconProps {\n type: FlashMessageType;\n size?: number;\n color?: string;\n}\n\nexport const BuiltInIcon: React.FC<BuiltInIconProps> = ({\n type,\n size = 22,\n color = '#FFFFFF',\n}) => {\n const containerStyle = [\n styles.circle,\n {\n width: size,\n height: size,\n borderRadius: size / 2,\n borderColor: color,\n },\n ];\n\n switch (type) {\n case 'success':\n return (\n <View style={containerStyle}>\n <Text style={[styles.symbol, { color, fontSize: size * 0.65 }]}>✓</Text>\n </View>\n );\n case 'danger':\n return (\n <View style={containerStyle}>\n <Text style={[styles.symbol, { color, fontSize: size * 0.65 }]}>✕</Text>\n </View>\n );\n case 'warning':\n return (\n <View style={containerStyle}>\n <Text style={[styles.symbol, { color, fontSize: size * 0.65 }]}>!</Text>\n </View>\n );\n case 'info':\n return (\n <View style={containerStyle}>\n <Text style={[styles.symbol, { color, fontSize: size * 0.65 }]}>ℹ</Text>\n </View>\n );\n case 'default':\n default:\n return (\n <View style={containerStyle}>\n <Text style={[styles.symbol, { color, fontSize: size * 0.6 }]}>●</Text>\n </View>\n );\n }\n};\n\nconst styles = StyleSheet.create({\n circle: {\n borderWidth: 1.5,\n justifyContent: 'center',\n alignItems: 'center',\n },\n symbol: {\n fontWeight: '800',\n textAlign: 'center',\n includeFontPadding: false,\n lineHeight: 22,\n },\n});\n\n","import { StyleSheet, Platform } from 'react-native';\nimport type { FlashMessageType } from './types';\n\nexport const COLORS: Record<FlashMessageType, { background: string; text: string; icon: string }> = {\n default: {\n background: '#1F2937', // Slate 800\n text: '#FFFFFF',\n icon: '#9CA3AF',\n },\n success: {\n background: '#059669', // Emerald 600\n text: '#FFFFFF',\n icon: '#D1FAE5',\n },\n danger: {\n background: '#DC2626', // Red 600\n text: '#FFFFFF',\n icon: '#FEE2E2',\n },\n warning: {\n background: '#D97706', // Amber 600\n text: '#FFFFFF',\n icon: '#FEF3C7',\n },\n info: {\n background: '#2563EB', // Blue 600\n text: '#FFFFFF',\n icon: '#DBEAFE',\n },\n};\n\nexport const styles = StyleSheet.create({\n rootOverlay: {\n position: 'absolute',\n left: 0,\n right: 0,\n zIndex: 99999,\n elevation: 99999,\n },\n rootTop: {\n top: 0,\n },\n rootBottom: {\n bottom: 0,\n },\n rootCenter: {\n top: 0,\n bottom: 0,\n justifyContent: 'center',\n alignItems: 'center',\n },\n toastContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n overflow: 'hidden',\n ...Platform.select({\n ios: {\n shadowColor: '#000000',\n shadowOffset: { width: 0, height: 6 },\n shadowOpacity: 0.18,\n shadowRadius: 12,\n },\n android: {\n elevation: 8,\n },\n web: {\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.2), 0 8px 10px -6px rgba(0, 0, 0, 0.1)',\n } as any,\n }),\n },\n floatingContainer: {\n marginHorizontal: 16,\n borderRadius: 14,\n borderWidth: StyleSheet.hairlineWidth,\n borderColor: 'rgba(255, 255, 255, 0.15)',\n },\n edgeToEdgeContainer: {\n marginHorizontal: 0,\n borderRadius: 0,\n },\n contentWrapper: {\n flex: 1,\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 14,\n paddingHorizontal: 16,\n },\n iconContainer: {\n marginRight: 12,\n justifyContent: 'center',\n alignItems: 'center',\n },\n textContainer: {\n flex: 1,\n justifyContent: 'center',\n },\n titleText: {\n fontSize: 15,\n fontWeight: '600',\n letterSpacing: -0.2,\n color: '#FFFFFF',\n },\n descriptionText: {\n fontSize: 13,\n fontWeight: '400',\n color: 'rgba(255, 255, 255, 0.88)',\n marginTop: 2,\n lineHeight: 18,\n },\n actionButton: {\n marginLeft: 10,\n paddingHorizontal: 12,\n paddingVertical: 6,\n borderRadius: 8,\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n },\n actionButtonText: {\n fontSize: 13,\n fontWeight: '700',\n color: '#FFFFFF',\n },\n progressBarContainer: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: 3,\n backgroundColor: 'rgba(255, 255, 255, 0.25)',\n },\n progressBarFill: {\n height: '100%',\n backgroundColor: '#FFFFFF',\n },\n});\n\n","import { Platform, StatusBar, Dimensions } from 'react-native';\n\nexport interface EdgeInsets {\n top: number;\n bottom: number;\n left: number;\n right: number;\n}\n\n/**\n * Returns safe default insets when react-native-safe-area-context is not present.\n * If the user's app wraps FlashMessage in SafeAreaProvider, safe-area context takes precedence.\n */\nexport function getDefaultSafeAreaInsets(): EdgeInsets {\n const { width, height } = Dimensions.get('window');\n const isLandscape = width > height;\n\n if (Platform.OS === 'android') {\n return {\n top: StatusBar.currentHeight ?? 24,\n bottom: 16,\n left: 0,\n right: 0,\n };\n }\n\n if (Platform.OS === 'ios') {\n // Dynamic island & modern notch iPhones typically have 47-59pt top inset\n const isModernIphone = !Platform.isPad && !Platform.isTV && (height >= 812 || width >= 812);\n return {\n top: isModernIphone ? (isLandscape ? 0 : 50) : 20,\n bottom: isModernIphone ? 34 : 0,\n left: 0,\n right: 0,\n };\n }\n\n return {\n top: 16,\n bottom: 16,\n left: 0,\n right: 0,\n };\n}\n\n","import React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport {\n Animated,\n PanResponder,\n Pressable,\n Text,\n View,\n} from 'react-native';\nimport { flashManager } from './FlashMessageManager';\nimport { BuiltInIcon } from './icons';\nimport { COLORS, styles } from './styles';\nimport type {\n FlashMessageContainerProps,\n FlashMessageOptions,\n FlashMessageRef,\n} from './types';\nimport { getDefaultSafeAreaInsets } from './utils/safeArea';\n\nexport const FlashMessage = React.forwardRef<FlashMessageRef, FlashMessageContainerProps>(\n (props, ref) => {\n const {\n position: defaultPosition = 'top',\n duration: defaultDuration = 3000,\n floating: defaultFloating = true,\n statusBarOffset,\n bottomOffset,\n style: containerCustomStyle,\n } = props;\n\n const [currentMessage, setCurrentMessage] = useState<FlashMessageOptions | null>(null);\n const [isVisible, setIsVisible] = useState(false);\n\n // Animation values\n const translateY = useRef(new Animated.Value(-150)).current;\n const opacity = useRef(new Animated.Value(0)).current;\n const progress = useRef(new Animated.Value(1)).current;\n\n // Timers & gesture tracking\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const progressAnimationRef = useRef<Animated.CompositeAnimation | null>(null);\n const remainingTimeRef = useRef<number>(0);\n const timerStartedAtRef = useRef<number>(0);\n\n const safeInsets = getDefaultSafeAreaInsets();\n\n const position = currentMessage?.position ?? defaultPosition;\n const isTop = position === 'top';\n const isBottom = position === 'bottom';\n\n const clearTimers = useCallback(() => {\n if (hideTimeoutRef.current) {\n clearTimeout(hideTimeoutRef.current);\n hideTimeoutRef.current = null;\n }\n if (progressAnimationRef.current) {\n progressAnimationRef.current.stop();\n progressAnimationRef.current = null;\n }\n }, []);\n\n const animateHide = useCallback(\n (callback?: () => void) => {\n clearTimers();\n\n const targetY = isTop ? -180 : isBottom ? 180 : 0;\n\n Animated.parallel([\n Animated.timing(translateY, {\n toValue: targetY,\n duration: 220,\n useNativeDriver: true,\n }),\n Animated.timing(opacity, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start(() => {\n setIsVisible(false);\n if (currentMessage?.onHide) {\n currentMessage.onHide();\n }\n setCurrentMessage(null);\n callback?.();\n });\n },\n [clearTimers, isTop, isBottom, opacity, translateY, currentMessage]\n );\n\n const startAutoHideTimer = useCallback(\n (durationMs: number) => {\n clearTimers();\n if (durationMs <= 0) return;\n\n remainingTimeRef.current = durationMs;\n timerStartedAtRef.current = Date.now();\n\n // Start progress bar animation\n progress.setValue(1);\n progressAnimationRef.current = Animated.timing(progress, {\n toValue: 0,\n duration: durationMs,\n useNativeDriver: false, // width needs layout or scaleX\n });\n progressAnimationRef.current.start();\n\n hideTimeoutRef.current = setTimeout(() => {\n animateHide();\n }, durationMs);\n },\n [animateHide, clearTimers, progress]\n );\n\n const pauseTimer = useCallback(() => {\n if (hideTimeoutRef.current && timerStartedAtRef.current > 0) {\n clearTimeout(hideTimeoutRef.current);\n hideTimeoutRef.current = null;\n const elapsed = Date.now() - timerStartedAtRef.current;\n remainingTimeRef.current = Math.max(0, remainingTimeRef.current - elapsed);\n if (progressAnimationRef.current) {\n progressAnimationRef.current.stop();\n }\n }\n }, []);\n\n const resumeTimer = useCallback(() => {\n if (remainingTimeRef.current > 0) {\n startAutoHideTimer(remainingTimeRef.current);\n }\n }, [startAutoHideTimer]);\n\n const show = useCallback(\n (options: FlashMessageOptions) => {\n clearTimers();\n setCurrentMessage(options);\n setIsVisible(true);\n\n const pos = options.position ?? defaultPosition;\n const initialY = pos === 'top' ? -150 : pos === 'bottom' ? 150 : 0;\n\n translateY.setValue(initialY);\n opacity.setValue(0);\n progress.setValue(1);\n\n Animated.parallel([\n Animated.spring(translateY, {\n toValue: 0,\n tension: 70,\n friction: 9,\n useNativeDriver: true,\n }),\n Animated.timing(opacity, {\n toValue: 1,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start(() => {\n if (options.onShow) {\n options.onShow();\n }\n });\n\n const shouldAutoHide = options.autoHide ?? true;\n const dur = shouldAutoHide ? options.duration ?? defaultDuration : 0;\n if (dur > 0) {\n startAutoHideTimer(dur);\n }\n },\n [clearTimers, defaultDuration, defaultPosition, opacity, progress, startAutoHideTimer, translateY]\n );\n\n // Register with manager and imperative ref\n useImperativeHandle(\n ref,\n () => ({\n showMessage: show,\n hideMessage: () => animateHide(),\n }),\n [show, animateHide]\n );\n\n useEffect(() => {\n const instanceRef: FlashMessageRef = {\n showMessage: show,\n hideMessage: () => animateHide(),\n };\n flashManager.register(instanceRef);\n return () => {\n flashManager.unregister();\n clearTimers();\n };\n }, [show, animateHide, clearTimers]);\n\n // PanResponder for smooth swipe-to-dismiss gesture\n const panResponder = useRef(\n PanResponder.create({\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: (_, gestureState) => {\n return Math.abs(gestureState.dy) > 5;\n },\n onPanResponderGrant: () => {\n if (currentMessage?.pauseOnPress ?? true) {\n pauseTimer();\n }\n },\n onPanResponderMove: (_, gestureState) => {\n if (!(currentMessage?.swipeToDismiss ?? true)) return;\n\n // Only allow dragging upwards for top, downwards for bottom\n if (isTop && gestureState.dy < 0) {\n translateY.setValue(gestureState.dy);\n } else if (isBottom && gestureState.dy > 0) {\n translateY.setValue(gestureState.dy);\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n const swipeThreshold = 30;\n const isDismissGesture =\n (isTop && gestureState.dy < -swipeThreshold) ||\n (isBottom && gestureState.dy > swipeThreshold);\n\n if (isDismissGesture && (currentMessage?.swipeToDismiss ?? true)) {\n animateHide();\n } else {\n // Spring back to center\n Animated.spring(translateY, {\n toValue: 0,\n tension: 80,\n friction: 8,\n useNativeDriver: true,\n }).start();\n\n if (currentMessage?.pauseOnPress ?? true) {\n resumeTimer();\n }\n }\n },\n })\n ).current;\n\n if (!isVisible || !currentMessage) {\n return null;\n }\n\n const type = currentMessage.type ?? 'default';\n const typeColors = COLORS[type];\n const backgroundColor = currentMessage.backgroundColor ?? typeColors.background;\n const textColor = currentMessage.color ?? typeColors.text;\n const floating = currentMessage.floating ?? defaultFloating;\n\n const topInset =\n currentMessage.statusBarHeight ??\n statusBarOffset ??\n (isTop ? safeInsets.top + (floating ? 8 : 0) : 0);\n\n const bottomInset =\n bottomOffset ?? (isBottom ? safeInsets.bottom + (floating ? 8 : 0) : 0);\n\n const rootPositionStyle = isTop\n ? [styles.rootTop, { paddingTop: topInset }]\n : isBottom\n ? [styles.rootBottom, { paddingBottom: bottomInset }]\n : styles.rootCenter;\n\n const renderIcon = () => {\n if (currentMessage.icon === 'none') return null;\n\n if (typeof currentMessage.icon === 'function') {\n return (\n <View style={styles.iconContainer}>\n {currentMessage.icon({ size: 22, color: textColor })}\n </View>\n );\n }\n\n if (React.isValidElement(currentMessage.icon)) {\n return <View style={styles.iconContainer}>{currentMessage.icon}</View>;\n }\n\n const iconType = typeof currentMessage.icon === 'string' ? currentMessage.icon : type;\n return (\n <View style={styles.iconContainer}>\n <BuiltInIcon type={iconType as any} color={textColor} size={22} />\n </View>\n );\n };\n\n const handlePress = () => {\n if (currentMessage.onPress) {\n currentMessage.onPress();\n }\n if (currentMessage.hideOnPress ?? true) {\n animateHide();\n }\n };\n\n const progressWidthInterpolation = progress.interpolate({\n inputRange: [0, 1],\n outputRange: ['0%', '100%'],\n });\n\n return (\n <View\n pointerEvents=\"box-none\"\n style={[styles.rootOverlay, rootPositionStyle, containerCustomStyle]}\n >\n <Animated.View\n {...panResponder.panHandlers}\n style={[\n styles.toastContainer,\n floating ? styles.floatingContainer : styles.edgeToEdgeContainer,\n { backgroundColor },\n currentMessage.style,\n {\n transform: [{ translateY }],\n opacity,\n },\n ]}\n >\n {currentMessage.customComponent ? (\n currentMessage.customComponent(currentMessage, () => animateHide())\n ) : (\n <Pressable\n onPress={handlePress}\n onLongPress={currentMessage.onLongPress}\n style={styles.contentWrapper}\n >\n {renderIcon()}\n\n <View style={styles.textContainer}>\n {typeof currentMessage.message === 'string' ? (\n <Text\n style={[styles.titleText, { color: textColor }, currentMessage.titleStyle]}\n numberOfLines={2}\n >\n {currentMessage.message}\n </Text>\n ) : (\n currentMessage.message\n )}\n\n {currentMessage.description ? (\n typeof currentMessage.description === 'string' ? (\n <Text\n style={[\n styles.descriptionText,\n { color: textColor },\n currentMessage.textStyle,\n ]}\n numberOfLines={3}\n >\n {currentMessage.description}\n </Text>\n ) : (\n currentMessage.description\n )\n ) : null}\n </View>\n\n {currentMessage.action ? (\n <Pressable\n onPress={() => {\n currentMessage.action?.onPress();\n animateHide();\n }}\n style={[styles.actionButton, currentMessage.action.style]}\n >\n <Text style={[styles.actionButtonText, currentMessage.action.textStyle]}>\n {currentMessage.action.label}\n </Text>\n </Pressable>\n ) : null}\n </Pressable>\n )}\n\n {currentMessage.showProgressBar && (\n <View style={styles.progressBarContainer}>\n <Animated.View\n style={[\n styles.progressBarFill,\n { width: progressWidthInterpolation },\n ]}\n />\n </View>\n )}\n </Animated.View>\n </View>\n );\n }\n);\n\nFlashMessage.displayName = 'FlashMessage';\n","import React, { createContext, useContext, useMemo } from 'react';\nimport { FlashMessage } from './FlashMessage';\nimport { flashManager } from './FlashMessageManager';\nimport type { FlashMessageContainerProps, FlashMessageOptions } from './types';\n\ninterface FlashMessageContextValue {\n show: (options: FlashMessageOptions) => void;\n hide: () => void;\n}\n\nconst FlashMessageContext = createContext<FlashMessageContextValue | null>(null);\n\nexport interface FlashMessageProviderProps extends FlashMessageContainerProps {\n children: React.ReactNode;\n}\n\nexport const FlashMessageProvider: React.FC<FlashMessageProviderProps> = ({\n children,\n ...containerProps\n}) => {\n const contextValue = useMemo<FlashMessageContextValue>(\n () => ({\n show: (options: FlashMessageOptions) => flashManager.showMessage(options),\n hide: () => flashManager.hideMessage(),\n }),\n []\n );\n\n return (\n <FlashMessageContext.Provider value={contextValue}>\n {children}\n <FlashMessage {...containerProps} />\n </FlashMessageContext.Provider>\n );\n};\n\nexport function useFlashMessage(): FlashMessageContextValue {\n const context = useContext(FlashMessageContext);\n if (!context) {\n // Graceful fallback to global manager even if Provider is omitted\n return {\n show: (options: FlashMessageOptions) => flashManager.showMessage(options),\n hide: () => flashManager.hideMessage(),\n };\n }\n return context;\n}\n\n","import { FlashMessage } from './FlashMessage';\n\nexport { FlashMessage };\nexport default FlashMessage;\n\nexport {\n flashManager,\n showMessage,\n hideMessage,\n flash,\n dismissFlash,\n} from './FlashMessageManager';\n\nexport {\n FlashMessageProvider,\n useFlashMessage,\n} from './FlashMessageProvider';\n\nexport { BuiltInIcon } from './icons';\nexport { COLORS, styles } from './styles';\n\nexport type {\n FlashMessageAction,\n FlashMessageContainerProps,\n FlashMessageIcon,\n FlashMessageOptions,\n FlashMessagePosition,\n FlashMessageRef,\n FlashMessageTransition,\n FlashMessageType,\n} from './types';\n"]}
package/package.json CHANGED
@@ -1,6 +1,89 @@
1
1
  {
2
2
  "name": "@mehul214/react-native-flash-toast",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Next-generation, highly customizable flash message and toast banner for React Native & Expo. 100% Fabric / New Architecture ready with swipe-to-dismiss gestures.",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "main": "dist/index.js",
9
+ "module": "dist/index.mjs",
10
+ "types": "dist/index.d.ts",
11
+ "react-native": "src/index.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "src",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "dev": "tsup --watch",
28
+ "test": "node test/smoke.test.js",
29
+ "typecheck": "tsc --noEmit",
30
+ "prepublishOnly": "npm run typecheck && npm test && npm run build"
31
+ },
32
+ "keywords": [
33
+ "react-native",
34
+ "react-native-flash-message",
35
+ "flash-message",
36
+ "toast",
37
+ "banner",
38
+ "notification",
39
+ "alert",
40
+ "snackbar",
41
+ "fabric",
42
+ "new-architecture",
43
+ "expo",
44
+ "swipe-to-dismiss",
45
+ "ios",
46
+ "android"
47
+ ],
48
+ "funding": [
49
+ {
50
+ "type": "github",
51
+ "url": "https://github.com/sponsors/Mehul214"
52
+ },
53
+ {
54
+ "type": "buy-me-a-coffee",
55
+ "url": "https://buymeacoffee.com/mehulreshac"
56
+ },
57
+ {
58
+ "type": "individual",
59
+ "url": "https://github.com/Mehul214/react-native-flash-toast#-support-via-upi"
60
+ }
61
+ ],
62
+ "author": "Mehul",
63
+ "license": "MIT",
64
+ "homepage": "https://github.com/Mehul214/react-native-flash-toast#readme",
65
+ "repository": {
66
+ "type": "git",
67
+ "url": "git+https://github.com/Mehul214/react-native-flash-toast.git"
68
+ },
69
+ "bugs": {
70
+ "url": "https://github.com/Mehul214/react-native-flash-toast/issues"
71
+ },
72
+ "peerDependencies": {
73
+ "react": ">=17.0.0",
74
+ "react-native": ">=0.68.0"
75
+ },
76
+ "peerDependenciesMeta": {
77
+ "react-native-safe-area-context": {
78
+ "optional": true
79
+ }
80
+ },
81
+ "devDependencies": {
82
+ "@types/react": "^19.0.0",
83
+ "@types/react-native": "^0.73.0",
84
+ "react": "^19.0.0",
85
+ "react-native": "^0.78.0",
86
+ "tsup": "^8.3.0",
87
+ "typescript": "^5.7.3"
88
+ }
89
+ }
@@ -0,0 +1,398 @@
1
+ import React, {
2
+ useCallback,
3
+ useEffect,
4
+ useImperativeHandle,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
8
+ import {
9
+ Animated,
10
+ PanResponder,
11
+ Pressable,
12
+ Text,
13
+ View,
14
+ } from 'react-native';
15
+ import { flashManager } from './FlashMessageManager';
16
+ import { BuiltInIcon } from './icons';
17
+ import { COLORS, styles } from './styles';
18
+ import type {
19
+ FlashMessageContainerProps,
20
+ FlashMessageOptions,
21
+ FlashMessageRef,
22
+ } from './types';
23
+ import { getDefaultSafeAreaInsets } from './utils/safeArea';
24
+
25
+ export const FlashMessage = React.forwardRef<FlashMessageRef, FlashMessageContainerProps>(
26
+ (props, ref) => {
27
+ const {
28
+ position: defaultPosition = 'top',
29
+ duration: defaultDuration = 3000,
30
+ floating: defaultFloating = true,
31
+ statusBarOffset,
32
+ bottomOffset,
33
+ style: containerCustomStyle,
34
+ } = props;
35
+
36
+ const [currentMessage, setCurrentMessage] = useState<FlashMessageOptions | null>(null);
37
+ const [isVisible, setIsVisible] = useState(false);
38
+
39
+ // Animation values
40
+ const translateY = useRef(new Animated.Value(-150)).current;
41
+ const opacity = useRef(new Animated.Value(0)).current;
42
+ const progress = useRef(new Animated.Value(1)).current;
43
+
44
+ // Timers & gesture tracking
45
+ const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
46
+ const progressAnimationRef = useRef<Animated.CompositeAnimation | null>(null);
47
+ const remainingTimeRef = useRef<number>(0);
48
+ const timerStartedAtRef = useRef<number>(0);
49
+
50
+ const safeInsets = getDefaultSafeAreaInsets();
51
+
52
+ const position = currentMessage?.position ?? defaultPosition;
53
+ const isTop = position === 'top';
54
+ const isBottom = position === 'bottom';
55
+
56
+ const clearTimers = useCallback(() => {
57
+ if (hideTimeoutRef.current) {
58
+ clearTimeout(hideTimeoutRef.current);
59
+ hideTimeoutRef.current = null;
60
+ }
61
+ if (progressAnimationRef.current) {
62
+ progressAnimationRef.current.stop();
63
+ progressAnimationRef.current = null;
64
+ }
65
+ }, []);
66
+
67
+ const animateHide = useCallback(
68
+ (callback?: () => void) => {
69
+ clearTimers();
70
+
71
+ const targetY = isTop ? -180 : isBottom ? 180 : 0;
72
+
73
+ Animated.parallel([
74
+ Animated.timing(translateY, {
75
+ toValue: targetY,
76
+ duration: 220,
77
+ useNativeDriver: true,
78
+ }),
79
+ Animated.timing(opacity, {
80
+ toValue: 0,
81
+ duration: 200,
82
+ useNativeDriver: true,
83
+ }),
84
+ ]).start(() => {
85
+ setIsVisible(false);
86
+ if (currentMessage?.onHide) {
87
+ currentMessage.onHide();
88
+ }
89
+ setCurrentMessage(null);
90
+ callback?.();
91
+ });
92
+ },
93
+ [clearTimers, isTop, isBottom, opacity, translateY, currentMessage]
94
+ );
95
+
96
+ const startAutoHideTimer = useCallback(
97
+ (durationMs: number) => {
98
+ clearTimers();
99
+ if (durationMs <= 0) return;
100
+
101
+ remainingTimeRef.current = durationMs;
102
+ timerStartedAtRef.current = Date.now();
103
+
104
+ // Start progress bar animation
105
+ progress.setValue(1);
106
+ progressAnimationRef.current = Animated.timing(progress, {
107
+ toValue: 0,
108
+ duration: durationMs,
109
+ useNativeDriver: false, // width needs layout or scaleX
110
+ });
111
+ progressAnimationRef.current.start();
112
+
113
+ hideTimeoutRef.current = setTimeout(() => {
114
+ animateHide();
115
+ }, durationMs);
116
+ },
117
+ [animateHide, clearTimers, progress]
118
+ );
119
+
120
+ const pauseTimer = useCallback(() => {
121
+ if (hideTimeoutRef.current && timerStartedAtRef.current > 0) {
122
+ clearTimeout(hideTimeoutRef.current);
123
+ hideTimeoutRef.current = null;
124
+ const elapsed = Date.now() - timerStartedAtRef.current;
125
+ remainingTimeRef.current = Math.max(0, remainingTimeRef.current - elapsed);
126
+ if (progressAnimationRef.current) {
127
+ progressAnimationRef.current.stop();
128
+ }
129
+ }
130
+ }, []);
131
+
132
+ const resumeTimer = useCallback(() => {
133
+ if (remainingTimeRef.current > 0) {
134
+ startAutoHideTimer(remainingTimeRef.current);
135
+ }
136
+ }, [startAutoHideTimer]);
137
+
138
+ const show = useCallback(
139
+ (options: FlashMessageOptions) => {
140
+ clearTimers();
141
+ setCurrentMessage(options);
142
+ setIsVisible(true);
143
+
144
+ const pos = options.position ?? defaultPosition;
145
+ const initialY = pos === 'top' ? -150 : pos === 'bottom' ? 150 : 0;
146
+
147
+ translateY.setValue(initialY);
148
+ opacity.setValue(0);
149
+ progress.setValue(1);
150
+
151
+ Animated.parallel([
152
+ Animated.spring(translateY, {
153
+ toValue: 0,
154
+ tension: 70,
155
+ friction: 9,
156
+ useNativeDriver: true,
157
+ }),
158
+ Animated.timing(opacity, {
159
+ toValue: 1,
160
+ duration: 200,
161
+ useNativeDriver: true,
162
+ }),
163
+ ]).start(() => {
164
+ if (options.onShow) {
165
+ options.onShow();
166
+ }
167
+ });
168
+
169
+ const shouldAutoHide = options.autoHide ?? true;
170
+ const dur = shouldAutoHide ? options.duration ?? defaultDuration : 0;
171
+ if (dur > 0) {
172
+ startAutoHideTimer(dur);
173
+ }
174
+ },
175
+ [clearTimers, defaultDuration, defaultPosition, opacity, progress, startAutoHideTimer, translateY]
176
+ );
177
+
178
+ // Register with manager and imperative ref
179
+ useImperativeHandle(
180
+ ref,
181
+ () => ({
182
+ showMessage: show,
183
+ hideMessage: () => animateHide(),
184
+ }),
185
+ [show, animateHide]
186
+ );
187
+
188
+ useEffect(() => {
189
+ const instanceRef: FlashMessageRef = {
190
+ showMessage: show,
191
+ hideMessage: () => animateHide(),
192
+ };
193
+ flashManager.register(instanceRef);
194
+ return () => {
195
+ flashManager.unregister();
196
+ clearTimers();
197
+ };
198
+ }, [show, animateHide, clearTimers]);
199
+
200
+ // PanResponder for smooth swipe-to-dismiss gesture
201
+ const panResponder = useRef(
202
+ PanResponder.create({
203
+ onStartShouldSetPanResponder: () => true,
204
+ onMoveShouldSetPanResponder: (_, gestureState) => {
205
+ return Math.abs(gestureState.dy) > 5;
206
+ },
207
+ onPanResponderGrant: () => {
208
+ if (currentMessage?.pauseOnPress ?? true) {
209
+ pauseTimer();
210
+ }
211
+ },
212
+ onPanResponderMove: (_, gestureState) => {
213
+ if (!(currentMessage?.swipeToDismiss ?? true)) return;
214
+
215
+ // Only allow dragging upwards for top, downwards for bottom
216
+ if (isTop && gestureState.dy < 0) {
217
+ translateY.setValue(gestureState.dy);
218
+ } else if (isBottom && gestureState.dy > 0) {
219
+ translateY.setValue(gestureState.dy);
220
+ }
221
+ },
222
+ onPanResponderRelease: (_, gestureState) => {
223
+ const swipeThreshold = 30;
224
+ const isDismissGesture =
225
+ (isTop && gestureState.dy < -swipeThreshold) ||
226
+ (isBottom && gestureState.dy > swipeThreshold);
227
+
228
+ if (isDismissGesture && (currentMessage?.swipeToDismiss ?? true)) {
229
+ animateHide();
230
+ } else {
231
+ // Spring back to center
232
+ Animated.spring(translateY, {
233
+ toValue: 0,
234
+ tension: 80,
235
+ friction: 8,
236
+ useNativeDriver: true,
237
+ }).start();
238
+
239
+ if (currentMessage?.pauseOnPress ?? true) {
240
+ resumeTimer();
241
+ }
242
+ }
243
+ },
244
+ })
245
+ ).current;
246
+
247
+ if (!isVisible || !currentMessage) {
248
+ return null;
249
+ }
250
+
251
+ const type = currentMessage.type ?? 'default';
252
+ const typeColors = COLORS[type];
253
+ const backgroundColor = currentMessage.backgroundColor ?? typeColors.background;
254
+ const textColor = currentMessage.color ?? typeColors.text;
255
+ const floating = currentMessage.floating ?? defaultFloating;
256
+
257
+ const topInset =
258
+ currentMessage.statusBarHeight ??
259
+ statusBarOffset ??
260
+ (isTop ? safeInsets.top + (floating ? 8 : 0) : 0);
261
+
262
+ const bottomInset =
263
+ bottomOffset ?? (isBottom ? safeInsets.bottom + (floating ? 8 : 0) : 0);
264
+
265
+ const rootPositionStyle = isTop
266
+ ? [styles.rootTop, { paddingTop: topInset }]
267
+ : isBottom
268
+ ? [styles.rootBottom, { paddingBottom: bottomInset }]
269
+ : styles.rootCenter;
270
+
271
+ const renderIcon = () => {
272
+ if (currentMessage.icon === 'none') return null;
273
+
274
+ if (typeof currentMessage.icon === 'function') {
275
+ return (
276
+ <View style={styles.iconContainer}>
277
+ {currentMessage.icon({ size: 22, color: textColor })}
278
+ </View>
279
+ );
280
+ }
281
+
282
+ if (React.isValidElement(currentMessage.icon)) {
283
+ return <View style={styles.iconContainer}>{currentMessage.icon}</View>;
284
+ }
285
+
286
+ const iconType = typeof currentMessage.icon === 'string' ? currentMessage.icon : type;
287
+ return (
288
+ <View style={styles.iconContainer}>
289
+ <BuiltInIcon type={iconType as any} color={textColor} size={22} />
290
+ </View>
291
+ );
292
+ };
293
+
294
+ const handlePress = () => {
295
+ if (currentMessage.onPress) {
296
+ currentMessage.onPress();
297
+ }
298
+ if (currentMessage.hideOnPress ?? true) {
299
+ animateHide();
300
+ }
301
+ };
302
+
303
+ const progressWidthInterpolation = progress.interpolate({
304
+ inputRange: [0, 1],
305
+ outputRange: ['0%', '100%'],
306
+ });
307
+
308
+ return (
309
+ <View
310
+ pointerEvents="box-none"
311
+ style={[styles.rootOverlay, rootPositionStyle, containerCustomStyle]}
312
+ >
313
+ <Animated.View
314
+ {...panResponder.panHandlers}
315
+ style={[
316
+ styles.toastContainer,
317
+ floating ? styles.floatingContainer : styles.edgeToEdgeContainer,
318
+ { backgroundColor },
319
+ currentMessage.style,
320
+ {
321
+ transform: [{ translateY }],
322
+ opacity,
323
+ },
324
+ ]}
325
+ >
326
+ {currentMessage.customComponent ? (
327
+ currentMessage.customComponent(currentMessage, () => animateHide())
328
+ ) : (
329
+ <Pressable
330
+ onPress={handlePress}
331
+ onLongPress={currentMessage.onLongPress}
332
+ style={styles.contentWrapper}
333
+ >
334
+ {renderIcon()}
335
+
336
+ <View style={styles.textContainer}>
337
+ {typeof currentMessage.message === 'string' ? (
338
+ <Text
339
+ style={[styles.titleText, { color: textColor }, currentMessage.titleStyle]}
340
+ numberOfLines={2}
341
+ >
342
+ {currentMessage.message}
343
+ </Text>
344
+ ) : (
345
+ currentMessage.message
346
+ )}
347
+
348
+ {currentMessage.description ? (
349
+ typeof currentMessage.description === 'string' ? (
350
+ <Text
351
+ style={[
352
+ styles.descriptionText,
353
+ { color: textColor },
354
+ currentMessage.textStyle,
355
+ ]}
356
+ numberOfLines={3}
357
+ >
358
+ {currentMessage.description}
359
+ </Text>
360
+ ) : (
361
+ currentMessage.description
362
+ )
363
+ ) : null}
364
+ </View>
365
+
366
+ {currentMessage.action ? (
367
+ <Pressable
368
+ onPress={() => {
369
+ currentMessage.action?.onPress();
370
+ animateHide();
371
+ }}
372
+ style={[styles.actionButton, currentMessage.action.style]}
373
+ >
374
+ <Text style={[styles.actionButtonText, currentMessage.action.textStyle]}>
375
+ {currentMessage.action.label}
376
+ </Text>
377
+ </Pressable>
378
+ ) : null}
379
+ </Pressable>
380
+ )}
381
+
382
+ {currentMessage.showProgressBar && (
383
+ <View style={styles.progressBarContainer}>
384
+ <Animated.View
385
+ style={[
386
+ styles.progressBarFill,
387
+ { width: progressWidthInterpolation },
388
+ ]}
389
+ />
390
+ </View>
391
+ )}
392
+ </Animated.View>
393
+ </View>
394
+ );
395
+ }
396
+ );
397
+
398
+ FlashMessage.displayName = 'FlashMessage';
@@ -0,0 +1,71 @@
1
+ import type { FlashMessageOptions, FlashMessageRef } from './types';
2
+
3
+ class FlashMessageManager {
4
+ private defaultInstance: FlashMessageRef | null = null;
5
+ private instances: Map<string, FlashMessageRef> = new Map();
6
+ private pendingQueue: FlashMessageOptions[] = [];
7
+
8
+ public register(ref: FlashMessageRef, id: string = 'default'): void {
9
+ this.instances.set(id, ref);
10
+ if (!this.defaultInstance || id === 'default') {
11
+ this.defaultInstance = ref;
12
+ }
13
+
14
+ // Flush any pending messages that arrived before mount
15
+ if (this.pendingQueue.length > 0) {
16
+ const next = this.pendingQueue.shift();
17
+ if (next) {
18
+ ref.showMessage(next);
19
+ }
20
+ }
21
+ }
22
+
23
+ public unregister(id: string = 'default'): void {
24
+ this.instances.delete(id);
25
+ if (this.defaultInstance === this.instances.get(id)) {
26
+ this.defaultInstance = this.instances.values().next().value || null;
27
+ }
28
+ }
29
+
30
+ public showMessage(options: FlashMessageOptions, targetId?: string): void {
31
+ const target = targetId ? this.instances.get(targetId) : this.defaultInstance;
32
+
33
+ if (target) {
34
+ target.showMessage(options);
35
+ } else {
36
+ // Buffer if component hasn't mounted yet
37
+ this.pendingQueue.push(options);
38
+ }
39
+ }
40
+
41
+ public hideMessage(targetId?: string): void {
42
+ const target = targetId ? this.instances.get(targetId) : this.defaultInstance;
43
+ if (target) {
44
+ target.hideMessage();
45
+ }
46
+ }
47
+ }
48
+
49
+ export const flashManager = new FlashMessageManager();
50
+
51
+ /**
52
+ * Imperative helper to trigger a flash message from anywhere in the app
53
+ * (services, Zustand, Redux, API handlers, navigation screens).
54
+ */
55
+ export function showMessage(options: FlashMessageOptions): void {
56
+ flashManager.showMessage(options);
57
+ }
58
+
59
+ /**
60
+ * Imperative helper to dismiss the currently displayed flash message.
61
+ */
62
+ export function hideMessage(): void {
63
+ flashManager.hideMessage();
64
+ }
65
+
66
+ /**
67
+ * Modern alias for showMessage
68
+ */
69
+ export const flash = showMessage;
70
+ export const dismissFlash = hideMessage;
71
+