@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.
Files changed (101) hide show
  1. package/dist/components/atoms/float-button/back-top.d.mts.map +1 -1
  2. package/dist/components/atoms/float-button/back-top.mjs +3 -1
  3. package/dist/components/atoms/float-button/back-top.mjs.map +1 -1
  4. package/dist/components/atoms/input/search.d.mts.map +1 -1
  5. package/dist/components/atoms/input/search.mjs +3 -1
  6. package/dist/components/atoms/input/search.mjs.map +1 -1
  7. package/dist/components/atoms/skeleton/skeleton.d.mts.map +1 -1
  8. package/dist/components/atoms/skeleton/skeleton.mjs +5 -1
  9. package/dist/components/atoms/skeleton/skeleton.mjs.map +1 -1
  10. package/dist/components/atoms/spin.d.mts.map +1 -1
  11. package/dist/components/atoms/spin.mjs +7 -2
  12. package/dist/components/atoms/spin.mjs.map +1 -1
  13. package/dist/components/organisms/drawer.d.mts.map +1 -1
  14. package/dist/components/organisms/drawer.mjs +3 -1
  15. package/dist/components/organisms/drawer.mjs.map +1 -1
  16. package/dist/components/organisms/imperative-stack.mjs +106 -0
  17. package/dist/components/organisms/imperative-stack.mjs.map +1 -0
  18. package/dist/components/organisms/index.d.mts +3 -1
  19. package/dist/components/organisms/list/index.d.mts +1 -1
  20. package/dist/components/organisms/list/index.mjs.map +1 -1
  21. package/dist/components/organisms/list/list.d.mts +2 -2
  22. package/dist/components/organisms/list/list.d.mts.map +1 -1
  23. package/dist/components/organisms/list/list.mjs +20 -11
  24. package/dist/components/organisms/list/list.mjs.map +1 -1
  25. package/dist/components/organisms/modal.d.mts +2 -2
  26. package/dist/components/organisms/modal.d.mts.map +1 -1
  27. package/dist/components/organisms/modal.mjs +21 -101
  28. package/dist/components/organisms/modal.mjs.map +1 -1
  29. package/dist/components/organisms/swiper/index.d.mts +1 -1
  30. package/dist/components/organisms/swiper/index.mjs.map +1 -1
  31. package/dist/components/organisms/swiper/swiper.d.mts +2 -1
  32. package/dist/components/organisms/swiper/swiper.d.mts.map +1 -1
  33. package/dist/components/organisms/swiper/swiper.mjs +5 -3
  34. package/dist/components/organisms/swiper/swiper.mjs.map +1 -1
  35. package/dist/components/organisms/toast.d.mts +1 -1
  36. package/dist/components/organisms/toast.d.mts.map +1 -1
  37. package/dist/components/organisms/toast.mjs +35 -111
  38. package/dist/components/organisms/toast.mjs.map +1 -1
  39. package/dist/components/templates/container.d.mts +19 -0
  40. package/dist/components/templates/container.d.mts.map +1 -0
  41. package/dist/components/templates/container.mjs +32 -0
  42. package/dist/components/templates/container.mjs.map +1 -0
  43. package/dist/components/templates/empty.d.mts +20 -0
  44. package/dist/components/templates/empty.d.mts.map +1 -0
  45. package/dist/components/templates/empty.mjs +34 -0
  46. package/dist/components/templates/empty.mjs.map +1 -0
  47. package/dist/components/templates/grid/col.d.mts +35 -0
  48. package/dist/components/templates/grid/col.d.mts.map +1 -0
  49. package/dist/components/templates/grid/col.mjs +55 -0
  50. package/dist/components/templates/grid/col.mjs.map +1 -0
  51. package/dist/components/templates/grid/index.d.mts +2 -0
  52. package/dist/components/templates/grid/row-context.mjs +13 -0
  53. package/dist/components/templates/grid/row-context.mjs.map +1 -0
  54. package/dist/components/templates/grid/row.d.mts +36 -0
  55. package/dist/components/templates/grid/row.d.mts.map +1 -0
  56. package/dist/components/templates/grid/row.mjs +54 -0
  57. package/dist/components/templates/grid/row.mjs.map +1 -0
  58. package/dist/components/templates/index.d.mts +13 -1
  59. package/dist/components/templates/layout/content.d.mts +4 -1
  60. package/dist/components/templates/layout/content.d.mts.map +1 -1
  61. package/dist/components/templates/layout/content.mjs +3 -2
  62. package/dist/components/templates/layout/content.mjs.map +1 -1
  63. package/dist/components/templates/layout/footer.d.mts +1 -1
  64. package/dist/components/templates/layout/footer.d.mts.map +1 -1
  65. package/dist/components/templates/layout/footer.mjs.map +1 -1
  66. package/dist/components/templates/layout/header.d.mts +4 -1
  67. package/dist/components/templates/layout/header.d.mts.map +1 -1
  68. package/dist/components/templates/layout/header.mjs +2 -2
  69. package/dist/components/templates/layout/header.mjs.map +1 -1
  70. package/dist/components/templates/layout/layout.d.mts +1 -1
  71. package/dist/components/templates/layout/layout.d.mts.map +1 -1
  72. package/dist/components/templates/layout/layout.mjs.map +1 -1
  73. package/dist/components/templates/layout/sider.d.mts +9 -2
  74. package/dist/components/templates/layout/sider.d.mts.map +1 -1
  75. package/dist/components/templates/layout/sider.mjs +40 -13
  76. package/dist/components/templates/layout/sider.mjs.map +1 -1
  77. package/dist/components/templates/page-header.d.mts +30 -0
  78. package/dist/components/templates/page-header.d.mts.map +1 -0
  79. package/dist/components/templates/page-header.mjs +45 -0
  80. package/dist/components/templates/page-header.mjs.map +1 -0
  81. package/dist/components/templates/result.d.mts +24 -0
  82. package/dist/components/templates/result.d.mts.map +1 -0
  83. package/dist/components/templates/result.mjs +46 -0
  84. package/dist/components/templates/result.mjs.map +1 -0
  85. package/dist/index.d.mts +28 -15
  86. package/dist/index.mjs +9 -3
  87. package/dist/providers/Config/context.d.mts +3 -2
  88. package/dist/providers/Config/context.d.mts.map +1 -1
  89. package/dist/providers/Config/context.mjs +13 -2
  90. package/dist/providers/Config/context.mjs.map +1 -1
  91. package/dist/providers/Config/index.d.mts +4 -2
  92. package/dist/providers/Config/index.d.mts.map +1 -1
  93. package/dist/providers/Config/index.mjs +14 -4
  94. package/dist/providers/Config/index.mjs.map +1 -1
  95. package/dist/providers/Config/types.d.mts +10 -1
  96. package/dist/providers/Config/types.d.mts.map +1 -1
  97. package/dist/providers.d.mts +4 -0
  98. package/dist/providers.mjs +4 -0
  99. package/dist/style.css +114 -0
  100. package/package.json +3 -3
  101. 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, { useEffect, useState } from "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", id, container, icon, onOk, onCancel, ...props }) => {
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
- Modal.destroy(id);
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
- }), createModalRoot(container));
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
- Modal.destroy();
123
+ modalStack.destroy();
204
124
  };
