UNPKG

@navinc/base-react-components

Version:
78 lines 3.46 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useCallback, useContext, useReducer } from 'react'; import BannerToast from './banner-toast.js'; import styled from 'styled-components'; import { uuidBrowser } from '@navinc/utils'; const CLEAR_MESSAGE = 'CLEAR_MESSAGE'; const SHOW_MESSAGE = 'SHOW_MESSAGE'; const reducer = (state, action) => { switch (action.type) { case CLEAR_MESSAGE: { return Object.assign(Object.assign({}, state), { messages: state.messages.filter((message) => message.id !== action.id) }); } case SHOW_MESSAGE: { // if we already have a message with the give id, we want to replace the old one. const hasMessageOfId = state.messages.some(({ id }) => id === action.props.id); return Object.assign(Object.assign({}, state), { messages: hasMessageOfId ? state.messages.map((message) => { return message.id === action.props.id ? action.props : message; }) : [ ...state.messages, Object.assign({}, action.props), ] }); } default: return state; } }; const toastContext = createContext({ showMessage: (_msg) => { }, clearMessage: (_id) => { }, getMessages: () => [], }); export const ToastProvider = ({ children }) => { const [state, dispatch] = useReducer(reducer, { messages: [] }); const clearMessage = useCallback((id) => dispatch({ type: CLEAR_MESSAGE, id }), [dispatch]); const showMessage = useCallback((_a) => { var { id = uuidBrowser() } = _a, props = __rest(_a, ["id"]); dispatch({ type: SHOW_MESSAGE, props: Object.assign({ id }, props) }); }, [dispatch]); const getMessages = useCallback(() => state.messages, [state]); return _jsx(toastContext.Provider, Object.assign({ value: { showMessage, clearMessage, getMessages } }, { children: children }), void 0); }; const MessageContainer = styled.div ` display: flex; justify-content: center; position: relative; width: 100%; `; const Grid = styled.div ` display: grid; grid-gap: 8px; max-width: 544px; width: 100%; position: absolute; top: 8px; `; export const useToast = () => useContext(toastContext); export const Toast = ({ className }) => { const { clearMessage, getMessages } = useToast(); const messages = getMessages(); return (_jsx(MessageContainer, Object.assign({ className: className }, { children: _jsx(Grid, { children: messages.map((_a = {}) => { var { id, isDismissible } = _a, message = __rest(_a, ["id", "isDismissible"]); return (_jsx(BannerToast, Object.assign({ "data-testid": `global-message-${id}`, shouldNotTimeout: isDismissible, onDismiss: () => clearMessage(id) }, message), id)); }) }, void 0) }), void 0)); }; //# sourceMappingURL=toast-hook.js.map