@keboola/design 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +25 -0
  2. package/dist/icon-names.cjs +18 -0
  3. package/dist/icon-names.cjs.map +1 -0
  4. package/dist/icon-names.js +16 -0
  5. package/dist/icon-names.js.map +1 -0
  6. package/dist/icons.cjs +731 -0
  7. package/dist/icons.cjs.map +1 -0
  8. package/dist/icons.js +29 -0
  9. package/dist/icons.js.map +1 -0
  10. package/dist/index.cjs +14728 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.js +14553 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/markdown-editor.cjs +4440 -0
  15. package/dist/markdown-editor.cjs.map +1 -0
  16. package/dist/markdown-editor.js +4413 -0
  17. package/dist/markdown-editor.js.map +1 -0
  18. package/dist/mermaid.cjs +1011 -0
  19. package/dist/mermaid.cjs.map +1 -0
  20. package/dist/mermaid.js +1005 -0
  21. package/dist/mermaid.js.map +1 -0
  22. package/dist/styles.css +1 -0
  23. package/package.json +10 -3
  24. package/src/blocks/AIKit/CollapsibleStepHeader.tsx +7 -8
  25. package/src/blocks/AIKit/InlineStepLabel.tsx +7 -7
  26. package/src/blocks/AIKit/MessageBubble.stories.tsx +11 -3
  27. package/src/blocks/AIKit/MessageBubble.tsx +1 -1
  28. package/src/blocks/AIKit/PlanApproval.tsx +9 -8
  29. package/src/blocks/AIKit/PlanRewritingIndicator.tsx +2 -2
  30. package/src/blocks/AIKit/PromptInput.stories.tsx +10 -2
  31. package/src/blocks/AIKit/PromptInputSubmit.tsx +12 -8
  32. package/src/blocks/AIKit/Question.tsx +8 -9
  33. package/src/blocks/AIKit/SuggestedPrompt.tsx +12 -5
  34. package/src/blocks/AIKit/ThinkingIndicator.tsx +2 -2
  35. package/src/blocks/AutoSaveTextarea/AutoSaveTextarea.tsx +4 -4
  36. package/src/blocks/ClipboardButton/ClipboardButton.tsx +7 -5
  37. package/src/blocks/ClipboardButton/ClipboardInline.tsx +2 -3
  38. package/src/blocks/ColorInput/ColorInput.tsx +4 -2
  39. package/src/blocks/ColorInput/ColorPicker.tsx +5 -2
  40. package/src/blocks/EmptyState/EmptyState.tsx +16 -0
  41. package/src/blocks/ErrorState/ErrorState.tsx +15 -0
  42. package/src/blocks/Form/formHook.ts +15 -0
  43. package/src/blocks/MultiActionButtonGroup/MultiActionButton.stories.tsx +12 -11
  44. package/src/blocks/MultiActionButtonGroup/MultiActionButton.tsx +5 -4
  45. package/src/blocks/MultiCombobox/MultiCombobox.tsx +28 -12
  46. package/src/blocks/PageHeader/AGENTS.md +63 -3
  47. package/src/blocks/PageHeader/PageHeader.stories.tsx +124 -28
  48. package/src/blocks/PageHeader/PageHeader.tsx +15 -0
  49. package/src/blocks/PageHeader/PageHeaderDetail.tsx +23 -1
  50. package/src/blocks/PageHeader/PageHeaderIndex.tsx +20 -1
  51. package/src/blocks/PageLayout/PageLayout.tsx +26 -0
  52. package/src/blocks/PageToolbar/PageToolbar.stories.tsx +348 -0
  53. package/src/blocks/PageToolbar/PageToolbar.tsx +119 -0
  54. package/src/blocks/PageToolbar/index.ts +1 -0
  55. package/src/blocks/PasswordInput/PasswordInput.tsx +10 -10
  56. package/src/blocks/SearchInput/SearchInput.tsx +30 -4
  57. package/src/blocks/SearchInputWithNavigation/SearchInputWithNavigation.tsx +9 -6
  58. package/src/blocks/SplitButton/SplitButton.stories.tsx +7 -4
  59. package/src/blocks/SplitButton/SplitButton.tsx +17 -4
  60. package/src/blocks/Tagger/TagItem.tsx +4 -1
  61. package/src/blocks/Tagger/TagSelectPopover/TagSelectCreateItem.tsx +3 -1
  62. package/src/blocks/Tagger/TagSelectPopover/TagSelectList.tsx +2 -2
  63. package/src/blocks/Tagger/Tagger.tsx +2 -2
  64. package/src/components/Alert/Alert.stories.tsx +11 -3
  65. package/src/components/Alert/Alert.tsx +19 -1
  66. package/src/components/Alert/AlertCollapsibleIcon.tsx +3 -4
  67. package/src/components/Alert/AlertIcon.tsx +18 -21
  68. package/src/components/Badge/Badge.stories.tsx +22 -4
  69. package/src/components/Badge/Badge.tsx +16 -0
  70. package/src/components/Badge/BadgeButton.tsx +7 -6
  71. package/src/components/Breadcrumb/BreadcrumbEllipsis.tsx +2 -2
  72. package/src/components/Breadcrumb/BreadcrumbSeparator.tsx +2 -2
  73. package/src/components/Button/Button.stories.tsx +14 -2
  74. package/src/components/Button/Button.tsx +42 -5
  75. package/src/components/Button/styles.ts +4 -6
  76. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +32 -10
  77. package/src/components/Card/Card.tsx +17 -0
  78. package/src/components/Checkbox/Checkbox.tsx +3 -6
  79. package/src/components/CodeEditor/highlighting.ts +1 -1
  80. package/src/components/CollapsiblePanel.tsx +2 -5
  81. package/src/components/Combobox/Combobox.tsx +12 -14
  82. package/src/components/Combobox/ComboboxChips.tsx +6 -1
  83. package/src/components/Combobox/ComboboxItem.tsx +3 -4
  84. package/src/components/Combobox/ComboboxItemIndicator.tsx +6 -4
  85. package/src/components/Combobox/types.ts +2 -6
  86. package/src/components/Command/Command.stories.tsx +47 -56
  87. package/src/components/Command/CommandItem/CheckIndicator.tsx +26 -14
  88. package/src/components/Command/CommandItem/CommandItem.tsx +6 -3
  89. package/src/components/DropdownMenu/DropdownMenu.stories.tsx +8 -4
  90. package/src/components/DropdownMenu/DropdownMenuCheckboxItem.tsx +4 -1
  91. package/src/components/DropdownMenu/DropdownMenuItem.tsx +12 -6
  92. package/src/components/DropdownMenu/DropdownMenuItemIndicator.tsx +12 -6
  93. package/src/components/DropdownMenu/DropdownMenuRadioGroup/DropdownMenuRadioItem.tsx +8 -5
  94. package/src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubTrigger.tsx +2 -2
  95. package/src/components/DropdownMenu/ItemIcon.tsx +16 -8
  96. package/src/components/FormGroup/FormGroup.tsx +15 -0
  97. package/src/components/FullScreenModal/FullScreenModalHeader.tsx +4 -1
  98. package/src/components/Input/DateInput/DateInput.tsx +4 -1
  99. package/src/components/Input/DateRangeInput/DateRangeInput.tsx +4 -6
  100. package/src/components/Input/Input.tsx +18 -2
  101. package/src/components/Input/TextInput/TextInput.tsx +16 -0
  102. package/src/components/Input/TimeInput/TimeInput.tsx +4 -1
  103. package/src/components/InputGroup/InputGroup.stories.tsx +11 -3
  104. package/src/components/MarkdownEditor/MarkdownEditor.stories.tsx +63 -1
  105. package/src/components/MarkdownEditor/MarkdownEditor.tsx +105 -15
  106. package/src/components/MarkdownEditor/nodes/ImageNode.tsx +10 -10
  107. package/src/components/MarkdownEditor/nodes/MermaidNode.tsx +8 -8
  108. package/src/components/MarkdownEditor/plugins/KeyboardPlugin.tsx +47 -3
  109. package/src/components/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx +12 -3
  110. package/src/components/MarkdownEditor/plugins/ToolbarPlugin.tsx +20 -10
  111. package/src/components/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx +20 -14
  112. package/src/components/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx +25 -16
  113. package/src/components/MarkdownEditor/plugins/toolbar/LinkPanel.tsx +3 -3
  114. package/src/components/MarkdownEditor/transformers.ts +10 -0
  115. package/src/components/MergeEditor/AcceptControls/AcceptButton.tsx +9 -4
  116. package/src/components/MergeEditor/AcceptControls/AcceptControls.tsx +25 -14
  117. package/src/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.tsx +2 -2
  118. package/src/components/MergeEditor/MergeEditor.stories.tsx +15 -0
  119. package/src/components/MergeEditor/MergeEditor.tsx +9 -0
  120. package/src/components/MergeEditor/MergePane.tsx +22 -4
  121. package/src/components/MergeEditor/decorations.ts +2 -2
  122. package/src/components/Modal/Modal.stories.tsx +6 -4
  123. package/src/components/Modal/Modal.tsx +26 -0
  124. package/src/components/Modal/ModalBody.tsx +5 -0
  125. package/src/components/Modal/ModalCloseIcon.tsx +2 -3
  126. package/src/components/Modal/ModalContent.tsx +8 -0
  127. package/src/components/Modal/ModalFooter.tsx +5 -0
  128. package/src/components/Modal/ModalHeader.tsx +11 -0
  129. package/src/components/Modal/ModalIcon.tsx +45 -19
  130. package/src/components/Navbar/Navbar.stories.tsx +26 -13
  131. package/src/components/Navbar/NavbarMenuButton.tsx +11 -10
  132. package/src/components/Pagination/PaginationEllipsis.tsx +2 -2
  133. package/src/components/Pagination/PaginationNext.tsx +2 -1
  134. package/src/components/Pagination/PaginationPrevious.tsx +4 -1
  135. package/src/components/PanelWithDetails.tsx +3 -4
  136. package/src/components/Popconfirm/Popconfirm.stories.tsx +13 -5
  137. package/src/components/RadioGroup/Radio.tsx +6 -12
  138. package/src/components/Search/ClearButton.tsx +2 -2
  139. package/src/components/Search/Search.tsx +3 -3
  140. package/src/components/Select/Select.tsx +16 -5
  141. package/src/components/Select/SelectContent.tsx +13 -4
  142. package/src/components/Select/SelectItem.tsx +6 -5
  143. package/src/components/Select/SelectTrigger.tsx +2 -2
  144. package/src/components/Sidebar/Sidebar.stories.tsx +55 -19
  145. package/src/components/Sidebar/SidebarGroup/SidebarGroupAction.tsx +8 -4
  146. package/src/components/Sidebar/SidebarMenu/SidebarMenuButton.tsx +4 -2
  147. package/src/components/Sidebar/SidebarMenu/SidebarMenuCard.tsx +3 -2
  148. package/src/components/Sidebar/SidebarMenu/SidebarMenuIcon.tsx +12 -12
  149. package/src/components/Sidebar/SidebarMenu/SidebarMenuSub.tsx +3 -7
  150. package/src/components/Sidebar/SidebarMenu/SidebarSearchInput.tsx +3 -5
  151. package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
  152. package/src/components/Skeleton/Skeleton.tsx +24 -1
  153. package/src/components/Table/Table.stories.tsx +223 -1
  154. package/src/components/Table/Table.tsx +17 -0
  155. package/src/components/Tabs.tsx +25 -2
  156. package/src/components/Toast/ToastDismiss.tsx +3 -3
  157. package/src/components/Toast/ToastRoot.tsx +24 -19
  158. package/src/components/Toggle/Toggle.tsx +11 -6
  159. package/src/components/Tooltip/Tooltip.tsx +23 -0
  160. package/src/components/ZoomableSvg/ZoomableSvg.tsx +8 -6
  161. package/src/icons/Keboola.tsx +28 -0
  162. package/src/icons/icons.stories.tsx +174 -0
  163. package/src/icons/index.ts +180 -0
  164. package/src/index.ts +1 -0
  165. package/src/patterns/AlertWithAction.stories.tsx +30 -0
  166. package/src/patterns/CardWithEmptyState.stories.tsx +66 -0
  167. package/src/patterns/ConfirmDialog.stories.tsx +72 -0
  168. package/src/patterns/CreatableMultiCombobox.stories.tsx +33 -0
  169. package/src/patterns/DataCardWithSkeleton.stories.tsx +48 -0
  170. package/src/patterns/DisabledButtonTooltip.stories.tsx +30 -0
  171. package/src/patterns/FilterToolbar.stories.tsx +71 -0
  172. package/src/patterns/InfoTooltip.stories.tsx +56 -0
  173. package/src/patterns/ListDetail.stories.tsx +65 -0
  174. package/src/patterns/ModalForm.stories.tsx +59 -0
  175. package/src/patterns/PageHeaderTabs.stories.tsx +48 -0
  176. package/src/styles.css +16 -8
  177. package/src/utils/legacyIcon.tsx +28 -0
