@backpackapp-io/react-native-toast

repository·master·Indexed 19 days ago

https://github.com/backpackapp-io/react-native-toast

A toasting library for React Native built on top of react-hot-toast. It supports multiple toasts, keyboard handling, swipe-to-dismiss, and positional toasts across iOS, Android, and Web. Features include specialized methods for success, error, and loading states, as well as a toast.promise method for asynchronous operations. The library provides a Toasts container for global configuration and supports custom UI via a customRenderer or customToast property.

Tokens
17K
Snippets
59
Records
66
Agent score
64%

What's inside @backpackapp-io/react-native-toast

  1. Features of React Native Toast

    master

    React Native Toast is a mobile-optimized toast library inspired by react-hot-toast. Key features include:

    • Multiple Toasts: Support for multiple toasts with different options (position, color, type) simultaneously.
    • Keyboard Handling: Automatically moves toasts out of the way when the keyboard is opened on iOS and Android.
    • Gestures: Supports swipe-to-dismiss functionality.
    • Positioning: Supports both top and bottom positional toasts.
    • Customization: Allows custom styles, dimensions, duration, and custom components.
    • Promise Support: Use toast.promise(my_promise) to automatically update toast messages based on the promise state (loading, success, or error).
    • Platform Support: Works on iOS, Android, and Web.
    • Native Integration: Supports native modals and provides callbacks for onPress, onShow, and onHide.
  2. Handle toast events (onPress, onShow, onHide)

    master

    You can attach lifecycle handlers to individual toasts to trigger specific logic (like navigation or analytics) when a toast is interacted with or dismissed.

    Available Handlers:

    • onPress: Called when the user taps the toast.
    • onShow: Called when the toast appears.
    • onHide: Called when the toast is dismissed. This handler receives a reason argument.

    Dismiss Reasons (DismissReason):

    • DismissReason.TIMEOUT: Duration elapsed.
    • DismissReason.SWIPE: User swiped it away.
    • DismissReason.PROGRAMMATIC: Dismissed via toast.dismiss().
    • DismissReason.TAP: User tapped to dismiss.

    Global vs Individual Handlers:

    • Individual: Defined in the toast() options. Runs only for that specific toast.
    • Global: Defined on the <Toasts /> component (e.g., onToastPress). Runs for every toast in the app.
    import { DismissReason } from "@backpackapp-io/react-native-toast";
    
    const id = toast('Hello World', {
      onPress: (toast) => {
        console.log('Toast pressed!', toast.id);
      },
      onShow: (toast) => {
        console.log('Toast shown!', toast.id);
      },
      onHide: (toast, reason) => {
        switch(reason) {
          case DismissReason.TIMEOUT: /* ... */ break;
          case DismissReason.SWIPE: /* ... */ break;
          case DismissReason.PROGRAMMATIC: /* ... */ break;
          case DismissReason.TAP: /* ... */ break;
        }
      }
    });
  3. Manage toasts in native modals using `providerKey`

    master

    By default, toasts are rendered in the root component (using the DEFAULT provider key). If you are using native modals, you may need to specify a providerKey to ensure toasts appear inside the modal rather than behind it.

    Rendering in a specific modal

    1. Add a <Toasts /> component inside your native modal with a unique providerKey (e.g., "MODAL::1").
    2. When calling the toast() function, pass the matching providerKey in the options object.

    Persisting toasts across components

    To keep the same toasts visible when switching between components or opening/closing modals, use the special provider key "PERSISTS":

    toast("Message...", { providerKey: "PERSISTS" });

    Manual provider key updates

    If you cannot use "PERSISTS", you can manually update the providerKey of existing toasts using useToasterStore:

    const { toasts } = useToasterStore();
    
    useEffect(() => {
      toasts.forEach((t) => {
        toast(t.message, {
          ...t,
          providerKey: isModalVisible ? 'MODAL::1' : 'DEFAULT',
        });
      });
    }, [isModalVisible]);
    // Component in native modal
    <Toasts providerKey="MODAL::1" />
    
    //... Call toast in root modal
    const id = toast("Hello from root modal") // uses DEFAULT
    
    //... Native modal becomes visible
    const id = toast("Hello from native modal", { providerKey: "MODAL::1" }) 
    // Now, toast is shown only in native modal
  4. Choose an animation type for toasts

    master

    You can specify one of three animation types using the animationType option. These control how the toast enters and exits the screen:

    • timing: (Default) Uses Reanimated withTiming for a smooth, predictable slide + fade animation.
    • spring: Uses Reanimated withSpring for a bouncy, physics-based slide + fade animation.
    • fade: Uses only opacity (fade in/out) without any sliding motion. This is ideal for center-positioned toasts or minimal visual distraction.
    toast('Spring Animation', {
      animationType: 'spring',
    });
    
    toast('Fade Animation', {
      animationType: 'fade',
    });
    
    toast('Default Timing Animation');
  5. Interaction between overrideScreenReaderEnabled and preventScreenReaderFromHiding

    master

    The overrideScreenReaderEnabled prop operates independently of the preventScreenReaderFromHiding prop. The following logic applies:

    1. If overrideScreenReaderEnabled={true} and preventScreenReaderFromHiding={true}, toasts will be shown.
    2. If overrideScreenReaderEnabled={false}, toasts will always be shown, regardless of the value of preventScreenReaderFromHiding or the actual device state.
  6. Setup React Native Toast in your application

    master

    To use the toast library, you must wrap your application root with GestureHandlerRootView and SafeAreaProvider. Additionally, you must include the <Toasts /> component at the root of your component tree to provide the rendering context for toast notifications.

    Once configured, you can trigger toasts from any part of your application using the toast function.

    import { View, StyleSheet } from 'react-native';
    import { GestureHandlerRootView } from 'react-native-gesture-handler';
    import { SafeAreaProvider } from 'react-native-safe-area-context';
    import { toast, Toasts } from '@backpackapp-io/react-native-toast';
    import { useEffect } from 'react';
    
    export default function App() {
      useEffect(() => {
        toast('Hello');
      }, []);
    
      return (
        <SafeAreaProvider>
          <GestureHandlerRootView style={styles.container}>
            <View>{/*The rest of your app*/}</View>
            <Toasts /> {/* <---- Add Here */}
          </GestureHandlerRootView>
        </SafeAreaProvider>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      },
    });
  7. Configure the Toasts provider and root layout

    master

    To use the library, you must wrap your application's root component with <GestureHandlerRootView> and <SafeAreaProvider>. Additionally, you must place the <Toasts /> component at the root level of your application tree to enable toast rendering.

    Once configured, you can trigger toasts from anywhere in your app using the toast() function.

    import { View, StyleSheet } from 'react-native';
    import { GestureHandlerRootView } from 'react-native-gesture-handler';
    import { SafeAreaProvider } from 'react-native-safe-area-context';
    import { toast, Toasts } from '@backpackapp-io/react-native-toast';
    import { useEffect } from 'react';
    
    export default function App() {
      useEffect(() => {
        toast('Hello');
      }, []);
    
      return (
        <SafeAreaProvider>
          <GestureHandlerRootView style={styles.container}>
            <View>{/* Your app components */}</View>
            <Toasts />
          </GestureHandlerRootView>
        </SafeAreaProvider>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      },
    });
  8. Integrate the `<Toasts />` component

    master

    To use the toast system, you must include the <Toasts /> component at the root of your application. This component acts as the container and manager for all toast notifications rendered in your app.

    import { Toasts } from '@backpackapp-io/react-native-toast';
    
    function App() {
      return (
        <View style={{ flex: 1 }}>
          {/* Your app content */}
          <Toasts />
        </View>
      );
    }