UNPKG

native-base

Version:

Essential cross-platform UI components for React Native

321 lines (271 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Toast = exports.ToastRef = exports.useToast = exports.ToastProvider = void 0; var _Overlay = require("../../primitives/Overlay"); var _Transitions = require("../Transitions"); var _VStack = _interopRequireDefault(require("../../primitives/Stack/VStack")); var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _Box = _interopRequireDefault(require("../../primitives/Box")); var _hooks = require("../../../hooks"); var _utils = require("../../../utils"); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 INSET = 50; const POSITIONS = { 'top': { top: INSET, left: 0, right: 0 }, 'top-right': { top: INSET, right: 0 }, 'top-left': { top: INSET, left: 0 }, 'bottom': { bottom: INSET, left: 0, right: 0 }, 'bottom-left': { bottom: INSET, left: 0 }, 'bottom-right': { bottom: INSET, right: 0 } }; const initialAnimationOffset = 24; const transitionConfig = { 'bottom': initialAnimationOffset, 'top': -initialAnimationOffset, 'top-right': -initialAnimationOffset, 'top-left': -initialAnimationOffset, 'bottom-left': initialAnimationOffset, 'bottom-right': initialAnimationOffset }; const ToastContext = /*#__PURE__*/(0, _react.createContext)({ toastInfo: {}, setToastInfo: () => {}, setToast: () => {}, removeToast: () => {}, hideAll: () => {}, isActive: () => false, visibleToasts: {}, setVisibleToasts: () => {}, hideToast: () => {} }); const CustomToast = ({ _overlay, _stack, _presenceTransition }) => { const { toastInfo, visibleToasts, removeToast } = _react.default.useContext(ToastContext); const bottomInset = (0, _utils.useKeyboardBottomInset)() * 2; const getPositions = () => { return Object.keys(toastInfo); }; let hasToastOnOverlay = false; getPositions().map(position => { var _toastInfo$position; if (((_toastInfo$position = toastInfo[position]) === null || _toastInfo$position === void 0 ? void 0 : _toastInfo$position.length) > 0) hasToastOnOverlay = true; }); return getPositions().length > 0 ? /*#__PURE__*/_react.default.createElement(_Overlay.Overlay, _extends({}, _overlay, { isOpen: hasToastOnOverlay, isKeyboardDismissable: false }), getPositions().map(position => { if (Object.keys(POSITIONS).includes(position)) return /*#__PURE__*/_react.default.createElement(_VStack.default, _extends({}, _stack, { key: position // @ts-ignore }, POSITIONS[position]), // @ts-ignore toastInfo[position].map(toast => { var _toast$config3; return /*#__PURE__*/_react.default.createElement(_Transitions.PresenceTransition, _extends({}, _presenceTransition, { key: toast.id, visible: visibleToasts[toast.id], onTransitionComplete: status => { if (status === 'exited') { var _toast$config, _toast$config2; removeToast(toast.id); ((_toast$config = toast.config) === null || _toast$config === void 0 ? void 0 : _toast$config.onCloseComplete) && ((_toast$config2 = toast.config) === null || _toast$config2 === void 0 ? void 0 : _toast$config2.onCloseComplete()); } }, initial: { opacity: 0, translateY: transitionConfig[position] } }), /*#__PURE__*/_react.default.createElement(_reactNative.SafeAreaView, null, /*#__PURE__*/_react.default.createElement(_Box.default, { bottom: ['bottom', 'bottom-left', 'bottom-right'].includes(position) && (_toast$config3 = toast.config) !== null && _toast$config3 !== void 0 && _toast$config3.avoidKeyboard ? bottomInset + 'px' : undefined }, toast.component))); }));else return null; })) : null; }; const ToastProvider = ({ children }) => { const [toastInfo, setToastInfo] = (0, _react.useState)({}); const [visibleToasts, setVisibleToasts] = (0, _react.useState)({}); const [themeProps] = (0, _react.useState)((0, _hooks.usePropsResolution)('Toast', {})); const toastIndex = _react.default.useRef(1); const hideAll = _react.default.useCallback(() => { setVisibleToasts({}); }, [setVisibleToasts]); const hideToast = _react.default.useCallback(id => { setVisibleToasts(prevVisibleToasts => ({ ...prevVisibleToasts, [id]: false })); }, [setVisibleToasts]); const isActive = _react.default.useCallback(id => { for (const toastPosition of Object.keys(toastInfo)) { const positionArray = toastInfo[toastPosition]; return positionArray.findIndex(toastData => toastData.id === id) > -1; } return false; }, [toastInfo]); const removeToast = _react.default.useCallback(id => { setToastInfo(prev => { for (const toastPosition of Object.keys(prev)) { const positionArray = prev[toastPosition]; const isToastPresent = positionArray.findIndex(toastData => toastData.id === id) > -1; if (isToastPresent) { const newPositionArray = positionArray.filter(item => item.id !== id); const temp = {}; temp[toastPosition] = newPositionArray; const newToastInfo = { ...prev, ...temp }; return newToastInfo; } } return prev; }); }, [setToastInfo]); const setToast = _react.default.useCallback(props => { const { placement = 'bottom', title, render, id = toastIndex.current++, description, duration = 5000, _title, _description, accessibilityAnnouncement, // @ts-ignore avoidKeyboard = false, //eslint-disable-line ...rest } = props; let positionToastArray = toastInfo[placement]; if (!positionToastArray) positionToastArray = []; let component = null; if (render) { component = render({ id }); } else { component = /*#__PURE__*/ // Below VStack is the default component where all the direct props spread. _react.default.createElement(_VStack.default, _extends({}, themeProps, rest), /*#__PURE__*/_react.default.createElement(_Box.default, { _text: { ...themeProps._title, ..._title } }, title), description && /*#__PURE__*/_react.default.createElement(_Box.default, { _text: { ...themeProps._description, ..._description } }, description)); } toastInfo[placement] = [...positionToastArray, { component, id, config: props }]; setToastInfo({ ...toastInfo }); setVisibleToasts({ ...visibleToasts, [id]: true }); if (duration !== null) { setTimeout(function () { hideToast(id); }, duration); } // iOS doesn't support accessibilityLiveRegion if (accessibilityAnnouncement && _reactNative.Platform.OS === 'ios') { _reactNative.AccessibilityInfo.announceForAccessibility(accessibilityAnnouncement); } return id; }, [themeProps, toastInfo, visibleToasts, hideToast]); const contextValue = _react.default.useMemo(() => { return { toastInfo, setToastInfo, setToast, removeToast, hideAll, isActive, visibleToasts, setVisibleToasts, hideToast }; }, [toastInfo, setToastInfo, setToast, removeToast, hideAll, isActive, visibleToasts, setVisibleToasts, hideToast]); return /*#__PURE__*/_react.default.createElement(ToastContext.Provider, { value: contextValue }, children, /*#__PURE__*/_react.default.createElement(CustomToast, { _overlay: themeProps._overlay, _stack: themeProps._stack, _presenceTransition: themeProps._presenceTransition })); }; exports.ToastProvider = ToastProvider; const useToast = () => { const { setToast, hideAll, isActive, hideToast } = _react.default.useContext(ToastContext); const toast = (0, _react.useMemo)(() => ({ show: setToast, close: hideToast, closeAll: hideAll, isActive }), [setToast, hideAll, isActive, hideToast]); return toast; }; exports.useToast = useToast; const ToastRef = /*#__PURE__*/_react.default.createRef(); exports.ToastRef = ToastRef; const Toast = { show: props => { var _ToastRef$current; return (_ToastRef$current = ToastRef.current) === null || _ToastRef$current === void 0 ? void 0 : _ToastRef$current.show(props); }, close: id => { var _ToastRef$current2; return (_ToastRef$current2 = ToastRef.current) === null || _ToastRef$current2 === void 0 ? void 0 : _ToastRef$current2.close(id); }, closeAll: () => { var _ToastRef$current3; return (_ToastRef$current3 = ToastRef.current) === null || _ToastRef$current3 === void 0 ? void 0 : _ToastRef$current3.closeAll(); }, isActive: id => { var _ToastRef$current4; return (_ToastRef$current4 = ToastRef.current) === null || _ToastRef$current4 === void 0 ? void 0 : _ToastRef$current4.isActive(id); } }; exports.Toast = Toast; //# sourceMappingURL=Toast.js.map