@@ -0,0 +1,1005 @@
1
+ import { useId, useState, useRef, useEffect, useCallback } from 'react';
2
+ import { renderMermaidSVG } from 'beautiful-mermaid';
3
+ import colors from '@keboola/tailwind-config/colors';
4
+ import { clsx } from 'clsx';
5
+ import { extendTailwindMerge } from 'tailwind-merge';
6
+ import { Root as Root$1, Trigger, Portal, Content } from '@radix-ui/react-tooltip';
7
+ import { cva } from 'class-variance-authority';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+ import { Root, Slottable } from '@radix-ui/react-slot';
10
+ import { Minimize2, Maximize2, Loader2, Copy } from 'lucide-react';
11
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
12
+ import { Tooltip as Tooltip$1, cn as cn$1 } from '@keboola/design';
13
+
14
+ // src/blocks/MermaidDiagram/MermaidDiagram.tsx
15
+ var twMerge = extendTailwindMerge({
16
+ prefix: "tw-"
17
+ });
18
+ var cn = (...classes) => twMerge(clsx(...classes));
19
+
20
+ // src/utils/copyToClipboard.ts
21
+ var copyToClipboard = (text) => {
22
+ return navigator.clipboard.writeText(text);
23
+ };
24
+
25
+ // src/constants/keyCodes.ts
26
+ var keyCodes = {
27
+ ENTER: "Enter",
28
+ SPACE: " "
29
+ };
30
+ var tooltipVariants = cva(
31
+ [
32
+ "tailwindcss-preflight",
33
+ "tw-inline-block",
34
+ "tw-rounded",
35
+ "tw-bg-neutral-800",
36
+ "tw-text-white",
37
+ "tw-break-anywhere",
38
+ "tw-max-h-96",
39
+ "tw-overflow-y-auto",
40
+ "tw-z-[1060]"
41
+ ],
42
+ {
43
+ defaultVariants: {
44
+ variant: "action"
45
+ },
46
+ variants: {
47
+ variant: {
48
+ action: [
49
+ "tw-max-w-fit",
50
+ "tw-px-3",
51
+ "tw-py-2",
52
+ "tw-text-center",
53
+ "tw-text-xs",
54
+ "tw-font-medium",
55
+ "tw-uppercase",
56
+ "tw-tracking-wider"
57
+ ],
58
+ explanatory: [
59
+ "tw-max-w-80",
60
+ "tw-px-4",
61
+ "tw-py-3",
62
+ "tw-text-left",
63
+ "tw-text-sm",
64
+ "tw-font-normal"
65
+ ]
66
+ }
67
+ }
68
+ }
69
+ );
70
+ var TooltipContent = ({
71
+ className,
72
+ variant,
73
+ keepOpenOnPointerDownOutside = false,
74
+ children,
75
+ onPointerDownOutside,
76
+ sideOffset = 8,
77
+ collisionPadding = 8,
78
+ hideWhenDetached = true,
79
+ placement = "right",
80
+ ...rest
81
+ }) => {
82
+ const handlePointerDownOutside = (event) => {
83
+ if (keepOpenOnPointerDownOutside) event.preventDefault();
84
+ onPointerDownOutside?.(event);
85
+ };
86
+ return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
87
+ Content,
88
+ {
89
+ ...rest,
90
+ "data-tooltip-content": true,
91
+ sideOffset,
92
+ collisionPadding,
93
+ onPointerDownOutside: handlePointerDownOutside,
94
+ className: tooltipVariants({ className, variant }),
95
+ hideWhenDetached,
96
+ side: placement,
97
+ children
98
+ }
99
+ ) });
100
+ };
101
+ var DELAY_SHOW_TOOLTIP = 300;
102
+ var TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest }) => /* @__PURE__ */ jsx(Root$1, { ...rest, delayDuration, children });
103
+ var TooltipTrigger = ({
104
+ ref,
105
+ children,
106
+ className,
107
+ keepOpenOnClick = false,
108
+ onClick,
109
+ onPointerDown,
110
+ asChild,
111
+ ...rest
112
+ }) => {
113
+ const handleClick = (event) => {
114
+ if (keepOpenOnClick) event.preventDefault();
115
+ onClick?.(event);
116
+ };
117
+ const handePointerDown = (event) => {
118
+ if (keepOpenOnClick) event.preventDefault();
119
+ onPointerDown?.(event);
120
+ };
121
+ return /* @__PURE__ */ jsx(
122
+ Trigger,
123
+ {
124
+ ...rest,
125
+ asChild: true,
126
+ ref,
127
+ className: cn("tailwindcss-preflight", className),
128
+ onClick: handleClick,
129
+ onPointerDown: handePointerDown,
130
+ children: asChild ? children : /* @__PURE__ */ jsx("span", { children })
131
+ }
132
+ );
133
+ };
134
+ var ACTION_TOOLTIP_LIMIT = 30;
135
+ var Tooltip = ({
136
+ tooltip,
137
+ children,
138
+ className,
139
+ keepOpenOnTriggerClick = false,
140
+ variant,
141
+ placement = "right",
142
+ forceHide = false,
143
+ forceShow = false,
144
+ // trigger props
145
+ triggerAsChild = false
146
+ }) => {
147
+ const [open, setOpen] = useState(false);
148
+ const resolvedVariant = (() => {
149
+ if (!!variant) return variant;
150
+ if (typeof tooltip === "string" && tooltip.length > ACTION_TOOLTIP_LIMIT) return "explanatory";
151
+ return "action";
152
+ })();
153
+ const isActionVariant = resolvedVariant === "action";
154
+ const handleKeyUp = (event) => {
155
+ if (![keyCodes.ENTER, keyCodes.SPACE].includes(event.key)) return;
156
+ event.stopPropagation();
157
+ };
158
+ return /* @__PURE__ */ jsxs(
159
+ TooltipRoot,
160
+ {
161
+ open: !!tooltip && (open || forceShow) && !forceHide,
162
+ onOpenChange: setOpen,
163
+ disableHoverableContent: isActionVariant,
164
+ children: [
165
+ /* @__PURE__ */ jsx(
166
+ TooltipTrigger,
167
+ {
168
+ asChild: triggerAsChild,
169
+ keepOpenOnClick: keepOpenOnTriggerClick,
170
+ onKeyUp: handleKeyUp,
171
+ children
172
+ }
173
+ ),
174
+ /* @__PURE__ */ jsx(
175
+ TooltipContent,
176
+ {
177
+ className,
178
+ variant: resolvedVariant,
179
+ placement,
180
+ keepOpenOnPointerDownOutside: keepOpenOnTriggerClick,
181
+ children: tooltip
182
+ }
183
+ )
184
+ ]
185
+ }
186
+ );
187
+ };
188
+ Tooltip.Root = TooltipRoot;
189
+ Tooltip.Content = TooltipContent;
190
+ Tooltip.Trigger = TooltipTrigger;
191
+ var HEIGHT_CLASS_NAME = {
192
+ xxs: "tw-h-3 tw-rounded",
193
+ xs: "tw-h-4 tw-rounded",
194
+ sm: "tw-h-5 tw-rounded",
195
+ md: "tw-h-6 tw-rounded-md",
196
+ lg: "tw-h-8 tw-rounded-lg",
197
+ xl: "tw-h-10 tw-rounded-lg",
198
+ "2xl": "tw-h-12 tw-rounded-lg"
199
+ };
200
+ var ANIMATION_CLASS_NAME = cn(
201
+ // base styles
202
+ "tw-relative",
203
+ "tw-overflow-hidden",
204
+ "tw-pointer-events-none",
205
+ "tw-bg-neutral-150",
206
+ // before
207
+ 'before:tw-content-[""]',
208
+ "before:tw-opacity-100",
209
+ "before:tw-absolute",
210
+ "before:tw-inset-0",
211
+ "before:-tw-translate-x-full",
212
+ "before:tw-animate-[shimmer_2s_infinite]",
213
+ "before:tw-bg-gradient-to-r",
214
+ "before:tw-from-transparent",
215
+ "before:tw-to-transparent",
216
+ "before:tw-via-neutral-50"
217
+ );
218
+ var Skeleton = ({ height = "md", className, count = 1 }) => {
219
+ const prefixId = useId();
220
+ const keys = Array.from({ length: count }, (_, i) => `${prefixId}-${i}`);
221
+ return /* @__PURE__ */ jsx(Fragment, { children: keys.map((key) => /* @__PURE__ */ jsx(
222
+ "div",
223
+ {
224
+ "data-skeleton": "true",
225
+ className: cn(HEIGHT_CLASS_NAME[height], ANIMATION_CLASS_NAME, className)
226
+ },
227
+ key
228
+ )) });
229
+ };
230
+ var Icon = ({ ref, icon, ...rest }) => /* @__PURE__ */ jsx(FontAwesomeIcon, { ...rest, ref, icon });
231
+ var variants = cva(
232
+ [
233
+ "tailwindcss-preflight",
234
+ "tw-group/button",
235
+ "tw-border-box",
236
+ // layout
237
+ "tw-relative",
238
+ "tw-flex",
239
+ "tw-items-center",
240
+ "tw-justify-center",
241
+ "tw-gap-2",
242
+ // text
243
+ "tw-text-xs",
244
+ "tw-leading-5",
245
+ "tw-font-medium",
246
+ "tw-tracking-[1px]",
247
+ "tw-uppercase",
248
+ // border
249
+ "tw-rounded",
250
+ "tw-border",
251
+ "tw-border-transparent",
252
+ // styling
253
+ "tw-shadow-none",
254
+ "[a]:tw-cursor-pointer",
255
+ // explicitly set for anchor
256
+ "focus-visible:tw-outline",
257
+ "focus-visible:tw-outline-1",
258
+ "focus-visible:-tw-outline-offset-1",
259
+ "focus-visible:tw-outline-secondary-500",
260
+ "focus-visible:tw-ring-4",
261
+ "focus-visible:tw-ring-secondary-200",
262
+ // disabled
263
+ "disabled:tw-opacity-40",
264
+ "disabled:tw-cursor-not-allowed",
265
+ // anchor support
266
+ "!tw-no-underline",
267
+ "aria-disabled:tw-opacity-40",
268
+ "aria-disabled:tw-cursor-not-allowed",
269
+ "[&_svg]:tw-shrink-0"
270
+ ],
271
+ {
272
+ defaultVariants: {
273
+ size: "medium",
274
+ variant: "primary",
275
+ block: false
276
+ },
277
+ variants: {
278
+ block: {
279
+ true: ["tw-w-full"]
280
+ },
281
+ variant: {
282
+ primary: [
283
+ "tw-text-white",
284
+ "tw-bg-primary-500",
285
+ "focus:tw-text-white",
286
+ "hover:tw-text-white",
287
+ "hover:not-disabled:tw-bg-primary-600",
288
+ "active:not-disabled:tw-bg-primary-800",
289
+ // anchor disabled override
290
+ "aria-disabled:!tw-bg-primary-500"
291
+ ],
292
+ secondary: [
293
+ "tw-text-white",
294
+ "tw-bg-secondary-500",
295
+ "focus:tw-text-white",
296
+ "hover:tw-text-white",
297
+ "hover:not-disabled:tw-bg-secondary-700",
298
+ "active:not-disabled:tw-bg-secondary-800",
299
+ // anchor disabled override
300
+ "aria-disabled:!tw-bg-secondary-500"
301
+ ],
302
+ danger: [
303
+ "tw-text-white",
304
+ "tw-bg-error-500",
305
+ "focus:tw-text-white",
306
+ "hover:tw-text-white",
307
+ "hover:not-disabled:tw-bg-error-600",
308
+ "active:not-disabled:tw-bg-error-700",
309
+ // anchor disabled override
310
+ "aria-disabled:!tw-bg-error-500"
311
+ ],
312
+ invisible: [
313
+ "tw-text-neutral-800",
314
+ "tw-bg-transparent",
315
+ "focus:tw-text-neutral-800",
316
+ "hover:not-disabled:tw-bg-neutral-100",
317
+ "hover:tw-text-neutral-800",
318
+ "active:not-disabled:tw-bg-neutral-150",
319
+ // contrasting icon on hover/active
320
+ "[&_svg]:tw-text-neutral-400",
321
+ "[&_svg]:hover:not-disabled:tw-text-secondary-600",
322
+ "[&_svg]:active:not-disabled:tw-text-secondary-600",
323
+ // anchor disabled override
324
+ "aria-disabled:!tw-bg-transparent"
325
+ ],
326
+ outline: [
327
+ "tw-text-neutral-800",
328
+ "tw-bg-white",
329
+ // border
330
+ "!tw-border-neutral-200",
331
+ "hover:tw-text-neutral-800",
332
+ "focus:tw-text-neutral-800",
333
+ "hover:not-disabled:!tw-border-neutral-300",
334
+ "hover:not-disabled:tw-bg-neutral-100",
335
+ "active:not-disabled:tw-bg-neutral-200",
336
+ // contrasting icon hover, same as invisible
337
+ "[&_svg]:tw-text-neutral-400",
338
+ "[&_svg]:not-disabled:hover:tw-text-secondary-600",
339
+ "[&_svg]:active:not-disabled:tw-text-secondary-600",
340
+ // anchor disabled override
341
+ "aria-disabled:!tw-bg-white",
342
+ "aria-disabled:!tw-border-neutral-200"
343
+ ],
344
+ inline: [
345
+ "tw-text-neutral-800",
346
+ "tw-bg-transparent",
347
+ "tw-rounded-full",
348
+ "[&_svg]:tw-text-neutral-400",
349
+ "[&_svg]:not-disabled:hover:tw-text-secondary-600",
350
+ "[&_svg]:not-disabled:focus:tw-text-secondary-600"
351
+ ]
352
+ },
353
+ size: {
354
+ medium: ["tw-max-h-10", "tw-min-h-10", "tw-px-4", "tw-py-2.5", "[&_svg]:tw-size-4"],
355
+ small: ["tw-max-h-8", "tw-min-h-8", "tw-px-4", "tw-py-1.5", "[&_svg]:tw-size-4"],
356
+ large: ["tw-max-h-12", "tw-min-h-12", "tw-px-4", "tw-py-3.5", "[&_svg]:tw-size-4"],
357
+ "icon-lg": ["tw-size-12", "tw-p-0", "[&_svg]:tw-size-6"],
358
+ icon: ["tw-size-10", "tw-p-0", "[&_svg]:tw-size-4"],
359
+ "icon-sm": ["tw-size-8", "tw-p-0", "[&_svg]:tw-size-4"],
360
+ "icon-xs": ["tw-size-6", "tw-p-0", "[&_svg]:tw-size-4"],
361
+ "icon-2xs": ["!tw-inline-flex", "tw-size-5", "tw-max-h-5", "[&_svg]:tw-size-3"],
362
+ "icon-3xs": ["tw-h-fit", "tw-w-fit", "[&_svg]:tw-size-4"]
363
+ }
364
+ }
365
+ }
366
+ );
367
+ var argoVariants = cva(
368
+ [
369
+ "tailwindcss-preflight",
370
+ // layout
371
+ "tw-relative",
372
+ "tw-inline-flex",
373
+ "tw-items-center",
374
+ "tw-justify-center",
375
+ "tw-whitespace-nowrap",
376
+ "tw-gap-2",
377
+ // border
378
+ "tw-border",
379
+ "tw-border-transparent",
380
+ "tw-rounded-lg",
381
+ // text
382
+ "tw-font-medium",
383
+ "tw-select-none",
384
+ // focus visible
385
+ "!tw-outline-none",
386
+ "focus-visible:tw-ring-2",
387
+ // disabled
388
+ "disabled:tw-cursor-not-allowed",
389
+ "disabled:tw-opacity-50",
390
+ "active:tw-opacity-60",
391
+ "tw-transition-all",
392
+ "tw-bg-clip-padding",
393
+ // anchor support
394
+ "!tw-no-underline",
395
+ // icon
396
+ "tw-shrink-0",
397
+ "[&_svg]:tw-pointer-events-none",
398
+ "[&_svg]:tw-shrink-0",
399
+ "[&_svg:not([class*='tw-size-'])]:tw-size-4"
400
+ ],
401
+ {
402
+ defaultVariants: {
403
+ variant: "primary",
404
+ size: "medium"
405
+ },
406
+ variants: {
407
+ block: {
408
+ true: ["tw-w-full"]
409
+ },
410
+ variant: {
411
+ primary: [
412
+ "tw-bg-primary",
413
+ "tw-text-primary-foreground",
414
+ "[a]:hover:tw-bg-primary/80",
415
+ "hover:not-disabled:tw-bg-primary/90",
416
+ "hover:tw-text-primary-foreground",
417
+ "focus:tw-text-primary-foreground",
418
+ "focus-visible:tw-border-primary",
419
+ "focus-visible:tw-ring-primary/50"
420
+ ],
421
+ secondary: [
422
+ "tw-bg-primary/10",
423
+ "tw-text-primary",
424
+ "hover:not-disabled:tw-bg-primary/20",
425
+ "focus-visible:tw-border-primary",
426
+ "focus-visible:tw-ring-primary/50"
427
+ ],
428
+ // should be called "destructive" by Figma
429
+ danger: [
430
+ "tw-bg-destructive",
431
+ "tw-text-destructive-foreground",
432
+ "hover:tw-text-destructive-foreground",
433
+ "focus:tw-text-destructive-foreground",
434
+ "focus-visible:tw-border-destructive",
435
+ "focus-visible:tw-ring-destructive/20"
436
+ ],
437
+ outline: [
438
+ "!tw-border-input",
439
+ "tw-bg-background",
440
+ "hover:not-disabled:tw-bg-accent",
441
+ "hover:not-disabled:tw-text-accent-foreground",
442
+ "hover:active:tw-bg-background",
443
+ "focus-visible:!tw-border-primary",
444
+ "focus-visible:tw-ring-primary/50"
445
+ ],
446
+ // should be called "ghost" by Figma
447
+ invisible: [
448
+ "tw-bg-transparent",
449
+ "tw-text-foreground",
450
+ "hover:not-disabled:tw-bg-accent",
451
+ "hover:not-disabled:tw-text-accent-foreground",
452
+ "hover:not-disabled:tw-border-accent",
453
+ "focus-visible:tw-ring-primary/50"
454
+ ],
455
+ // should be called "link" by Figma
456
+ inline: [
457
+ "tw-bg-transparent",
458
+ "tw-text-primary",
459
+ "hover:tw-underline",
460
+ "hover:active:tw-bg-transparent",
461
+ "focus-visible:tw-ring-primary/50"
462
+ ]
463
+ },
464
+ size: {
465
+ // should be called "default" by Figma
466
+ medium: ["tw-max-h-9", "tw-py-2", "tw-px-4", "tw-text-sm"],
467
+ // should be called "small" by Figma
468
+ small: ["tw-max-h-8", "tw-py-2", "tw-px-3", "tw-text-xs"],
469
+ // should be called "large" by Figma
470
+ large: ["tw-max-h-10", "tw-py-2.5", "tw-px-6", "tw-text-sm"],
471
+ "icon-lg": ["tw-size-10"],
472
+ icon: ["tw-size-9"],
473
+ "icon-sm": ["tw-size-8"],
474
+ // unsupported in ARGO, remove when old design is gone
475
+ "icon-xs": [],
476
+ "icon-2xs": [],
477
+ "icon-3xs": []
478
+ }
479
+ }
480
+ }
481
+ );
482
+ var Button = ({
483
+ ref,
484
+ children,
485
+ disabled = false,
486
+ className,
487
+ type = "button",
488
+ isLoading = false,
489
+ asChild = false,
490
+ onClick,
491
+ argo = false,
492
+ variant = "primary",
493
+ size = "medium",
494
+ block = false,
495
+ icon,
496
+ ...buttonProps
497
+ }) => {
498
+ const Comp = asChild ? Root : "button";
499
+ const classNames = argo ? argoVariants({ variant, size, block, className }) : variants({
500
+ size,
501
+ variant,
502
+ block,
503
+ className
504
+ });
505
+ const handleClick = (event) => {
506
+ const isAnchor = event.currentTarget.tagName === "A";
507
+ if (isAnchor && disabled) {
508
+ event.preventDefault();
509
+ return;
510
+ }
511
+ onClick?.(event);
512
+ };
513
+ return /* @__PURE__ */ jsxs(
514
+ Comp,
515
+ {
516
+ ...buttonProps,
517
+ ref,
518
+ disabled,
519
+ "aria-disabled": disabled,
520
+ "data-variant": variant,
521
+ "data-icon-only": String(size).startsWith("icon"),
522
+ type,
523
+ onClick: handleClick,
524
+ className: cn(classNames),
525
+ children: [
526
+ isLoading && /* @__PURE__ */ jsx(Loader2, { className: "tw-size-4 tw-shrink-0 tw-animate-spin" }),
527
+ !isLoading && icon && /* @__PURE__ */ jsx(Icon, { icon }),
528
+ /* @__PURE__ */ jsx(Slottable, { children })
529
+ ]
530
+ }
531
+ );
532
+ };
533
+ var Clipboard = ({
534
+ ref,
535
+ text: textProp,
536
+ children,
537
+ tooltip = "Copy to Clipboard",
538
+ tooltipPlacement = "top",
539
+ tooltipVariant: tooltipVariantProp = "action",
540
+ asChild = false,
541
+ onClick,
542
+ className,
543
+ ...restButtonProps
544
+ }) => {
545
+ const [isTooltipOpen, setIsTooltipOpen] = useState(false);
546
+ const [state, setState] = useState("ready");
547
+ const text = typeof textProp === "function" ? textProp() : textProp;
548
+ const copy = async (text2) => {
549
+ try {
550
+ if (!document.hasFocus()) window.focus();
551
+ await copyToClipboard(text2);
552
+ setState("copied");
553
+ } catch {
554
+ setState("error");
555
+ }
556
+ };
557
+ const handleOnClick = (event) => {
558
+ if (text && state === "ready") void copy(text);
559
+ onClick?.(event);
560
+ };
561
+ const handleOnOpenChange = (open) => {
562
+ if (!open && state !== "ready") setState("ready");
563
+ setIsTooltipOpen(open);
564
+ };
565
+ const tooltipContent = (() => {
566
+ if (!text) return "Nothing to copy";
567
+ if (state === "error") return "Failed to copy";
568
+ if (state === "copied") return "Copied to Clipboard";
569
+ return tooltip;
570
+ })();
571
+ const tooltipVariant = state === "ready" && !!text ? tooltipVariantProp : "action";
572
+ return /* @__PURE__ */ jsxs(Tooltip$1.Root, { open: isTooltipOpen, onOpenChange: handleOnOpenChange, children: [
573
+ /* @__PURE__ */ jsx(
574
+ Tooltip$1.Trigger,
575
+ {
576
+ ...restButtonProps,
577
+ asChild,
578
+ keepOpenOnClick: true,
579
+ onClick: handleOnClick,
580
+ className: cn$1("tw-cursor-pointer", className),
581
+ ref,
582
+ children: children ?? text
583
+ }
584
+ ),
585
+ /* @__PURE__ */ jsx(
586
+ Tooltip$1.Content,
587
+ {
588
+ keepOpenOnPointerDownOutside: true,
589
+ placement: tooltipPlacement,
590
+ variant: tooltipVariant,
591
+ children: tooltipContent
592
+ }
593
+ )
594
+ ] });
595
+ };
596
+ var DEFAULT_ICON = /* @__PURE__ */ jsx(Copy, {});
597
+ var ClipboardButton = ({
598
+ // clipboard props
599
+ text,
600
+ tooltip,
601
+ tooltipPlacement,
602
+ tooltipVariant,
603
+ // button props
604
+ icon = DEFAULT_ICON,
605
+ variant = "outline",
606
+ children,
607
+ ...rest
608
+ }) => /* @__PURE__ */ jsx(
609
+ Clipboard,
610
+ {
611
+ asChild: true,
612
+ tooltip,
613
+ tooltipPlacement,
614
+ tooltipVariant,
615
+ text,
616
+ children: /* @__PURE__ */ jsxs(Button, { ...rest, variant, disabled: !text, children: [
617
+ icon,
618
+ children
619
+ ] })
620
+ }
621
+ );
622
+ var MIN_SCALE = 0.5;
623
+ var MAX_SCALE = 3;
624
+ var ZOOM_STEP = 0.1;
625
+ var ZoomableSvg = ({ html, copyText, className }) => {
626
+ const containerRef = useRef(null);
627
+ const [scale, setScale] = useState(1);
628
+ const [translate, setTranslate] = useState({ x: 0, y: 0 });
629
+ const [isFullscreen, setIsFullscreen] = useState(false);
630
+ useEffect(() => {
631
+ if (!isFullscreen) return;
632
+ const onKeyDown = (e) => {
633
+ if (e.key === "Escape") {
634
+ e.stopPropagation();
635
+ setIsFullscreen(false);
636
+ }
637
+ };
638
+ document.addEventListener("keydown", onKeyDown, { capture: true });
639
+ return () => document.removeEventListener("keydown", onKeyDown, { capture: true });
640
+ }, [isFullscreen]);
641
+ const dragRef = useRef(null);
642
+ useEffect(() => {
643
+ const el = containerRef.current;
644
+ if (!el) return;
645
+ const onWheel = (e) => {
646
+ if (!e.ctrlKey && !e.metaKey) return;
647
+ e.preventDefault();
648
+ const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;
649
+ setScale((s) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s + delta)));
650
+ };
651
+ el.addEventListener("wheel", onWheel, { passive: false });
652
+ return () => el.removeEventListener("wheel", onWheel);
653
+ }, []);
654
+ const didDragRef = useRef(false);
655
+ const handleMouseDown = useCallback(
656
+ (e) => {
657
+ if (e.button !== 0) return;
658
+ e.preventDefault();
659
+ didDragRef.current = false;
660
+ dragRef.current = {
661
+ startX: e.clientX,
662
+ startY: e.clientY,
663
+ startTx: translate.x,
664
+ startTy: translate.y
665
+ };
666
+ },
667
+ [translate]
668
+ );
669
+ const handleMouseMove = useCallback((e) => {
670
+ if (!dragRef.current) return;
671
+ didDragRef.current = true;
672
+ setTranslate({
673
+ x: dragRef.current.startTx + e.clientX - dragRef.current.startX,
674
+ y: dragRef.current.startTy + e.clientY - dragRef.current.startY
675
+ });
676
+ }, []);
677
+ const handleMouseUp = useCallback(() => {
678
+ dragRef.current = null;
679
+ }, []);
680
+ const handleReset = useCallback(() => {
681
+ setScale(1);
682
+ setTranslate({ x: 0, y: 0 });
683
+ }, []);
684
+ const isZoomed = Math.abs(scale - 1) > 1e-3 || translate.x !== 0 || translate.y !== 0;
685
+ const handleClick = useCallback((e) => {
686
+ if (didDragRef.current) {
687
+ e.stopPropagation();
688
+ }
689
+ }, []);
690
+ const stopPropagation = useCallback((e) => {
691
+ e.stopPropagation();
692
+ }, []);
693
+ const diagramContent = /* @__PURE__ */ jsxs(
694
+ "div",
695
+ {
696
+ role: "presentation",
697
+ className: cn("tw-group/zoom tw-relative", isFullscreen && "tw-h-full"),
698
+ onClick: handleClick,
699
+ children: [
700
+ /* @__PURE__ */ jsx(
701
+ "div",
702
+ {
703
+ role: "presentation",
704
+ ref: containerRef,
705
+ className: cn(
706
+ "tw-overflow-hidden tw-cursor-grab active:tw-cursor-grabbing tw-p-3",
707
+ isFullscreen && "tw-h-full"
708
+ ),
709
+ onMouseDown: handleMouseDown,
710
+ onMouseMove: handleMouseMove,
711
+ onMouseUp: handleMouseUp,
712
+ onMouseLeave: handleMouseUp,
713
+ children: /* @__PURE__ */ jsx(
714
+ "div",
715
+ {
716
+ className: cn(
717
+ "tw-flex tw-justify-center tw-origin-center",
718
+ isFullscreen && "tw-h-full [&>svg]:tw-h-full"
719
+ ),
720
+ style: { transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})` },
721
+ dangerouslySetInnerHTML: { __html: html }
722
+ }
723
+ )
724
+ }
725
+ ),
726
+ /* @__PURE__ */ jsxs(
727
+ "div",
728
+ {
729
+ role: "presentation",
730
+ className: "tw-absolute tw-right-1 tw-top-1 tw-flex tw-gap-1 tw-opacity-0 tw-transition-opacity group-hover/zoom:tw-opacity-100",
731
+ onClick: stopPropagation,
732
+ children: [
733
+ isZoomed && /* @__PURE__ */ jsx(Tooltip, { tooltip: "Reset zoom", placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "outline", onClick: handleReset, argo: true, children: "Reset" }) }),
734
+ copyText && /* @__PURE__ */ jsx(
735
+ ClipboardButton,
736
+ {
737
+ text: copyText,
738
+ tooltip: "Copy code",
739
+ size: "icon-sm",
740
+ variant: "outline",
741
+ argo: true
742
+ }
743
+ ),
744
+ /* @__PURE__ */ jsx(
745
+ Tooltip,
746
+ {
747
+ tooltip: isFullscreen ? "Exit fullscreen" : "Fullscreen",
748
+ placement: "top",
749
+ triggerAsChild: true,
750
+ children: /* @__PURE__ */ jsx(
751
+ Button,
752
+ {
753
+ size: "icon-sm",
754
+ variant: "outline",
755
+ "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
756
+ onClick: () => setIsFullscreen((f) => !f),
757
+ argo: true,
758
+ children: isFullscreen ? /* @__PURE__ */ jsx(Minimize2, { className: "tw-size-4" }) : /* @__PURE__ */ jsx(Maximize2, { className: "tw-size-4" })
759
+ }
760
+ )
761
+ }
762
+ )
763
+ ]
764
+ }
765
+ )
766
+ ]
767
+ }
768
+ );
769
+ if (isFullscreen) {
770
+ return /* @__PURE__ */ jsx(
771
+ "div",
772
+ {
773
+ role: "presentation",
774
+ className: "tw-fixed tw-inset-0 tw-z-[1060] tw-bg-neutral-50 tw-p-4",
775
+ onClick: stopPropagation,
776
+ children: diagramContent
777
+ }
778
+ );
779
+ }
780
+ return /* @__PURE__ */ jsx(
781
+ "div",
782
+ {
783
+ className: cn(
784
+ "tw-overflow-hidden tw-rounded-md tw-border tw-border-neutral-150 tw-bg-neutral-50",
785
+ className
786
+ ),
787
+ children: diagramContent
788
+ }
789
+ );
790
+ };
791
+ var mermaidPromise = null;
792
+ var getMermaid = () => {
793
+ if (!mermaidPromise) {
794
+ mermaidPromise = import('mermaid').then((m) => {
795
+ m.default.initialize({
796
+ startOnLoad: false,
797
+ securityLevel: "strict",
798
+ theme: "base",
799
+ themeVariables: {
800
+ primaryColor: colors.secondary[100],
801
+ primaryTextColor: colors.neutral[800],
802
+ primaryBorderColor: colors.secondary[700],
803
+ secondaryColor: colors.white,
804
+ secondaryTextColor: colors.neutral[800],
805
+ secondaryBorderColor: colors.neutral[150],
806
+ tertiaryColor: colors.warning[100],
807
+ tertiaryTextColor: colors.neutral[800],
808
+ tertiaryBorderColor: colors.warning[500],
809
+ lineColor: colors.neutral[300],
810
+ textColor: colors.neutral[800],
811
+ mainBkg: colors.secondary[100],
812
+ nodeBorder: colors.secondary[700],
813
+ clusterBkg: colors.white,
814
+ clusterBorder: colors.neutral[150],
815
+ titleColor: colors.neutral[800],
816
+ edgeLabelBackground: colors.white,
817
+ nodeTextColor: colors.neutral[800],
818
+ actorBorder: colors.secondary[700],
819
+ actorBkg: colors.secondary[100],
820
+ actorTextColor: colors.neutral[800],
821
+ actorLineColor: colors.neutral[300],
822
+ signalColor: colors.neutral[800],
823
+ signalTextColor: colors.neutral[800],
824
+ labelBoxBkgColor: colors.secondary[100],
825
+ labelBoxBorderColor: colors.secondary[700],
826
+ labelTextColor: colors.neutral[800],
827
+ loopTextColor: colors.neutral[800],
828
+ noteBorderColor: colors.warning[500],
829
+ noteBkgColor: colors.warning[100],
830
+ noteTextColor: colors.neutral[800],
831
+ sectionBkgColor: colors.secondary[100],
832
+ altSectionBkgColor: colors.white,
833
+ sectionBkgColor2: colors.neutral[100],
834
+ taskBorderColor: colors.secondary[700],
835
+ taskBkgColor: colors.secondary[100],
836
+ taskTextColor: colors.neutral[800],
837
+ taskTextDarkColor: colors.neutral[800],
838
+ taskTextLightColor: colors.neutral[800],
839
+ activeTaskBorderColor: colors.primary.DEFAULT,
840
+ activeTaskBkgColor: colors.secondary[200],
841
+ doneTaskBorderColor: colors.primary[600],
842
+ doneTaskBkgColor: colors.primary[100],
843
+ critBorderColor: colors.error[500],
844
+ critBkgColor: colors.error[100],
845
+ fontFamily: "Inter, system-ui, sans-serif",
846
+ fontSize: "14px"
847
+ }
848
+ });
849
+ return m;
850
+ }).catch((err) => {
851
+ mermaidPromise = null;
852
+ throw err;
853
+ });
854
+ }
855
+ return mermaidPromise;
856
+ };
857
+ var stripFontImports = (svg) => svg.replace(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*\);?\s*/g, "");
858
+ var tryFastRender = (code) => {
859
+ try {
860
+ return stripFontImports(
861
+ renderMermaidSVG(code, {
862
+ bg: colors.white,
863
+ fg: colors.neutral[800],
864
+ transparent: true,
865
+ font: "Inter, system-ui, sans-serif"
866
+ })
867
+ );
868
+ } catch {
869
+ return null;
870
+ }
871
+ };
872
+ var makeResponsive = (svgString) => {
873
+ const viewBoxMatch = svgString.match(/viewBox="[^"]*\s([\d.]+)\s[\d.]+"/);
874
+ const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : void 0;
875
+ let result = svgString.replace(/(<svg[^>]*?)\s+width="[^"]*"/i, '$1 width="100%"').replace(/(<svg[^>]*?)\s+height="[^"]*"/i, "$1");
876
+ if (!vbWidth) return result;
877
+ const hasStyle = /(<svg[^>]*?)\s+style="([^"]*)"/i.test(result);
878
+ if (hasStyle) {
879
+ result = result.replace(/(<svg[^>]*?)\s+style="([^"]*)"/i, (_m, pre, styles) => {
880
+ const cleaned = styles.replace(/max-width:\s*[^;"]*;?\s*/g, "").trim();
881
+ const combined = [cleaned, `max-width: ${vbWidth}px`].filter(Boolean).join("; ");
882
+ return `${pre} style="${combined}"`;
883
+ });
884
+ } else {
885
+ result = result.replace(/<svg/, `<svg style="max-width: ${vbWidth}px"`);
886
+ }
887
+ return result;
888
+ };
889
+ var RENDER_DEBOUNCE_MS = 300;
890
+ var svgCache = /* @__PURE__ */ new Map();
891
+ var MermaidDiagram = ({ code }) => {
892
+ const id = useId();
893
+ const [svg, setSvg] = useState(() => {
894
+ const cached = svgCache.get(code);
895
+ if (cached) return cached;
896
+ const fast = tryFastRender(code);
897
+ if (fast) {
898
+ svgCache.set(code, fast);
899
+ return fast;
900
+ }
901
+ return null;
902
+ });
903
+ const [renderFailed, setRenderFailed] = useState(false);
904
+ const debounceRef = useRef(null);
905
+ const renderIdRef = useRef(0);
906
+ const [prevCode, setPrevCode] = useState(code);
907
+ if (code !== prevCode) {
908
+ setPrevCode(code);
909
+ const cached = svgCache.get(code);
910
+ const fast = cached ?? tryFastRender(code);
911
+ if (fast && !cached) svgCache.set(code, fast);
912
+ setSvg(fast);
913
+ setRenderFailed(false);
914
+ }
915
+ useEffect(() => {
916
+ if (svgCache.has(code)) {
917
+ setSvg(svgCache.get(code));
918
+ setRenderFailed(false);
919
+ return;
920
+ }
921
+ const fastResult = tryFastRender(code);
922
+ if (fastResult) {
923
+ svgCache.set(code, fastResult);
924
+ setSvg(fastResult);
925
+ setRenderFailed(false);
926
+ return;
927
+ }
928
+ setSvg(null);
929
+ const currentRenderId = ++renderIdRef.current;
930
+ setRenderFailed(false);
931
+ if (debounceRef.current) {
932
+ clearTimeout(debounceRef.current);
933
+ }
934
+ debounceRef.current = setTimeout(() => {
935
+ getMermaid().then(async (mermaidModule) => {
936
+ if (renderIdRef.current !== currentRenderId) return;
937
+ const rendererId = `mermaid-${id.replaceAll(":", "")}`;
938
+ const container = document.createElement("div");
939
+ container.style.visibility = "hidden";
940
+ container.style.position = "absolute";
941
+ container.style.top = "-9999px";
942
+ container.style.width = "900px";
943
+ document.body.appendChild(container);
944
+ try {
945
+ const result = await mermaidModule.default.render(rendererId, code, container);
946
+ if (renderIdRef.current === currentRenderId && result) {
947
+ svgCache.set(code, result.svg);
948
+ setSvg(result.svg);
949
+ setRenderFailed(false);
950
+ }
951
+ } finally {
952
+ container.remove();
953
+ }
954
+ }).catch((err) => {
955
+ if (renderIdRef.current === currentRenderId) {
956
+ console.error("[MermaidDiagram] fallback failed:", err);
957
+ setSvg(null);
958
+ setRenderFailed(true);
959
+ }
960
+ });
961
+ }, RENDER_DEBOUNCE_MS);
962
+ const timer = debounceRef.current;
963
+ const renderId = renderIdRef;
964
+ return () => {
965
+ renderId.current++;
966
+ if (timer) {
967
+ clearTimeout(timer);
968
+ }
969
+ };
970
+ }, [code, id]);
971
+ const processedSvg = svg ? makeResponsive(svg) : null;
972
+ if (renderFailed) {
973
+ return /* @__PURE__ */ jsx(
974
+ "pre",
975
+ {
976
+ className: cn(
977
+ "tw-my-3 tw-overflow-auto tw-whitespace-pre-wrap tw-break-all",
978
+ "tw-py-3 tw-px-4",
979
+ "tw-bg-neutral-50",
980
+ "tw-rounded-md tw-text-neutral-400",
981
+ "tw-text-sm tw-font-mono"
982
+ ),
983
+ children: /* @__PURE__ */ jsx("code", { children: code })
984
+ }
985
+ );
986
+ }
987
+ if (processedSvg) {
988
+ return /* @__PURE__ */ jsx(
989
+ ZoomableSvg,
990
+ {
991
+ html: processedSvg,
992
+ copyText: `\`\`\`mermaid
993
+ ${code}
994
+ \`\`\``,
995
+ className: "tw-my-3"
996
+ },
997
+ code
998
+ );
999
+ }
1000
+ return /* @__PURE__ */ jsx("div", { className: "tw-my-3 tw-overflow-hidden tw-rounded-md tw-border tw-border-neutral-150 tw-bg-neutral-50 tw-p-6", children: /* @__PURE__ */ jsx(Skeleton, { className: "tw-h-40" }) });
1001
+ };
1002
+
1003
+ export { MermaidDiagram };
1004
+ //# sourceMappingURL=mermaid.js.map
1005
+ //# sourceMappingURL=mermaid.js.map