205
- Modal.info = (props) => renderModal({
125
+ Modal.info = (props) => modalStack.render({
206
126
  type: "info",
207
127
  ...props
208
128
  });
209
- Modal.success = (props) => renderModal({
129
+ Modal.success = (props) => modalStack.render({
210
130
  type: "success",
211
131
  ...props
212
132
  });
213
- Modal.error = (props) => renderModal({
133
+ Modal.error = (props) => modalStack.render({
214
134
  type: "error",
215
135
  ...props
216
136
  });
217
- Modal.warning = (props) => renderModal({
137
+ Modal.warning = (props) => modalStack.render({
218
138
  type: "warning",
219
139
  ...props
220
140
  });
221
- Modal.confirm = (props) => renderModal({
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,5 +1,5 @@
1
1
  import { Slide } from "./slide.mjs";
2
- import { Swiper as Swiper$1 } from "./swiper.mjs";
2
+ import { Props, Swiper as Swiper$1 } from "./swiper.mjs";
3
3
 
4
4
  //#region src/components/organisms/swiper/index.d.ts
5
5
  type SwiperComponent = typeof Swiper$1 & {
@@ -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+BU,KAAA,YAAiB,WAAA;EACzB,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,UAAA;EAAA,gBAAA;EAAA,GAAA;AAAA,GAUjB,KAAA,CAAM,CAAA,MAAE,kBAAA,CAAA,GAAA,CAAA,OAAA"}
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
- children: loader || /* @__PURE__ */ jsx(Spin, { spinning: true })
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\ninterface 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 renderItem,\n loadingClassName,\n ...props\n}: Props<T>) => {\n if (loading) {\n return (\n <div className={cn('h-32', loadingClassName)}>\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 {...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,YACA,kBACA,GAAG,YACW;AACd,KAAI,QACF,QACE,oBAAC;EAAI,WAAW,GAAG,QAAQ,iBAAiB;YACzC,UAAU,oBAAC,QAAK,iBAAW;GACxB;AAIV,QACE,oBAACC;EACU;EACT,GAAI;EACJ,GAAI;EACJ,OAAO;GAAE,GAAG;GAAc,GAAG;GAAO;EACpC,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"}
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): void;
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":";;;KAcK,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,cA4DR,KAAA;EAAA;;;;;;;;;KASH,KAAA,GAAK,kBAAA,CAAA,GAAA,CAAA,OAAA;;;cAiKa,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"}
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 { useEffect, useState } from "react";
7
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
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
- Toast.destroy(id);
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
- }), createToastRoot(container));
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
- Toast.destroy();
100
+ toastStack.destroy();
177
101
  };
178
- Toast.info = (title, props) => renderToast({
102
+ Toast.info = (title, props) => toastStack.render({
179
103
  type: "info",
180
104
  title,
181
105
  ...props
182
106
  });
183
- Toast.success = (title, props) => renderToast({
107
+ Toast.success = (title, props) => toastStack.render({
184
108
  type: "success",
185
109
  title,
186
110
  ...props
187
111
  });
188
- Toast.error = (title, props) => renderToast({
112
+ Toast.error = (title, props) => toastStack.render({
189
113
  type: "error",
190
114
  title,
191
115
  ...props
192
116
  });
193
- Toast.warning = (title, props) => renderToast({
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"}