@jbpark/ui-kit 3.7.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/Card.d.mts +1 -1
- package/dist/Card.d.mts.map +1 -1
- package/dist/Card.mjs.map +1 -1
- package/dist/Space.d.mts +1 -1
- package/dist/Space.d.mts.map +1 -1
- package/dist/Space.mjs.map +1 -1
- package/dist/components/atoms/checkbox/group.d.mts.map +1 -1
- package/dist/components/atoms/checkbox/group.mjs +4 -3
- package/dist/components/atoms/checkbox/group.mjs.map +1 -1
- package/dist/components/atoms/color-picker.d.mts +7 -1
- package/dist/components/atoms/color-picker.d.mts.map +1 -1
- package/dist/components/atoms/color-picker.mjs +8 -1
- package/dist/components/atoms/color-picker.mjs.map +1 -1
- 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/option-group.mjs +11 -1
- package/dist/components/atoms/option-group.mjs.map +1 -1
- package/dist/components/atoms/radio/group.d.mts.map +1 -1
- package/dist/components/atoms/radio/group.mjs +3 -2
- package/dist/components/atoms/radio/group.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 +2 -1
- package/dist/components/atoms/spin.d.mts.map +1 -1
- package/dist/components/atoms/spin.mjs +10 -4
- package/dist/components/atoms/spin.mjs.map +1 -1
- package/dist/components/molecules/collapse.d.mts +1 -1
- package/dist/components/molecules/collapse.d.mts.map +1 -1
- package/dist/components/molecules/collapse.mjs.map +1 -1
- package/dist/components/molecules/dropdown.d.mts +2 -2
- package/dist/components/molecules/dropdown.d.mts.map +1 -1
- package/dist/components/molecules/dropdown.mjs +25 -12
- package/dist/components/molecules/dropdown.mjs.map +1 -1
- package/dist/components/molecules/index.d.mts +9 -6
- package/dist/components/molecules/menu/item/item.mjs +27 -11
- package/dist/components/molecules/menu/item/item.mjs.map +1 -1
- package/dist/components/molecules/menu/menu.d.mts.map +1 -1
- package/dist/components/molecules/menu/menu.mjs +9 -7
- package/dist/components/molecules/menu/menu.mjs.map +1 -1
- package/dist/components/molecules/splitter/splitter.mjs +2 -2
- package/dist/components/molecules/splitter/splitter.mjs.map +1 -1
- package/dist/components/molecules/upload.d.mts +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 +29 -13
- 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 -3
- package/package.json +4 -3
- package/dist/providers/index.d.mts +0 -3
|
@@ -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":"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"}
|
|
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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/templates/empty.d.ts
|
|
4
|
+
interface Props extends Omit<React.ComponentProps<'div'>, 'title'> {
|
|
5
|
+
icon?: React.ReactNode;
|
|
6
|
+
title?: React.ReactNode;
|
|
7
|
+
description?: React.ReactNode;
|
|
8
|
+
action?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
declare const Empty: ({
|
|
11
|
+
icon,
|
|
12
|
+
title,
|
|
13
|
+
description,
|
|
14
|
+
action,
|
|
15
|
+
className,
|
|
16
|
+
...props
|
|
17
|
+
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { Empty, Props };
|
|
20
|
+
//# sourceMappingURL=empty.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty.d.mts","names":[],"sources":["../../../src/components/templates/empty.tsx"],"mappings":";;;UAIiB,KAAA,SAAc,IAAA,CAAK,KAAA,CAAM,cAAA;EACxC,IAAA,GAAO,KAAA,CAAM,SAAA;EACb,KAAA,GAAQ,KAAA,CAAM,SAAA;EACd,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,MAAA,GAAS,KAAA,CAAM,SAAA;AAAA;AAAA,cAQX,KAAA;EAAS,IAAA;EAAA,KAAA;EAAA,WAAA;EAAA,MAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAOZ,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { cn } from "../../utils.mjs";
|
|
2
|
+
import { Inbox } from "lucide-react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/components/templates/empty.tsx
|
|
6
|
+
const Empty = ({ icon, title, description = "No data", action, className, ...props }) => {
|
|
7
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8
|
+
role: "status",
|
|
9
|
+
className: cn("flex flex-col items-center justify-center gap-3 py-12 text-center", className),
|
|
10
|
+
...props,
|
|
11
|
+
children: [
|
|
12
|
+
/* @__PURE__ */ jsx("div", {
|
|
13
|
+
className: "text-muted-foreground [&_svg]:size-12",
|
|
14
|
+
children: icon ?? /* @__PURE__ */ jsx(Inbox, {})
|
|
15
|
+
}),
|
|
16
|
+
title && /* @__PURE__ */ jsx("p", {
|
|
17
|
+
className: "text-sm font-medium",
|
|
18
|
+
children: title
|
|
19
|
+
}),
|
|
20
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
21
|
+
className: "text-muted-foreground text-sm",
|
|
22
|
+
children: description
|
|
23
|
+
}),
|
|
24
|
+
action && /* @__PURE__ */ jsx("div", {
|
|
25
|
+
className: "mt-1",
|
|
26
|
+
children: action
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { Empty as default };
|
|
34
|
+
//# sourceMappingURL=empty.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty.mjs","names":[],"sources":["../../../src/components/templates/empty.tsx"],"sourcesContent":["import { Inbox } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nexport interface Props extends Omit<React.ComponentProps<'div'>, 'title'> {\n icon?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n action?: React.ReactNode;\n}\n\n// The counterpart List's `empty` prop was asking for — List/Upload/Swiper\n// each render arbitrary content for their empty state today with nothing\n// in the library actually meant to go there. Pairs with Skeleton the same\n// way Skeleton pairs with real content: one placeholder for \"nothing\n// loaded yet\", one for \"loaded, and there's nothing\".\nconst Empty = ({\n icon,\n title,\n description = 'No data',\n action,\n className,\n ...props\n}: Props) => {\n return (\n <div\n role=\"status\"\n className={cn(\n 'flex flex-col items-center justify-center gap-3 py-12 text-center',\n className,\n //\n )}\n {...props}\n >\n <div className=\"text-muted-foreground [&_svg]:size-12\">\n {icon ?? <Inbox />}\n </div>\n {title && <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=\"mt-1\">{action}</div>}\n </div>\n );\n};\n\nexport default Empty;\n"],"mappings":";;;;;AAgBA,MAAM,SAAS,EACb,MACA,OACA,cAAc,WACd,QACA,WACA,GAAG,YACQ;AACX,QACE,qBAAC;EACC,MAAK;EACL,WAAW,GACT,qEACA,UAED;EACD,GAAI;;GAEJ,oBAAC;IAAI,WAAU;cACZ,QAAQ,oBAAC,UAAQ;KACd;GACL,SAAS,oBAAC;IAAE,WAAU;cAAuB;KAAU;GACvD,eACC,oBAAC;IAAE,WAAU;cAAiC;KAAgB;GAE/D,UAAU,oBAAC;IAAI,WAAU;cAAQ;KAAa;;GAC3C"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/templates/grid/col.d.ts
|
|
4
|
+
interface ResponsiveColSpan {
|
|
5
|
+
span?: number;
|
|
6
|
+
offset?: number;
|
|
7
|
+
}
|
|
8
|
+
type ColSpanProp = number | ResponsiveColSpan;
|
|
9
|
+
interface Props extends React.ComponentProps<'div'> {
|
|
10
|
+
span?: number;
|
|
11
|
+
offset?: number;
|
|
12
|
+
xs?: ColSpanProp;
|
|
13
|
+
sm?: ColSpanProp;
|
|
14
|
+
md?: ColSpanProp;
|
|
15
|
+
lg?: ColSpanProp;
|
|
16
|
+
xl?: ColSpanProp;
|
|
17
|
+
'2xl'?: ColSpanProp;
|
|
18
|
+
}
|
|
19
|
+
declare const Col: ({
|
|
20
|
+
span,
|
|
21
|
+
offset,
|
|
22
|
+
xs,
|
|
23
|
+
sm,
|
|
24
|
+
md,
|
|
25
|
+
lg,
|
|
26
|
+
xl,
|
|
27
|
+
"2xl": xxl,
|
|
28
|
+
className,
|
|
29
|
+
style,
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Col, Props };
|
|
35
|
+
//# sourceMappingURL=col.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"col.d.mts","names":[],"sources":["../../../../src/components/templates/grid/col.tsx"],"mappings":";;;UAUU,iBAAA;EACR,IAAA;EACA,MAAA;AAAA;AAAA,KAGG,WAAA,YAAuB,iBAAA;AAAA,UAEX,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,IAAA;EACA,MAAA;EACA,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,KAAA,GAAQ,WAAA;AAAA;AAAA,cAaJ,GAAA;EAAO,IAAA;EAAA,MAAA;EAAA,EAAA;EAAA,EAAA;EAAA,EAAA;EAAA,EAAA;EAAA,EAAA;EAAA,OAAA,GAAA;EAAA,SAAA;EAAA,KAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAaV,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../../utils.mjs";
|
|
4
|
+
import { useRowContext } from "./row-context.mjs";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/components/templates/grid/col.tsx
|
|
8
|
+
const TOTAL_COLUMNS = 24;
|
|
9
|
+
const BREAKPOINT_ORDER = [
|
|
10
|
+
"xs",
|
|
11
|
+
"sm",
|
|
12
|
+
"md",
|
|
13
|
+
"lg",
|
|
14
|
+
"xl",
|
|
15
|
+
"2xl"
|
|
16
|
+
];
|
|
17
|
+
const resolveColSpan = (value) => typeof value === "number" ? { span: value } : value;
|
|
18
|
+
const Col = ({ span = TOTAL_COLUMNS, offset = 0, xs, sm, md, lg, xl, "2xl": xxl, className, style, children, ...props }) => {
|
|
19
|
+
const { gutterX, breakpoint } = useRowContext();
|
|
20
|
+
const responsiveProps = {
|
|
21
|
+
xs,
|
|
22
|
+
sm,
|
|
23
|
+
md,
|
|
24
|
+
lg,
|
|
25
|
+
xl,
|
|
26
|
+
"2xl": xxl
|
|
27
|
+
};
|
|
28
|
+
let effectiveSpan = span;
|
|
29
|
+
let effectiveOffset = offset;
|
|
30
|
+
for (const bp of BREAKPOINT_ORDER) {
|
|
31
|
+
if (BREAKPOINT_ORDER.indexOf(bp) > BREAKPOINT_ORDER.indexOf(breakpoint)) break;
|
|
32
|
+
const resolved = resolveColSpan(responsiveProps[bp]);
|
|
33
|
+
if (resolved?.span !== void 0) effectiveSpan = resolved.span;
|
|
34
|
+
if (resolved?.offset !== void 0) effectiveOffset = resolved.offset;
|
|
35
|
+
}
|
|
36
|
+
const widthPercent = effectiveSpan / TOTAL_COLUMNS * 100;
|
|
37
|
+
const offsetPercent = effectiveOffset / TOTAL_COLUMNS * 100;
|
|
38
|
+
return /* @__PURE__ */ jsx("div", {
|
|
39
|
+
className: cn("box-border shrink-0 grow-0", className),
|
|
40
|
+
style: {
|
|
41
|
+
flexBasis: `${widthPercent}%`,
|
|
42
|
+
maxWidth: `${widthPercent}%`,
|
|
43
|
+
marginLeft: offsetPercent ? `${offsetPercent}%` : void 0,
|
|
44
|
+
paddingLeft: gutterX ? gutterX / 2 : void 0,
|
|
45
|
+
paddingRight: gutterX ? gutterX / 2 : void 0,
|
|
46
|
+
...style
|
|
47
|
+
},
|
|
48
|
+
...props,
|
|
49
|
+
children
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
export { Col as default };
|
|
55
|
+
//# sourceMappingURL=col.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"col.mjs","names":[],"sources":["../../../../src/components/templates/grid/col.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { type Breakpoint, useRowContext } from './row-context';\n\nconst TOTAL_COLUMNS = 24;\n\nconst BREAKPOINT_ORDER: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'];\n\ninterface ResponsiveColSpan {\n span?: number;\n offset?: number;\n}\n\ntype ColSpanProp = number | ResponsiveColSpan;\n\nexport interface Props extends React.ComponentProps<'div'> {\n span?: number;\n offset?: number;\n xs?: ColSpanProp;\n sm?: ColSpanProp;\n md?: ColSpanProp;\n lg?: ColSpanProp;\n xl?: ColSpanProp;\n '2xl'?: ColSpanProp;\n}\n\nconst resolveColSpan = (value: ColSpanProp | undefined) =>\n typeof value === 'number' ? { span: value } : value;\n\n// 24-column system (matches Ant Design's Row/Col, a familiar mental model\n// for anyone coming from it) implemented with plain percentage widths\n// rather than Tailwind's col-span-* utilities — those utilities need a\n// literal, statically-scannable class per (breakpoint, span) combination,\n// and 6 breakpoints x 24 spans is 144 combinations, most of which would\n// never be used. Percentage math scales to any span/breakpoint\n// combination with one code path instead.\nconst Col = ({\n span = TOTAL_COLUMNS,\n offset = 0,\n xs,\n sm,\n md,\n lg,\n xl,\n '2xl': xxl,\n className,\n style,\n children,\n ...props\n}: Props) => {\n const { gutterX, breakpoint } = useRowContext();\n\n const responsiveProps: Partial<Record<Breakpoint, ColSpanProp | undefined>> =\n { xs, sm, md, lg, xl, '2xl': xxl };\n\n let effectiveSpan = span;\n let effectiveOffset = offset;\n\n // Mobile-first cascade: walk breakpoints up to (and including) the\n // current one, letting each defined prop override the last — so\n // `<Col span={24} md={12} />` is 24 below md and 12 from md upward, with\n // no need to also specify lg/xl/2xl for the value to keep applying.\n for (const bp of BREAKPOINT_ORDER) {\n if (BREAKPOINT_ORDER.indexOf(bp) > BREAKPOINT_ORDER.indexOf(breakpoint)) {\n break;\n }\n\n const resolved = resolveColSpan(responsiveProps[bp]);\n\n if (resolved?.span !== undefined) {\n effectiveSpan = resolved.span;\n }\n if (resolved?.offset !== undefined) {\n effectiveOffset = resolved.offset;\n }\n }\n\n const widthPercent = (effectiveSpan / TOTAL_COLUMNS) * 100;\n const offsetPercent = (effectiveOffset / TOTAL_COLUMNS) * 100;\n\n return (\n <div\n className={cn('box-border shrink-0 grow-0', className)}\n style={{\n flexBasis: `${widthPercent}%`,\n maxWidth: `${widthPercent}%`,\n marginLeft: offsetPercent ? `${offsetPercent}%` : undefined,\n paddingLeft: gutterX ? gutterX / 2 : undefined,\n paddingRight: gutterX ? gutterX / 2 : undefined,\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n\nexport default Col;\n"],"mappings":";;;;;;;AAMA,MAAM,gBAAgB;AAEtB,MAAM,mBAAiC;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;AAoB5E,MAAM,kBAAkB,UACtB,OAAO,UAAU,WAAW,EAAE,MAAM,OAAO,GAAG;AAShD,MAAM,OAAO,EACX,OAAO,eACP,SAAS,GACT,IACA,IACA,IACA,IACA,IACA,OAAO,KACP,WACA,OACA,UACA,GAAG,YACQ;CACX,MAAM,EAAE,SAAS,eAAe,eAAe;CAE/C,MAAM,kBACJ;EAAE;EAAI;EAAI;EAAI;EAAI;EAAI,OAAO;EAAK;CAEpC,IAAI,gBAAgB;CACpB,IAAI,kBAAkB;AAMtB,MAAK,MAAM,MAAM,kBAAkB;AACjC,MAAI,iBAAiB,QAAQ,GAAG,GAAG,iBAAiB,QAAQ,WAAW,CACrE;EAGF,MAAM,WAAW,eAAe,gBAAgB,IAAI;AAEpD,MAAI,UAAU,SAAS,OACrB,iBAAgB,SAAS;AAE3B,MAAI,UAAU,WAAW,OACvB,mBAAkB,SAAS;;CAI/B,MAAM,eAAgB,gBAAgB,gBAAiB;CACvD,MAAM,gBAAiB,kBAAkB,gBAAiB;AAE1D,QACE,oBAAC;EACC,WAAW,GAAG,8BAA8B,UAAU;EACtD,OAAO;GACL,WAAW,GAAG,aAAa;GAC3B,UAAU,GAAG,aAAa;GAC1B,YAAY,gBAAgB,GAAG,cAAc,KAAK;GAClD,aAAa,UAAU,UAAU,IAAI;GACrC,cAAc,UAAU,UAAU,IAAI;GACtC,GAAG;GACJ;EACD,GAAI;EAEH;GACG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/components/templates/grid/row-context.ts
|
|
4
|
+
const RowContext = createContext({
|
|
5
|
+
gutterX: 0,
|
|
6
|
+
gutterY: 0,
|
|
7
|
+
breakpoint: "xs"
|
|
8
|
+
});
|
|
9
|
+
const useRowContext = () => useContext(RowContext);
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { RowContext, useRowContext };
|
|
13
|
+
//# sourceMappingURL=row-context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-context.mjs","names":[],"sources":["../../../../src/components/templates/grid/row-context.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nexport type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\nexport interface RowContextValue {\n gutterX: number;\n gutterY: number;\n breakpoint: Breakpoint;\n}\n\n// Defaults assume Col is used without a Row (not the intended usage, but\n// shouldn't crash) — 'xs' matches useResponsiveSize's own SSR-safe initial\n// guess (measures 0 width before mount), same mobile-first default Sider's\n// breakpoint feature already relies on.\nexport const RowContext = createContext<RowContextValue>({\n gutterX: 0,\n gutterY: 0,\n breakpoint: 'xs',\n});\n\nexport const useRowContext = () => useContext(RowContext);\n"],"mappings":";;;AAcA,MAAa,aAAa,cAA+B;CACvD,SAAS;CACT,SAAS;CACT,YAAY;CACb,CAAC;AAEF,MAAa,sBAAsB,WAAW,WAAW"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/templates/grid/row.d.ts
|
|
4
|
+
declare const ALIGN_CLASSES: {
|
|
5
|
+
top: string;
|
|
6
|
+
middle: string;
|
|
7
|
+
bottom: string;
|
|
8
|
+
stretch: string;
|
|
9
|
+
};
|
|
10
|
+
declare const JUSTIFY_CLASSES: {
|
|
11
|
+
start: string;
|
|
12
|
+
end: string;
|
|
13
|
+
center: string;
|
|
14
|
+
'space-around': string;
|
|
15
|
+
'space-between': string;
|
|
16
|
+
'space-evenly': string;
|
|
17
|
+
};
|
|
18
|
+
interface Props extends React.ComponentProps<'div'> {
|
|
19
|
+
gutter?: number | [number, number];
|
|
20
|
+
align?: keyof typeof ALIGN_CLASSES;
|
|
21
|
+
justify?: keyof typeof JUSTIFY_CLASSES;
|
|
22
|
+
wrap?: boolean;
|
|
23
|
+
}
|
|
24
|
+
declare const Row: ({
|
|
25
|
+
gutter,
|
|
26
|
+
align,
|
|
27
|
+
justify,
|
|
28
|
+
wrap,
|
|
29
|
+
className,
|
|
30
|
+
style,
|
|
31
|
+
children,
|
|
32
|
+
...props
|
|
33
|
+
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Props, Row };
|
|
36
|
+
//# sourceMappingURL=row.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row.d.mts","names":[],"sources":["../../../../src/components/templates/grid/row.tsx"],"mappings":";;;cAUM,aAAA;;;;;;cAOA,eAAA;;;;;;;;UASW,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,MAAA;EACA,KAAA,gBAAqB,aAAA;EACrB,OAAA,gBAAuB,eAAA;EACvB,IAAA;AAAA;AAAA,cAMI,GAAA;EAAO,MAAA;EAAA,KAAA;EAAA,OAAA;EAAA,IAAA;EAAA,SAAA;EAAA,KAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GASV,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../../utils.mjs";
|
|
4
|
+
import { RowContext } from "./row-context.mjs";
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { useResponsiveSize } from "@jbpark/use-hooks";
|
|
8
|
+
|
|
9
|
+
//#region src/components/templates/grid/row.tsx
|
|
10
|
+
const ALIGN_CLASSES = {
|
|
11
|
+
top: "items-start",
|
|
12
|
+
middle: "items-center",
|
|
13
|
+
bottom: "items-end",
|
|
14
|
+
stretch: "items-stretch"
|
|
15
|
+
};
|
|
16
|
+
const JUSTIFY_CLASSES = {
|
|
17
|
+
start: "justify-start",
|
|
18
|
+
end: "justify-end",
|
|
19
|
+
center: "justify-center",
|
|
20
|
+
"space-around": "justify-around",
|
|
21
|
+
"space-between": "justify-between",
|
|
22
|
+
"space-evenly": "justify-evenly"
|
|
23
|
+
};
|
|
24
|
+
const Row = ({ gutter = 0, align, justify, wrap = true, className, style, children, ...props }) => {
|
|
25
|
+
const [gutterX, gutterY] = Array.isArray(gutter) ? gutter : [gutter, 0];
|
|
26
|
+
const { breakpoint } = useResponsiveSize({ viewport: true });
|
|
27
|
+
const contextValue = useMemo(() => ({
|
|
28
|
+
gutterX,
|
|
29
|
+
gutterY,
|
|
30
|
+
breakpoint: breakpoint.current
|
|
31
|
+
}), [
|
|
32
|
+
gutterX,
|
|
33
|
+
gutterY,
|
|
34
|
+
breakpoint
|
|
35
|
+
]);
|
|
36
|
+
return /* @__PURE__ */ jsx(RowContext.Provider, {
|
|
37
|
+
value: contextValue,
|
|
38
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
39
|
+
className: cn("flex", wrap && "flex-wrap", align && ALIGN_CLASSES[align], justify && JUSTIFY_CLASSES[justify], className),
|
|
40
|
+
style: {
|
|
41
|
+
marginLeft: gutterX ? -gutterX / 2 : void 0,
|
|
42
|
+
marginRight: gutterX ? -gutterX / 2 : void 0,
|
|
43
|
+
rowGap: gutterY || void 0,
|
|
44
|
+
...style
|
|
45
|
+
},
|
|
46
|
+
...props,
|
|
47
|
+
children
|
|
48
|
+
})
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
export { Row as default };
|
|
54
|
+
//# sourceMappingURL=row.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row.mjs","names":[],"sources":["../../../../src/components/templates/grid/row.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { useResponsiveSize } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { RowContext } from './row-context';\n\nconst ALIGN_CLASSES = {\n top: 'items-start',\n middle: 'items-center',\n bottom: 'items-end',\n stretch: 'items-stretch',\n};\n\nconst JUSTIFY_CLASSES = {\n start: 'justify-start',\n end: 'justify-end',\n center: 'justify-center',\n 'space-around': 'justify-around',\n 'space-between': 'justify-between',\n 'space-evenly': 'justify-evenly',\n};\n\nexport interface Props extends React.ComponentProps<'div'> {\n gutter?: number | [number, number];\n align?: keyof typeof ALIGN_CLASSES;\n justify?: keyof typeof JUSTIFY_CLASSES;\n wrap?: boolean;\n}\n\n// The breakpoint tier is resolved once here (not per-Col) so N columns\n// share a single resize listener instead of each mounting its own via\n// useResponsiveSize — matters once a grid has more than a couple Cols.\nconst Row = ({\n gutter = 0,\n align,\n justify,\n wrap = true,\n className,\n style,\n children,\n ...props\n}: Props) => {\n const [gutterX, gutterY] = Array.isArray(gutter) ? gutter : [gutter, 0];\n const { breakpoint } = useResponsiveSize({ viewport: true });\n\n const contextValue = useMemo(\n () => ({ gutterX, gutterY, breakpoint: breakpoint.current }),\n [gutterX, gutterY, breakpoint],\n );\n\n return (\n <RowContext.Provider value={contextValue}>\n <div\n className={cn(\n 'flex',\n wrap && 'flex-wrap',\n align && ALIGN_CLASSES[align],\n justify && JUSTIFY_CLASSES[justify],\n className,\n //\n )}\n style={{\n // Negative margin + Col's matching padding is the classic\n // gutter technique — unlike a plain `gap`, it doesn't break the\n // percentage-width math when several Cols are meant to sum to\n // exactly 100% of the row. Vertical gutter has no such\n // constraint (it only affects spacing *between* wrapped rows),\n // so it uses native `row-gap` directly.\n marginLeft: gutterX ? -gutterX / 2 : undefined,\n marginRight: gutterX ? -gutterX / 2 : undefined,\n rowGap: gutterY || undefined,\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n </RowContext.Provider>\n );\n};\n\nexport default Row;\n"],"mappings":";;;;;;;;;AAUA,MAAM,gBAAgB;CACpB,KAAK;CACL,QAAQ;CACR,QAAQ;CACR,SAAS;CACV;AAED,MAAM,kBAAkB;CACtB,OAAO;CACP,KAAK;CACL,QAAQ;CACR,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CACjB;AAYD,MAAM,OAAO,EACX,SAAS,GACT,OACA,SACA,OAAO,MACP,WACA,OACA,UACA,GAAG,YACQ;CACX,MAAM,CAAC,SAAS,WAAW,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,QAAQ,EAAE;CACvE,MAAM,EAAE,eAAe,kBAAkB,EAAE,UAAU,MAAM,CAAC;CAE5D,MAAM,eAAe,eACZ;EAAE;EAAS;EAAS,YAAY,WAAW;EAAS,GAC3D;EAAC;EAAS;EAAS;EAAW,CAC/B;AAED,QACE,oBAAC,WAAW;EAAS,OAAO;YAC1B,oBAAC;GACC,WAAW,GACT,QACA,QAAQ,aACR,SAAS,cAAc,QACvB,WAAW,gBAAgB,UAC3B,UAED;GACD,OAAO;IAOL,YAAY,UAAU,CAAC,UAAU,IAAI;IACrC,aAAa,UAAU,CAAC,UAAU,IAAI;IACtC,QAAQ,WAAW;IACnB,GAAG;IACJ;GACD,GAAI;GAEH;IACG;GACc"}
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Props } from "./layout/content.mjs";
|
|
2
|
+
import { Props as Props$1 } from "./layout/footer.mjs";
|
|
3
|
+
import { Props as Props$2 } from "./layout/header.mjs";
|
|
4
|
+
import { Props as Props$3 } from "./layout/layout.mjs";
|
|
5
|
+
import { Props as Props$4 } from "./layout/sider.mjs";
|
|
6
|
+
import Layout from "../../Layout.mjs";
|
|
7
|
+
import { Container, Props as Props$5 } from "./container.mjs";
|
|
8
|
+
import { Empty, Props as Props$6 } from "./empty.mjs";
|
|
9
|
+
import { Props as Props$7, Result } from "./result.mjs";
|
|
10
|
+
import { PageHeader, Props as Props$8 } from "./page-header.mjs";
|
|
11
|
+
import { Props as Props$9, Row } from "./grid/row.mjs";
|
|
12
|
+
import { Col, Props as Props$10 } from "./grid/col.mjs";
|
|
13
|
+
import "./grid/index.mjs";
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/components/templates/layout/content.d.ts
|
|
4
|
-
interface Props extends React.
|
|
4
|
+
interface Props extends React.ComponentProps<'main'> {
|
|
5
|
+
asChild?: boolean;
|
|
6
|
+
}
|
|
5
7
|
declare const Content: ({
|
|
6
8
|
children,
|
|
7
9
|
className,
|
|
10
|
+
asChild,
|
|
8
11
|
...props
|
|
9
12
|
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
10
13
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.mts","names":[],"sources":["../../../../src/components/templates/layout/content.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"content.d.mts","names":[],"sources":["../../../../src/components/templates/layout/content.tsx"],"mappings":";;;UAIiB,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,OAAA;AAAA;AAAA,cAGI,OAAA;EAAW,QAAA;EAAA,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAAoD,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|