@jbpark/ui-kit 3.8.0 → 4.0.0
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/dist/components/atoms/float-button/back-top.d.mts.map +1 -1
- package/dist/components/atoms/float-button/back-top.mjs +3 -1
- package/dist/components/atoms/float-button/back-top.mjs.map +1 -1
- package/dist/components/atoms/input/search.d.mts.map +1 -1
- package/dist/components/atoms/input/search.mjs +3 -1
- package/dist/components/atoms/input/search.mjs.map +1 -1
- package/dist/components/atoms/skeleton/skeleton.d.mts.map +1 -1
- package/dist/components/atoms/skeleton/skeleton.mjs +5 -1
- package/dist/components/atoms/skeleton/skeleton.mjs.map +1 -1
- package/dist/components/atoms/spin.d.mts.map +1 -1
- package/dist/components/atoms/spin.mjs +7 -2
- package/dist/components/atoms/spin.mjs.map +1 -1
- package/dist/components/organisms/drawer.d.mts.map +1 -1
- package/dist/components/organisms/drawer.mjs +3 -1
- package/dist/components/organisms/drawer.mjs.map +1 -1
- package/dist/components/organisms/imperative-stack.mjs +106 -0
- package/dist/components/organisms/imperative-stack.mjs.map +1 -0
- package/dist/components/organisms/index.d.mts +3 -1
- package/dist/components/organisms/list/index.d.mts +1 -1
- package/dist/components/organisms/list/index.mjs.map +1 -1
- package/dist/components/organisms/list/list.d.mts +2 -2
- package/dist/components/organisms/list/list.d.mts.map +1 -1
- package/dist/components/organisms/list/list.mjs +20 -11
- package/dist/components/organisms/list/list.mjs.map +1 -1
- package/dist/components/organisms/modal.d.mts +2 -2
- package/dist/components/organisms/modal.d.mts.map +1 -1
- package/dist/components/organisms/modal.mjs +21 -101
- package/dist/components/organisms/modal.mjs.map +1 -1
- package/dist/components/organisms/swiper/index.d.mts +1 -1
- package/dist/components/organisms/swiper/index.mjs.map +1 -1
- package/dist/components/organisms/swiper/swiper.d.mts +2 -1
- package/dist/components/organisms/swiper/swiper.d.mts.map +1 -1
- package/dist/components/organisms/swiper/swiper.mjs +5 -3
- package/dist/components/organisms/swiper/swiper.mjs.map +1 -1
- package/dist/components/organisms/toast.d.mts +1 -1
- package/dist/components/organisms/toast.d.mts.map +1 -1
- package/dist/components/organisms/toast.mjs +35 -111
- package/dist/components/organisms/toast.mjs.map +1 -1
- package/dist/components/templates/container.d.mts +19 -0
- package/dist/components/templates/container.d.mts.map +1 -0
- package/dist/components/templates/container.mjs +32 -0
- package/dist/components/templates/container.mjs.map +1 -0
- package/dist/components/templates/empty.d.mts +20 -0
- package/dist/components/templates/empty.d.mts.map +1 -0
- package/dist/components/templates/empty.mjs +34 -0
- package/dist/components/templates/empty.mjs.map +1 -0
- package/dist/components/templates/grid/col.d.mts +35 -0
- package/dist/components/templates/grid/col.d.mts.map +1 -0
- package/dist/components/templates/grid/col.mjs +55 -0
- package/dist/components/templates/grid/col.mjs.map +1 -0
- package/dist/components/templates/grid/index.d.mts +2 -0
- package/dist/components/templates/grid/row-context.mjs +13 -0
- package/dist/components/templates/grid/row-context.mjs.map +1 -0
- package/dist/components/templates/grid/row.d.mts +36 -0
- package/dist/components/templates/grid/row.d.mts.map +1 -0
- package/dist/components/templates/grid/row.mjs +54 -0
- package/dist/components/templates/grid/row.mjs.map +1 -0
- package/dist/components/templates/index.d.mts +13 -1
- package/dist/components/templates/layout/content.d.mts +4 -1
- package/dist/components/templates/layout/content.d.mts.map +1 -1
- package/dist/components/templates/layout/content.mjs +3 -2
- package/dist/components/templates/layout/content.mjs.map +1 -1
- package/dist/components/templates/layout/footer.d.mts +1 -1
- package/dist/components/templates/layout/footer.d.mts.map +1 -1
- package/dist/components/templates/layout/footer.mjs.map +1 -1
- package/dist/components/templates/layout/header.d.mts +4 -1
- package/dist/components/templates/layout/header.d.mts.map +1 -1
- package/dist/components/templates/layout/header.mjs +2 -2
- package/dist/components/templates/layout/header.mjs.map +1 -1
- package/dist/components/templates/layout/layout.d.mts +1 -1
- package/dist/components/templates/layout/layout.d.mts.map +1 -1
- package/dist/components/templates/layout/layout.mjs.map +1 -1
- package/dist/components/templates/layout/sider.d.mts +9 -2
- package/dist/components/templates/layout/sider.d.mts.map +1 -1
- package/dist/components/templates/layout/sider.mjs +40 -13
- package/dist/components/templates/layout/sider.mjs.map +1 -1
- package/dist/components/templates/page-header.d.mts +30 -0
- package/dist/components/templates/page-header.d.mts.map +1 -0
- package/dist/components/templates/page-header.mjs +45 -0
- package/dist/components/templates/page-header.mjs.map +1 -0
- package/dist/components/templates/result.d.mts +24 -0
- package/dist/components/templates/result.d.mts.map +1 -0
- package/dist/components/templates/result.mjs +46 -0
- package/dist/components/templates/result.mjs.map +1 -0
- package/dist/index.d.mts +28 -15
- package/dist/index.mjs +9 -3
- package/dist/providers/Config/context.d.mts +3 -2
- package/dist/providers/Config/context.d.mts.map +1 -1
- package/dist/providers/Config/context.mjs +13 -2
- package/dist/providers/Config/context.mjs.map +1 -1
- package/dist/providers/Config/index.d.mts +4 -2
- package/dist/providers/Config/index.d.mts.map +1 -1
- package/dist/providers/Config/index.mjs +14 -4
- package/dist/providers/Config/index.mjs.map +1 -1
- package/dist/providers/Config/types.d.mts +10 -1
- package/dist/providers/Config/types.d.mts.map +1 -1
- package/dist/providers.d.mts +4 -0
- package/dist/providers.mjs +4 -0
- package/dist/style.css +114 -0
- package/package.json +3 -3
- package/dist/providers/index.d.mts +0 -3
|
@@ -3,42 +3,14 @@
|
|
|
3
3
|
import { cn } from "../../utils.mjs";
|
|
4
4
|
import { dialog_exports } from "../../core/dialog.mjs";
|
|
5
5
|
import Button from "../../Button.mjs";
|
|
6
|
+
import { createImperativeStack, isBrowser } from "./imperative-stack.mjs";
|
|
6
7
|
import { Check, CircleQuestionMark, Info, OctagonAlert, OctagonX } from "lucide-react";
|
|
7
|
-
import React, {
|
|
8
|
+
import React, { useState } from "react";
|
|
8
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
-
import { v4 } from "uuid";
|
|
10
10
|
import { createPortal } from "react-dom";
|
|
11
|
-
import { createRoot } from "react-dom/client";
|
|
12
11
|
|
|
13
12
|
//#region src/components/organisms/modal.tsx
|
|
14
13
|
const { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } = dialog_exports;
|
|
15
|
-
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
16
|
-
const containerStates = /* @__PURE__ */ new Map();
|
|
17
|
-
const modalRootElements = /* @__PURE__ */ new WeakMap();
|
|
18
|
-
const getContainerState = (container) => {
|
|
19
|
-
let state = containerStates.get(container);
|
|
20
|
-
if (!state) {
|
|
21
|
-
state = {
|
|
22
|
-
stack: [],
|
|
23
|
-
update: null
|
|
24
|
-
};
|
|
25
|
-
containerStates.set(container, state);
|
|
26
|
-
}
|
|
27
|
-
return state;
|
|
28
|
-
};
|
|
29
|
-
const createModalRoot = (container) => {
|
|
30
|
-
if (!isBrowser) return null;
|
|
31
|
-
const targetContainer = container || document.body;
|
|
32
|
-
let rootEl = modalRootElements.get(targetContainer);
|
|
33
|
-
if (!rootEl) {
|
|
34
|
-
rootEl = document.createElement("div");
|
|
35
|
-
rootEl.style.zIndex = "10000";
|
|
36
|
-
rootEl.style.position = "absolute";
|
|
37
|
-
targetContainer.appendChild(rootEl);
|
|
38
|
-
modalRootElements.set(targetContainer, rootEl);
|
|
39
|
-
}
|
|
40
|
-
return rootEl;
|
|
41
|
-
};
|
|
42
14
|
const Modal = ({ open = false, maskClosable = false, closable = false, closeIcon, className, classNames, style, title, content, footer, container, children, okText = "OK", cancelText = "Cancel", onOk, onCancel, ...props }) => {
|
|
43
15
|
if (typeof window === "undefined") return null;
|
|
44
16
|
return /* @__PURE__ */ jsx(Dialog, {
|
|
@@ -91,13 +63,13 @@ const STATIC_ICONS = {
|
|
|
91
63
|
warning: /* @__PURE__ */ jsx(OctagonAlert, { className: "text-yellow-400" }),
|
|
92
64
|
confirm: /* @__PURE__ */ jsx(CircleQuestionMark, {})
|
|
93
65
|
};
|
|
94
|
-
const StaticModal = ({ type, title, content, okText = "OK", cancelText = "Cancel",
|
|
66
|
+
const StaticModal = ({ id, type, title, content, okText = "OK", cancelText = "Cancel", container, icon, onOk, onCancel, ...props }) => {
|
|
95
67
|
const [open, setOpen] = useState(true);
|
|
96
68
|
const closeModal = (callback) => {
|
|
97
69
|
callback?.();
|
|
98
70
|
setOpen(false);
|
|
99
71
|
setTimeout(() => {
|
|
100
|
-
|
|
72
|
+
modalStack.destroy(id);
|
|
101
73
|
}, 200);
|
|
102
74
|
};
|
|
103
75
|
const footer = type === "confirm" ? /* @__PURE__ */ jsxs("div", {
|
|
@@ -135,90 +107,38 @@ const StaticModal = ({ type, title, content, okText = "OK", cancelText = "Cancel
|
|
|
135
107
|
onCancel: () => closeModal(onCancel),
|
|
136
108
|
...props,
|
|
137
109
|
children: content
|
|
138
|
-
}),
|
|
139
|
-
};
|
|
140
|
-
const ModalStackRenderer = ({ container }) => {
|
|
141
|
-
const [, forceUpdate] = useState({});
|
|
142
|
-
useEffect(() => {
|
|
143
|
-
const state = getContainerState(container);
|
|
144
|
-
state.update = () => forceUpdate({});
|
|
145
|
-
return () => {
|
|
146
|
-
state.update = null;
|
|
147
|
-
};
|
|
148
|
-
}, [container]);
|
|
149
|
-
const { stack } = getContainerState(container);
|
|
150
|
-
return /* @__PURE__ */ jsx(Fragment$1, { children: stack.map(({ id, ...props }) => /* @__PURE__ */ jsx(StaticModal, {
|
|
151
|
-
id,
|
|
152
|
-
...props
|
|
153
|
-
}, id)) });
|
|
154
|
-
};
|
|
155
|
-
const modalRoots = /* @__PURE__ */ new Map();
|
|
156
|
-
const renderModal = (props) => {
|
|
157
|
-
if (!isBrowser) return;
|
|
158
|
-
const targetContainer = props.container || document.body;
|
|
159
|
-
const rootElement = createModalRoot(targetContainer);
|
|
160
|
-
if (!modalRoots.has(targetContainer)) {
|
|
161
|
-
const root = createRoot(rootElement);
|
|
162
|
-
modalRoots.set(targetContainer, root);
|
|
163
|
-
root.render(/* @__PURE__ */ jsx(ModalStackRenderer, { container: targetContainer }));
|
|
164
|
-
}
|
|
165
|
-
const state = getContainerState(targetContainer);
|
|
166
|
-
const id = props.id || v4();
|
|
167
|
-
state.stack.push({
|
|
168
|
-
...props,
|
|
169
|
-
id
|
|
170
|
-
});
|
|
171
|
-
state.update?.();
|
|
172
|
-
return id;
|
|
173
|
-
};
|
|
174
|
-
Modal.destroy = (id) => {
|
|
175
|
-
if (!id) {
|
|
176
|
-
containerStates.forEach((state) => {
|
|
177
|
-
state.stack = [];
|
|
178
|
-
state.update?.();
|
|
179
|
-
});
|
|
180
|
-
modalRoots.forEach((root, container) => {
|
|
181
|
-
root.unmount();
|
|
182
|
-
modalRootElements.get(container)?.remove();
|
|
183
|
-
modalRootElements.delete(container);
|
|
184
|
-
});
|
|
185
|
-
modalRoots.clear();
|
|
186
|
-
containerStates.clear();
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
containerStates.forEach((state, container) => {
|
|
190
|
-
if (!state.stack.some((modal) => modal.id === id)) return;
|
|
191
|
-
state.stack = state.stack.filter((modal) => modal.id !== id);
|
|
192
|
-
state.update?.();
|
|
193
|
-
if (!state.stack.length) {
|
|
194
|
-
modalRoots.get(container)?.unmount();
|
|
195
|
-
modalRoots.delete(container);
|
|
196
|
-
containerStates.delete(container);
|
|
197
|
-
modalRootElements.get(container)?.remove();
|
|
198
|
-
modalRootElements.delete(container);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
110
|
+
}), modalStack.getRootElement(container));
|
|
201
111
|
};
|
|
112
|
+
const modalStack = createImperativeStack({
|
|
113
|
+
createRootElement: () => {
|
|
114
|
+
const el = document.createElement("div");
|
|
115
|
+
el.style.zIndex = "10000";
|
|
116
|
+
el.style.position = "absolute";
|
|
117
|
+
return el;
|
|
118
|
+
},
|
|
119
|
+
StackItem: StaticModal
|
|
120
|
+
});
|
|
121
|
+
Modal.destroy = modalStack.destroy;
|
|
202
122
|
Modal.destroyAll = () => {
|
|
203
|
-
|
|
123
|
+
modalStack.destroy();
|
|
204
124
|
};
|
|
205
|
-
Modal.info = (props) =>
|
|
125
|
+
Modal.info = (props) => modalStack.render({
|
|
206
126
|
type: "info",
|
|
207
127
|
...props
|
|
208
128
|
});
|
|
209
|
-
Modal.success = (props) =>
|
|
129
|
+
Modal.success = (props) => modalStack.render({
|
|
210
130
|
type: "success",
|
|
211
131
|
...props
|
|
212
132
|
});
|
|
213
|
-
Modal.error = (props) =>
|
|
133
|
+
Modal.error = (props) => modalStack.render({
|
|
214
134
|
type: "error",
|
|
215
135
|
...props
|
|
216
136
|
});
|
|
217
|
-
Modal.warning = (props) =>
|
|
137
|
+
Modal.warning = (props) => modalStack.render({
|
|
218
138
|
type: "warning",
|
|
219
139
|
...props
|
|
220
140
|
});
|
|
221
|
-
Modal.confirm = (props) =>
|
|
141
|
+
Modal.confirm = (props) => modalStack.render({
|
|
222
142
|
type: "confirm",
|
|
223
143
|
...props
|
|
224
144
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.mjs","names":["dialog","uuid"],"sources":["../../../src/components/organisms/modal.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Root, createRoot } from 'react-dom/client';\n\nimport {\n Check,\n CircleQuestionMark,\n Info,\n OctagonAlert,\n OctagonX,\n} from 'lucide-react';\nimport { v4 as uuid } from 'uuid';\n\nimport { dialog } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\n\nconst {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} = dialog;\n\ninterface Props {\n open?: boolean;\n maskClosable?: boolean;\n closable?:\n | boolean\n | {\n closeIcon?: React.ReactNode;\n disabled?: boolean;\n };\n closeIcon?: React.ReactNode;\n title?: React.ReactNode;\n content?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n classNames?: {\n mask?: string;\n header?: string;\n body?: string;\n footer?: string;\n };\n style?: React.CSSProperties;\n okText?: string;\n cancelText?: string;\n container?: HTMLElement;\n children?: React.ReactNode;\n onOk?: () => void;\n onCancel?: () => void;\n}\n\ninterface StaticProps extends Props {\n type?: 'info' | 'success' | 'error' | 'warning' | 'confirm';\n id?: string;\n icon?: React.ReactNode;\n container?: HTMLElement;\n}\n\nconst isBrowser =\n typeof window !== 'undefined' && typeof document !== 'undefined';\n\ntype ContainerState = {\n stack: StaticProps[];\n update: (() => void) | null;\n};\n\nconst containerStates = new Map<HTMLElement, ContainerState>();\nconst modalRootElements = new WeakMap<HTMLElement, HTMLElement>();\n\nconst getContainerState = (container: HTMLElement): ContainerState => {\n let state = containerStates.get(container);\n\n if (!state) {\n state = { stack: [], update: null };\n containerStates.set(container, state);\n }\n\n return state;\n};\n\n// No `role`/`aria-modal` here — this element is only a mount point for the\n// imperative stack, not the dialog itself. Radix already renders its own\n// `role=\"dialog\"`/`aria-modal=\"true\"` on the actual `DialogContent` via\n// portal once a modal is open. Setting it here as well would (a) leave\n// `aria-modal=\"true\"` on the page permanently, even with zero modals open,\n// hiding the rest of the document from screen readers, and (b) duplicate\n// Radix's own dialog role once one is open.\nconst createModalRoot = (container?: HTMLElement) => {\n if (!isBrowser) {\n return null;\n }\n\n const targetContainer = container || document.body;\n let rootEl = modalRootElements.get(targetContainer);\n\n if (!rootEl) {\n rootEl = document.createElement('div');\n rootEl.style.zIndex = '10000';\n rootEl.style.position = 'absolute';\n targetContainer.appendChild(rootEl);\n modalRootElements.set(targetContainer, rootEl);\n }\n\n return rootEl;\n};\n\nconst Modal = ({\n open = false,\n maskClosable = false,\n closable = false,\n closeIcon,\n className,\n classNames,\n style,\n title,\n content,\n footer,\n container,\n children,\n okText = 'OK',\n cancelText = 'Cancel',\n onOk,\n onCancel,\n ...props\n}: Props) => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(open: boolean) => {\n if (!open) {\n onCancel?.();\n }\n }}\n {...props}\n >\n <DialogContent\n className={cn(\n 'rounded-lg p-4 max-sm:max-w-[80%]',\n 'border-none outline-none',\n className,\n )}\n classNames={{\n ...classNames,\n mask: cn('bg-black/60', classNames?.mask),\n }}\n style={style}\n closable={closable}\n closeIcon={closeIcon}\n container={container}\n onPointerDownOutside={event => {\n if (!maskClosable) {\n event.preventDefault();\n }\n }}\n >\n {/**\n * @todo [Dialog & AlertDialog] fix: can't get id correctly in shadow dom\n * @see https://github.com/radix-ui/primitives/pull/3384\n **/}\n <DialogHeader\n className={cn(\n classNames?.header,\n !title && 'hidden',\n //\n )}\n >\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription className=\"hidden\" />\n </DialogHeader>\n <div className={cn('break-all', classNames?.body)}>\n {children ?? content}\n </div>\n {footer !== null && (\n <DialogFooter\n className={cn('flex-row justify-end gap-x-2', classNames?.footer)}\n >\n {footer || (\n <>\n <Button onClick={onOk}>{okText}</Button>\n <Button variant=\"outlined\" onClick={onCancel}>\n {cancelText}\n </Button>\n </>\n )}\n </DialogFooter>\n )}\n </DialogContent>\n </Dialog>\n );\n};\n\nconst STATIC_ICONS = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n confirm: <CircleQuestionMark />,\n};\n\nconst StaticModal = ({\n type,\n title,\n content,\n okText = 'OK',\n cancelText = 'Cancel',\n id,\n container,\n icon,\n onOk,\n onCancel,\n ...props\n}: StaticProps) => {\n const [open, setOpen] = useState(true);\n\n const closeModal = (callback?: () => void) => {\n callback?.();\n setOpen(false);\n setTimeout(() => {\n Modal.destroy(id);\n }, 200);\n };\n\n const footer =\n type === 'confirm' ? (\n <div className=\"grid w-full grid-cols-5 gap-x-2\">\n <Button\n variant=\"outlined\"\n className=\"col-span-2\"\n onClick={() => closeModal(onCancel)}\n >\n {cancelText}\n </Button>\n <Button className=\"col-span-3\" onClick={() => closeModal(onOk)}>\n {okText}\n </Button>\n </div>\n ) : (\n <Button\n className={cn(\n 'grow',\n //\n )}\n onClick={() => closeModal(onOk)}\n >\n {okText}\n </Button>\n );\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <Modal\n open={open}\n footer={footer}\n className={cn(\n 'z-10000',\n 'box-content w-100',\n 'rounded-3xl p-4',\n 'gap-y-0',\n )}\n classNames={{\n mask: 'z-10000 bg-black/[.6]',\n body: cn(\n 'text-black-70 whitespace-pre-wrap text-center',\n content && 'mt-3',\n ),\n footer: 'mt-9',\n }}\n title={\n <p\n className={cn(\n 'text-center text-lg leading-normal whitespace-pre-wrap',\n 'flex items-center justify-center gap-x-2',\n //\n )}\n >\n {icon || (type && STATIC_ICONS[type])}\n {title}\n </p>\n }\n container={container}\n onCancel={() => closeModal(onCancel)}\n {...props}\n >\n {content}\n </Modal>,\n createModalRoot(container)!,\n );\n};\n\nconst ModalStackRenderer = ({ container }: { container: HTMLElement }) => {\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n const state = getContainerState(container);\n state.update = () => forceUpdate({});\n return () => {\n state.update = null;\n };\n }, [container]);\n\n const { stack } = getContainerState(container);\n\n return (\n <>\n {stack.map(({ id, ...props }) => (\n <StaticModal key={id} id={id} {...props} />\n ))}\n </>\n );\n};\n\nconst modalRoots = new Map<HTMLElement, Root>();\n\nconst renderModal = (props: StaticProps) => {\n if (!isBrowser) {\n return;\n }\n\n const targetContainer = props.container || document.body;\n const rootElement = createModalRoot(targetContainer)!;\n\n if (!modalRoots.has(targetContainer)) {\n const root = createRoot(rootElement);\n modalRoots.set(targetContainer, root);\n root.render(<ModalStackRenderer container={targetContainer} />);\n }\n\n const state = getContainerState(targetContainer);\n const id = props.id || uuid();\n state.stack.push({ ...props, id });\n state.update?.();\n\n return id;\n};\n\nModal.destroy = (id?: string) => {\n if (!id) {\n containerStates.forEach(state => {\n state.stack = [];\n state.update?.();\n });\n modalRoots.forEach((root, container) => {\n root.unmount();\n modalRootElements.get(container)?.remove();\n modalRootElements.delete(container);\n });\n modalRoots.clear();\n containerStates.clear();\n return;\n }\n\n containerStates.forEach((state, container) => {\n if (!state.stack.some(modal => modal.id === id)) {\n return;\n }\n\n state.stack = state.stack.filter(modal => modal.id !== id);\n state.update?.();\n\n if (!state.stack.length) {\n modalRoots.get(container)?.unmount();\n modalRoots.delete(container);\n containerStates.delete(container);\n modalRootElements.get(container)?.remove();\n modalRootElements.delete(container);\n }\n });\n};\n\nModal.destroyAll = () => {\n Modal.destroy();\n};\n\nModal.info = (props: StaticProps) => renderModal({ type: 'info', ...props });\nModal.success = (props: StaticProps) =>\n renderModal({ type: 'success', ...props });\nModal.error = (props: StaticProps) => renderModal({ type: 'error', ...props });\nModal.warning = (props: StaticProps) =>\n renderModal({ type: 'warning', ...props });\nModal.confirm = (props: StaticProps) =>\n renderModal({ type: 'confirm', ...props });\n\nexport default Modal;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"modal.mjs","names":["dialog"],"sources":["../../../src/components/organisms/modal.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport {\n Check,\n CircleQuestionMark,\n Info,\n OctagonAlert,\n OctagonX,\n} from 'lucide-react';\n\nimport { dialog } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\nimport {\n type ImperativeStack,\n createImperativeStack,\n isBrowser,\n} from './imperative-stack';\n\nconst {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} = dialog;\n\nexport interface Props {\n open?: boolean;\n maskClosable?: boolean;\n closable?:\n | boolean\n | {\n closeIcon?: React.ReactNode;\n disabled?: boolean;\n };\n closeIcon?: React.ReactNode;\n title?: React.ReactNode;\n content?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n classNames?: {\n mask?: string;\n header?: string;\n body?: string;\n footer?: string;\n };\n style?: React.CSSProperties;\n okText?: string;\n cancelText?: string;\n container?: HTMLElement;\n children?: React.ReactNode;\n onOk?: () => void;\n onCancel?: () => void;\n}\n\ninterface StaticProps extends Props {\n type?: 'info' | 'success' | 'error' | 'warning' | 'confirm';\n id?: string;\n icon?: React.ReactNode;\n container?: HTMLElement;\n}\n\nconst Modal = ({\n open = false,\n maskClosable = false,\n closable = false,\n closeIcon,\n className,\n classNames,\n style,\n title,\n content,\n footer,\n container,\n children,\n okText = 'OK',\n cancelText = 'Cancel',\n onOk,\n onCancel,\n ...props\n}: Props) => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(open: boolean) => {\n if (!open) {\n onCancel?.();\n }\n }}\n {...props}\n >\n <DialogContent\n className={cn(\n 'rounded-lg p-4 max-sm:max-w-[80%]',\n 'border-none outline-none',\n className,\n )}\n classNames={{\n ...classNames,\n mask: cn('bg-black/60', classNames?.mask),\n }}\n style={style}\n closable={closable}\n closeIcon={closeIcon}\n container={container}\n onPointerDownOutside={event => {\n if (!maskClosable) {\n event.preventDefault();\n }\n }}\n >\n {/**\n * @todo [Dialog & AlertDialog] fix: can't get id correctly in shadow dom\n * @see https://github.com/radix-ui/primitives/pull/3384\n **/}\n <DialogHeader\n className={cn(\n classNames?.header,\n !title && 'hidden',\n //\n )}\n >\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription className=\"hidden\" />\n </DialogHeader>\n <div className={cn('break-all', classNames?.body)}>\n {children ?? content}\n </div>\n {footer !== null && (\n <DialogFooter\n className={cn('flex-row justify-end gap-x-2', classNames?.footer)}\n >\n {footer || (\n <>\n <Button onClick={onOk}>{okText}</Button>\n <Button variant=\"outlined\" onClick={onCancel}>\n {cancelText}\n </Button>\n </>\n )}\n </DialogFooter>\n )}\n </DialogContent>\n </Dialog>\n );\n};\n\nconst STATIC_ICONS = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n confirm: <CircleQuestionMark />,\n};\n\nconst StaticModal = ({\n id,\n type,\n title,\n content,\n okText = 'OK',\n cancelText = 'Cancel',\n container,\n icon,\n onOk,\n onCancel,\n ...props\n}: StaticProps & { id: string }): React.ReactPortal | null => {\n const [open, setOpen] = useState(true);\n\n const closeModal = (callback?: () => void) => {\n callback?.();\n setOpen(false);\n setTimeout(() => {\n modalStack.destroy(id);\n }, 200);\n };\n\n const footer =\n type === 'confirm' ? (\n <div className=\"grid w-full grid-cols-5 gap-x-2\">\n <Button\n variant=\"outlined\"\n className=\"col-span-2\"\n onClick={() => closeModal(onCancel)}\n >\n {cancelText}\n </Button>\n <Button className=\"col-span-3\" onClick={() => closeModal(onOk)}>\n {okText}\n </Button>\n </div>\n ) : (\n <Button\n className={cn(\n 'grow',\n //\n )}\n onClick={() => closeModal(onOk)}\n >\n {okText}\n </Button>\n );\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <Modal\n open={open}\n footer={footer}\n className={cn(\n 'z-10000',\n 'box-content w-100',\n 'rounded-3xl p-4',\n 'gap-y-0',\n )}\n classNames={{\n mask: 'z-10000 bg-black/[.6]',\n body: cn(\n 'text-black-70 whitespace-pre-wrap text-center',\n content && 'mt-3',\n ),\n footer: 'mt-9',\n }}\n title={\n <p\n className={cn(\n 'text-center text-lg leading-normal whitespace-pre-wrap',\n 'flex items-center justify-center gap-x-2',\n //\n )}\n >\n {icon || (type && STATIC_ICONS[type])}\n {title}\n </p>\n }\n container={container}\n onCancel={() => closeModal(onCancel)}\n {...props}\n >\n {content}\n </Modal>,\n modalStack.getRootElement(container)!,\n );\n};\n\n// No `role`/`aria-modal` here — this element is only a mount point for the\n// imperative stack, not the dialog itself. Radix already renders its own\n// `role=\"dialog\"`/`aria-modal=\"true\"` on the actual `DialogContent` via\n// portal once a modal is open. Setting it here as well would (a) leave\n// `aria-modal=\"true\"` on the page permanently, even with zero modals open,\n// hiding the rest of the document from screen readers, and (b) duplicate\n// Radix's own dialog role once one is open.\nconst modalStack: ImperativeStack<StaticProps> =\n createImperativeStack<StaticProps>({\n createRootElement: () => {\n const el = document.createElement('div');\n el.style.zIndex = '10000';\n el.style.position = 'absolute';\n return el;\n },\n StackItem: StaticModal,\n });\n\nModal.destroy = modalStack.destroy;\n\nModal.destroyAll = () => {\n modalStack.destroy();\n};\n\nModal.info = (props: StaticProps) =>\n modalStack.render({ type: 'info', ...props });\nModal.success = (props: StaticProps) =>\n modalStack.render({ type: 'success', ...props });\nModal.error = (props: StaticProps) =>\n modalStack.render({ type: 'error', ...props });\nModal.warning = (props: StaticProps) =>\n modalStack.render({ type: 'warning', ...props });\nModal.confirm = (props: StaticProps) =>\n modalStack.render({ type: 'confirm', ...props });\n\nexport default Modal;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["SwiperImpl"],"sources":["../../../../src/components/organisms/swiper/index.ts"],"sourcesContent":["import Slide from './slide';\nimport SwiperImpl, { initialOptions } from './swiper';\n\ntype SwiperComponent = typeof SwiperImpl & { Slide: typeof Slide };\n\nconst Swiper = SwiperImpl as SwiperComponent;\n\nSwiper.Slide = Slide;\n\nexport default Swiper;\nexport { initialOptions };\n"],"mappings":";;;;AAKA,MAAM,SAASA;AAEf,OAAO,QAAQ"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["SwiperImpl"],"sources":["../../../../src/components/organisms/swiper/index.ts"],"sourcesContent":["import Slide from './slide';\nimport SwiperImpl, { initialOptions } from './swiper';\n\ntype SwiperComponent = typeof SwiperImpl & { Slide: typeof Slide };\n\nconst Swiper = SwiperImpl as SwiperComponent;\n\nSwiper.Slide = Slide;\n\nexport default Swiper;\nexport { initialOptions };\nexport type { Props as SwiperProps } from './swiper';\n"],"mappings":";;;;AAKA,MAAM,SAASA;AAEf,OAAO,QAAQ"}
|
|
@@ -34,10 +34,11 @@ declare const Swiper$1: <T>({
|
|
|
34
34
|
modules,
|
|
35
35
|
data,
|
|
36
36
|
style,
|
|
37
|
+
className,
|
|
37
38
|
renderItem,
|
|
38
39
|
loadingClassName,
|
|
39
40
|
...props
|
|
40
41
|
}: Props<T>) => react_jsx_runtime0.JSX.Element;
|
|
41
42
|
//#endregion
|
|
42
|
-
export { Swiper$1 as Swiper };
|
|
43
|
+
export { Props, Swiper$1 as Swiper };
|
|
43
44
|
//# sourceMappingURL=swiper.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swiper.d.mts","names":[],"sources":["../../../../src/components/organisms/swiper/swiper.tsx"],"mappings":";;;;;;UA+
|
|
1
|
+
{"version":3,"file":"swiper.d.mts","names":[],"sources":["../../../../src/components/organisms/swiper/swiper.tsx"],"mappings":";;;;;;UA+BiB,KAAA,YAAiB,WAAA;EAChC,OAAA;EACA,MAAA,GAAS,KAAA,CAAM,SAAA;EACf,gBAAA;EACA,OAAA,GAAU,aAAA;EAiBwB;;;;;;;;;;;;;;EAFlC,OAAA,GAAU,YAAA;EACV,IAAA,EAAM,CAAA;EACN,UAAA,CAAW,IAAA,EAAM,CAAA,EAAG,GAAA,WAAc,KAAA,CAAM,SAAA;AAAA;AAAA,cAGpC,QAAA;EAAc,OAAA;EAAA,MAAA;EAAA,OAAA;EAAA,OAAA;EAAA,IAAA;EAAA,KAAA;EAAA,SAAA;EAAA,UAAA;EAAA,gBAAA;EAAA,GAAA;AAAA,GAWjB,KAAA,CAAM,CAAA,MAAE,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -28,10 +28,11 @@ const initialStyle = {
|
|
|
28
28
|
maxWidth: "100vw",
|
|
29
29
|
overflow: "hidden"
|
|
30
30
|
};
|
|
31
|
-
const Swiper$1 = ({ loading, loader, options = {}, modules = [], data = [], style, renderItem, loadingClassName, ...props }) => {
|
|
31
|
+
const Swiper$1 = ({ loading, loader, options = {}, modules = [], data = [], style, className, renderItem, loadingClassName, ...props }) => {
|
|
32
32
|
if (loading) return /* @__PURE__ */ jsx("div", {
|
|
33
|
-
className: cn("h-32", loadingClassName),
|
|
34
|
-
|
|
33
|
+
className: cn("h-32", className, loadingClassName),
|
|
34
|
+
style,
|
|
35
|
+
children: loader ?? /* @__PURE__ */ jsx(Spin, { spinning: true })
|
|
35
36
|
});
|
|
36
37
|
return /* @__PURE__ */ jsx(Swiper, {
|
|
37
38
|
modules,
|
|
@@ -41,6 +42,7 @@ const Swiper$1 = ({ loading, loader, options = {}, modules = [], data = [], styl
|
|
|
41
42
|
...initialStyle,
|
|
42
43
|
...style
|
|
43
44
|
},
|
|
45
|
+
className,
|
|
44
46
|
...props,
|
|
45
47
|
children: data.map((item, i) => {
|
|
46
48
|
const node = renderItem(item, i);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swiper.mjs","names":["Swiper","SwiperCore"],"sources":["../../../../src/components/organisms/swiper/swiper.tsx"],"sourcesContent":["'use client';\n\nimport { cloneElement, isValidElement } from 'react';\n\nimport { Swiper as SwiperCore, SwiperProps } from 'swiper/react';\nimport { SwiperModule, SwiperOptions } from 'swiper/types';\n\nimport { cn } from '@repo/ui/utils';\n\nimport 'swiper/css';\n\nimport { Spin } from '../../atoms';\n\n/**\n * Baseline Swiper options. `navigation` / `autoplay` are inert unless the\n * matching modules are passed through the `modules` prop — see the README next\n * to this file.\n */\nexport const initialOptions: SwiperOptions = {\n loop: false,\n spaceBetween: 8,\n slidesPerView: 'auto',\n navigation: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false,\n },\n};\n\nconst initialStyle = { width: '100%', maxWidth: '100vw', overflow: 'hidden' };\n\
|
|
1
|
+
{"version":3,"file":"swiper.mjs","names":["Swiper","SwiperCore"],"sources":["../../../../src/components/organisms/swiper/swiper.tsx"],"sourcesContent":["'use client';\n\nimport { cloneElement, isValidElement } from 'react';\n\nimport { Swiper as SwiperCore, SwiperProps } from 'swiper/react';\nimport { SwiperModule, SwiperOptions } from 'swiper/types';\n\nimport { cn } from '@repo/ui/utils';\n\nimport 'swiper/css';\n\nimport { Spin } from '../../atoms';\n\n/**\n * Baseline Swiper options. `navigation` / `autoplay` are inert unless the\n * matching modules are passed through the `modules` prop — see the README next\n * to this file.\n */\nexport const initialOptions: SwiperOptions = {\n loop: false,\n spaceBetween: 8,\n slidesPerView: 'auto',\n navigation: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false,\n },\n};\n\nconst initialStyle = { width: '100%', maxWidth: '100vw', overflow: 'hidden' };\n\nexport interface Props<T> extends SwiperProps {\n loading?: boolean;\n loader?: React.ReactNode;\n loadingClassName?: string;\n options?: SwiperOptions;\n /**\n * Swiper feature modules to activate. Nothing is bundled by default — import\n * the modules you need from `swiper/modules` together with their stylesheets\n * (`swiper/css/<module>`) and pass them here.\n *\n * @example\n * import { Autoplay, Navigation } from 'swiper/modules';\n * import 'swiper/css/autoplay';\n * import 'swiper/css/navigation';\n *\n * <Swiper modules={[Autoplay, Navigation]} ... />\n *\n * @default []\n */\n modules?: SwiperModule[];\n data: T[];\n renderItem(item: T, key: number): React.ReactNode;\n}\n\nconst Swiper = <T,>({\n loading,\n loader,\n options = {},\n modules = [],\n data = [],\n style,\n className,\n renderItem,\n loadingClassName,\n ...props\n}: Props<T>) => {\n if (loading) {\n // `{...props}` isn't spread here (unlike the non-loading branch) —\n // SwiperProps carries a lot of Swiper.js-specific config/callbacks\n // (spaceBetween, slidesPerView, onSwiper, etc.) that aren't valid DOM\n // attributes, so blindly spreading them onto a plain placeholder div\n // would trigger React's unknown-DOM-attribute warnings. className/\n // style are the two that actually matter for this div and are safe.\n return (\n <div className={cn('h-32', className, loadingClassName)} style={style}>\n {loader ?? <Spin spinning />}\n </div>\n );\n }\n\n return (\n <SwiperCore\n modules={modules}\n {...initialOptions}\n {...options}\n style={{ ...initialStyle, ...style }}\n className={className}\n {...props}\n >\n {data.map((item: T, i) => {\n const node = renderItem(item, i);\n // Fall back to an index key only when the consumer's renderItem\n // didn't already set one — cloning (rather than wrapping in a\n // Fragment) keeps the returned element a direct child of\n // SwiperCore, which swiper/react's slide detection relies on.\n return isValidElement(node) && node.key == null\n ? cloneElement(node, { key: i })\n : node;\n })}\n </SwiperCore>\n );\n};\n\nexport default Swiper;\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAa,iBAAgC;CAC3C,MAAM;CACN,cAAc;CACd,eAAe;CACf,YAAY;CACZ,UAAU;EACR,OAAO;EACP,sBAAsB;EACvB;CACF;AAED,MAAM,eAAe;CAAE,OAAO;CAAQ,UAAU;CAAS,UAAU;CAAU;AA0B7E,MAAMA,YAAc,EAClB,SACA,QACA,UAAU,EAAE,EACZ,UAAU,EAAE,EACZ,OAAO,EAAE,EACT,OACA,WACA,YACA,kBACA,GAAG,YACW;AACd,KAAI,QAOF,QACE,oBAAC;EAAI,WAAW,GAAG,QAAQ,WAAW,iBAAiB;EAAS;YAC7D,UAAU,oBAAC,QAAK,iBAAW;GACxB;AAIV,QACE,oBAACC;EACU;EACT,GAAI;EACJ,GAAI;EACJ,OAAO;GAAE,GAAG;GAAc,GAAG;GAAO;EACzB;EACX,GAAI;YAEH,KAAK,KAAK,MAAS,MAAM;GACxB,MAAM,OAAO,WAAW,MAAM,EAAE;AAKhC,UAAO,eAAe,KAAK,IAAI,KAAK,OAAO,OACvC,aAAa,MAAM,EAAE,KAAK,GAAG,CAAC,GAC9B;IACJ;GACS"}
|
|
@@ -28,7 +28,7 @@ declare const Toast: {
|
|
|
28
28
|
className,
|
|
29
29
|
onClose
|
|
30
30
|
}: Props): react_jsx_runtime0.JSX.Element;
|
|
31
|
-
destroy(id?: string)
|
|
31
|
+
destroy: (id?: string) => void;
|
|
32
32
|
destroyAll(): void;
|
|
33
33
|
info(title: React.ReactNode, props?: TriggerOptions): string | undefined;
|
|
34
34
|
success(title: React.ReactNode, props?: TriggerOptions): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.d.mts","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"toast.d.mts","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"mappings":";;;KAiBK,SAAA;AAAA,UAEY,KAAA;EACf,IAAA,GAAO,SAAA;EACP,KAAA,EAAO,KAAA,CAAM,SAAA;EACb,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,IAAA,GAAO,KAAA,CAAM,SAAA;EACb,QAAA;EACA,MAAA,GAAS,KAAA,CAAM,SAAA;EACf,SAAA;EACA,OAAA;AAAA;AAAA,UAGQ,WAAA,SAAoB,KAAA;EAC5B,EAAA;EACA,QAAA;EACA,SAAA,GAAY,WAAA;AAAA;AAAA,cAUR,KAAA;EAAA;;;;;;;;;KASH,KAAA,GAAK,kBAAA,CAAA,GAAA,CAAA,OAAA;;;cA+Ga,KAAA,CAAM,SAAA,EAAS,KAAA,GAAU,cAAA;iBAEtB,KAAA,CAAM,SAAA,EAAS,KAAA,GAAU,cAAA;eAE3B,KAAA,CAAM,SAAA,EAAS,KAAA,GAAU,cAAA;iBAEvB,KAAA,CAAM,SAAA,EAAS,KAAA,GAAU,cAAA;AAAA;AAAA,KAR5C,cAAA,GAAiB,IAAA,CAAK,WAAA"}
|
|
@@ -2,51 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils.mjs";
|
|
4
4
|
import Button from "../../Button.mjs";
|
|
5
|
+
import { createImperativeStack, isBrowser } from "./imperative-stack.mjs";
|
|
5
6
|
import { Check, Info, OctagonAlert, OctagonX, X } from "lucide-react";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { useTimeout } from "@jbpark/use-hooks";
|
|
9
|
-
import { v4 } from "uuid";
|
|
10
10
|
import { createPortal } from "react-dom";
|
|
11
|
-
import { createRoot } from "react-dom/client";
|
|
12
11
|
|
|
13
12
|
//#region src/components/organisms/toast.tsx
|
|
14
|
-
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
15
|
-
const containerStates = /* @__PURE__ */ new Map();
|
|
16
|
-
const toastRootElements = /* @__PURE__ */ new WeakMap();
|
|
17
|
-
const getContainerState = (container) => {
|
|
18
|
-
let state = containerStates.get(container);
|
|
19
|
-
if (!state) {
|
|
20
|
-
state = {
|
|
21
|
-
stack: [],
|
|
22
|
-
update: null
|
|
23
|
-
};
|
|
24
|
-
containerStates.set(container, state);
|
|
25
|
-
}
|
|
26
|
-
return state;
|
|
27
|
-
};
|
|
28
|
-
const createToastRoot = (container) => {
|
|
29
|
-
if (!isBrowser) return null;
|
|
30
|
-
const targetContainer = container || document.body;
|
|
31
|
-
let rootEl = toastRootElements.get(targetContainer);
|
|
32
|
-
if (!rootEl) {
|
|
33
|
-
rootEl = document.createElement("div");
|
|
34
|
-
rootEl.setAttribute("role", "region");
|
|
35
|
-
rootEl.setAttribute("aria-label", "Notifications");
|
|
36
|
-
rootEl.style.zIndex = "10000";
|
|
37
|
-
rootEl.style.position = "fixed";
|
|
38
|
-
rootEl.style.right = "0";
|
|
39
|
-
rootEl.style.bottom = "0";
|
|
40
|
-
rootEl.style.display = "flex";
|
|
41
|
-
rootEl.style.flexDirection = "column-reverse";
|
|
42
|
-
rootEl.style.gap = "8px";
|
|
43
|
-
rootEl.style.padding = "16px";
|
|
44
|
-
rootEl.style.pointerEvents = "none";
|
|
45
|
-
targetContainer.appendChild(rootEl);
|
|
46
|
-
toastRootElements.set(targetContainer, rootEl);
|
|
47
|
-
}
|
|
48
|
-
return rootEl;
|
|
49
|
-
};
|
|
50
13
|
const TYPE_ICONS = {
|
|
51
14
|
info: /* @__PURE__ */ jsx(Info, { className: "text-blue-400" }),
|
|
52
15
|
success: /* @__PURE__ */ jsx(Check, { className: "text-green-400" }),
|
|
@@ -55,7 +18,7 @@ const TYPE_ICONS = {
|
|
|
55
18
|
};
|
|
56
19
|
const Toast = ({ type, title, description, icon, closable = true, action, className, onClose }) => {
|
|
57
20
|
return /* @__PURE__ */ jsxs("div", {
|
|
58
|
-
role: "status",
|
|
21
|
+
role: type === "error" ? "alert" : "status",
|
|
59
22
|
className: cn("pointer-events-auto flex w-80 items-start gap-3 rounded-lg", "bg-background text-foreground border p-4 shadow-lg", className),
|
|
60
23
|
children: [
|
|
61
24
|
(icon || type) && /* @__PURE__ */ jsx("div", {
|
|
@@ -97,100 +60,61 @@ const StaticToast = ({ id, duration = DEFAULT_DURATION, container, onClose, ...p
|
|
|
97
60
|
onClose?.();
|
|
98
61
|
setVisible(false);
|
|
99
62
|
setTimeout(() => {
|
|
100
|
-
|
|
63
|
+
toastStack.destroy(id);
|
|
101
64
|
}, 200);
|
|
102
65
|
};
|
|
103
|
-
useTimeout(close, duration || null);
|
|
66
|
+
const { reset, clear } = useTimeout(close, duration || null);
|
|
104
67
|
if (!isBrowser) return null;
|
|
105
68
|
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
106
69
|
className: cn("transition-all duration-200", visible ? "opacity-100" : "translate-x-2 opacity-0"),
|
|
70
|
+
onMouseEnter: clear,
|
|
71
|
+
onMouseLeave: reset,
|
|
72
|
+
onFocus: clear,
|
|
73
|
+
onBlur: reset,
|
|
107
74
|
children: /* @__PURE__ */ jsx(Toast, {
|
|
108
75
|
...props,
|
|
109
76
|
onClose: close
|
|
110
77
|
})
|
|
111
|
-
}),
|
|
112
|
-
};
|
|
113
|
-
const ToastStackRenderer = ({ container }) => {
|
|
114
|
-
const [, forceUpdate] = useState({});
|
|
115
|
-
useEffect(() => {
|
|
116
|
-
const state = getContainerState(container);
|
|
117
|
-
state.update = () => forceUpdate({});
|
|
118
|
-
return () => {
|
|
119
|
-
state.update = null;
|
|
120
|
-
};
|
|
121
|
-
}, [container]);
|
|
122
|
-
const { stack } = getContainerState(container);
|
|
123
|
-
return /* @__PURE__ */ jsx(Fragment$1, { children: stack.map(({ id, ...props }) => /* @__PURE__ */ jsx(StaticToast, {
|
|
124
|
-
id,
|
|
125
|
-
...props
|
|
126
|
-
}, id)) });
|
|
127
|
-
};
|
|
128
|
-
const toastRoots = /* @__PURE__ */ new Map();
|
|
129
|
-
const renderToast = (props) => {
|
|
130
|
-
if (!isBrowser) return;
|
|
131
|
-
const targetContainer = props.container || document.body;
|
|
132
|
-
const rootElement = createToastRoot(targetContainer);
|
|
133
|
-
if (!toastRoots.has(targetContainer)) {
|
|
134
|
-
const root = createRoot(rootElement);
|
|
135
|
-
toastRoots.set(targetContainer, root);
|
|
136
|
-
root.render(/* @__PURE__ */ jsx(ToastStackRenderer, { container: targetContainer }));
|
|
137
|
-
}
|
|
138
|
-
const state = getContainerState(targetContainer);
|
|
139
|
-
const id = props.id || v4();
|
|
140
|
-
state.stack.push({
|
|
141
|
-
...props,
|
|
142
|
-
id
|
|
143
|
-
});
|
|
144
|
-
state.update?.();
|
|
145
|
-
return id;
|
|
146
|
-
};
|
|
147
|
-
Toast.destroy = (id) => {
|
|
148
|
-
if (!id) {
|
|
149
|
-
containerStates.forEach((state) => {
|
|
150
|
-
state.stack = [];
|
|
151
|
-
state.update?.();
|
|
152
|
-
});
|
|
153
|
-
toastRoots.forEach((root, container) => {
|
|
154
|
-
root.unmount();
|
|
155
|
-
toastRootElements.get(container)?.remove();
|
|
156
|
-
toastRootElements.delete(container);
|
|
157
|
-
});
|
|
158
|
-
toastRoots.clear();
|
|
159
|
-
containerStates.clear();
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
containerStates.forEach((state, container) => {
|
|
163
|
-
if (!state.stack.some((toast) => toast.id === id)) return;
|
|
164
|
-
state.stack = state.stack.filter((toast) => toast.id !== id);
|
|
165
|
-
state.update?.();
|
|
166
|
-
if (!state.stack.length) {
|
|
167
|
-
toastRoots.get(container)?.unmount();
|
|
168
|
-
toastRoots.delete(container);
|
|
169
|
-
containerStates.delete(container);
|
|
170
|
-
toastRootElements.get(container)?.remove();
|
|
171
|
-
toastRootElements.delete(container);
|
|
172
|
-
}
|
|
173
|
-
});
|
|
78
|
+
}), toastStack.getRootElement(container));
|
|
174
79
|
};
|
|
80
|
+
const toastStack = createImperativeStack({
|
|
81
|
+
createRootElement: () => {
|
|
82
|
+
const el = document.createElement("div");
|
|
83
|
+
el.setAttribute("role", "region");
|
|
84
|
+
el.setAttribute("aria-label", "Notifications");
|
|
85
|
+
el.style.zIndex = "10000";
|
|
86
|
+
el.style.position = "fixed";
|
|
87
|
+
el.style.right = "0";
|
|
88
|
+
el.style.bottom = "0";
|
|
89
|
+
el.style.display = "flex";
|
|
90
|
+
el.style.flexDirection = "column-reverse";
|
|
91
|
+
el.style.gap = "8px";
|
|
92
|
+
el.style.padding = "16px";
|
|
93
|
+
el.style.pointerEvents = "none";
|
|
94
|
+
return el;
|
|
95
|
+
},
|
|
96
|
+
StackItem: StaticToast
|
|
97
|
+
});
|
|
98
|
+
Toast.destroy = toastStack.destroy;
|
|
175
99
|
Toast.destroyAll = () => {
|
|
176
|
-
|
|
100
|
+
toastStack.destroy();
|
|
177
101
|
};
|
|
178
|
-
Toast.info = (title, props) =>
|
|
102
|
+
Toast.info = (title, props) => toastStack.render({
|
|
179
103
|
type: "info",
|
|
180
104
|
title,
|
|
181
105
|
...props
|
|
182
106
|
});
|
|
183
|
-
Toast.success = (title, props) =>
|
|
107
|
+
Toast.success = (title, props) => toastStack.render({
|
|
184
108
|
type: "success",
|
|
185
109
|
title,
|
|
186
110
|
...props
|
|
187
111
|
});
|
|
188
|
-
Toast.error = (title, props) =>
|
|
112
|
+
Toast.error = (title, props) => toastStack.render({
|
|
189
113
|
type: "error",
|
|
190
114
|
title,
|
|
191
115
|
...props
|
|
192
116
|
});
|
|
193
|
-
Toast.warning = (title, props) =>
|
|
117
|
+
Toast.warning = (title, props) => toastStack.render({
|
|
194
118
|
type: "warning",
|
|
195
119
|
title,
|
|
196
120
|
...props
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.mjs","names":["uuid"],"sources":["../../../src/components/organisms/toast.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Root, createRoot } from 'react-dom/client';\n\nimport { useTimeout } from '@jbpark/use-hooks';\nimport { Check, Info, OctagonAlert, OctagonX, X } from 'lucide-react';\nimport { v4 as uuid } from 'uuid';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\n\ntype ToastType = 'info' | 'success' | 'error' | 'warning';\n\nexport interface Props {\n type?: ToastType;\n title: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n closable?: boolean;\n action?: React.ReactNode;\n className?: string;\n onClose?: () => void;\n}\n\ninterface StaticProps extends Props {\n id?: string;\n duration?: number;\n container?: HTMLElement;\n}\n\nconst isBrowser =\n typeof window !== 'undefined' && typeof document !== 'undefined';\n\ntype ContainerState = {\n stack: StaticProps[];\n update: (() => void) | null;\n};\n\nconst containerStates = new Map<HTMLElement, ContainerState>();\nconst toastRootElements = new WeakMap<HTMLElement, HTMLElement>();\n\nconst getContainerState = (container: HTMLElement): ContainerState => {\n let state = containerStates.get(container);\n\n if (!state) {\n state = { stack: [], update: null };\n containerStates.set(container, state);\n }\n\n return state;\n};\n\nconst createToastRoot = (container?: HTMLElement) => {\n if (!isBrowser) {\n return null;\n }\n\n const targetContainer = container || document.body;\n let rootEl = toastRootElements.get(targetContainer);\n\n if (!rootEl) {\n rootEl = document.createElement('div');\n rootEl.setAttribute('role', 'region');\n rootEl.setAttribute('aria-label', 'Notifications');\n rootEl.style.zIndex = '10000';\n rootEl.style.position = 'fixed';\n rootEl.style.right = '0';\n rootEl.style.bottom = '0';\n rootEl.style.display = 'flex';\n rootEl.style.flexDirection = 'column-reverse';\n rootEl.style.gap = '8px';\n rootEl.style.padding = '16px';\n rootEl.style.pointerEvents = 'none';\n targetContainer.appendChild(rootEl);\n toastRootElements.set(targetContainer, rootEl);\n }\n\n return rootEl;\n};\n\nconst TYPE_ICONS: Record<ToastType, React.ReactNode> = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n};\n\nconst Toast = ({\n type,\n title,\n description,\n icon,\n closable = true,\n action,\n className,\n onClose,\n}: Props) => {\n return (\n <div\n role=\"status\"\n className={cn(\n 'pointer-events-auto flex w-80 items-start gap-3 rounded-lg',\n 'bg-background text-foreground border p-4 shadow-lg',\n className,\n //\n )}\n >\n {(icon || type) && (\n <div className=\"mt-0.5 shrink-0 [&_svg]:size-5\">\n {icon || (type && TYPE_ICONS[type])}\n </div>\n )}\n <div className=\"flex-1 space-y-1\">\n <p className=\"text-sm font-medium\">{title}</p>\n {description && (\n <p className=\"text-muted-foreground text-sm\">{description}</p>\n )}\n {action && <div className=\"pt-1\">{action}</div>}\n </div>\n {closable && (\n <Button\n type=\"text\"\n shape=\"circle\"\n size=\"small\"\n aria-label=\"Close\"\n icon={<X />}\n onClick={onClose}\n />\n )}\n </div>\n );\n};\n\nconst DEFAULT_DURATION = 4000;\n\nconst StaticToast = ({\n id,\n duration = DEFAULT_DURATION,\n container,\n onClose,\n ...props\n}: StaticProps) => {\n const [visible, setVisible] = useState(true);\n\n const close = () => {\n onClose?.();\n setVisible(false);\n setTimeout(() => {\n Toast.destroy(id);\n }, 200);\n };\n\n useTimeout(close, duration || null);\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <div\n className={cn(\n 'transition-all duration-200',\n visible ? 'opacity-100' : 'translate-x-2 opacity-0',\n )}\n >\n <Toast {...props} onClose={close} />\n </div>,\n createToastRoot(container)!,\n );\n};\n\nconst ToastStackRenderer = ({ container }: { container: HTMLElement }) => {\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n const state = getContainerState(container);\n state.update = () => forceUpdate({});\n return () => {\n state.update = null;\n };\n }, [container]);\n\n const { stack } = getContainerState(container);\n\n return (\n <>\n {stack.map(({ id, ...props }) => (\n <StaticToast key={id} id={id} {...props} />\n ))}\n </>\n );\n};\n\nconst toastRoots = new Map<HTMLElement, Root>();\n\nconst renderToast = (props: StaticProps) => {\n if (!isBrowser) {\n return;\n }\n\n const targetContainer = props.container || document.body;\n const rootElement = createToastRoot(targetContainer)!;\n\n if (!toastRoots.has(targetContainer)) {\n const root = createRoot(rootElement);\n toastRoots.set(targetContainer, root);\n root.render(<ToastStackRenderer container={targetContainer} />);\n }\n\n const state = getContainerState(targetContainer);\n const id = props.id || uuid();\n state.stack.push({ ...props, id });\n state.update?.();\n\n return id;\n};\n\nToast.destroy = (id?: string) => {\n if (!id) {\n containerStates.forEach(state => {\n state.stack = [];\n state.update?.();\n });\n toastRoots.forEach((root, container) => {\n root.unmount();\n toastRootElements.get(container)?.remove();\n toastRootElements.delete(container);\n });\n toastRoots.clear();\n containerStates.clear();\n return;\n }\n\n containerStates.forEach((state, container) => {\n if (!state.stack.some(toast => toast.id === id)) {\n return;\n }\n\n state.stack = state.stack.filter(toast => toast.id !== id);\n state.update?.();\n\n if (!state.stack.length) {\n toastRoots.get(container)?.unmount();\n toastRoots.delete(container);\n containerStates.delete(container);\n toastRootElements.get(container)?.remove();\n toastRootElements.delete(container);\n }\n });\n};\n\nToast.destroyAll = () => {\n Toast.destroy();\n};\n\ntype TriggerOptions = Omit<StaticProps, 'type' | 'title'>;\n\nToast.info = (title: React.ReactNode, props?: TriggerOptions) =>\n renderToast({ type: 'info', title, ...props });\nToast.success = (title: React.ReactNode, props?: TriggerOptions) =>\n renderToast({ type: 'success', title, ...props });\nToast.error = (title: React.ReactNode, props?: TriggerOptions) =>\n renderToast({ type: 'error', title, ...props });\nToast.warning = (title: React.ReactNode, props?: TriggerOptions) =>\n renderToast({ type: 'warning', title, ...props });\n\nexport default Toast;\nexport type { StaticProps as ToastOptions };\n"],"mappings":";;;;;;;;;;;;;AAiCA,MAAM,YACJ,OAAO,WAAW,eAAe,OAAO,aAAa;AAOvD,MAAM,kCAAkB,IAAI,KAAkC;AAC9D,MAAM,oCAAoB,IAAI,SAAmC;AAEjE,MAAM,qBAAqB,cAA2C;CACpE,IAAI,QAAQ,gBAAgB,IAAI,UAAU;AAE1C,KAAI,CAAC,OAAO;AACV,UAAQ;GAAE,OAAO,EAAE;GAAE,QAAQ;GAAM;AACnC,kBAAgB,IAAI,WAAW,MAAM;;AAGvC,QAAO;;AAGT,MAAM,mBAAmB,cAA4B;AACnD,KAAI,CAAC,UACH,QAAO;CAGT,MAAM,kBAAkB,aAAa,SAAS;CAC9C,IAAI,SAAS,kBAAkB,IAAI,gBAAgB;AAEnD,KAAI,CAAC,QAAQ;AACX,WAAS,SAAS,cAAc,MAAM;AACtC,SAAO,aAAa,QAAQ,SAAS;AACrC,SAAO,aAAa,cAAc,gBAAgB;AAClD,SAAO,MAAM,SAAS;AACtB,SAAO,MAAM,WAAW;AACxB,SAAO,MAAM,QAAQ;AACrB,SAAO,MAAM,SAAS;AACtB,SAAO,MAAM,UAAU;AACvB,SAAO,MAAM,gBAAgB;AAC7B,SAAO,MAAM,MAAM;AACnB,SAAO,MAAM,UAAU;AACvB,SAAO,MAAM,gBAAgB;AAC7B,kBAAgB,YAAY,OAAO;AACnC,oBAAkB,IAAI,iBAAiB,OAAO;;AAGhD,QAAO;;AAGT,MAAM,aAAiD;CACrD,MAAM,oBAAC,QAAK,WAAU,kBAAkB;CACxC,SAAS,oBAAC,SAAM,WAAU,mBAAmB;CAC7C,OAAO,oBAAC,YAAS,WAAU,iBAAiB;CAC5C,SAAS,oBAAC,gBAAa,WAAU,oBAAoB;CACtD;AAED,MAAM,SAAS,EACb,MACA,OACA,aACA,MACA,WAAW,MACX,QACA,WACA,cACW;AACX,QACE,qBAAC;EACC,MAAK;EACL,WAAW,GACT,8DACA,sDACA,UAED;;IAEC,QAAQ,SACR,oBAAC;IAAI,WAAU;cACZ,QAAS,QAAQ,WAAW;KACzB;GAER,qBAAC;IAAI,WAAU;;KACb,oBAAC;MAAE,WAAU;gBAAuB;OAAU;KAC7C,eACC,oBAAC;MAAE,WAAU;gBAAiC;OAAgB;KAE/D,UAAU,oBAAC;MAAI,WAAU;gBAAQ;OAAa;;KAC3C;GACL,YACC,oBAAC;IACC,MAAK;IACL,OAAM;IACN,MAAK;IACL,cAAW;IACX,MAAM,oBAAC,MAAI;IACX,SAAS;KACT;;GAEA;;AAIV,MAAM,mBAAmB;AAEzB,MAAM,eAAe,EACnB,IACA,WAAW,kBACX,WACA,SACA,GAAG,YACc;CACjB,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,MAAM,cAAc;AAClB,aAAW;AACX,aAAW,MAAM;AACjB,mBAAiB;AACf,SAAM,QAAQ,GAAG;KAChB,IAAI;;AAGT,YAAW,OAAO,YAAY,KAAK;AAEnC,KAAI,CAAC,UACH,QAAO;AAGT,QAAO,aACL,oBAAC;EACC,WAAW,GACT,+BACA,UAAU,gBAAgB,0BAC3B;YAED,oBAAC;GAAM,GAAI;GAAO,SAAS;IAAS;GAChC,EACN,gBAAgB,UAAU,CAC3B;;AAGH,MAAM,sBAAsB,EAAE,gBAA4C;CACxE,MAAM,GAAG,eAAe,SAAS,EAAE,CAAC;AAEpC,iBAAgB;EACd,MAAM,QAAQ,kBAAkB,UAAU;AAC1C,QAAM,eAAe,YAAY,EAAE,CAAC;AACpC,eAAa;AACX,SAAM,SAAS;;IAEhB,CAAC,UAAU,CAAC;CAEf,MAAM,EAAE,UAAU,kBAAkB,UAAU;AAE9C,QACE,4CACG,MAAM,KAAK,EAAE,IAAI,GAAG,YACnB,oBAAC;EAAyB;EAAI,GAAI;IAAhB,GAAyB,CAC3C,GACD;;AAIP,MAAM,6BAAa,IAAI,KAAwB;AAE/C,MAAM,eAAe,UAAuB;AAC1C,KAAI,CAAC,UACH;CAGF,MAAM,kBAAkB,MAAM,aAAa,SAAS;CACpD,MAAM,cAAc,gBAAgB,gBAAgB;AAEpD,KAAI,CAAC,WAAW,IAAI,gBAAgB,EAAE;EACpC,MAAM,OAAO,WAAW,YAAY;AACpC,aAAW,IAAI,iBAAiB,KAAK;AACrC,OAAK,OAAO,oBAAC,sBAAmB,WAAW,kBAAmB,CAAC;;CAGjE,MAAM,QAAQ,kBAAkB,gBAAgB;CAChD,MAAM,KAAK,MAAM,MAAMA,IAAM;AAC7B,OAAM,MAAM,KAAK;EAAE,GAAG;EAAO;EAAI,CAAC;AAClC,OAAM,UAAU;AAEhB,QAAO;;AAGT,MAAM,WAAW,OAAgB;AAC/B,KAAI,CAAC,IAAI;AACP,kBAAgB,SAAQ,UAAS;AAC/B,SAAM,QAAQ,EAAE;AAChB,SAAM,UAAU;IAChB;AACF,aAAW,SAAS,MAAM,cAAc;AACtC,QAAK,SAAS;AACd,qBAAkB,IAAI,UAAU,EAAE,QAAQ;AAC1C,qBAAkB,OAAO,UAAU;IACnC;AACF,aAAW,OAAO;AAClB,kBAAgB,OAAO;AACvB;;AAGF,iBAAgB,SAAS,OAAO,cAAc;AAC5C,MAAI,CAAC,MAAM,MAAM,MAAK,UAAS,MAAM,OAAO,GAAG,CAC7C;AAGF,QAAM,QAAQ,MAAM,MAAM,QAAO,UAAS,MAAM,OAAO,GAAG;AAC1D,QAAM,UAAU;AAEhB,MAAI,CAAC,MAAM,MAAM,QAAQ;AACvB,cAAW,IAAI,UAAU,EAAE,SAAS;AACpC,cAAW,OAAO,UAAU;AAC5B,mBAAgB,OAAO,UAAU;AACjC,qBAAkB,IAAI,UAAU,EAAE,QAAQ;AAC1C,qBAAkB,OAAO,UAAU;;GAErC;;AAGJ,MAAM,mBAAmB;AACvB,OAAM,SAAS;;AAKjB,MAAM,QAAQ,OAAwB,UACpC,YAAY;CAAE,MAAM;CAAQ;CAAO,GAAG;CAAO,CAAC;AAChD,MAAM,WAAW,OAAwB,UACvC,YAAY;CAAE,MAAM;CAAW;CAAO,GAAG;CAAO,CAAC;AACnD,MAAM,SAAS,OAAwB,UACrC,YAAY;CAAE,MAAM;CAAS;CAAO,GAAG;CAAO,CAAC;AACjD,MAAM,WAAW,OAAwB,UACvC,YAAY;CAAE,MAAM;CAAW;CAAO,GAAG;CAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"toast.mjs","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTimeout } from '@jbpark/use-hooks';\nimport { Check, Info, OctagonAlert, OctagonX, X } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\nimport {\n type ImperativeStack,\n createImperativeStack,\n isBrowser,\n} from './imperative-stack';\n\ntype ToastType = 'info' | 'success' | 'error' | 'warning';\n\nexport interface Props {\n type?: ToastType;\n title: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n closable?: boolean;\n action?: React.ReactNode;\n className?: string;\n onClose?: () => void;\n}\n\ninterface StaticProps extends Props {\n id?: string;\n duration?: number;\n container?: HTMLElement;\n}\n\nconst TYPE_ICONS: Record<ToastType, React.ReactNode> = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n};\n\nconst Toast = ({\n type,\n title,\n description,\n icon,\n closable = true,\n action,\n className,\n onClose,\n}: Props) => {\n return (\n <div\n role={type === 'error' ? 'alert' : 'status'}\n className={cn(\n 'pointer-events-auto flex w-80 items-start gap-3 rounded-lg',\n 'bg-background text-foreground border p-4 shadow-lg',\n className,\n //\n )}\n >\n {(icon || type) && (\n <div className=\"mt-0.5 shrink-0 [&_svg]:size-5\">\n {icon || (type && TYPE_ICONS[type])}\n </div>\n )}\n <div className=\"flex-1 space-y-1\">\n <p className=\"text-sm font-medium\">{title}</p>\n {description && (\n <p className=\"text-muted-foreground text-sm\">{description}</p>\n )}\n {action && <div className=\"pt-1\">{action}</div>}\n </div>\n {closable && (\n <Button\n type=\"text\"\n shape=\"circle\"\n size=\"small\"\n aria-label=\"Close\"\n icon={<X />}\n onClick={onClose}\n />\n )}\n </div>\n );\n};\n\nconst DEFAULT_DURATION = 4000;\n\nconst StaticToast = ({\n id,\n duration = DEFAULT_DURATION,\n container,\n onClose,\n ...props\n}: StaticProps & { id: string }): React.ReactPortal | null => {\n const [visible, setVisible] = useState(true);\n\n const close = () => {\n onClose?.();\n setVisible(false);\n setTimeout(() => {\n toastStack.destroy(id);\n }, 200);\n };\n\n const { reset, clear } = useTimeout(close, duration || null);\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <div\n className={cn(\n 'transition-all duration-200',\n visible ? 'opacity-100' : 'translate-x-2 opacity-0',\n )}\n // Without this, a toast with a closable/action button (or one the\n // user is mid-read on) could auto-dismiss itself out from under\n // them — hovering or focusing anything inside pauses the timer,\n // moving away restarts it from the full duration.\n onMouseEnter={clear}\n onMouseLeave={reset}\n onFocus={clear}\n onBlur={reset}\n >\n <Toast {...props} onClose={close} />\n </div>,\n toastStack.getRootElement(container)!,\n );\n};\n\nconst toastStack: ImperativeStack<StaticProps> =\n createImperativeStack<StaticProps>({\n createRootElement: () => {\n const el = document.createElement('div');\n el.setAttribute('role', 'region');\n el.setAttribute('aria-label', 'Notifications');\n el.style.zIndex = '10000';\n el.style.position = 'fixed';\n el.style.right = '0';\n el.style.bottom = '0';\n el.style.display = 'flex';\n el.style.flexDirection = 'column-reverse';\n el.style.gap = '8px';\n el.style.padding = '16px';\n el.style.pointerEvents = 'none';\n return el;\n },\n StackItem: StaticToast,\n });\n\nToast.destroy = toastStack.destroy;\n\nToast.destroyAll = () => {\n toastStack.destroy();\n};\n\ntype TriggerOptions = Omit<StaticProps, 'type' | 'title'>;\n\nToast.info = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ type: 'info', title, ...props });\nToast.success = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ type: 'success', title, ...props });\nToast.error = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ type: 'error', title, ...props });\nToast.warning = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ type: 'warning', title, ...props });\n\nexport default Toast;\nexport type { StaticProps as ToastOptions };\n"],"mappings":";;;;;;;;;;;;AAoCA,MAAM,aAAiD;CACrD,MAAM,oBAAC,QAAK,WAAU,kBAAkB;CACxC,SAAS,oBAAC,SAAM,WAAU,mBAAmB;CAC7C,OAAO,oBAAC,YAAS,WAAU,iBAAiB;CAC5C,SAAS,oBAAC,gBAAa,WAAU,oBAAoB;CACtD;AAED,MAAM,SAAS,EACb,MACA,OACA,aACA,MACA,WAAW,MACX,QACA,WACA,cACW;AACX,QACE,qBAAC;EACC,MAAM,SAAS,UAAU,UAAU;EACnC,WAAW,GACT,8DACA,sDACA,UAED;;IAEC,QAAQ,SACR,oBAAC;IAAI,WAAU;cACZ,QAAS,QAAQ,WAAW;KACzB;GAER,qBAAC;IAAI,WAAU;;KACb,oBAAC;MAAE,WAAU;gBAAuB;OAAU;KAC7C,eACC,oBAAC;MAAE,WAAU;gBAAiC;OAAgB;KAE/D,UAAU,oBAAC;MAAI,WAAU;gBAAQ;OAAa;;KAC3C;GACL,YACC,oBAAC;IACC,MAAK;IACL,OAAM;IACN,MAAK;IACL,cAAW;IACX,MAAM,oBAAC,MAAI;IACX,SAAS;KACT;;GAEA;;AAIV,MAAM,mBAAmB;AAEzB,MAAM,eAAe,EACnB,IACA,WAAW,kBACX,WACA,SACA,GAAG,YACyD;CAC5D,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,MAAM,cAAc;AAClB,aAAW;AACX,aAAW,MAAM;AACjB,mBAAiB;AACf,cAAW,QAAQ,GAAG;KACrB,IAAI;;CAGT,MAAM,EAAE,OAAO,UAAU,WAAW,OAAO,YAAY,KAAK;AAE5D,KAAI,CAAC,UACH,QAAO;AAGT,QAAO,aACL,oBAAC;EACC,WAAW,GACT,+BACA,UAAU,gBAAgB,0BAC3B;EAKD,cAAc;EACd,cAAc;EACd,SAAS;EACT,QAAQ;YAER,oBAAC;GAAM,GAAI;GAAO,SAAS;IAAS;GAChC,EACN,WAAW,eAAe,UAAU,CACrC;;AAGH,MAAM,aACJ,sBAAmC;CACjC,yBAAyB;EACvB,MAAM,KAAK,SAAS,cAAc,MAAM;AACxC,KAAG,aAAa,QAAQ,SAAS;AACjC,KAAG,aAAa,cAAc,gBAAgB;AAC9C,KAAG,MAAM,SAAS;AAClB,KAAG,MAAM,WAAW;AACpB,KAAG,MAAM,QAAQ;AACjB,KAAG,MAAM,SAAS;AAClB,KAAG,MAAM,UAAU;AACnB,KAAG,MAAM,gBAAgB;AACzB,KAAG,MAAM,MAAM;AACf,KAAG,MAAM,UAAU;AACnB,KAAG,MAAM,gBAAgB;AACzB,SAAO;;CAET,WAAW;CACZ,CAAC;AAEJ,MAAM,UAAU,WAAW;AAE3B,MAAM,mBAAmB;AACvB,YAAW,SAAS;;AAKtB,MAAM,QAAQ,OAAwB,UACpC,WAAW,OAAO;CAAE,MAAM;CAAQ;CAAO,GAAG;CAAO,CAAC;AACtD,MAAM,WAAW,OAAwB,UACvC,WAAW,OAAO;CAAE,MAAM;CAAW;CAAO,GAAG;CAAO,CAAC;AACzD,MAAM,SAAS,OAAwB,UACrC,WAAW,OAAO;CAAE,MAAM;CAAS;CAAO,GAAG;CAAO,CAAC;AACvD,MAAM,WAAW,OAAwB,UACvC,WAAW,OAAO;CAAE,MAAM;CAAW;CAAO,GAAG;CAAO,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/templates/container.d.ts
|
|
4
|
+
type MaxWidth = '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | 'full' | 'none';
|
|
5
|
+
interface Props extends React.ComponentProps<'div'> {
|
|
6
|
+
maxWidth?: MaxWidth;
|
|
7
|
+
padded?: boolean;
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const Container: ({
|
|
11
|
+
className,
|
|
12
|
+
maxWidth,
|
|
13
|
+
padded,
|
|
14
|
+
asChild,
|
|
15
|
+
...props
|
|
16
|
+
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Container, Props };
|
|
19
|
+
//# sourceMappingURL=container.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.d.mts","names":[],"sources":["../../../src/components/templates/container.tsx"],"mappings":";;;KAIK,QAAA;AAAA,UAmCY,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,QAAA,GAAW,QAAA;EACX,MAAA;EACA,OAAA;AAAA;AAAA,cAMI,SAAA;EAAa,SAAA;EAAA,QAAA;EAAA,MAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAMhB,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cn } from "../../utils.mjs";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
4
|
+
|
|
5
|
+
//#region src/components/templates/container.tsx
|
|
6
|
+
const MAX_WIDTH_CLASSES = {
|
|
7
|
+
"3xs": "max-w-3xs",
|
|
8
|
+
"2xs": "max-w-2xs",
|
|
9
|
+
xs: "max-w-xs",
|
|
10
|
+
sm: "max-w-sm",
|
|
11
|
+
md: "max-w-md",
|
|
12
|
+
lg: "max-w-lg",
|
|
13
|
+
xl: "max-w-xl",
|
|
14
|
+
"2xl": "max-w-2xl",
|
|
15
|
+
"3xl": "max-w-3xl",
|
|
16
|
+
"4xl": "max-w-4xl",
|
|
17
|
+
"5xl": "max-w-5xl",
|
|
18
|
+
"6xl": "max-w-6xl",
|
|
19
|
+
"7xl": "max-w-7xl",
|
|
20
|
+
full: "max-w-full",
|
|
21
|
+
none: "max-w-none"
|
|
22
|
+
};
|
|
23
|
+
const Container = ({ className, maxWidth = "7xl", padded = true, asChild = false, ...props }) => {
|
|
24
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
25
|
+
className: cn("mx-auto w-full", MAX_WIDTH_CLASSES[maxWidth], padded && "px-4 sm:px-6 lg:px-8", className),
|
|
26
|
+
...props
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Container as default };
|
|
32
|
+
//# sourceMappingURL=container.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.mjs","names":[],"sources":["../../../src/components/templates/container.tsx"],"sourcesContent":["import { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '@repo/ui/utils';\n\ntype MaxWidth =\n | '3xs'\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl'\n | '7xl'\n | 'full'\n | 'none';\n\nconst MAX_WIDTH_CLASSES: Record<MaxWidth, string> = {\n '3xs': 'max-w-3xs',\n '2xs': 'max-w-2xs',\n xs: 'max-w-xs',\n sm: 'max-w-sm',\n md: 'max-w-md',\n lg: 'max-w-lg',\n xl: 'max-w-xl',\n '2xl': 'max-w-2xl',\n '3xl': 'max-w-3xl',\n '4xl': 'max-w-4xl',\n '5xl': 'max-w-5xl',\n '6xl': 'max-w-6xl',\n '7xl': 'max-w-7xl',\n full: 'max-w-full',\n none: 'max-w-none',\n};\n\nexport interface Props extends React.ComponentProps<'div'> {\n maxWidth?: MaxWidth;\n padded?: boolean;\n asChild?: boolean;\n}\n\n// Standardizes the `mx-auto max-w-7xl px-4` wrapper every app in this\n// monorepo was rewriting by hand inside Content — one place to change the\n// page's content width/gutters instead of N call sites.\nconst Container = ({\n className,\n maxWidth = '7xl',\n padded = true,\n asChild = false,\n ...props\n}: Props) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n className={cn(\n 'mx-auto w-full',\n MAX_WIDTH_CLASSES[maxWidth],\n padded && 'px-4 sm:px-6 lg:px-8',\n className,\n //\n )}\n {...props}\n />\n );\n};\n\nexport default Container;\n"],"mappings":";;;;;AAqBA,MAAM,oBAA8C;CAClD,OAAO;CACP,OAAO;CACP,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACP;AAWD,MAAM,aAAa,EACjB,WACA,WAAW,OACX,SAAS,MACT,UAAU,OACV,GAAG,YACQ;AAGX,QACE,oBAHW,UAAU,OAAO;EAI1B,WAAW,GACT,kBACA,kBAAkB,WAClB,UAAU,wBACV,UAED;EACD,GAAI;GACJ"}
|