diff --git a/src/animations.ts b/src/animations.ts index 9e685ed..90d0431 100644 --- a/src/animations.ts +++ b/src/animations.ts @@ -1,8 +1,7 @@ -import { useToastContext } from './context'; -import { ToastPosition } from './types'; import React from 'react'; import { Easing, withTiming } from 'react-native-reanimated'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { useToastContext } from './context'; +import { ToastPosition } from './types'; export const ANIMATION_DURATION = 300; const easing = Easing.inOut(Easing.ease); @@ -10,32 +9,27 @@ const animationOptions = { duration: ANIMATION_DURATION, easing }; export const useToastLayoutAnimations = () => { const { position } = useToastContext(); - const insets = useSafeAreaInsets(); return React.useMemo( () => ({ entering: () => { 'worklet'; - return getToastEntering({ position, insets }); + return getToastEntering({ position }); }, exiting: () => { 'worklet'; - return getToastExiting({ position, insets }); + return getToastExiting({ position }); }, }), - [insets, position] + [position] ); }; type GetToastAnimationParams = { position: ToastPosition; - insets: ReturnType; }; -export const getToastEntering = ({ - position, - insets, -}: GetToastAnimationParams) => { +export const getToastEntering = ({ position }: GetToastAnimationParams) => { 'worklet'; const animations = { @@ -43,10 +37,7 @@ export const getToastEntering = ({ transform: [ { scale: withTiming(1, animationOptions) }, { - translateY: withTiming( - position === ToastPosition.TOP_CENTER ? insets.top : -insets.bottom, - animationOptions - ), + translateY: withTiming(0, animationOptions), }, ], }; @@ -67,10 +58,7 @@ export const getToastEntering = ({ }; }; -export const getToastExiting = ({ - position, - insets, -}: GetToastAnimationParams) => { +export const getToastExiting = ({ position }: GetToastAnimationParams) => { 'worklet'; const animations = { @@ -91,8 +79,7 @@ export const getToastExiting = ({ transform: [ { scale: 1 }, { - translateY: - position === ToastPosition.TOP_CENTER ? insets.top : -insets.bottom, + translateY: 0, }, ], }; diff --git a/src/gestures.tsx b/src/gestures.tsx index 5c6c961..70c1cc5 100644 --- a/src/gestures.tsx +++ b/src/gestures.tsx @@ -1,6 +1,3 @@ -import { ANIMATION_DURATION } from './animations'; -import { useToastContext } from './context'; -import { ToastSwipeDirection } from './types'; import * as React from 'react'; import { Dimensions, type ViewStyle } from 'react-native'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; @@ -13,6 +10,9 @@ import Animated, { useSharedValue, withTiming, } from 'react-native-reanimated'; +import { ANIMATION_DURATION } from './animations'; +import { useToastContext } from './context'; +import { ToastSwipeDirection } from './types'; const { LEFT, UP } = ToastSwipeDirection; @@ -105,7 +105,15 @@ export const ToastSwipeHandler: React.FC< return ( diff --git a/src/toast.tsx b/src/toast.tsx index 261dcb5..645168e 100644 --- a/src/toast.tsx +++ b/src/toast.tsx @@ -1,12 +1,12 @@ -import { useColors } from './use-colors'; -import { ANIMATION_DURATION, useToastLayoutAnimations } from './animations'; -import { useToastContext } from './context'; -import { ToastSwipeHandler } from './gestures'; -import { ToastVariant, type ToastProps } from './types'; import { CircleCheck, CircleX, Info, X } from 'lucide-react-native'; import * as React from 'react'; import { ActivityIndicator, Pressable, Text, View } from 'react-native'; import Animated from 'react-native-reanimated'; +import { ANIMATION_DURATION, useToastLayoutAnimations } from './animations'; +import { useToastContext } from './context'; +import { ToastSwipeHandler } from './gestures'; +import { ToastVariant, type ToastProps } from './types'; +import { useColors } from './use-colors'; export const Toast: React.FC = ({ id, @@ -36,6 +36,7 @@ export const Toast: React.FC = ({ const duration = durationProps ?? durationContext; const colors = useColors(); + const { entering, exiting } = useToastLayoutAnimations(); const isDragging = React.useRef(false); const timer = React.useRef(); @@ -77,8 +78,6 @@ export const Toast: React.FC = ({ return () => clearTimeout(timer.current); }, [duration, id, onHide, promiseOptions, updateToast]); - const { entering, exiting } = useToastLayoutAnimations(); - return ( { @@ -107,15 +106,15 @@ export const Toast: React.FC = ({ className={className} style={[ elevationStyle, + style, { + justifyContent: 'center', padding: 16, borderRadius: 16, - marginBottom: 16, marginHorizontal: 16, backgroundColor: colors['background-primary'], borderCurve: 'continuous', }, - style, ]} entering={entering} exiting={exiting} diff --git a/src/toaster.tsx b/src/toaster.tsx index 9ddac26..ddec2fe 100644 --- a/src/toaster.tsx +++ b/src/toaster.tsx @@ -1,4 +1,11 @@ +import * as React from 'react'; +import { View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { FullWindowOverlay } from 'react-native-screens'; +import { v4 as uuidv4 } from 'uuid'; +import { toastDefaultValues } from './constants'; import { ToastContext } from './context'; +import { Toast } from './toast'; import { ToastPosition, type ToastFunctionBase, @@ -7,20 +14,21 @@ import { type ToastProviderProps, type ToastUpdateFunction, } from './types'; -import { toastDefaultValues } from './constants'; -import * as React from 'react'; -import { View } from 'react-native'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { FullWindowOverlay } from 'react-native-screens'; -import { v4 as uuidv4 } from 'uuid'; -import { Toast } from './toast'; let addToastHandler: ToastFunctionBase; let updateToastHandler: ToastUpdateFunction; const { TOP_CENTER, BOTTOM_CENTER } = ToastPosition; -export const Toaster: React.FC = ({ +export const Toaster: React.FC = (props) => { + return ( + + + + ); +}; + +export const ToasterUI: React.FC = ({ duration, position, maxToasts = 3, @@ -35,6 +43,7 @@ export const Toaster: React.FC = ({ }) => { const [toasts, setToasts] = React.useState([]); const { top, bottom } = useSafeAreaInsets(); + console.log(top, bottom, position); addToastHandler = (title, options?: ToastFunctionOptions) => { const id = uuidv4(); @@ -97,52 +106,58 @@ export const Toaster: React.FC = ({ : toasts.slice().reverse(); }, [position, toasts]); + const insetValues = React.useMemo(() => { + if (position === BOTTOM_CENTER) { + if (bottom > 0) { + return { bottom }; + } + return { bottom: 40 }; + } + + if (position === TOP_CENTER) { + if (top > 0) { + return { top }; + } + return { top: 40 }; + } + + console.warn('Invalid position value'); + return {}; + }, [position, bottom, top]); + return ( - - - 0 - ? 0 - : position === BOTTOM_CENTER && bottom === 0 - ? 40 - : undefined, - top: - position === TOP_CENTER && top > 0 - ? 0 - : position === TOP_CENTER && top === 0 - ? 40 - : undefined, - }, - rootStyle, - ]} - className={rootClassName} - > - {positionedToasts.map((toast) => { - return ( - { - removeToast(toast.id); - toast.onHide?.(); - }} - className={toastContentClassName} - style={toastContentStyle} - containerStyle={toastContainerStyle} - containerClassName={toastContainerClassName} - {...props} - /> - ); - })} - - - + + + {positionedToasts.map((toast) => { + return ( + { + removeToast(toast.id); + toast.onHide?.(); + }} + className={toastContentClassName} + style={toastContentStyle} + containerStyle={toastContainerStyle} + containerClassName={toastContainerClassName} + {...props} + /> + ); + })} + + ); };