Socket
Socket
Sign inDemoInstall

react-native-fast-toast

Package Overview
Dependencies
514
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.3.1 to 3.0.0

59

lib/commonjs/toast-container.js

@@ -66,2 +66,8 @@ "use strict";

_defineProperty(this, "hideAll", () => {
this.setState({
toasts: []
});
});
this.state = {

@@ -72,3 +78,3 @@ toasts: []

render() {
renderBottomToasts() {
const {

@@ -78,10 +84,8 @@ toasts

let {
placement,
offset
} = this.props;
let style = {
bottom: placement === "bottom" ? offset : undefined,
top: placement === "top" ? offset : undefined,
justifyContent: placement === "bottom" ? "flex-end" : "flex-start",
flexDirection: placement === "bottom" ? "column" : "column-reverse"
bottom: offset,
justifyContent: "flex-end",
flexDirection: "column"
};

@@ -92,3 +96,3 @@ return /*#__PURE__*/_react.default.createElement(_reactNative.KeyboardAvoidingView, {

pointerEvents: "box-none"
}, toasts.map(toast => /*#__PURE__*/_react.default.createElement(_toast.default, _extends({
}, toasts.filter(t => !t.placement || t.placement === "bottom").map(toast => /*#__PURE__*/_react.default.createElement(_toast.default, _extends({
key: toast.id

@@ -98,2 +102,27 @@ }, this.props, toast))));

renderTopToasts() {
const {
toasts
} = this.state;
let {
offset
} = this.props;
let style = {
top: offset,
justifyContent: "flex-start",
flexDirection: "column-reverse"
};
return /*#__PURE__*/_react.default.createElement(_reactNative.KeyboardAvoidingView, {
behavior: _reactNative.Platform.OS === "ios" ? "position" : undefined,
style: [styles.container, style],
pointerEvents: "box-none"
}, toasts.filter(t => t.placement === "top").map(toast => /*#__PURE__*/_react.default.createElement(_toast.default, _extends({
key: toast.id
}, this.props, toast))));
}
render() {
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, this.renderTopToasts(), this.renderBottomToasts());
}
}

@@ -103,3 +132,3 @@

placement: "bottom",
offset: 60
offset: 10
});

@@ -111,10 +140,10 @@

position: "absolute",
maxWidth: dims.width * 10 * 9,
bottom: 100,
justifyContent: "flex-end",
alignItems: "center",
borderRadius: 5,
width: dims.width,
maxWidth: dims.width,
zIndex: 999,
left: "10%",
right: "10%"
left: 0,
right: 0,
...(_reactNative.Platform.OS === "web" ? {
overflow: "hidden"
} : null)
},

@@ -121,0 +150,0 @@ message: {

@@ -16,23 +16,32 @@ "use strict";

const Toast = ({
id,
onClose,
icon,
type = "normal",
message,
duration = 3000,
style,
textStyle,
successIcon,
dangerIcon,
warningIcon,
successColor,
dangerColor,
warningColor,
normalColor,
placement,
onPress
}) => {
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const dims = _reactNative.Dimensions.get("window");
const Toast = props => {
let {
id,
onClose,
icon,
type = "normal",
message,
duration = 5000,
style,
textStyle,
animationDuration = 250,
animationType = "slide-in",
successIcon,
dangerIcon,
warningIcon,
successColor,
dangerColor,
warningColor,
normalColor,
placement,
onPress
} = props;
const containerRef = (0, _react.useRef)(null);
const [animation] = (0, _react.useState)(new _reactNative.Animated.Value(0));
const panResponderRef = (0, _react.useRef)();
const panResponderAnimRef = (0, _react.useRef)();
(0, _react.useEffect)(() => {

@@ -42,3 +51,3 @@ _reactNative.Animated.timing(animation, {

useNativeDriver: true,
duration: 250
duration: animationDuration
}).start();

@@ -53,3 +62,3 @@

useNativeDriver: true,
duration: 250
duration: animationDuration
}).start(() => onClose());

@@ -64,2 +73,67 @@ }, duration);

const panReleaseToLeft = gestureState => {
_reactNative.Animated.timing(getPanResponderAnim(), {
toValue: {
x: -dims.width / 10 * 9,
y: gestureState.dy
},
useNativeDriver: true,
duration: 250
}).start(() => onClose());
};
const panReleaseToRight = gestureState => {
_reactNative.Animated.timing(getPanResponderAnim(), {
toValue: {
x: dims.width / 10 * 9,
y: gestureState.dy
},
useNativeDriver: true,
duration: 250
}).start(() => onClose());
};
const getPanResponder = () => {
if (panResponderRef.current) return panResponderRef.current;
panResponderRef.current = _reactNative.PanResponder.create({
onMoveShouldSetPanResponder: (_, gestureState) => {
//return true if user is swiping, return false if it's a single click
return !(gestureState.dx === 0 && gestureState.dy === 0);
},
onPanResponderMove: (_, gestureState) => {
var _getPanResponderAnim;
(_getPanResponderAnim = getPanResponderAnim()) === null || _getPanResponderAnim === void 0 ? void 0 : _getPanResponderAnim.setValue({
x: gestureState.dx,
y: gestureState.dy
});
},
onPanResponderRelease: (_, gestureState) => {
if (gestureState.dx > 50) {
panReleaseToRight(gestureState);
} else if (gestureState.dx < -50) {
panReleaseToLeft(gestureState);
} else {
_reactNative.Animated.spring(getPanResponderAnim(), {
toValue: {
x: 0,
y: 0
},
useNativeDriver: true
}).start();
}
}
});
return panResponderRef.current;
};
const getPanResponderAnim = () => {
if (panResponderAnimRef.current) return panResponderAnimRef.current;
panResponderAnimRef.current = new _reactNative.Animated.ValueXY({
x: 0,
y: 0
});
return panResponderAnimRef.current;
};
if (icon === undefined) {

@@ -96,12 +170,2 @@ switch (type) {

const animationStyle = {
opacity: animation,
transform: [{
translateY: animation.interpolate({
inputRange: [0, 1],
outputRange: placement === "bottom" ? [20, 0] : [0, 20] // 0 : 150, 0.5 : 75, 1 : 0
})
}]
};
let backgroundColor = "";

@@ -126,5 +190,33 @@

const renderToast = () => /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
ref: containerRef,
style: [styles.container, animationStyle, {
const animationStyle = {
opacity: animation,
transform: [{
translateY: animation.interpolate({
inputRange: [0, 1],
outputRange: placement === "bottom" ? [20, 0] : [-20, 0] // 0 : 150, 0.5 : 75, 1 : 0
})
}, getPanResponderAnim().getTranslateTransform()[0]]
};
if (animationType === "zoom-in") {
var _animationStyle$trans;
(_animationStyle$trans = animationStyle.transform) === null || _animationStyle$trans === void 0 ? void 0 : _animationStyle$trans.push({
scale: animation.interpolate({
inputRange: [0, 1],
outputRange: [0.7, 1]
})
});
}
return /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, _extends({
ref: containerRef
}, getPanResponder().panHandlers, {
style: [styles.container, animationStyle]
}), props.renderType && props.renderType[type] ? props.renderType[type](props) : props.renderToast ? props.renderToast(props) : /*#__PURE__*/_react.default.createElement(_reactNative.TouchableWithoutFeedback, {
disabled: !onPress,
onPress: () => onPress && onPress(id)
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [styles.toastContainer, {
backgroundColor

@@ -136,7 +228,3 @@ }, style]

style: [styles.message, textStyle]
}, message));
return onPress ? /*#__PURE__*/_react.default.createElement(_reactNative.TouchableWithoutFeedback, {
onPress: () => onPress(id)
}, renderToast()) : renderToast();
}, message))));
};

