notistack-v2-maintained
Version:
Highly customizable notification snackbars (toasts) that can be stacked on top of each other
168 lines (167 loc) • 10.6 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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTransitionDirection = void 0;
exports.default = SnackbarItem;
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
const Collapse_1 = __importDefault(require("@mui/material/Collapse"));
const styles_1 = require("@mui/material/styles");
const clsx_1 = __importDefault(require("clsx"));
const react_1 = require("react");
const Snackbar_1 = __importDefault(require("./Snackbar"));
const SnackbarContent_1 = require("./SnackbarContent");
const constants_1 = require("./constants");
const defaultIconVariants_1 = __importDefault(require("./defaultIconVariants"));
const DIRECTION = {
right: "left",
left: "right",
bottom: "up",
top: "down"
};
const getTransitionDirection = (anchorOrigin) => {
if (anchorOrigin.horizontal !== "center") {
return DIRECTION[anchorOrigin.horizontal];
}
return DIRECTION[anchorOrigin.vertical];
};
exports.getTransitionDirection = getTransitionDirection;
const componentName = "SnackbarItem";
const classes = {
contentRoot: `${componentName}-contentRoot`,
lessPadding: `${componentName}-lessPadding`,
variantSuccess: `${componentName}-variantSuccess`,
variantError: `${componentName}-variantError`,
variantInfo: `${componentName}-variantInfo`,
variantWarning: `${componentName}-variantWarning`,
message: `${componentName}-message`,
action: `${componentName}-action`,
wrappedRoot: `${componentName}-wrappedRoot`
};
const StyledSnackbar = (0, styles_1.styled)(Snackbar_1.default)(({ theme }) => {
const mode = theme.palette.mode;
const backgroundColor = (0, styles_1.emphasize)(theme.palette.background.default, mode === "light" ? 0.8 : 0.98);
return {
[`&.${classes.wrappedRoot}`]: {
position: "relative",
transform: "translateX(0)",
top: 0,
right: 0,
bottom: 0,
left: 0
},
[`.${classes.contentRoot}`]: Object.assign(Object.assign({}, theme.typography.body2), { backgroundColor, color: theme.palette.getContrastText(backgroundColor), alignItems: "center", padding: "6px 16px", borderRadius: "4px", boxShadow: "0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)" }),
[`.${classes.lessPadding}`]: {
paddingLeft: 8 * 2.5
},
[`.${classes.variantSuccess}`]: {
backgroundColor: "#43a047", // green
color: "#fff"
},
[`.${classes.variantError}`]: {
backgroundColor: "#d32f2f", // dark red
color: "#fff"
},
[`.${classes.variantInfo}`]: {
backgroundColor: "#2196f3", // nice blue
color: "#fff"
},
[`.${classes.variantWarning}`]: {
backgroundColor: "#ff9800", // amber
color: "#fff"
},
[`.${classes.message}`]: {
display: "flex",
alignItems: "center",
padding: "8px 0"
},
[`.${classes.action}`]: {
display: "flex",
alignItems: "center",
marginLeft: "auto",
paddingLeft: 16,
marginRight: -8
}
};
});
function SnackbarItem(_a) {
var { classes: propClasses } = _a, props = __rest(_a, ["classes"]);
const timeout = (0, react_1.useRef)(null);
const [collapsed, setCollapsed] = (0, react_1.useState)(true);
(0, react_1.useEffect)(() => () => {
if (timeout.current) {
clearTimeout(timeout.current);
}
}, []);
const handleClose = (event, reason) => {
var _a, _b;
(_b = (_a = props.snack).onClose) === null || _b === void 0 ? void 0 : _b.call(_a, event, reason, props.snack.key);
props.onClose(event, reason, props.snack.key);
};
const handleEntered = () => {
if (props.snack.requestClose) {
handleClose(null, constants_1.REASONS.INSTRCUTED);
}
};
const handleExitedScreen = () => {
timeout.current = setTimeout(() => {
setCollapsed(!collapsed);
}, 125);
};
const { style, dense, ariaAttributes: otherAriaAttributes, className: otherClassName, hideIconVariant, iconVariant, snack, action: otherAction, content: otherContent, TransitionComponent: otherTranComponent, TransitionProps: otherTranProps, transitionDuration: otherTranDuration, onEnter: ignoredOnEnter, onEntered: ignoredOnEntered, onEntering: ignoredOnEntering, onExit: ignoredOnExit, onExited: ignoredOnExited, onExiting: ignoredOnExiting } = props, other = __rest(props, ["style", "dense", "ariaAttributes", "className", "hideIconVariant", "iconVariant", "snack", "action", "content", "TransitionComponent", "TransitionProps", "transitionDuration", "onEnter", "onEntered", "onEntering", "onExit", "onExited", "onExiting"]);
const { persist, key, open, entered, requestClose, className: singleClassName, variant, content: singleContent, action: singleAction, ariaAttributes: singleAriaAttributes, anchorOrigin, message: snackMessage, TransitionComponent: singleTranComponent, TransitionProps: singleTranProps, transitionDuration: singleTranDuration, onEnter, onEntered, onEntering, onExit, onExited, onExiting } = snack, singleSnackProps = __rest(snack, ["persist", "key", "open", "entered", "requestClose", "className", "variant", "content", "action", "ariaAttributes", "anchorOrigin", "message", "TransitionComponent", "TransitionProps", "transitionDuration", "onEnter", "onEntered", "onEntering", "onExit", "onExited", "onExiting"]);
const icon = Object.assign(Object.assign({}, defaultIconVariants_1.default), iconVariant)[variant];
const ariaAttributes = Object.assign({ "aria-describedby": "notistack-snackbar" }, (0, constants_1.objectMerge)(singleAriaAttributes, otherAriaAttributes));
const TransitionComponent = singleTranComponent || otherTranComponent || constants_1.DEFAULTS.TransitionComponent;
const transitionDuration = (0, constants_1.objectMerge)(singleTranDuration, otherTranDuration, constants_1.DEFAULTS.transitionDuration);
const transitionProps = Object.assign({ direction: (0, exports.getTransitionDirection)(anchorOrigin) }, (0, constants_1.objectMerge)(singleTranProps, otherTranProps));
let action = singleAction || otherAction;
if (typeof action === "function") {
action = action(key);
}
let content = singleContent || otherContent;
if (typeof content === "function") {
content = content(key, snack.message);
}
return ((0, jsx_runtime_1.jsx)(Collapse_1.default, { unmountOnExit: true, timeout: 175, in: collapsed, onExited: (node) => {
var _a, _b, _c;
(_b = (_a = props.snack).onExited) === null || _b === void 0 ? void 0 : _b.call(_a, node, props.snack.key);
(_c = props.onExited) === null || _c === void 0 ? void 0 : _c.call(props, node, props.snack.key);
}, children: (0, jsx_runtime_1.jsx)(StyledSnackbar, Object.assign({}, other, singleSnackProps, { open: open, className: (0, clsx_1.default)(propClasses.root, classes.wrappedRoot, propClasses[constants_1.transformer.toAnchorOrigin(anchorOrigin)]), onClose: handleClose, children: (0, jsx_runtime_1.jsx)(TransitionComponent, Object.assign({ appear: true, in: open, timeout: transitionDuration }, transitionProps, { onExit: (node) => {
var _a, _b, _c;
(_b = (_a = props.snack).onExit) === null || _b === void 0 ? void 0 : _b.call(_a, node, props.snack.key);
(_c = props.onExit) === null || _c === void 0 ? void 0 : _c.call(props, node, props.snack.key);
}, onExiting: (node) => {
var _a, _b, _c;
(_b = (_a = props.snack).onExiting) === null || _b === void 0 ? void 0 : _b.call(_a, node, props.snack.key);
(_c = props.onExiting) === null || _c === void 0 ? void 0 : _c.call(props, node, props.snack.key);
}, onExited: handleExitedScreen, onEnter: (node) => {
var _a, _b, _c;
(_b = (_a = props.snack).onEnter) === null || _b === void 0 ? void 0 : _b.call(_a, node, props.snack.key);
(_c = props.onEnter) === null || _c === void 0 ? void 0 : _c.call(props, node, props.snack.key);
}, onEntering: (node) => {
var _a, _b, _c;
(_b = (_a = props.snack).onEntering) === null || _b === void 0 ? void 0 : _b.call(_a, node, props.snack.key);
(_c = props.onEntering) === null || _c === void 0 ? void 0 : _c.call(props, node, props.snack.key);
},
// order matters. first callbacks.onEntered to set entered: true,
// then handleEntered to check if there's a request for closing
onEntered: (node, isAppearing) => {
var _a, _b, _c;
(_b = (_a = props.snack).onEntered) === null || _b === void 0 ? void 0 : _b.call(_a, node, isAppearing, props.snack.key);
(_c = props.onEntered) === null || _c === void 0 ? void 0 : _c.call(props, node, isAppearing, props.snack.key);
handleEntered(node, isAppearing, props.snack.key);
}, children: content || ((0, jsx_runtime_1.jsxs)(SnackbarContent_1.SnackbarContent, Object.assign({}, ariaAttributes, { role: "alert", style: style, className: (0, clsx_1.default)(classes.contentRoot, { [classes.lessPadding]: !hideIconVariant && icon }, classes[constants_1.transformer.toVariant(variant)], propClasses[constants_1.transformer.toVariant(variant)], otherClassName, singleClassName), children: [(0, jsx_runtime_1.jsxs)("div", { id: ariaAttributes["aria-describedby"], className: classes.message, children: [!hideIconVariant ? icon : null, snackMessage] }), action && (0, jsx_runtime_1.jsx)("div", { className: classes.action, children: action })] }))) })) })) }));
}