UNPKG

@mantine/notifications

Version:

Mantine notifications system

207 lines (206 loc) 7.91 kB
"use client"; const require_get_auto_close = require("./get-auto-close/get-auto-close.cjs"); let _mantine_hooks = require("@mantine/hooks"); let react = require("react"); let _mantine_core = require("@mantine/core"); let react_jsx_runtime = require("react/jsx-runtime"); //#region packages/@mantine/notifications/src/NotificationContainer.tsx const SCROLL_DISMISS_RESET_TIMEOUT = 120; function NotificationContainer({ data, onHide, autoClose, transitionDuration, allowDragDismiss, allowScrollDismiss, paused, onHoverStart, onHoverEnd, ref, style, ...others }) { const [offset, setOffset] = (0, react.useState)(0); const [dismissed, setDismissed] = (0, react.useState)(false); const [dismissDirection, setDismissDirection] = (0, react.useState)(1); const [scrollDismissActive, setScrollDismissActive] = (0, react.useState)(false); const theme = (0, _mantine_core.useMantineTheme)(); const { autoClose: _autoClose, message, allowClose, position: _position, style: dataStyle, withCloseButton, onOpen: _onOpen, ...notificationProps } = data; const autoCloseDuration = require_get_auto_close.getAutoClose(autoClose, data.autoClose); const autoCloseTimeout = (0, react.useRef)(-1); const hideTimeout = (0, react.useRef)(-1); const scrollDismissTimeout = (0, react.useRef)(-1); const notificationRef = (0, react.useRef)(null); const hoveredRef = (0, react.useRef)(false); const offsetRef = (0, react.useRef)(0); const isCloseDisabled = allowClose === false; const cancelAutoClose = () => window.clearTimeout(autoCloseTimeout.current); const cancelHide = () => window.clearTimeout(hideTimeout.current); const cancelScrollDismissReset = () => window.clearTimeout(scrollDismissTimeout.current); const setSwipeOffset = (value) => { offsetRef.current = value; setOffset(value); }; const handleHide = () => { onHide(data.id); cancelAutoClose(); cancelHide(); cancelScrollDismissReset(); }; const handleAutoClose = () => { if (dismissed || active || paused || hoveredRef.current || typeof autoCloseDuration !== "number") return; autoCloseTimeout.current = window.setTimeout(handleHide, autoCloseDuration); }; const getExitOffset = (direction) => { return direction * ((notificationRef.current?.offsetWidth ?? 440) + 40); }; const shouldDismiss = (movement, velocity) => { const width = notificationRef.current?.offsetWidth ?? 440; return Math.abs(movement) > width * .35 || velocity > .5; }; const resetSwipe = () => { cancelScrollDismissReset(); setScrollDismissActive(false); setSwipeOffset(0); }; const dismissNotification = (direction) => { setDismissDirection(direction); setDismissed(true); setScrollDismissActive(false); setSwipeOffset(getExitOffset(direction)); cancelAutoClose(); cancelHide(); cancelScrollDismissReset(); hideTimeout.current = window.setTimeout(handleHide, transitionDuration); }; const scheduleScrollDismissReset = () => { cancelScrollDismissReset(); scrollDismissTimeout.current = window.setTimeout(() => { setScrollDismissActive(false); setSwipeOffset(0); handleAutoClose(); }, SCROLL_DISMISS_RESET_TIMEOUT); }; const { ref: dragRef, active } = (0, _mantine_hooks.useDrag)((state) => { if (dismissed) return; if (state.first) cancelAutoClose(); if (state.last) { if (state.tap || state.canceled) { setSwipeOffset(0); handleAutoClose(); return; } const movement = state.movement[0]; const direction = movement === 0 ? state.direction[0] === -1 ? -1 : 1 : movement > 0 ? 1 : -1; if (shouldDismiss(movement, state.velocity[0])) dismissNotification(direction); else { setSwipeOffset(0); handleAutoClose(); } } else setSwipeOffset(state.movement[0]); }, { axis: "x", threshold: 5, filterTaps: true, enabled: allowDragDismiss && !isCloseDisabled && !dismissed }); const mergedRef = (0, _mantine_hooks.useMergedRef)(ref, notificationRef, dragRef); const resolvedStyle = (0, _mantine_core.getStyleObject)(style, theme); const resolvedDataStyle = (0, _mantine_core.getStyleObject)(dataStyle, theme); const baseStyle = { ...resolvedStyle, ...resolvedDataStyle }; const baseOpacity = typeof baseStyle.opacity === "number" ? baseStyle.opacity : 1; const swipeOpacity = dismissed ? 0 : 1 - Math.min(Math.abs(offset) / 200, 1) * .6; const resolvedTransitionDuration = baseStyle.transitionDuration ?? `${transitionDuration}ms, ${transitionDuration}ms, ${transitionDuration}ms`; const notificationStyle = { ...baseStyle, ["--notifications-state-transform"]: typeof baseStyle.transform === "string" ? baseStyle.transform : "translateX(0)", ["--notifications-state-opacity"]: String(baseOpacity), ["--notifications-swipe-offset"]: `${offset}px`, ["--notifications-swipe-opacity"]: String(swipeOpacity), transform: "var(--notifications-state-transform) translate3d(var(--notifications-swipe-offset), 0, 0)", opacity: "calc(var(--notifications-state-opacity) * var(--notifications-swipe-opacity))", transitionDuration: active || scrollDismissActive ? "0ms, 0ms, 0ms" : resolvedTransitionDuration, cursor: "default", touchAction: "pan-y" }; const handleMouseEnter = () => { hoveredRef.current = true; cancelAutoClose(); onHoverStart?.(); }; const handleMouseLeave = () => { hoveredRef.current = false; if (!scrollDismissActive) { resetSwipe(); handleAutoClose(); } onHoverEnd?.(); }; const handleWheel = (0, react.useEffectEvent)((event) => { if (dismissed || active) return; const isDocumentEvent = event.currentTarget === document; if (!isDocumentEvent && !hoveredRef.current) return; const { deltaX, deltaY } = event; if (Math.abs(deltaX) <= Math.abs(deltaY) || deltaX === 0) return; if (!allowScrollDismiss || isCloseDisabled) return; if (!isDocumentEvent) { event.preventDefault(); event.stopPropagation(); } cancelAutoClose(); setScrollDismissActive(true); const nextOffset = offsetRef.current - deltaX; const direction = nextOffset > 0 ? 1 : -1; if (shouldDismiss(nextOffset, 0)) { dismissNotification(direction); return; } setSwipeOffset(nextOffset); scheduleScrollDismissReset(); }); (0, react.useEffect)(() => { if (!scrollDismissActive) return; document.addEventListener("wheel", handleWheel, { passive: false }); return () => document.removeEventListener("wheel", handleWheel, { passive: false }); }, [scrollDismissActive]); (0, react.useEffect)(() => { const handleResize = () => { if (dismissed) setSwipeOffset(getExitOffset(dismissDirection)); }; window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, [dismissDirection, dismissed]); (0, react.useEffect)(() => { const node = notificationRef.current; if (!node) return; node.addEventListener("wheel", handleWheel, { passive: false }); return () => node.removeEventListener("wheel", handleWheel, { passive: false }); }, []); (0, react.useEffect)(() => { return () => { cancelHide(); cancelScrollDismissReset(); }; }, []); (0, react.useEffect)(() => { data.onOpen?.(data); }, []); (0, react.useEffect)(() => { handleAutoClose(); return cancelAutoClose; }, [ autoCloseDuration, active, dismissed ]); (0, react.useEffect)(() => { if (paused) cancelAutoClose(); else handleAutoClose(); return cancelAutoClose; }, [paused]); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Notification, { ref: mergedRef, ...others, style: notificationStyle, ...notificationProps, withCloseButton: isCloseDisabled ? false : withCloseButton, onClose: handleHide, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: message }); } NotificationContainer.displayName = "@mantine/notifications/NotificationContainer"; //#endregion exports.NotificationContainer = NotificationContainer; //# sourceMappingURL=NotificationContainer.cjs.map