@@ -146,2 +234,6 @@

container: {
width: "100%",
alignItems: "center"
},
toastContainer: {
paddingHorizontal: 12,

@@ -152,3 +244,5 @@ paddingVertical: 12,

flexDirection: "row",
alignItems: "center"
alignItems: "center",
maxWidth: dims.width / 10 * 9,
overflow: "hidden"
},

@@ -155,0 +249,0 @@ message: {

@@ -50,2 +50,8 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

_defineProperty(this, "hideAll", () => {
this.setState({
toasts: []
});
});
this.state = {

@@ -56,3 +62,3 @@ toasts: []

render() {
renderBottomToasts() {
const {

@@ -62,10 +68,8 @@ toasts

let {
placement,
offset
} = this.props;
let style = {
bottom: placement === "bottom" ? offset : undefined,
top: placement === "top" ? offset : undefined,
justifyContent: placement === "bottom" ? "flex-end" : "flex-start",
flexDirection: placement === "bottom" ? "column" : "column-reverse"
bottom: offset,
justifyContent: "flex-end",
flexDirection: "column"
};

@@ -76,3 +80,3 @@ return /*#__PURE__*/React.createElement(KeyboardAvoidingView, {

pointerEvents: "box-none"
}, toasts.map(toast => /*#__PURE__*/React.createElement(Toast, _extends({
}, toasts.filter(t => !t.placement || t.placement === "bottom").map(toast => /*#__PURE__*/React.createElement(Toast, _extends({
key: toast.id

@@ -82,2 +86,27 @@ }, this.props, toast))));

renderTopToasts() {
const {
toasts
} = this.state;
let {
offset
} = this.props;
let style = {
top: offset,
justifyContent: "flex-start",
flexDirection: "column-reverse"
};
return /*#__PURE__*/React.createElement(KeyboardAvoidingView, {
behavior: Platform.OS === "ios" ? "position" : undefined,
style: [styles.container, style],
pointerEvents: "box-none"
}, toasts.filter(t => t.placement === "top").map(toast => /*#__PURE__*/React.createElement(Toast, _extends({
key: toast.id
}, this.props, toast))));
}
render() {
return /*#__PURE__*/React.createElement(React.Fragment, null, this.renderTopToasts(), this.renderBottomToasts());
}
}

@@ -87,3 +116,3 @@

placement: "bottom",
offset: 60
offset: 10
});

@@ -95,10 +124,10 @@

position: "absolute",
maxWidth: dims.width * 10 * 9,
bottom: 100,
justifyContent: "flex-end",
alignItems: "center",
borderRadius: 5,
width: dims.width,
maxWidth: dims.width,
zIndex: 999,
left: "10%",
right: "10%"
left: 0,
right: 0,
...(Platform.OS === "web" ? {
overflow: "hidden"
} : null)
},

@@ -105,0 +134,0 @@ message: {

@@ -0,25 +1,33 @@

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useRef, useEffect, useState } from "react";
import { View, StyleSheet, Animated, Text, TouchableWithoutFeedback } from "react-native";
import { View, StyleSheet, Animated, Text, TouchableWithoutFeedback, PanResponder, Dimensions } from "react-native";
const dims = Dimensions.get("window");
const Toast = ({
id,
onClose,
icon,
type = "normal",
message,
duration = 3000,
style,
textStyle,
successIcon,
dangerIcon,
warningIcon,
successColor,
dangerColor,
warningColor,
normalColor,
placement,
onPress
}) => {
const Toast = props => {
let {
id,
onClose,
icon,
type = "normal",
message,
duration = 5000,
style,
textStyle,
animationDuration = 250,
animationType = "slide-in",
successIcon,
dangerIcon,
warningIcon,
successColor,
dangerColor,
warningColor,
normalColor,
placement,
onPress
} = props;
const containerRef = useRef(null);
const [animation] = useState(new Animated.Value(0));
const panResponderRef = useRef();
const panResponderAnimRef = useRef();
useEffect(() => {

@@ -29,3 +37,3 @@ Animated.timing(animation, {

useNativeDriver: true,
duration: 250
duration: animationDuration
}).start();

@@ -39,3 +47,3 @@ let closeTimeout = null;

useNativeDriver: true,
duration: 250
duration: animationDuration
}).start(() => onClose());

@@ -50,2 +58,67 @@ }, duration);

const panReleaseToLeft = gestureState => {
Animated.timing(getPanResponderAnim(), {
toValue: {
x: -dims.width / 10 * 9,
y: gestureState.dy
},
useNativeDriver: true,
duration: 250
}).start(() => onClose());
};
const panReleaseToRight = gestureState => {
Animated.timing(getPanResponderAnim(), {
toValue: {
x: dims.width / 10 * 9,
y: gestureState.dy
},
useNativeDriver: true,
duration: 250
}).start(() => onClose());
};
const getPanResponder = () => {
if (panResponderRef.current) return panResponderRef.current;
panResponderRef.current = PanResponder.create({
onMoveShouldSetPanResponder: (_, gestureState) => {
//return true if user is swiping, return false if it's a single click
return !(gestureState.dx === 0 && gestureState.dy === 0);
},
onPanResponderMove: (_, gestureState) => {
var _getPanResponderAnim;
(_getPanResponderAnim = getPanResponderAnim()) === null || _getPanResponderAnim === void 0 ? void 0 : _getPanResponderAnim.setValue({
x: gestureState.dx,
y: gestureState.dy
});
},
onPanResponderRelease: (_, gestureState) => {
if (gestureState.dx > 50) {
panReleaseToRight(gestureState);
} else if (gestureState.dx < -50) {
panReleaseToLeft(gestureState);
} else {
Animated.spring(getPanResponderAnim(), {
toValue: {
x: 0,
y: 0
},
useNativeDriver: true
}).start();
}
}
});
return panResponderRef.current;
};
const getPanResponderAnim = () => {
if (panResponderAnimRef.current) return panResponderAnimRef.current;
panResponderAnimRef.current = new Animated.ValueXY({
x: 0,
y: 0
});
return panResponderAnimRef.current;
};
if (icon === undefined) {

@@ -82,12 +155,2 @@ switch (type) {

const animationStyle = {
opacity: animation,
transform: [{
translateY: animation.interpolate({
inputRange: [0, 1],
outputRange: placement === "bottom" ? [20, 0] : [0, 20] // 0 : 150, 0.5 : 75, 1 : 0
})
}]
};
let backgroundColor = "";

@@ -112,5 +175,33 @@

const renderToast = () => /*#__PURE__*/React.createElement(Animated.View, {
ref: containerRef,
style: [styles.container, animationStyle, {
const animationStyle = {
opacity: animation,
transform: [{
translateY: animation.interpolate({
inputRange: [0, 1],
outputRange: placement === "bottom" ? [20, 0] : [-20, 0] // 0 : 150, 0.5 : 75, 1 : 0
})
}, getPanResponderAnim().getTranslateTransform()[0]]
};
if (animationType === "zoom-in") {
var _animationStyle$trans;
(_animationStyle$trans = animationStyle.transform) === null || _animationStyle$trans === void 0 ? void 0 : _animationStyle$trans.push({
scale: animation.interpolate({
inputRange: [0, 1],
outputRange: [0.7, 1]
})
});
}
return /*#__PURE__*/React.createElement(Animated.View, _extends({
ref: containerRef
}, getPanResponder().panHandlers, {
style: [styles.container, animationStyle]
}), props.renderType && props.renderType[type] ? props.renderType[type](props) : props.renderToast ? props.renderToast(props) : /*#__PURE__*/React.createElement(TouchableWithoutFeedback, {
disabled: !onPress,
onPress: () => onPress && onPress(id)
}, /*#__PURE__*/React.createElement(View, {
style: [styles.toastContainer, {
backgroundColor

@@ -122,7 +213,3 @@ }, style]

style: [styles.message, textStyle]
}, message));
return onPress ? /*#__PURE__*/React.createElement(TouchableWithoutFeedback, {
onPress: () => onPress(id)
}, renderToast()) : renderToast();
}, message))));
};

@@ -132,2 +219,6 @@

container: {
width: "100%",
alignItems: "center"
},
toastContainer: {
paddingHorizontal: 12,

@@ -138,3 +229,5 @@ paddingVertical: 12,

flexDirection: "row",
alignItems: "center"
alignItems: "center",
maxWidth: dims.width / 10 * 9,
overflow: "hidden"
},

@@ -141,0 +234,0 @@ message: {

import React from "react";
import ToastContainer from "../toast-container";
export declare type ToastType = Pick<ToastContainer, "show" | "update" | "hide">;
declare const ToastContext: React.Context<Pick<ToastContainer, "show" | "update" | "hide">>;
export declare type ToastType = Pick<ToastContainer, "show" | "update" | "hide" | "hideAll">;
declare const ToastContext: React.Context<Pick<ToastContainer, "show" | "update" | "hide" | "hideAll">>;
export default ToastContext;

@@ -5,3 +5,6 @@ import { Component } from "react";

offset?: number;
placement: "top" | "bottom";
renderToast?(toast: ToastProps): JSX.Element;
renderType?: {
[type: string]: (toast: ToastProps) => JSX.Element;
};
}

@@ -17,7 +20,22 @@ interface State {

};
/**
* Shows a new toast.
*/
show: (message: string | JSX.Element, toastOptions?: ToastOptions | undefined) => string;
/**
* Updates a toast, To use this create you must pass an id to show method first, then pass it here to update the toast.
*/
update: (id: string, message: string | JSX.Element, toastOptions?: ToastOptions | undefined) => void;
/**
* Removes a toast from stack
*/
hide: (id: string) => void;
/**
* Removes all toasts in stack
*/
hideAll: () => void;
renderBottomToasts(): JSX.Element;
renderTopToasts(): JSX.Element;
render(): JSX.Element;
}
export default ToastContainer;
import { FC } from "react";
import { StyleProp, ViewStyle, TextStyle } from "react-native";
export interface ToastOptions {
/**
* Id is optional, you may provide an id only if you want to update toast later using toast.update()
*/
id?: string;
/**
* Customize Toast icon
*/
icon?: JSX.Element;
type?: "normal" | "success" | "danger" | "warning";
/**
* Toast types, You can implement you custom type with JSX using renderType method on ToastContainer
*/
type?: "normal" | "success" | "danger" | "warning" | string;
/**
* In milliseconds, How long toast will stay before it go away
*/
duration?: number;
/**
* Customize when toast should be placed
*/
placement?: "top" | "bottom";
/**
* Customize style of toast
*/
style?: StyleProp<ViewStyle>;
/**
* Customize style of toast text
*/
textStyle?: StyleProp<TextStyle>;
/**
* Customize how fast toast will show and hide
*/
animationDuration?: number;
/**
* Customize how toast is animated when added or removed
*/
animationType?: "slide-in" | "zoom-in";
/**
* Customize success type icon
*/
successIcon?: JSX.Element;
/**
* Customize danger type icon
*/
dangerIcon?: JSX.Element;
/**
* Customize warning type icon
*/
warningIcon?: JSX.Element;
/**
* Customize success type color. changes toast background color
*/
successColor?: string;
/**
* Customize danger type color. changes toast background color
*/
dangerColor?: string;
/**
* Customize warning type color. changes toast background color
*/
warningColor?: string;
/**
* Customize normal type color. changes toast background color
*/
normalColor?: string;
/**
* Register event for when toast is pressed. If you're using a custom toast you have to pass this to a Touchable.
*/
onPress?(id: string): void;
/**
* payload data for custom toasts. You can pass whatever you want
*
*/
data?: any;
}

@@ -23,5 +82,8 @@ export interface ToastProps extends ToastOptions {

message: string | JSX.Element;
placement?: "top" | "bottom";
renderToast?(toast: ToastProps): JSX.Element;
renderType?: {
[type: string]: (toast: ToastProps) => JSX.Element;
};
}
declare const Toast: FC<ToastProps>;
export default Toast;
{
"name": "react-native-fast-toast",
"version": "2.3.1",
"version": "3.0.0",
"main": "lib/commonjs/index.js",
"module": "lib/module/index.js",
"types": "lib/typescript/index.d.ts",
"react-native": "lib/module/index.js",
"react-native": "src/index.ts",
"files": [

@@ -18,2 +18,6 @@ "src",

"homepage": "https://github.com/arnnis/react-native-fast-toast#readme",
"peerDependencies": {
"react": "*",
"react-native": "*"
},
"devDependencies": {

@@ -20,0 +24,0 @@ "@react-native-community/bob": "^0.16.2",

@@ -48,24 +48,4 @@ # react-native-fast-toast

## Global Example
If you want to have one Toast and use it everywhere on your app. do this in root component of your app (index.js or App.js)
```js
import Toast from "react-native-fast-toast";
export default function App() {
return (
<>
<RestOfYourApp />
<Toast ref={(ref) => global['toast'] = ref} />
</>
);
```
now you can call `toast.show()` everywhere on app. like alert.
TypeScript Note: add [index.d.ts](/example/index.d.ts) to your project root.
## Hook Example
Alternatively you can use hooks to call toasts, to do so, wrap `ToastProvier` to your root component (index.js or App.js)
You can use hooks to call toasts everywhere, to do so, wrap `ToastProvier` to your root component (index.js or App.js)
```js

@@ -83,3 +63,3 @@ import { ToastProvider } from 'react-native-fast-toast'

Then use hook like this everywhere:
Then use hook like this everywhere in your app:
```js

@@ -93,2 +73,22 @@ import { useToast } from 'react-native-fast-toast'

## Global Example
Alternatively, To call toasts everywhere (even outside of React components like in redux actions), do this in root component of your app (index.js or App.js)
```js
import Toast from "react-native-fast-toast";
export default function App() {
return (
<>
<RestOfYourApp />
<Toast ref={(ref) => global['toast'] = ref} />
</>
);
```
Now you can call `toast.show()` everywhere on app. like alert.
TypeScript Note: add [index.d.ts](/example/index.d.ts) to your project root.
## Type Example

@@ -151,2 +151,8 @@

## Contributing
Pull request are welcome.
While developing, you can run the [example app](/example) to test your changes.
## Donation

@@ -157,9 +163,7 @@ If this project helped you reduce time to develop, you can buy me a cup of coffee :)

## Contributing
## Hire
Pull request are welcome.
Looking for a React/React-Native Expert? Email at alirezarzna@gmail.com
While developing, you can run the [example app](/example) to test your changes.
## License

@@ -166,0 +170,0 @@ MIT

import React from "react";
import ToastContainer from "../toast-container";
export type ToastType = Pick<ToastContainer, "show" | "update" | "hide">;
export type ToastType = Pick<
ToastContainer,
"show" | "update" | "hide" | "hideAll"
>;

@@ -6,0 +9,0 @@ const ToastContext = React.createContext({} as ToastType);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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