@codeworker.br/govbr-tw-react
Version:
Biblioteca de componentes React usando Tailwind CSS que implementa o Padrão Digital de Governo.
89 lines (88 loc) • 4.19 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 { useCallback, useEffect, useMemo, useRef, useState, } from "react";
import Message from "../Message";
import { cn } from "../../libs/utils";
import BASE_CLASSNAMES from "../../config/baseClassNames";
const EXIT_ANIMATION_DURATION = 300;
const DEFAULT_AUTO_DISMISS_DELAY = 3000;
const positionClasses = {
"top-left": "top-6 left-6 items-start",
"top-right": "top-6 right-6 items-end",
"bottom-left": "bottom-6 left-6 items-start",
"bottom-right": "bottom-6 right-6 items-end",
};
const initialTransforms = {
"top-left": "-translate-x-full",
"bottom-left": "-translate-x-full",
"top-right": "translate-x-full",
"bottom-right": "translate-x-full",
};
const ToastElement = ({ toast, position, autoDismiss, autoDismissDelay, onRemove, }) => {
const [phase, setPhase] = useState("entering");
const closingRef = useRef(false);
const exitTimeoutRef = useRef(null);
const handleRemove = useCallback(() => {
if (closingRef.current) {
return;
}
closingRef.current = true;
setPhase("leaving");
exitTimeoutRef.current = setTimeout(() => {
if (onRemove) {
onRemove(toast.id);
}
}, EXIT_ANIMATION_DURATION);
}, [onRemove, toast.id]);
useEffect(() => {
const frame = requestAnimationFrame(() => {
setPhase("settled");
});
return () => cancelAnimationFrame(frame);
}, []);
useEffect(() => {
var _a, _b;
const shouldDismiss = (_a = toast.autoDismiss) !== null && _a !== void 0 ? _a : autoDismiss;
if (!shouldDismiss) {
return;
}
const delay = (_b = toast.autoDismissDelay) !== null && _b !== void 0 ? _b : autoDismissDelay;
const timer = setTimeout(() => {
handleRemove();
}, delay);
return () => clearTimeout(timer);
}, [
toast.autoDismiss,
toast.autoDismissDelay,
autoDismiss,
autoDismissDelay,
handleRemove,
]);
useEffect(() => {
return () => {
if (exitTimeoutRef.current) {
clearTimeout(exitTimeoutRef.current);
}
};
}, []);
const transformClass = phase === "settled" ? "translate-x-0" : initialTransforms[position];
const opacityClass = phase === "settled" ? "opacity-100" : "opacity-0";
const { content, className } = toast, messageProps = __rest(toast, ["content", "className"]);
return (_jsx("div", { className: cn("pointer-events-auto transition-all duration-300 ease-in-out w-full max-w-sm", "will-change-transform", transformClass, opacityClass), children: _jsx(Message, Object.assign({}, messageProps, { disableAutoRemove: true, onClose: handleRemove, className: cn(BASE_CLASSNAMES.toaster.toast, className), children: content })) }));
};
const Toaster = (_a) => {
var { toasts, position = "top-left", autoDismiss = false, autoDismissDelay = DEFAULT_AUTO_DISMISS_DELAY, onRemove, className } = _a, props = __rest(_a, ["toasts", "position", "autoDismiss", "autoDismissDelay", "onRemove", "className"]);
const renderToasts = useMemo(() => toasts.map((toast) => (_jsx(ToastElement, { toast: toast, position: position, autoDismiss: autoDismiss, autoDismissDelay: autoDismissDelay, onRemove: onRemove }, toast.id))), [toasts, position, autoDismiss, autoDismissDelay, onRemove]);
return (_jsx("div", Object.assign({ className: cn("fixed z-[9999] flex pointer-events-none gap-3 flex-col", positionClasses[position], BASE_CLASSNAMES.toaster.root, className) }, props, { children: renderToasts })));
};
export default Toaster;