@particle-academy/react-fancy 5.40.0 → 5.41.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/dist/chunk-3AQLEMH7.js +297 -0
- package/dist/chunk-3AQLEMH7.js.map +1 -0
- package/dist/chunk-UBZFOTZN.cjs +300 -0
- package/dist/chunk-UBZFOTZN.cjs.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/toast.cjs +6 -3
- package/dist/toast.d.cts +55 -1
- package/dist/toast.d.ts +55 -1
- package/dist/toast.js +4 -1
- package/package.json +1 -1
- package/dist/chunk-7HMEDY24.cjs +0 -136
- package/dist/chunk-7HMEDY24.cjs.map +0 -1
- package/dist/chunk-JICO4LTT.js +0 -133
- package/dist/chunk-JICO4LTT.js.map +0 -1
package/dist/chunk-7HMEDY24.cjs
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var chunkNBZC6LOB_cjs = require('./chunk-NBZC6LOB.cjs');
|
|
4
|
-
var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
|
|
5
|
-
var react = require('react');
|
|
6
|
-
var lucideReact = require('lucide-react');
|
|
7
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
-
|
|
9
|
-
var ToastContext = react.createContext(null);
|
|
10
|
-
function useToast() {
|
|
11
|
-
const ctx = react.useContext(ToastContext);
|
|
12
|
-
if (!ctx) {
|
|
13
|
-
throw new Error("useToast must be used within a <Toast.Provider>");
|
|
14
|
-
}
|
|
15
|
-
return ctx;
|
|
16
|
-
}
|
|
17
|
-
var VARIANT_STYLES = {
|
|
18
|
-
default: "border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
|
|
19
|
-
success: "border-emerald-200 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950",
|
|
20
|
-
error: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950",
|
|
21
|
-
warning: "border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950",
|
|
22
|
-
info: "border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950"
|
|
23
|
-
};
|
|
24
|
-
var VARIANT_ICON_COLORS = {
|
|
25
|
-
default: "text-zinc-400",
|
|
26
|
-
success: "text-emerald-500",
|
|
27
|
-
error: "text-red-500",
|
|
28
|
-
warning: "text-amber-500",
|
|
29
|
-
info: "text-blue-500"
|
|
30
|
-
};
|
|
31
|
-
function ToastItem({ data, onDismiss }) {
|
|
32
|
-
const { id, title, description, variant = "default", action } = data;
|
|
33
|
-
const duration = data.duration ?? (action ? 0 : 5e3);
|
|
34
|
-
react.useEffect(() => {
|
|
35
|
-
if (duration <= 0) return;
|
|
36
|
-
const timer = setTimeout(() => onDismiss(id), duration);
|
|
37
|
-
return () => clearTimeout(timer);
|
|
38
|
-
}, [id, duration, onDismiss]);
|
|
39
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
40
|
-
"div",
|
|
41
|
-
{
|
|
42
|
-
"data-react-fancy-toast-item": "",
|
|
43
|
-
role: "alert",
|
|
44
|
-
onKeyDown: (e) => {
|
|
45
|
-
if (e.key === "Escape") onDismiss(id);
|
|
46
|
-
},
|
|
47
|
-
className: chunkZU5Q77OT_cjs.cn(
|
|
48
|
-
"fancy-toast-in pointer-events-auto w-80 rounded-xl border p-4 shadow-lg",
|
|
49
|
-
VARIANT_STYLES[variant]
|
|
50
|
-
),
|
|
51
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
52
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkZU5Q77OT_cjs.cn("mt-0.5 shrink-0", VARIANT_ICON_COLORS[variant]), children: [
|
|
53
|
-
variant === "success" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 16 }),
|
|
54
|
-
variant === "error" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { size: 16 }),
|
|
55
|
-
variant === "warning" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: 16 }),
|
|
56
|
-
variant === "info" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { size: 16 })
|
|
57
|
-
] }),
|
|
58
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
59
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: title }),
|
|
60
|
-
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: description })
|
|
61
|
-
] }),
|
|
62
|
-
action && /* @__PURE__ */ jsxRuntime.jsx(
|
|
63
|
-
"button",
|
|
64
|
-
{
|
|
65
|
-
type: "button",
|
|
66
|
-
onClick: () => {
|
|
67
|
-
action.onClick();
|
|
68
|
-
onDismiss(id);
|
|
69
|
-
},
|
|
70
|
-
className: "shrink-0 self-center rounded-md px-2 py-1 text-xs font-medium text-zinc-700 underline-offset-2 transition-colors hover:bg-zinc-100 hover:underline dark:text-zinc-200 dark:hover:bg-zinc-800",
|
|
71
|
-
children: action.label
|
|
72
|
-
}
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
75
|
-
"button",
|
|
76
|
-
{
|
|
77
|
-
type: "button",
|
|
78
|
-
onClick: () => onDismiss(id),
|
|
79
|
-
className: "shrink-0 rounded p-0.5 text-zinc-400 transition-colors hover:text-zinc-600 dark:hover:text-zinc-300",
|
|
80
|
-
"aria-label": "Dismiss",
|
|
81
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 14 })
|
|
82
|
-
}
|
|
83
|
-
)
|
|
84
|
-
] })
|
|
85
|
-
}
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
ToastItem.displayName = "ToastItem";
|
|
89
|
-
var POSITION_STYLES = {
|
|
90
|
-
"top-right": "top-4 right-4",
|
|
91
|
-
"top-left": "top-4 left-4",
|
|
92
|
-
"bottom-right": "bottom-4 right-4",
|
|
93
|
-
"bottom-left": "bottom-4 left-4"
|
|
94
|
-
};
|
|
95
|
-
function ToastProvider({
|
|
96
|
-
children,
|
|
97
|
-
position = "bottom-right",
|
|
98
|
-
maxToasts = 5
|
|
99
|
-
}) {
|
|
100
|
-
const [toasts, setToasts] = react.useState([]);
|
|
101
|
-
const idCounter = react.useRef(0);
|
|
102
|
-
const toast = react.useCallback(
|
|
103
|
-
(data) => {
|
|
104
|
-
const id = `toast-${++idCounter.current}`;
|
|
105
|
-
setToasts((prev) => [...prev.slice(-(maxToasts - 1)), { ...data, id }]);
|
|
106
|
-
return id;
|
|
107
|
-
},
|
|
108
|
-
[maxToasts]
|
|
109
|
-
);
|
|
110
|
-
const dismiss = react.useCallback((id) => {
|
|
111
|
-
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
112
|
-
}, []);
|
|
113
|
-
const ctx = react.useMemo(() => ({ toasts, toast, dismiss }), [toasts, toast, dismiss]);
|
|
114
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: ctx, children: [
|
|
115
|
-
children,
|
|
116
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunkNBZC6LOB_cjs.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
117
|
-
"div",
|
|
118
|
-
{
|
|
119
|
-
"data-react-fancy-toast": "",
|
|
120
|
-
className: chunkZU5Q77OT_cjs.cn(
|
|
121
|
-
"fixed z-[100] flex flex-col gap-2 pointer-events-none",
|
|
122
|
-
POSITION_STYLES[position]
|
|
123
|
-
),
|
|
124
|
-
children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(ToastItem, { data: t, onDismiss: dismiss }, t.id))
|
|
125
|
-
}
|
|
126
|
-
) })
|
|
127
|
-
] });
|
|
128
|
-
}
|
|
129
|
-
var Toast = {
|
|
130
|
-
Provider: ToastProvider
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
exports.Toast = Toast;
|
|
134
|
-
exports.useToast = useToast;
|
|
135
|
-
//# sourceMappingURL=chunk-7HMEDY24.cjs.map
|
|
136
|
-
//# sourceMappingURL=chunk-7HMEDY24.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Toast/Toast.context.ts","../src/components/Toast/ToastItem.tsx","../src/components/Toast/Toast.tsx"],"names":["createContext","useContext","useEffect","jsx","cn","jsxs","Check","XCircle","AlertTriangle","Info","X","useState","useRef","useCallback","useMemo","Portal"],"mappings":"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","file":"chunk-7HMEDY24.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { ToastContextValue } from \"./Toast.types\";\n\nexport const ToastContext = createContext<ToastContextValue | null>(null);\n\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext);\n if (!ctx) {\n throw new Error(\"useToast must be used within a <Toast.Provider>\");\n }\n return ctx;\n}\n","import { useEffect } from \"react\";\nimport { AlertTriangle, Check, Info, X, XCircle } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type { ToastItemProps } from \"./Toast.types\";\n\nconst VARIANT_STYLES = {\n default:\n \"border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900\",\n success:\n \"border-emerald-200 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950\",\n error:\n \"border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950\",\n warning:\n \"border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950\",\n info: \"border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950\",\n} as const;\n\nconst VARIANT_ICON_COLORS = {\n default: \"text-zinc-400\",\n success: \"text-emerald-500\",\n error: \"text-red-500\",\n warning: \"text-amber-500\",\n info: \"text-blue-500\",\n} as const;\n\nexport function ToastItem({ data, onDismiss }: ToastItemProps) {\n const { id, title, description, variant = \"default\", action } = data;\n // An action toast does not expire by default.\n const duration = data.duration ?? (action ? 0 : 5000);\n\n useEffect(() => {\n if (duration <= 0) return;\n const timer = setTimeout(() => onDismiss(id), duration);\n return () => clearTimeout(timer);\n }, [id, duration, onDismiss]);\n\n return (\n <div\n data-react-fancy-toast-item=\"\"\n role=\"alert\"\n // Scoped to the toast rather than the document: a global Escape handler\n // would fight whatever modal or drawer is already listening.\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onDismiss(id);\n }}\n className={cn(\n \"fancy-toast-in pointer-events-auto w-80 rounded-xl border p-4 shadow-lg\",\n VARIANT_STYLES[variant],\n )}\n >\n <div className=\"flex items-start gap-3\">\n <div className={cn(\"mt-0.5 shrink-0\", VARIANT_ICON_COLORS[variant])}>\n {variant === \"success\" && <Check size={16} />}\n {variant === \"error\" && <XCircle size={16} />}\n {variant === \"warning\" && <AlertTriangle size={16} />}\n {variant === \"info\" && <Info size={16} />}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-zinc-900 dark:text-zinc-100\">{title}</p>\n {description && (\n <p className=\"mt-1 text-xs text-zinc-500 dark:text-zinc-400\">\n {description}\n </p>\n )}\n </div>\n {action && (\n <button\n type=\"button\"\n onClick={() => {\n action.onClick();\n // The offer is consumed; leaving it up invites undoing an\n // already-undone action.\n onDismiss(id);\n }}\n className=\"shrink-0 self-center rounded-md px-2 py-1 text-xs font-medium text-zinc-700 underline-offset-2 transition-colors hover:bg-zinc-100 hover:underline dark:text-zinc-200 dark:hover:bg-zinc-800\"\n >\n {action.label}\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onDismiss(id)}\n className=\"shrink-0 rounded p-0.5 text-zinc-400 transition-colors hover:text-zinc-600 dark:hover:text-zinc-300\"\n aria-label=\"Dismiss\"\n >\n <X size={14} />\n </button>\n </div>\n </div>\n );\n}\n\nToastItem.displayName = \"ToastItem\";\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Portal } from \"../Portal\";\nimport { ToastContext } from \"./Toast.context\";\nimport { ToastItem } from \"./ToastItem\";\nimport type { ToastData, ToastProviderProps } from \"./Toast.types\";\n\nconst POSITION_STYLES = {\n \"top-right\": \"top-4 right-4\",\n \"top-left\": \"top-4 left-4\",\n \"bottom-right\": \"bottom-4 right-4\",\n \"bottom-left\": \"bottom-4 left-4\",\n} as const;\n\nfunction ToastProvider({\n children,\n position = \"bottom-right\",\n maxToasts = 5,\n}: ToastProviderProps) {\n const [toasts, setToasts] = useState<ToastData[]>([]);\n const idCounter = useRef(0);\n\n const toast = useCallback(\n (data: Omit<ToastData, \"id\">) => {\n const id = `toast-${++idCounter.current}`;\n setToasts((prev) => [...prev.slice(-(maxToasts - 1)), { ...data, id }]);\n return id;\n },\n [maxToasts],\n );\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const ctx = useMemo(() => ({ toasts, toast, dismiss }), [toasts, toast, dismiss]);\n\n return (\n <ToastContext.Provider value={ctx}>\n {children}\n <Portal>\n <div\n data-react-fancy-toast=\"\"\n className={cn(\n \"fixed z-[100] flex flex-col gap-2 pointer-events-none\",\n POSITION_STYLES[position],\n )}\n >\n {toasts.map((t) => (\n <ToastItem key={t.id} data={t} onDismiss={dismiss} />\n ))}\n </div>\n </Portal>\n </ToastContext.Provider>\n );\n}\n\nexport const Toast = {\n Provider: ToastProvider,\n};\n"]}
|
package/dist/chunk-JICO4LTT.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { Portal } from './chunk-WHEXTDPV.js';
|
|
2
|
-
import { cn } from './chunk-MMW2JGKZ.js';
|
|
3
|
-
import { createContext, useContext, useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
4
|
-
import { Check, XCircle, AlertTriangle, Info, X } from 'lucide-react';
|
|
5
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
-
|
|
7
|
-
var ToastContext = createContext(null);
|
|
8
|
-
function useToast() {
|
|
9
|
-
const ctx = useContext(ToastContext);
|
|
10
|
-
if (!ctx) {
|
|
11
|
-
throw new Error("useToast must be used within a <Toast.Provider>");
|
|
12
|
-
}
|
|
13
|
-
return ctx;
|
|
14
|
-
}
|
|
15
|
-
var VARIANT_STYLES = {
|
|
16
|
-
default: "border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
|
|
17
|
-
success: "border-emerald-200 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950",
|
|
18
|
-
error: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950",
|
|
19
|
-
warning: "border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950",
|
|
20
|
-
info: "border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950"
|
|
21
|
-
};
|
|
22
|
-
var VARIANT_ICON_COLORS = {
|
|
23
|
-
default: "text-zinc-400",
|
|
24
|
-
success: "text-emerald-500",
|
|
25
|
-
error: "text-red-500",
|
|
26
|
-
warning: "text-amber-500",
|
|
27
|
-
info: "text-blue-500"
|
|
28
|
-
};
|
|
29
|
-
function ToastItem({ data, onDismiss }) {
|
|
30
|
-
const { id, title, description, variant = "default", action } = data;
|
|
31
|
-
const duration = data.duration ?? (action ? 0 : 5e3);
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
if (duration <= 0) return;
|
|
34
|
-
const timer = setTimeout(() => onDismiss(id), duration);
|
|
35
|
-
return () => clearTimeout(timer);
|
|
36
|
-
}, [id, duration, onDismiss]);
|
|
37
|
-
return /* @__PURE__ */ jsx(
|
|
38
|
-
"div",
|
|
39
|
-
{
|
|
40
|
-
"data-react-fancy-toast-item": "",
|
|
41
|
-
role: "alert",
|
|
42
|
-
onKeyDown: (e) => {
|
|
43
|
-
if (e.key === "Escape") onDismiss(id);
|
|
44
|
-
},
|
|
45
|
-
className: cn(
|
|
46
|
-
"fancy-toast-in pointer-events-auto w-80 rounded-xl border p-4 shadow-lg",
|
|
47
|
-
VARIANT_STYLES[variant]
|
|
48
|
-
),
|
|
49
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
50
|
-
/* @__PURE__ */ jsxs("div", { className: cn("mt-0.5 shrink-0", VARIANT_ICON_COLORS[variant]), children: [
|
|
51
|
-
variant === "success" && /* @__PURE__ */ jsx(Check, { size: 16 }),
|
|
52
|
-
variant === "error" && /* @__PURE__ */ jsx(XCircle, { size: 16 }),
|
|
53
|
-
variant === "warning" && /* @__PURE__ */ jsx(AlertTriangle, { size: 16 }),
|
|
54
|
-
variant === "info" && /* @__PURE__ */ jsx(Info, { size: 16 })
|
|
55
|
-
] }),
|
|
56
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
57
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: title }),
|
|
58
|
-
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-zinc-500 dark:text-zinc-400", children: description })
|
|
59
|
-
] }),
|
|
60
|
-
action && /* @__PURE__ */ jsx(
|
|
61
|
-
"button",
|
|
62
|
-
{
|
|
63
|
-
type: "button",
|
|
64
|
-
onClick: () => {
|
|
65
|
-
action.onClick();
|
|
66
|
-
onDismiss(id);
|
|
67
|
-
},
|
|
68
|
-
className: "shrink-0 self-center rounded-md px-2 py-1 text-xs font-medium text-zinc-700 underline-offset-2 transition-colors hover:bg-zinc-100 hover:underline dark:text-zinc-200 dark:hover:bg-zinc-800",
|
|
69
|
-
children: action.label
|
|
70
|
-
}
|
|
71
|
-
),
|
|
72
|
-
/* @__PURE__ */ jsx(
|
|
73
|
-
"button",
|
|
74
|
-
{
|
|
75
|
-
type: "button",
|
|
76
|
-
onClick: () => onDismiss(id),
|
|
77
|
-
className: "shrink-0 rounded p-0.5 text-zinc-400 transition-colors hover:text-zinc-600 dark:hover:text-zinc-300",
|
|
78
|
-
"aria-label": "Dismiss",
|
|
79
|
-
children: /* @__PURE__ */ jsx(X, { size: 14 })
|
|
80
|
-
}
|
|
81
|
-
)
|
|
82
|
-
] })
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
ToastItem.displayName = "ToastItem";
|
|
87
|
-
var POSITION_STYLES = {
|
|
88
|
-
"top-right": "top-4 right-4",
|
|
89
|
-
"top-left": "top-4 left-4",
|
|
90
|
-
"bottom-right": "bottom-4 right-4",
|
|
91
|
-
"bottom-left": "bottom-4 left-4"
|
|
92
|
-
};
|
|
93
|
-
function ToastProvider({
|
|
94
|
-
children,
|
|
95
|
-
position = "bottom-right",
|
|
96
|
-
maxToasts = 5
|
|
97
|
-
}) {
|
|
98
|
-
const [toasts, setToasts] = useState([]);
|
|
99
|
-
const idCounter = useRef(0);
|
|
100
|
-
const toast = useCallback(
|
|
101
|
-
(data) => {
|
|
102
|
-
const id = `toast-${++idCounter.current}`;
|
|
103
|
-
setToasts((prev) => [...prev.slice(-(maxToasts - 1)), { ...data, id }]);
|
|
104
|
-
return id;
|
|
105
|
-
},
|
|
106
|
-
[maxToasts]
|
|
107
|
-
);
|
|
108
|
-
const dismiss = useCallback((id) => {
|
|
109
|
-
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
110
|
-
}, []);
|
|
111
|
-
const ctx = useMemo(() => ({ toasts, toast, dismiss }), [toasts, toast, dismiss]);
|
|
112
|
-
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: ctx, children: [
|
|
113
|
-
children,
|
|
114
|
-
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
|
|
115
|
-
"div",
|
|
116
|
-
{
|
|
117
|
-
"data-react-fancy-toast": "",
|
|
118
|
-
className: cn(
|
|
119
|
-
"fixed z-[100] flex flex-col gap-2 pointer-events-none",
|
|
120
|
-
POSITION_STYLES[position]
|
|
121
|
-
),
|
|
122
|
-
children: toasts.map((t) => /* @__PURE__ */ jsx(ToastItem, { data: t, onDismiss: dismiss }, t.id))
|
|
123
|
-
}
|
|
124
|
-
) })
|
|
125
|
-
] });
|
|
126
|
-
}
|
|
127
|
-
var Toast = {
|
|
128
|
-
Provider: ToastProvider
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export { Toast, useToast };
|
|
132
|
-
//# sourceMappingURL=chunk-JICO4LTT.js.map
|
|
133
|
-
//# sourceMappingURL=chunk-JICO4LTT.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Toast/Toast.context.ts","../src/components/Toast/ToastItem.tsx","../src/components/Toast/Toast.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"chunk-JICO4LTT.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { ToastContextValue } from \"./Toast.types\";\n\nexport const ToastContext = createContext<ToastContextValue | null>(null);\n\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext);\n if (!ctx) {\n throw new Error(\"useToast must be used within a <Toast.Provider>\");\n }\n return ctx;\n}\n","import { useEffect } from \"react\";\nimport { AlertTriangle, Check, Info, X, XCircle } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type { ToastItemProps } from \"./Toast.types\";\n\nconst VARIANT_STYLES = {\n default:\n \"border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900\",\n success:\n \"border-emerald-200 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950\",\n error:\n \"border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950\",\n warning:\n \"border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950\",\n info: \"border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950\",\n} as const;\n\nconst VARIANT_ICON_COLORS = {\n default: \"text-zinc-400\",\n success: \"text-emerald-500\",\n error: \"text-red-500\",\n warning: \"text-amber-500\",\n info: \"text-blue-500\",\n} as const;\n\nexport function ToastItem({ data, onDismiss }: ToastItemProps) {\n const { id, title, description, variant = \"default\", action } = data;\n // An action toast does not expire by default.\n const duration = data.duration ?? (action ? 0 : 5000);\n\n useEffect(() => {\n if (duration <= 0) return;\n const timer = setTimeout(() => onDismiss(id), duration);\n return () => clearTimeout(timer);\n }, [id, duration, onDismiss]);\n\n return (\n <div\n data-react-fancy-toast-item=\"\"\n role=\"alert\"\n // Scoped to the toast rather than the document: a global Escape handler\n // would fight whatever modal or drawer is already listening.\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onDismiss(id);\n }}\n className={cn(\n \"fancy-toast-in pointer-events-auto w-80 rounded-xl border p-4 shadow-lg\",\n VARIANT_STYLES[variant],\n )}\n >\n <div className=\"flex items-start gap-3\">\n <div className={cn(\"mt-0.5 shrink-0\", VARIANT_ICON_COLORS[variant])}>\n {variant === \"success\" && <Check size={16} />}\n {variant === \"error\" && <XCircle size={16} />}\n {variant === \"warning\" && <AlertTriangle size={16} />}\n {variant === \"info\" && <Info size={16} />}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-zinc-900 dark:text-zinc-100\">{title}</p>\n {description && (\n <p className=\"mt-1 text-xs text-zinc-500 dark:text-zinc-400\">\n {description}\n </p>\n )}\n </div>\n {action && (\n <button\n type=\"button\"\n onClick={() => {\n action.onClick();\n // The offer is consumed; leaving it up invites undoing an\n // already-undone action.\n onDismiss(id);\n }}\n className=\"shrink-0 self-center rounded-md px-2 py-1 text-xs font-medium text-zinc-700 underline-offset-2 transition-colors hover:bg-zinc-100 hover:underline dark:text-zinc-200 dark:hover:bg-zinc-800\"\n >\n {action.label}\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onDismiss(id)}\n className=\"shrink-0 rounded p-0.5 text-zinc-400 transition-colors hover:text-zinc-600 dark:hover:text-zinc-300\"\n aria-label=\"Dismiss\"\n >\n <X size={14} />\n </button>\n </div>\n </div>\n );\n}\n\nToastItem.displayName = \"ToastItem\";\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Portal } from \"../Portal\";\nimport { ToastContext } from \"./Toast.context\";\nimport { ToastItem } from \"./ToastItem\";\nimport type { ToastData, ToastProviderProps } from \"./Toast.types\";\n\nconst POSITION_STYLES = {\n \"top-right\": \"top-4 right-4\",\n \"top-left\": \"top-4 left-4\",\n \"bottom-right\": \"bottom-4 right-4\",\n \"bottom-left\": \"bottom-4 left-4\",\n} as const;\n\nfunction ToastProvider({\n children,\n position = \"bottom-right\",\n maxToasts = 5,\n}: ToastProviderProps) {\n const [toasts, setToasts] = useState<ToastData[]>([]);\n const idCounter = useRef(0);\n\n const toast = useCallback(\n (data: Omit<ToastData, \"id\">) => {\n const id = `toast-${++idCounter.current}`;\n setToasts((prev) => [...prev.slice(-(maxToasts - 1)), { ...data, id }]);\n return id;\n },\n [maxToasts],\n );\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const ctx = useMemo(() => ({ toasts, toast, dismiss }), [toasts, toast, dismiss]);\n\n return (\n <ToastContext.Provider value={ctx}>\n {children}\n <Portal>\n <div\n data-react-fancy-toast=\"\"\n className={cn(\n \"fixed z-[100] flex flex-col gap-2 pointer-events-none\",\n POSITION_STYLES[position],\n )}\n >\n {toasts.map((t) => (\n <ToastItem key={t.id} data={t} onDismiss={dismiss} />\n ))}\n </div>\n </Portal>\n </ToastContext.Provider>\n );\n}\n\nexport const Toast = {\n Provider: ToastProvider,\n};\n"]}
|