react-native-paper-toast
Version:
A toast implementation for React Native Paper
253 lines (250 loc) • 7.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useToast = exports.ToastProvider = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _reactNativePaper = require("react-native-paper");
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
var _MaterialCommunityIcons = _interopRequireDefault(require("react-native-vector-icons/MaterialCommunityIcons"));
var _types = require("./types");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
const ToastContext = /*#__PURE__*/(0, _react.createContext)(null);
const defaults = {
message: 'Hello React Native Paper Toast!',
type: 'normal',
position: 'bottom',
duration: 2000,
visibility: false,
action: undefined,
actionLabel: 'DONE',
messageStyle: {},
messageContainerStyle: {},
snackbarStyle: {}
};
const reducer = (state, action) => {
switch (action.type) {
case _types.ToastActionType.SHOW:
return {
...state,
...action.payload
};
case _types.ToastActionType.HYDRATE:
return {
...state,
...action.payload,
visibility: false
};
case _types.ToastActionType.HIDE:
return {
...state,
visibility: false
};
default:
return state;
}
};
/**
* Wrap your component tree with ToastProvider. This should be after SafeAreaProvider & PaperProvider!
* ## Usage
* ```tsx
* import React from 'react';
* import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
* import { initialWindowMetrics, SafeAreaProvider } from 'react-native-safe-area-context';
* import { ToastProvider } from 'react-native-paper-toast';
* import Application from './application';
*
* export default function App() {
* return (
* <SafeAreaProvider initialMetrics={initialWindowMetrics}>
* <PaperProvider theme={DefaultTheme}>
* <ToastProvider overrides={{ position: 'top' }}>
* <Application />
* </ToastProvider>
* </PaperProvider>
* </SafeAreaProvider>
* );
* }
* ```
*/
const ToastProvider = ({
children,
overrides
}) => {
const initialState = (0, _react.useMemo)(() => ({
...defaults,
...overrides
}), [overrides]);
const [state, dispatch] = (0, _react.useReducer)(reducer, initialState);
const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
const toast = (0, _react.useMemo)(() => ({
show(options) {
const newState = {
...initialState,
...options,
visibility: true
};
newState.position === 'bottom' && _reactNative.Keyboard.dismiss();
dispatch({
type: _types.ToastActionType.SHOW,
payload: newState
});
},
hide() {
dispatch({
type: _types.ToastActionType.HIDE
});
}
}), [initialState]);
const computedStyle = (0, _react.useMemo)(() => {
const base = {
position: 'absolute',
left: insets.left,
right: insets.right,
width: undefined,
alignItems: 'center',
flexDirection: 'row'
};
let style;
if (state.position === 'bottom') {
style = {
...base,
bottom: insets.bottom
};
return style;
}
if (state.position === 'top') {
style = {
...base,
top: insets.top,
bottom: undefined
};
return style;
}
style = {
...base,
top: insets.top,
bottom: insets.bottom,
justifyContent: 'center'
};
return style;
}, [insets, state.position]);
(0, _react.useEffect)(() => {
dispatch({
type: _types.ToastActionType.HYDRATE,
payload: initialState
});
}, [initialState]);
return /*#__PURE__*/_react.default.createElement(ToastContext.Provider, {
value: toast
}, /*#__PURE__*/_react.default.createElement(_reactNativePaper.Portal.Host, null, children), /*#__PURE__*/_react.default.createElement(_reactNativePaper.Portal, null, /*#__PURE__*/_react.default.createElement(_reactNativePaper.Snackbar, {
onDismiss: toast.hide,
style: [types[state.type], state.snackbarStyle],
wrapperStyle: computedStyle,
duration: state.duration,
visible: state.visibility,
action: state.action ? {
label: state.actionLabel,
onPress: state.action
} : undefined
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [styles.container, state.messageContainerStyle]
}, /*#__PURE__*/_react.default.createElement(_MaterialCommunityIcons.default, {
size: 24,
name: icons[state.type],
color: "#ffffff"
}), /*#__PURE__*/_react.default.createElement(_reactNativePaper.Text, {
style: [styles.message, state.messageStyle]
}, ` ${state.message}`)))));
};
/**
* useToast hook is used to show and hide Toast messages.
* ## Usage
* Import the `useToast` hook from the library. Calling it will return you an object with two functions `show` and `hide` to show or hide toast.
*
* ```tsx
* import { useToast } from 'react-native-paper-toast';
*
* export const Screen: React.FC<Props> = (props) => {
* const toaster = useToast();
* // You can now toast methods from handler functions, effects or onPress props!
*
* // Call from handler function
* const handleError = () =>
* toaster.show({ message: 'Invalid Username', type: 'error' });
*
* // Call from Effects
* useEffect(() => {
* login(username, password).then((v) =>
* toaster.show({ message: 'Login successful', duration: 2000 })
* );
* });
*
* return (
* <Surface>
* <Button onPress={() => toaster.show({ message: 'Here is a toast for ya!' })}>
* Show Toast
* </Button>
* <Button onPress={toaster.hide}>Hide Toast</Button>
* </Surface>
* );
* };
* ```
*/
exports.ToastProvider = ToastProvider;
const useToast = () => {
const toast = (0, _react.useContext)(ToastContext);
if (!toast) {
throw new Error('useToast must be used within a ToastProvider.');
}
return toast;
};
exports.useToast = useToast;
const icons = {
normal: 'information-outline',
info: 'information-outline',
warning: 'alert-circle-outline',
success: 'check-circle-outline',
error: 'close-circle-outline'
};
const common = {
borderRadius: 20,
flex: 1
};
const types = {
info: {
...common,
backgroundColor: 'rgba(81,98,188,0.9)'
},
normal: {
...common,
backgroundColor: 'rgba(72,77,81,0.9)'
},
success: {
...common,
backgroundColor: 'rgba(75,153,79,0.9)'
},
warning: {
...common,
backgroundColor: 'rgba(254,177,25,0.9)'
},
error: {
...common,
backgroundColor: 'rgba(216,25,25,0.9)'
}
};
const styles = _reactNative.StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center'
},
message: {
marginLeft: 4,
fontSize: 20,
color: '#ffffff'
}
});
//# sourceMappingURL=index.js.map