Socket
Socket
Sign inDemoInstall

react-native-customizable-toast

Package Overview
Dependencies
521
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    react-native-customizable-toast

yet another toast library based on reanimated 2 layout animations


Version published
Weekly downloads
119
decreased by-32.39%
Maintainers
1
Install size
143 kB
Created
Weekly downloads
 

Readme

Source

react-native-customizable-toast

yet another toast library based on reanimated 2 layout animations

Features

  • Imperative API
  • Fully Customizable
    • Custom toast renderer
    • Custom vertical swipe animations
    • Custom layout animations
    • Display from top (default) or from bottom
  • Swipeable both vertical and horizontal
  • Fully typed with TypeScript

Requirements

  • react-native-reanimated ^3
  • react-native-gesture-handler ^2

Installation

npm install react-native-customizable-toast

Basic Usage

Use default Toaster component in your base component.

import { Toaster } from "react-native-customizable-toast";

export default function App() {
  return (
    <View style={{ flex: 1 }}>
      <Content />

      <Toaster />
    </View>
  );
}

Use ToasterHelper to show a simple toast.

import { ToasterHelper } from "react-native-customizable-toast";

ToasterHelper.show({
  text: 'lorem ipsum',
  type: 'success',
  timeout: 5000,
});

Default Methods

// show toast
const toast = ToasterHelper.show({
  text: 'custom string',
  timeout: 5000,
  type: 'info',
  onPress: () => {},
  dismissible: false,
  loading: true,
});

// update toast
ToasterHelper.update(toast, {
  dismissible: true,
  loading: false,
});


// hide toast
ToasterHelper.hide(toast)

Customizing

In case that you don't want to use default Fade animations and want to replace them with Slide animations and specify custom properties for toast message;

First create responsible type for your custom toast.

type MyCustomToaster = {
  text: string;
  dismissible?: boolean;
  backgroundColor?: string;
};

Create ref object to use toaster methods via imperative api. You can create helper object to get rid of 'current' keyword.

const CustomToasterRef = createRef<ToasterMethods<MyCustomToaster>>();


// optional
export const CustomToasterHelper = {
  show: (options: MyCustomToaster) => CustomToasterRef.current?.show(options)!,
  hide: (id: string) => CustomToasterRef.current?.hide(id),
  filter: (fn: (value: MyCustomToaster, index: number) => void) =>
    CustomToasterRef.current?.filter(fn),
  update: (id: string, options: Partial<MyCustomToaster>) =>
    CustomToasterRef.current?.update(id, options),
};

Next, create a toaster component based on ToasterBase, attach the ref object to it and customize a bit. You can use Reanimated 2 Layout Animations.

https://docs.swmansion.com/react-native-reanimated/docs/next/api/LayoutAnimations/exitAnimations

import {
  SlideInLeft,
  SlideOutRight,
} from 'react-native-reanimated';

export const CustomToaster = () => {
  return (
    <ToasterBase
      entering={SlideInLeft}
      exiting={SlideOutRight}
      ref={CustomToasterRef}
    />
  );
};

By default onSwipeEdge callback removes all toast messages from toaster but we want to remove dismissible toasts.

export const CustomToaster = () => {
  return (
    <ToasterBase
      entering={SlideInLeft}
      exiting={SlideOutRight}
      ref={CustomToasterRef}
      onSwipeEdge={({ filter }) => filter((e) => !e.dismissible)} // <--- add
    />
  );
};

Since we want to use a custom toast that has custom properties, we need to create a Toast component. We will use useToast hook to get the toast data from current context.

const CustomToastComponent = () => {
  const {
    text,
    hide,
    dismissible,
    backgroundColor = '#222',
  } = useToast<MyCustomToaster>();

  return (
    <Swipeable onSwipe={hide} disabled={!dismissible}>
      <View style={styles.container}>
        <TouchableOpacity
          disabled={!dismissible}
          style={[
            styles.touchable,
            {
              backgroundColor,
            },
          ]}
          onPress={hide}
        >
          <Text style={styles.text}>{text}</Text>
        </TouchableOpacity>
      </View>
    </Swipeable>
  );
};

const styles = StyleSheet.create({
  container: {
    paddingHorizontal: 10,
    paddingVertical: 2,
  },
  touchable: {
    alignItems: 'center',
    flexDirection: 'row',
    borderRadius: 5,
    padding: 10,
    minHeight: 40,
  },
  text: {
    color: '#ffffff',
    flex: 1,
  },
});

Update CustomToaster component to render out custom toast.

export const CustomToaster = () => {
  return (
    <ToasterBase
      entering={SlideInLeft}
      exiting={SlideOutRight}
      ref={CustomToasterRef}
      onSwipeEdge={({ filter }) => filter((e) => !e.dismissible)}
      render={CustomToastComponent} // <--- add
    />
  );
};

Create toast via your helper.

CustomToasterHelper.show({
  text: 'message',
  dismissible: false,
  backgroundColor: 'RANDOM HEX COLOR'
});

🎉Congratulations!!

You have your custom implementation of react-native-customizable-toast.

Dont mind FPS :(

What if you wanted to change the vertical stack animation to another animation?

Create Reanimated 2 worklet that returns style object. Dont forget to take a look at ToastItemProps. You can find lots of animated values and toast properties that you can combine with the provided link.

export const clamp = (
  value: number,
  lowerBound: number,
  upperBound: number
) => {
  'worklet';
  return Math.min(Math.max(lowerBound, value), upperBound);
};

export const customStyleWorklet = ({
  itemLayout: { y },
  gesture: { translationY },
  properties: { index },
}: ToastItemProps) => {
  'worklet';

  return {
    transform: [
      {
        translateY: clamp(translationY.value, -y.value, 0),
      },
      {
        translateX: interpolate(
          -translationY.value - y.value,
          [0, 100],
          [0, index % 2 ? 1000 : -1000],
          Extrapolate.CLAMP
        ),
      },
    ],
  };
};

Use custom style worklet in your toaster component.

export const CustomToaster = () => {
  return (
    <ToasterBase
      entering={SlideInLeft}
      exiting={SlideOutRight}
      ref={CustomToasterRef}
      onSwipeEdge={({ filter }) => filter((e) => !e.dismissible)}
      render={CustomToastComponent}
      itemStyle={customStyleWorklet}  // <--- add
    />
  );
};

Dont mind FPS again :(

You can find full implementation in CustomToaster

TODO

  • Better README.md or docs

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT

Keywords

FAQs

Last updated on 13 Aug 2023

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc