588 lines
17 KiB
JavaScript
588 lines
17 KiB
JavaScript
'use client'
|
|
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
// src/index.ts
|
|
var src_exports = {};
|
|
__export(src_exports, {
|
|
Toast: () => Toast,
|
|
ToastOptionProvider: () => ToastOptionProvider,
|
|
ToastProvider: () => ToastProvider,
|
|
createRenderToast: () => createRenderToast,
|
|
createStandaloneToast: () => createStandaloneToast,
|
|
createToastFn: () => createToastFn,
|
|
getToastPlacement: () => getToastPlacement,
|
|
useToast: () => useToast
|
|
});
|
|
module.exports = __toCommonJS(src_exports);
|
|
|
|
// src/use-toast.tsx
|
|
var import_system3 = require("@chakra-ui/system");
|
|
|
|
// src/toast.tsx
|
|
var import_alert = require("@chakra-ui/alert");
|
|
var import_system = require("@chakra-ui/system");
|
|
var import_close_button = require("@chakra-ui/close-button");
|
|
var import_shared_utils = require("@chakra-ui/shared-utils");
|
|
|
|
// src/toast.placement.ts
|
|
function getToastPlacement(position, dir) {
|
|
var _a;
|
|
const computedPosition = position != null ? position : "bottom";
|
|
const logicals = {
|
|
"top-start": { ltr: "top-left", rtl: "top-right" },
|
|
"top-end": { ltr: "top-right", rtl: "top-left" },
|
|
"bottom-start": { ltr: "bottom-left", rtl: "bottom-right" },
|
|
"bottom-end": { ltr: "bottom-right", rtl: "bottom-left" }
|
|
};
|
|
const logical = logicals[computedPosition];
|
|
return (_a = logical == null ? void 0 : logical[dir]) != null ? _a : computedPosition;
|
|
}
|
|
|
|
// src/toast.utils.ts
|
|
var findById = (arr, id) => arr.find((toast) => toast.id === id);
|
|
function findToast(toasts, id) {
|
|
const position = getToastPosition(toasts, id);
|
|
const index = position ? toasts[position].findIndex((toast) => toast.id === id) : -1;
|
|
return {
|
|
position,
|
|
index
|
|
};
|
|
}
|
|
function getToastPosition(toasts, id) {
|
|
for (const [position, values] of Object.entries(toasts)) {
|
|
if (findById(values, id)) {
|
|
return position;
|
|
}
|
|
}
|
|
}
|
|
function getToastStyle(position) {
|
|
const isRighty = position.includes("right");
|
|
const isLefty = position.includes("left");
|
|
let alignItems = "center";
|
|
if (isRighty)
|
|
alignItems = "flex-end";
|
|
if (isLefty)
|
|
alignItems = "flex-start";
|
|
return {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
alignItems
|
|
};
|
|
}
|
|
function getToastListStyle(position) {
|
|
const isTopOrBottom = position === "top" || position === "bottom";
|
|
const margin = isTopOrBottom ? "0 auto" : void 0;
|
|
const top = position.includes("top") ? "env(safe-area-inset-top, 0px)" : void 0;
|
|
const bottom = position.includes("bottom") ? "env(safe-area-inset-bottom, 0px)" : void 0;
|
|
const right = !position.includes("left") ? "env(safe-area-inset-right, 0px)" : void 0;
|
|
const left = !position.includes("right") ? "env(safe-area-inset-left, 0px)" : void 0;
|
|
return {
|
|
position: "fixed",
|
|
zIndex: "var(--toast-z-index, 5500)",
|
|
pointerEvents: "none",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
margin,
|
|
top,
|
|
bottom,
|
|
right,
|
|
left
|
|
};
|
|
}
|
|
|
|
// src/toast.store.ts
|
|
var initialState = {
|
|
top: [],
|
|
"top-left": [],
|
|
"top-right": [],
|
|
"bottom-left": [],
|
|
bottom: [],
|
|
"bottom-right": []
|
|
};
|
|
var toastStore = createStore(initialState);
|
|
function createStore(initialState2) {
|
|
let state = initialState2;
|
|
const listeners = /* @__PURE__ */ new Set();
|
|
const setState = (setStateFn) => {
|
|
state = setStateFn(state);
|
|
listeners.forEach((l) => l());
|
|
};
|
|
return {
|
|
getState: () => state,
|
|
subscribe: (listener) => {
|
|
listeners.add(listener);
|
|
return () => {
|
|
setState(() => initialState2);
|
|
listeners.delete(listener);
|
|
};
|
|
},
|
|
/**
|
|
* Delete a toast record at its position
|
|
*/
|
|
removeToast: (id, position) => {
|
|
setState((prevState) => ({
|
|
...prevState,
|
|
// id may be string or number
|
|
// eslint-disable-next-line eqeqeq
|
|
[position]: prevState[position].filter((toast) => toast.id != id)
|
|
}));
|
|
},
|
|
notify: (message, options) => {
|
|
const toast = createToast(message, options);
|
|
const { position, id } = toast;
|
|
setState((prevToasts) => {
|
|
var _a, _b;
|
|
const isTop = position.includes("top");
|
|
const toasts = isTop ? [toast, ...(_a = prevToasts[position]) != null ? _a : []] : [...(_b = prevToasts[position]) != null ? _b : [], toast];
|
|
return {
|
|
...prevToasts,
|
|
[position]: toasts
|
|
};
|
|
});
|
|
return id;
|
|
},
|
|
update: (id, options) => {
|
|
if (!id)
|
|
return;
|
|
setState((prevState) => {
|
|
const nextState = { ...prevState };
|
|
const { position, index } = findToast(nextState, id);
|
|
if (position && index !== -1) {
|
|
nextState[position][index] = {
|
|
...nextState[position][index],
|
|
...options,
|
|
message: createRenderToast(options)
|
|
};
|
|
}
|
|
return nextState;
|
|
});
|
|
},
|
|
closeAll: ({ positions } = {}) => {
|
|
setState((prev) => {
|
|
const allPositions = [
|
|
"bottom",
|
|
"bottom-right",
|
|
"bottom-left",
|
|
"top",
|
|
"top-left",
|
|
"top-right"
|
|
];
|
|
const positionsToClose = positions != null ? positions : allPositions;
|
|
return positionsToClose.reduce(
|
|
(acc, position) => {
|
|
acc[position] = prev[position].map((toast) => ({
|
|
...toast,
|
|
requestClose: true
|
|
}));
|
|
return acc;
|
|
},
|
|
{ ...prev }
|
|
);
|
|
});
|
|
},
|
|
close: (id) => {
|
|
setState((prevState) => {
|
|
const position = getToastPosition(prevState, id);
|
|
if (!position)
|
|
return prevState;
|
|
return {
|
|
...prevState,
|
|
[position]: prevState[position].map((toast) => {
|
|
if (toast.id == id) {
|
|
return {
|
|
...toast,
|
|
requestClose: true
|
|
};
|
|
}
|
|
return toast;
|
|
})
|
|
};
|
|
});
|
|
},
|
|
isActive: (id) => Boolean(findToast(toastStore.getState(), id).position)
|
|
};
|
|
}
|
|
var counter = 0;
|
|
function createToast(message, options = {}) {
|
|
var _a, _b;
|
|
counter += 1;
|
|
const id = (_a = options.id) != null ? _a : counter;
|
|
const position = (_b = options.position) != null ? _b : "bottom";
|
|
return {
|
|
id,
|
|
message,
|
|
position,
|
|
duration: options.duration,
|
|
onCloseComplete: options.onCloseComplete,
|
|
onRequestRemove: () => toastStore.removeToast(String(id), position),
|
|
status: options.status,
|
|
requestClose: false,
|
|
containerStyle: options.containerStyle
|
|
};
|
|
}
|
|
|
|
// src/toast.tsx
|
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
var Toast = (props) => {
|
|
const {
|
|
status,
|
|
variant = "solid",
|
|
id,
|
|
title,
|
|
isClosable,
|
|
onClose,
|
|
description,
|
|
colorScheme,
|
|
icon
|
|
} = props;
|
|
const ids = id ? {
|
|
root: `toast-${id}`,
|
|
title: `toast-${id}-title`,
|
|
description: `toast-${id}-description`
|
|
} : void 0;
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
import_alert.Alert,
|
|
{
|
|
addRole: false,
|
|
status,
|
|
variant,
|
|
id: ids == null ? void 0 : ids.root,
|
|
alignItems: "start",
|
|
borderRadius: "md",
|
|
boxShadow: "lg",
|
|
paddingEnd: 8,
|
|
textAlign: "start",
|
|
width: "auto",
|
|
colorScheme,
|
|
children: [
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertIcon, { children: icon }),
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_system.chakra.div, { flex: "1", maxWidth: "100%", children: [
|
|
title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertTitle, { id: ids == null ? void 0 : ids.title, children: title }),
|
|
description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertDescription, { id: ids == null ? void 0 : ids.description, display: "block", children: description })
|
|
] }),
|
|
isClosable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
import_close_button.CloseButton,
|
|
{
|
|
size: "sm",
|
|
onClick: onClose,
|
|
position: "absolute",
|
|
insetEnd: 1,
|
|
top: 1
|
|
}
|
|
)
|
|
]
|
|
}
|
|
);
|
|
};
|
|
function createRenderToast(options = {}) {
|
|
const { render, toastComponent: ToastComponent2 = Toast } = options;
|
|
const renderToast = (props) => {
|
|
if (typeof render === "function") {
|
|
return render({ ...props, ...options });
|
|
}
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastComponent2, { ...props, ...options });
|
|
};
|
|
return renderToast;
|
|
}
|
|
function createToastFn(dir, defaultOptions) {
|
|
const normalizeToastOptions = (options) => {
|
|
var _a;
|
|
return {
|
|
...defaultOptions,
|
|
...options,
|
|
position: getToastPlacement(
|
|
(_a = options == null ? void 0 : options.position) != null ? _a : defaultOptions == null ? void 0 : defaultOptions.position,
|
|
dir
|
|
)
|
|
};
|
|
};
|
|
const toast = (options) => {
|
|
const normalizedToastOptions = normalizeToastOptions(options);
|
|
const Message = createRenderToast(normalizedToastOptions);
|
|
return toastStore.notify(Message, normalizedToastOptions);
|
|
};
|
|
toast.update = (id, options) => {
|
|
toastStore.update(id, normalizeToastOptions(options));
|
|
};
|
|
toast.promise = (promise, options) => {
|
|
const id = toast({
|
|
...options.loading,
|
|
status: "loading",
|
|
duration: null
|
|
});
|
|
promise.then(
|
|
(data) => toast.update(id, {
|
|
status: "success",
|
|
duration: 5e3,
|
|
...(0, import_shared_utils.runIfFn)(options.success, data)
|
|
})
|
|
).catch(
|
|
(error) => toast.update(id, {
|
|
status: "error",
|
|
duration: 5e3,
|
|
...(0, import_shared_utils.runIfFn)(options.error, error)
|
|
})
|
|
);
|
|
};
|
|
toast.closeAll = toastStore.closeAll;
|
|
toast.close = toastStore.close;
|
|
toast.isActive = toastStore.isActive;
|
|
return toast;
|
|
}
|
|
|
|
// src/use-toast.tsx
|
|
var import_react3 = require("react");
|
|
|
|
// src/toast.provider.tsx
|
|
var import_framer_motion2 = require("framer-motion");
|
|
var import_portal = require("@chakra-ui/portal");
|
|
|
|
// src/toast.component.tsx
|
|
var import_react_use_timeout = require("@chakra-ui/react-use-timeout");
|
|
var import_react_use_update_effect = require("@chakra-ui/react-use-update-effect");
|
|
var import_shared_utils2 = require("@chakra-ui/shared-utils");
|
|
var import_framer_motion = require("framer-motion");
|
|
var import_system2 = require("@chakra-ui/system");
|
|
var import_react = require("react");
|
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
var toastMotionVariants = {
|
|
initial: (props) => {
|
|
const { position } = props;
|
|
const dir = ["top", "bottom"].includes(position) ? "y" : "x";
|
|
let factor = ["top-right", "bottom-right"].includes(position) ? 1 : -1;
|
|
if (position === "bottom")
|
|
factor = 1;
|
|
return {
|
|
opacity: 0,
|
|
[dir]: factor * 24
|
|
};
|
|
},
|
|
animate: {
|
|
opacity: 1,
|
|
y: 0,
|
|
x: 0,
|
|
scale: 1,
|
|
transition: {
|
|
duration: 0.4,
|
|
ease: [0.4, 0, 0.2, 1]
|
|
}
|
|
},
|
|
exit: {
|
|
opacity: 0,
|
|
scale: 0.85,
|
|
transition: {
|
|
duration: 0.2,
|
|
ease: [0.4, 0, 1, 1]
|
|
}
|
|
}
|
|
};
|
|
var ToastComponent = (0, import_react.memo)((props) => {
|
|
const {
|
|
id,
|
|
message,
|
|
onCloseComplete,
|
|
onRequestRemove,
|
|
requestClose = false,
|
|
position = "bottom",
|
|
duration = 5e3,
|
|
containerStyle,
|
|
motionVariants = toastMotionVariants,
|
|
toastSpacing = "0.5rem"
|
|
} = props;
|
|
const [delay, setDelay] = (0, import_react.useState)(duration);
|
|
const isPresent = (0, import_framer_motion.useIsPresent)();
|
|
(0, import_react_use_update_effect.useUpdateEffect)(() => {
|
|
if (!isPresent) {
|
|
onCloseComplete == null ? void 0 : onCloseComplete();
|
|
}
|
|
}, [isPresent]);
|
|
(0, import_react_use_update_effect.useUpdateEffect)(() => {
|
|
setDelay(duration);
|
|
}, [duration]);
|
|
const onMouseEnter = () => setDelay(null);
|
|
const onMouseLeave = () => setDelay(duration);
|
|
const close = () => {
|
|
if (isPresent)
|
|
onRequestRemove();
|
|
};
|
|
(0, import_react.useEffect)(() => {
|
|
if (isPresent && requestClose) {
|
|
onRequestRemove();
|
|
}
|
|
}, [isPresent, requestClose, onRequestRemove]);
|
|
(0, import_react_use_timeout.useTimeout)(close, delay);
|
|
const containerStyles = (0, import_react.useMemo)(
|
|
() => ({
|
|
pointerEvents: "auto",
|
|
maxWidth: 560,
|
|
minWidth: 300,
|
|
margin: toastSpacing,
|
|
...containerStyle
|
|
}),
|
|
[containerStyle, toastSpacing]
|
|
);
|
|
const toastStyle = (0, import_react.useMemo)(() => getToastStyle(position), [position]);
|
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
import_framer_motion.motion.div,
|
|
{
|
|
layout: true,
|
|
className: "chakra-toast",
|
|
variants: motionVariants,
|
|
initial: "initial",
|
|
animate: "animate",
|
|
exit: "exit",
|
|
onHoverStart: onMouseEnter,
|
|
onHoverEnd: onMouseLeave,
|
|
custom: { position },
|
|
style: toastStyle,
|
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
import_system2.chakra.div,
|
|
{
|
|
role: "status",
|
|
"aria-atomic": "true",
|
|
className: "chakra-toast__inner",
|
|
__css: containerStyles,
|
|
children: (0, import_shared_utils2.runIfFn)(message, { id, onClose: close })
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
ToastComponent.displayName = "ToastComponent";
|
|
|
|
// src/toast.provider.tsx
|
|
var import_react2 = require("react");
|
|
var import_react_context = require("@chakra-ui/react-context");
|
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
var [ToastOptionProvider, useToastOptionContext] = (0, import_react_context.createContext)({
|
|
name: `ToastOptionsContext`,
|
|
strict: false
|
|
});
|
|
var ToastProvider = (props) => {
|
|
const state = (0, import_react2.useSyncExternalStore)(
|
|
toastStore.subscribe,
|
|
toastStore.getState,
|
|
toastStore.getState
|
|
);
|
|
const {
|
|
motionVariants,
|
|
component: Component = ToastComponent,
|
|
portalProps
|
|
} = props;
|
|
const stateKeys = Object.keys(state);
|
|
const toastList = stateKeys.map((position) => {
|
|
const toasts = state[position];
|
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
"div",
|
|
{
|
|
role: "region",
|
|
"aria-live": "polite",
|
|
"aria-label": `Notifications-${position}`,
|
|
id: `chakra-toast-manager-${position}`,
|
|
style: getToastListStyle(position),
|
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_framer_motion2.AnimatePresence, { initial: false, children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
Component,
|
|
{
|
|
motionVariants,
|
|
...toast
|
|
},
|
|
toast.id
|
|
)) })
|
|
},
|
|
position
|
|
);
|
|
});
|
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_portal.Portal, { ...portalProps, children: toastList });
|
|
};
|
|
|
|
// src/use-toast.tsx
|
|
function useToast(options) {
|
|
const { theme } = (0, import_system3.useChakra)();
|
|
const defaultOptions = useToastOptionContext();
|
|
return (0, import_react3.useMemo)(
|
|
() => createToastFn(theme.direction, {
|
|
...defaultOptions,
|
|
...options
|
|
}),
|
|
[options, theme.direction, defaultOptions]
|
|
);
|
|
}
|
|
|
|
// src/create-standalone-toast.tsx
|
|
var import_system4 = require("@chakra-ui/system");
|
|
var import_theme = require("@chakra-ui/theme");
|
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
var defaults = {
|
|
duration: 5e3,
|
|
variant: "solid"
|
|
};
|
|
var defaultStandaloneParam = {
|
|
theme: import_theme.theme,
|
|
colorMode: "light",
|
|
toggleColorMode: () => {
|
|
},
|
|
setColorMode: () => {
|
|
},
|
|
defaultOptions: defaults,
|
|
forced: false
|
|
};
|
|
function createStandaloneToast({
|
|
theme = defaultStandaloneParam.theme,
|
|
colorMode = defaultStandaloneParam.colorMode,
|
|
toggleColorMode = defaultStandaloneParam.toggleColorMode,
|
|
setColorMode = defaultStandaloneParam.setColorMode,
|
|
defaultOptions = defaultStandaloneParam.defaultOptions,
|
|
motionVariants,
|
|
toastSpacing,
|
|
component,
|
|
forced
|
|
} = defaultStandaloneParam) {
|
|
const colorModeContextValue = {
|
|
colorMode,
|
|
setColorMode,
|
|
toggleColorMode,
|
|
forced
|
|
};
|
|
const ToastContainer = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_system4.ThemeProvider, { theme, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_system4.ColorModeContext.Provider, { value: colorModeContextValue, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
ToastProvider,
|
|
{
|
|
defaultOptions,
|
|
motionVariants,
|
|
toastSpacing,
|
|
component
|
|
}
|
|
) }) });
|
|
return {
|
|
ToastContainer,
|
|
toast: createToastFn(theme.direction, defaultOptions)
|
|
};
|
|
}
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
Toast,
|
|
ToastOptionProvider,
|
|
ToastProvider,
|
|
createRenderToast,
|
|
createStandaloneToast,
|
|
createToastFn,
|
|
getToastPlacement,
|
|
useToast
|
|
});
|
|
//# sourceMappingURL=index.js.map
|