@navinc/base-react-components
Version:
Nav's Pattern Library
78 lines • 3.46 kB
JavaScript
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