@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,4440 @@
1
+ 'use strict';
2
+
3
+ var clsx = require('clsx');
4
+ var tailwindMerge = require('tailwind-merge');
5
+ var reactTooltip = require('@radix-ui/react-tooltip');
6
+ var classVarianceAuthority = require('class-variance-authority');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+ var react = require('react');
9
+ var lucideReact = require('lucide-react');
10
+ var reactFontawesome = require('@fortawesome/react-fontawesome');
11
+ require('@awesome.me/kit-be8bcf7e5e/icons');
12
+ var reactSlot = require('@radix-ui/react-slot');
13
+ var design = require('@keboola/design');
14
+ var beautifulMermaid = require('beautiful-mermaid');
15
+ var colors = require('@keboola/tailwind-config/colors');
16
+ var code = require('@lexical/code');
17
+ var link = require('@lexical/link');
18
+ var list = require('@lexical/list');
19
+ var markdown = require('@lexical/markdown');
20
+ var LexicalAutoFocusPlugin = require('@lexical/react/LexicalAutoFocusPlugin');
21
+ var LexicalCheckListPlugin = require('@lexical/react/LexicalCheckListPlugin');
22
+ var LexicalClickableLinkPlugin = require('@lexical/react/LexicalClickableLinkPlugin');
23
+ var LexicalComposer = require('@lexical/react/LexicalComposer');
24
+ var LexicalContentEditable = require('@lexical/react/LexicalContentEditable');
25
+ var LexicalErrorBoundary = require('@lexical/react/LexicalErrorBoundary');
26
+ var LexicalHistoryPlugin = require('@lexical/react/LexicalHistoryPlugin');
27
+ var LexicalHorizontalRuleNode = require('@lexical/react/LexicalHorizontalRuleNode');
28
+ var LexicalHorizontalRulePlugin = require('@lexical/react/LexicalHorizontalRulePlugin');
29
+ var LexicalLinkPlugin = require('@lexical/react/LexicalLinkPlugin');
30
+ var LexicalListPlugin = require('@lexical/react/LexicalListPlugin');
31
+ var LexicalMarkdownShortcutPlugin = require('@lexical/react/LexicalMarkdownShortcutPlugin');
32
+ var LexicalRichTextPlugin = require('@lexical/react/LexicalRichTextPlugin');
33
+ var LexicalTabIndentationPlugin = require('@lexical/react/LexicalTabIndentationPlugin');
34
+ var richText = require('@lexical/rich-text');
35
+ var lexical = require('lexical');
36
+ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
37
+ var sonner = require('sonner');
38
+ var reactDom = require('react-dom');
39
+ var utils = require('@lexical/utils');
40
+ var DropdownMenuPrimitive3 = require('@radix-ui/react-dropdown-menu');
41
+ var ScrollAreaPrimitive2 = require('@radix-ui/react-scroll-area');
42
+ var TextareaAutosize = require('react-textarea-autosize');
43
+ var icons = require('@keboola/design/icons');
44
+ var RLabel = require('@radix-ui/react-label');
45
+
46
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
47
+
48
+ function _interopNamespace(e) {
49
+ if (e && e.__esModule) return e;
50
+ var n = Object.create(null);
51
+ if (e) {
52
+ Object.keys(e).forEach(function (k) {
53
+ if (k !== 'default') {
54
+ var d = Object.getOwnPropertyDescriptor(e, k);
55
+ Object.defineProperty(n, k, d.get ? d : {
56
+ enumerable: true,
57
+ get: function () { return e[k]; }
58
+ });
59
+ }
60
+ });
61
+ }
62
+ n.default = e;
63
+ return Object.freeze(n);
64
+ }
65
+
66
+ var colors__default = /*#__PURE__*/_interopDefault(colors);
67
+ var DropdownMenuPrimitive3__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive3);
68
+ var ScrollAreaPrimitive2__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive2);
69
+ var TextareaAutosize__default = /*#__PURE__*/_interopDefault(TextareaAutosize);
70
+ var RLabel__namespace = /*#__PURE__*/_interopNamespace(RLabel);
71
+
72
+ var __defProp = Object.defineProperty;
73
+ var __getOwnPropNames = Object.getOwnPropertyNames;
74
+ var __esm = (fn, res) => function __init() {
75
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
76
+ };
77
+ var __export = (target, all) => {
78
+ for (var name in all)
79
+ __defProp(target, name, { get: all[name], enumerable: true });
80
+ };
81
+ var twMerge, cn;
82
+ var init_classNames = __esm({
83
+ "src/utils/classNames.ts"() {
84
+ twMerge = tailwindMerge.extendTailwindMerge({
85
+ prefix: "tw-"
86
+ });
87
+ cn = (...classes) => twMerge(clsx.clsx(...classes));
88
+ }
89
+ });
90
+
91
+ // src/utils/copyToClipboard.ts
92
+ var copyToClipboard;
93
+ var init_copyToClipboard = __esm({
94
+ "src/utils/copyToClipboard.ts"() {
95
+ copyToClipboard = (text) => {
96
+ return navigator.clipboard.writeText(text);
97
+ };
98
+ }
99
+ });
100
+
101
+ // src/utils/createChangeInputEvent.ts
102
+ var createChangeInputEvent;
103
+ var init_createChangeInputEvent = __esm({
104
+ "src/utils/createChangeInputEvent.ts"() {
105
+ createChangeInputEvent = (input) => {
106
+ const changeEvent = {
107
+ target: input,
108
+ currentTarget: input,
109
+ type: "change",
110
+ nativeEvent: new Event("change", { bubbles: true }),
111
+ bubbles: true,
112
+ cancelable: false,
113
+ defaultPrevented: false,
114
+ eventPhase: 2,
115
+ // AT_TARGET
116
+ isTrusted: false,
117
+ // Synthetic events are not trusted
118
+ preventDefault: () => {
119
+ },
120
+ // Provide dummy functions if not needed
121
+ isDefaultPrevented: () => false,
122
+ stopPropagation: () => {
123
+ },
124
+ isPropagationStopped: () => false,
125
+ persist: () => {
126
+ },
127
+ timeStamp: Date.now()
128
+ };
129
+ Object.defineProperty(changeEvent, "target", {
130
+ value: input,
131
+ writable: false
132
+ });
133
+ return changeEvent;
134
+ };
135
+ }
136
+ });
137
+
138
+ // src/constants/keyCodes.ts
139
+ var keyCodes;
140
+ var init_keyCodes = __esm({
141
+ "src/constants/keyCodes.ts"() {
142
+ keyCodes = {
143
+ ENTER: "Enter",
144
+ ESCAPE: "Escape",
145
+ SPACE: " "
146
+ };
147
+ }
148
+ });
149
+ var tooltipVariants, TooltipContent;
150
+ var init_TooltipContent = __esm({
151
+ "src/components/Tooltip/TooltipContent.tsx"() {
152
+ tooltipVariants = classVarianceAuthority.cva(
153
+ [
154
+ "tailwindcss-preflight",
155
+ "tw-inline-block",
156
+ "tw-rounded",
157
+ "tw-bg-neutral-800",
158
+ "tw-text-white",
159
+ "tw-break-anywhere",
160
+ "tw-max-h-96",
161
+ "tw-overflow-y-auto",
162
+ "tw-z-[1060]"
163
+ ],
164
+ {
165
+ defaultVariants: {
166
+ variant: "action"
167
+ },
168
+ variants: {
169
+ variant: {
170
+ action: [
171
+ "tw-max-w-fit",
172
+ "tw-px-3",
173
+ "tw-py-2",
174
+ "tw-text-center",
175
+ "tw-text-xs",
176
+ "tw-font-medium",
177
+ "tw-uppercase",
178
+ "tw-tracking-wider"
179
+ ],
180
+ explanatory: [
181
+ "tw-max-w-80",
182
+ "tw-px-4",
183
+ "tw-py-3",
184
+ "tw-text-left",
185
+ "tw-text-sm",
186
+ "tw-font-normal"
187
+ ]
188
+ }
189
+ }
190
+ }
191
+ );
192
+ TooltipContent = ({
193
+ className,
194
+ variant,
195
+ keepOpenOnPointerDownOutside = false,
196
+ children,
197
+ onPointerDownOutside,
198
+ sideOffset = 8,
199
+ collisionPadding = 8,
200
+ hideWhenDetached = true,
201
+ placement = "right",
202
+ ...rest
203
+ }) => {
204
+ const handlePointerDownOutside = (event) => {
205
+ if (keepOpenOnPointerDownOutside) event.preventDefault();
206
+ onPointerDownOutside?.(event);
207
+ };
208
+ return /* @__PURE__ */ jsxRuntime.jsx(reactTooltip.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
209
+ reactTooltip.Content,
210
+ {
211
+ ...rest,
212
+ "data-tooltip-content": true,
213
+ sideOffset,
214
+ collisionPadding,
215
+ onPointerDownOutside: handlePointerDownOutside,
216
+ className: tooltipVariants({ className, variant }),
217
+ hideWhenDetached,
218
+ side: placement,
219
+ children
220
+ }
221
+ ) });
222
+ };
223
+ }
224
+ });
225
+ var DELAY_SHOW_TOOLTIP, TooltipRoot;
226
+ var init_TooltipRoot = __esm({
227
+ "src/components/Tooltip/TooltipRoot.tsx"() {
228
+ DELAY_SHOW_TOOLTIP = 300;
229
+ TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(reactTooltip.Root, { ...rest, delayDuration, children });
230
+ }
231
+ });
232
+ var TooltipTrigger;
233
+ var init_TooltipTrigger = __esm({
234
+ "src/components/Tooltip/TooltipTrigger.tsx"() {
235
+ init_utils();
236
+ TooltipTrigger = ({
237
+ ref,
238
+ children,
239
+ className,
240
+ keepOpenOnClick = false,
241
+ onClick,
242
+ onPointerDown,
243
+ asChild,
244
+ ...rest
245
+ }) => {
246
+ const handleClick = (event) => {
247
+ if (keepOpenOnClick) event.preventDefault();
248
+ onClick?.(event);
249
+ };
250
+ const handePointerDown = (event) => {
251
+ if (keepOpenOnClick) event.preventDefault();
252
+ onPointerDown?.(event);
253
+ };
254
+ return /* @__PURE__ */ jsxRuntime.jsx(
255
+ reactTooltip.Trigger,
256
+ {
257
+ ...rest,
258
+ asChild: true,
259
+ ref,
260
+ className: cn("tailwindcss-preflight", className),
261
+ onClick: handleClick,
262
+ onPointerDown: handePointerDown,
263
+ children: asChild ? children : /* @__PURE__ */ jsxRuntime.jsx("span", { children })
264
+ }
265
+ );
266
+ };
267
+ }
268
+ });
269
+ var ACTION_TOOLTIP_LIMIT, Tooltip;
270
+ var init_Tooltip = __esm({
271
+ "src/components/Tooltip/Tooltip.tsx"() {
272
+ init_keyCodes();
273
+ init_TooltipContent();
274
+ init_TooltipRoot();
275
+ init_TooltipTrigger();
276
+ ACTION_TOOLTIP_LIMIT = 30;
277
+ Tooltip = ({
278
+ tooltip,
279
+ children,
280
+ className,
281
+ keepOpenOnTriggerClick = false,
282
+ variant,
283
+ placement = "right",
284
+ forceHide = false,
285
+ forceShow = false,
286
+ // trigger props
287
+ triggerAsChild = false
288
+ }) => {
289
+ const [open, setOpen] = react.useState(false);
290
+ const resolvedVariant = (() => {
291
+ if (!!variant) return variant;
292
+ if (typeof tooltip === "string" && tooltip.length > ACTION_TOOLTIP_LIMIT) return "explanatory";
293
+ return "action";
294
+ })();
295
+ const isActionVariant = resolvedVariant === "action";
296
+ const handleKeyUp = (event) => {
297
+ if (![keyCodes.ENTER, keyCodes.SPACE].includes(event.key)) return;
298
+ event.stopPropagation();
299
+ };
300
+ return /* @__PURE__ */ jsxRuntime.jsxs(
301
+ TooltipRoot,
302
+ {
303
+ open: !!tooltip && (open || forceShow) && !forceHide,
304
+ onOpenChange: setOpen,
305
+ disableHoverableContent: isActionVariant,
306
+ children: [
307
+ /* @__PURE__ */ jsxRuntime.jsx(
308
+ TooltipTrigger,
309
+ {
310
+ asChild: triggerAsChild,
311
+ keepOpenOnClick: keepOpenOnTriggerClick,
312
+ onKeyUp: handleKeyUp,
313
+ children
314
+ }
315
+ ),
316
+ /* @__PURE__ */ jsxRuntime.jsx(
317
+ TooltipContent,
318
+ {
319
+ className,
320
+ variant: resolvedVariant,
321
+ placement,
322
+ keepOpenOnPointerDownOutside: keepOpenOnTriggerClick,
323
+ children: tooltip
324
+ }
325
+ )
326
+ ]
327
+ }
328
+ );
329
+ };
330
+ Tooltip.Root = TooltipRoot;
331
+ Tooltip.Content = TooltipContent;
332
+ Tooltip.Trigger = TooltipTrigger;
333
+ }
334
+ });
335
+
336
+ // src/components/Tooltip/index.ts
337
+ var init_Tooltip2 = __esm({
338
+ "src/components/Tooltip/index.ts"() {
339
+ init_Tooltip();
340
+ }
341
+ });
342
+ var init_decorators = __esm({
343
+ "src/utils/decorators.tsx"() {
344
+ }
345
+ });
346
+
347
+ // src/utils/createPrefixedString.ts
348
+ var createPrefixedString;
349
+ var init_createPrefixedString = __esm({
350
+ "src/utils/createPrefixedString.ts"() {
351
+ createPrefixedString = (prefix) => (literals) => literals.reduce((acc, literal) => acc + literal, `${prefix}-`);
352
+ }
353
+ });
354
+
355
+ // src/utils/escapeStringRegexp.ts
356
+ var init_escapeStringRegexp = __esm({
357
+ "src/utils/escapeStringRegexp.ts"() {
358
+ }
359
+ });
360
+
361
+ // src/utils/mergeRefs.ts
362
+ function setRef(ref, value) {
363
+ if (typeof ref === "function") {
364
+ ref(value);
365
+ } else if (ref != null) {
366
+ ref.current = value;
367
+ }
368
+ }
369
+ var mergeRefs;
370
+ var init_mergeRefs = __esm({
371
+ "src/utils/mergeRefs.ts"() {
372
+ mergeRefs = (...refs) => {
373
+ return (node) => refs.forEach((ref) => setRef(ref, node));
374
+ };
375
+ }
376
+ });
377
+
378
+ // src/utils/noop.ts
379
+ var init_noop = __esm({
380
+ "src/utils/noop.ts"() {
381
+ }
382
+ });
383
+
384
+ // src/utils/debounce.ts
385
+ var init_debounce = __esm({
386
+ "src/utils/debounce.ts"() {
387
+ }
388
+ });
389
+
390
+ // src/utils/isMac.ts
391
+ var getIsMac;
392
+ var init_isMac = __esm({
393
+ "src/utils/isMac.ts"() {
394
+ getIsMac = () => {
395
+ if (typeof navigator !== "undefined" && "userAgentData" in navigator) {
396
+ const platform = navigator.userAgentData.platform;
397
+ if (typeof platform === "string") {
398
+ return platform.toLowerCase() === "macos";
399
+ }
400
+ }
401
+ if (typeof navigator !== "undefined" && typeof navigator.platform === "string") {
402
+ return navigator.platform.toUpperCase().indexOf("MAC") >= 0;
403
+ }
404
+ return false;
405
+ };
406
+ getIsMac();
407
+ }
408
+ });
409
+ var init_useSHA256 = __esm({
410
+ "src/utils/useSHA256.ts"() {
411
+ }
412
+ });
413
+
414
+ // src/utils/index.ts
415
+ var init_utils = __esm({
416
+ "src/utils/index.ts"() {
417
+ init_classNames();
418
+ init_copyToClipboard();
419
+ init_createChangeInputEvent();
420
+ init_decorators();
421
+ init_createPrefixedString();
422
+ init_escapeStringRegexp();
423
+ init_mergeRefs();
424
+ init_noop();
425
+ init_debounce();
426
+ init_isMac();
427
+ init_useSHA256();
428
+ }
429
+ });
430
+ var HEIGHT_CLASS_NAME, ANIMATION_CLASS_NAME, Skeleton;
431
+ var init_Skeleton = __esm({
432
+ "src/components/Skeleton/Skeleton.tsx"() {
433
+ init_utils();
434
+ HEIGHT_CLASS_NAME = {
435
+ xxs: "tw-h-3 tw-rounded",
436
+ xs: "tw-h-4 tw-rounded",
437
+ sm: "tw-h-5 tw-rounded",
438
+ md: "tw-h-6 tw-rounded-md",
439
+ lg: "tw-h-8 tw-rounded-lg",
440
+ xl: "tw-h-10 tw-rounded-lg",
441
+ "2xl": "tw-h-12 tw-rounded-lg"
442
+ };
443
+ ANIMATION_CLASS_NAME = cn(
444
+ // base styles
445
+ "tw-relative",
446
+ "tw-overflow-hidden",
447
+ "tw-pointer-events-none",
448
+ "tw-bg-neutral-150",
449
+ // before
450
+ 'before:tw-content-[""]',
451
+ "before:tw-opacity-100",
452
+ "before:tw-absolute",
453
+ "before:tw-inset-0",
454
+ "before:-tw-translate-x-full",
455
+ "before:tw-animate-[shimmer_2s_infinite]",
456
+ "before:tw-bg-gradient-to-r",
457
+ "before:tw-from-transparent",
458
+ "before:tw-to-transparent",
459
+ "before:tw-via-neutral-50"
460
+ );
461
+ Skeleton = ({ height = "md", className, count = 1 }) => {
462
+ const prefixId = react.useId();
463
+ const keys = Array.from({ length: count }, (_, i) => `${prefixId}-${i}`);
464
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: keys.map((key) => /* @__PURE__ */ jsxRuntime.jsx(
465
+ "div",
466
+ {
467
+ "data-skeleton": "true",
468
+ className: cn(HEIGHT_CLASS_NAME[height], ANIMATION_CLASS_NAME, className)
469
+ },
470
+ key
471
+ )) });
472
+ };
473
+ }
474
+ });
475
+ var init_icons = __esm({
476
+ "src/icons/index.ts"() {
477
+ }
478
+ });
479
+ var Icon;
480
+ var init_Icon = __esm({
481
+ "src/components/Icon/Icon.tsx"() {
482
+ Icon = ({ ref, icon, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { ...rest, ref, icon });
483
+ }
484
+ });
485
+ var init_Icon2 = __esm({
486
+ "src/components/Icon/index.ts"() {
487
+ init_Icon();
488
+ }
489
+ });
490
+ var variants, argoVariants;
491
+ var init_styles = __esm({
492
+ "src/components/Button/styles.ts"() {
493
+ variants = classVarianceAuthority.cva(
494
+ [
495
+ "tailwindcss-preflight",
496
+ "tw-group/button",
497
+ "tw-border-box",
498
+ // layout
499
+ "tw-relative",
500
+ "tw-flex",
501
+ "tw-items-center",
502
+ "tw-justify-center",
503
+ "tw-gap-2",
504
+ // text
505
+ "tw-text-xs",
506
+ "tw-leading-5",
507
+ "tw-font-medium",
508
+ "tw-tracking-[1px]",
509
+ "tw-uppercase",
510
+ // border
511
+ "tw-rounded",
512
+ "tw-border",
513
+ "tw-border-transparent",
514
+ // styling
515
+ "tw-shadow-none",
516
+ "[a]:tw-cursor-pointer",
517
+ // explicitly set for anchor
518
+ "focus-visible:tw-outline",
519
+ "focus-visible:tw-outline-1",
520
+ "focus-visible:-tw-outline-offset-1",
521
+ "focus-visible:tw-outline-secondary-500",
522
+ "focus-visible:tw-ring-4",
523
+ "focus-visible:tw-ring-secondary-200",
524
+ // disabled
525
+ "disabled:tw-opacity-40",
526
+ "disabled:tw-cursor-not-allowed",
527
+ // anchor support
528
+ "!tw-no-underline",
529
+ "aria-disabled:tw-opacity-40",
530
+ "aria-disabled:tw-cursor-not-allowed",
531
+ "[&_svg]:tw-shrink-0"
532
+ ],
533
+ {
534
+ defaultVariants: {
535
+ size: "medium",
536
+ variant: "primary",
537
+ block: false
538
+ },
539
+ variants: {
540
+ block: {
541
+ true: ["tw-w-full"]
542
+ },
543
+ variant: {
544
+ primary: [
545
+ "tw-text-white",
546
+ "tw-bg-primary-500",
547
+ "focus:tw-text-white",
548
+ "hover:tw-text-white",
549
+ "hover:not-disabled:tw-bg-primary-600",
550
+ "active:not-disabled:tw-bg-primary-800",
551
+ // anchor disabled override
552
+ "aria-disabled:!tw-bg-primary-500"
553
+ ],
554
+ secondary: [
555
+ "tw-text-white",
556
+ "tw-bg-secondary-500",
557
+ "focus:tw-text-white",
558
+ "hover:tw-text-white",
559
+ "hover:not-disabled:tw-bg-secondary-700",
560
+ "active:not-disabled:tw-bg-secondary-800",
561
+ // anchor disabled override
562
+ "aria-disabled:!tw-bg-secondary-500"
563
+ ],
564
+ danger: [
565
+ "tw-text-white",
566
+ "tw-bg-error-500",
567
+ "focus:tw-text-white",
568
+ "hover:tw-text-white",
569
+ "hover:not-disabled:tw-bg-error-600",
570
+ "active:not-disabled:tw-bg-error-700",
571
+ // anchor disabled override
572
+ "aria-disabled:!tw-bg-error-500"
573
+ ],
574
+ invisible: [
575
+ "tw-text-neutral-800",
576
+ "tw-bg-transparent",
577
+ "focus:tw-text-neutral-800",
578
+ "hover:not-disabled:tw-bg-neutral-100",
579
+ "hover:tw-text-neutral-800",
580
+ "active:not-disabled:tw-bg-neutral-150",
581
+ // contrasting icon on hover/active
582
+ "[&_svg]:tw-text-neutral-400",
583
+ "[&_svg]:hover:not-disabled:tw-text-secondary-600",
584
+ "[&_svg]:active:not-disabled:tw-text-secondary-600",
585
+ // anchor disabled override
586
+ "aria-disabled:!tw-bg-transparent"
587
+ ],
588
+ outline: [
589
+ "tw-text-neutral-800",
590
+ "tw-bg-white",
591
+ // border
592
+ "!tw-border-neutral-200",
593
+ "hover:tw-text-neutral-800",
594
+ "focus:tw-text-neutral-800",
595
+ "hover:not-disabled:!tw-border-neutral-300",
596
+ "hover:not-disabled:tw-bg-neutral-100",
597
+ "active:not-disabled:tw-bg-neutral-200",
598
+ // contrasting icon hover, same as invisible
599
+ "[&_svg]:tw-text-neutral-400",
600
+ "[&_svg]:not-disabled:hover:tw-text-secondary-600",
601
+ "[&_svg]:active:not-disabled:tw-text-secondary-600",
602
+ // anchor disabled override
603
+ "aria-disabled:!tw-bg-white",
604
+ "aria-disabled:!tw-border-neutral-200"
605
+ ],
606
+ inline: [
607
+ "tw-text-neutral-800",
608
+ "tw-bg-transparent",
609
+ "tw-rounded-full",
610
+ "[&_svg]:tw-text-neutral-400",
611
+ "[&_svg]:not-disabled:hover:tw-text-secondary-600",
612
+ "[&_svg]:not-disabled:focus:tw-text-secondary-600"
613
+ ]
614
+ },
615
+ size: {
616
+ medium: ["tw-max-h-10", "tw-min-h-10", "tw-px-4", "tw-py-2.5", "[&_svg]:tw-size-4"],
617
+ small: ["tw-max-h-8", "tw-min-h-8", "tw-px-4", "tw-py-1.5", "[&_svg]:tw-size-4"],
618
+ large: ["tw-max-h-12", "tw-min-h-12", "tw-px-4", "tw-py-3.5", "[&_svg]:tw-size-4"],
619
+ "icon-lg": ["tw-size-12", "tw-p-0", "[&_svg]:tw-size-6"],
620
+ icon: ["tw-size-10", "tw-p-0", "[&_svg]:tw-size-4"],
621
+ "icon-sm": ["tw-size-8", "tw-p-0", "[&_svg]:tw-size-4"],
622
+ "icon-xs": ["tw-size-6", "tw-p-0", "[&_svg]:tw-size-4"],
623
+ "icon-2xs": ["!tw-inline-flex", "tw-size-5", "tw-max-h-5", "[&_svg]:tw-size-3"],
624
+ "icon-3xs": ["tw-h-fit", "tw-w-fit", "[&_svg]:tw-size-4"]
625
+ }
626
+ }
627
+ }
628
+ );
629
+ argoVariants = classVarianceAuthority.cva(
630
+ [
631
+ "tailwindcss-preflight",
632
+ // layout
633
+ "tw-relative",
634
+ "tw-inline-flex",
635
+ "tw-items-center",
636
+ "tw-justify-center",
637
+ "tw-whitespace-nowrap",
638
+ "tw-gap-2",
639
+ // border
640
+ "tw-border",
641
+ "tw-border-transparent",
642
+ "tw-rounded-lg",
643
+ // text
644
+ "tw-font-medium",
645
+ "tw-select-none",
646
+ // focus visible
647
+ "!tw-outline-none",
648
+ "focus-visible:tw-ring-2",
649
+ // disabled
650
+ "disabled:tw-cursor-not-allowed",
651
+ "disabled:tw-opacity-50",
652
+ "active:tw-opacity-60",
653
+ "tw-transition-all",
654
+ "tw-bg-clip-padding",
655
+ // anchor support
656
+ "!tw-no-underline",
657
+ // icon
658
+ "tw-shrink-0",
659
+ "[&_svg]:tw-pointer-events-none",
660
+ "[&_svg]:tw-shrink-0",
661
+ "[&_svg:not([class*='tw-size-'])]:tw-size-4"
662
+ ],
663
+ {
664
+ defaultVariants: {
665
+ variant: "primary",
666
+ size: "medium"
667
+ },
668
+ variants: {
669
+ block: {
670
+ true: ["tw-w-full"]
671
+ },
672
+ variant: {
673
+ primary: [
674
+ "tw-bg-primary",
675
+ "tw-text-primary-foreground",
676
+ "[a]:hover:tw-bg-primary/80",
677
+ "hover:not-disabled:tw-bg-primary/90",
678
+ "hover:tw-text-primary-foreground",
679
+ "focus:tw-text-primary-foreground",
680
+ "focus-visible:tw-border-primary",
681
+ "focus-visible:tw-ring-primary/50"
682
+ ],
683
+ secondary: [
684
+ "tw-bg-primary/10",
685
+ "tw-text-primary",
686
+ "hover:not-disabled:tw-bg-primary/20",
687
+ "focus-visible:tw-border-primary",
688
+ "focus-visible:tw-ring-primary/50"
689
+ ],
690
+ // should be called "destructive" by Figma
691
+ danger: [
692
+ "tw-bg-destructive",
693
+ "tw-text-destructive-foreground",
694
+ "hover:tw-text-destructive-foreground",
695
+ "focus:tw-text-destructive-foreground",
696
+ "focus-visible:tw-border-destructive",
697
+ "focus-visible:tw-ring-destructive/20"
698
+ ],
699
+ outline: [
700
+ "!tw-border-input",
701
+ "tw-bg-background",
702
+ "hover:not-disabled:tw-bg-accent",
703
+ "hover:not-disabled:tw-text-accent-foreground",
704
+ "hover:active:tw-bg-background",
705
+ "focus-visible:!tw-border-primary",
706
+ "focus-visible:tw-ring-primary/50"
707
+ ],
708
+ // should be called "ghost" by Figma
709
+ invisible: [
710
+ "tw-bg-transparent",
711
+ "tw-text-foreground",
712
+ "hover:not-disabled:tw-bg-accent",
713
+ "hover:not-disabled:tw-text-accent-foreground",
714
+ "hover:not-disabled:tw-border-accent",
715
+ "focus-visible:tw-ring-primary/50"
716
+ ],
717
+ // should be called "link" by Figma
718
+ inline: [
719
+ "tw-bg-transparent",
720
+ "tw-text-primary",
721
+ "hover:tw-underline",
722
+ "hover:active:tw-bg-transparent",
723
+ "focus-visible:tw-ring-primary/50"
724
+ ]
725
+ },
726
+ size: {
727
+ // should be called "default" by Figma
728
+ medium: ["tw-max-h-9", "tw-py-2", "tw-px-4", "tw-text-sm"],
729
+ // should be called "small" by Figma
730
+ small: ["tw-max-h-8", "tw-py-2", "tw-px-3", "tw-text-xs"],
731
+ // should be called "large" by Figma
732
+ large: ["tw-max-h-10", "tw-py-2.5", "tw-px-6", "tw-text-sm"],
733
+ "icon-lg": ["tw-size-10"],
734
+ icon: ["tw-size-9"],
735
+ "icon-sm": ["tw-size-8"],
736
+ // unsupported in ARGO, remove when old design is gone
737
+ "icon-xs": [],
738
+ "icon-2xs": [],
739
+ "icon-3xs": []
740
+ }
741
+ }
742
+ }
743
+ );
744
+ }
745
+ });
746
+ var Button;
747
+ var init_Button = __esm({
748
+ "src/components/Button/Button.tsx"() {
749
+ init_icons();
750
+ init_utils();
751
+ init_Icon2();
752
+ init_styles();
753
+ Button = ({
754
+ ref,
755
+ children,
756
+ disabled = false,
757
+ className,
758
+ type = "button",
759
+ isLoading = false,
760
+ asChild = false,
761
+ onClick,
762
+ argo = false,
763
+ variant = "primary",
764
+ size = "medium",
765
+ block = false,
766
+ icon,
767
+ ...buttonProps
768
+ }) => {
769
+ const Comp = asChild ? reactSlot.Root : "button";
770
+ const classNames = argo ? argoVariants({ variant, size, block, className }) : variants({
771
+ size,
772
+ variant,
773
+ block,
774
+ className
775
+ });
776
+ const handleClick = (event) => {
777
+ const isAnchor = event.currentTarget.tagName === "A";
778
+ if (isAnchor && disabled) {
779
+ event.preventDefault();
780
+ return;
781
+ }
782
+ onClick?.(event);
783
+ };
784
+ return /* @__PURE__ */ jsxRuntime.jsxs(
785
+ Comp,
786
+ {
787
+ ...buttonProps,
788
+ ref,
789
+ disabled,
790
+ "aria-disabled": disabled,
791
+ "data-variant": variant,
792
+ "data-icon-only": String(size).startsWith("icon"),
793
+ type,
794
+ onClick: handleClick,
795
+ className: cn(classNames),
796
+ children: [
797
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "tw-size-4 tw-shrink-0 tw-animate-spin" }),
798
+ !isLoading && icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }),
799
+ /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slottable, { children })
800
+ ]
801
+ }
802
+ );
803
+ };
804
+ }
805
+ });
806
+ var init_ButtonInline = __esm({
807
+ "src/components/Button/ButtonInline.tsx"() {
808
+ classVarianceAuthority.cva(
809
+ [
810
+ "tailwindcss-preflight",
811
+ "tw-inline-flex",
812
+ "tw-items-center",
813
+ "tw-gap-2",
814
+ "tw-underline-offset-2",
815
+ "disabled:tw-opacity-40",
816
+ "disabled:tw-cursor-not-allowed",
817
+ "disabled:tw-text-neutral-500",
818
+ "disabled:tw-no-underline",
819
+ "[&_svg]:disabled:tw-text-neutral-400"
820
+ ],
821
+ {
822
+ defaultVariants: {
823
+ variant: "link",
824
+ color: "link"
825
+ },
826
+ variants: {
827
+ color: {
828
+ link: [
829
+ "tw-text-secondary-500",
830
+ "hover:tw-text-secondary-600",
831
+ "[&_svg]:tw-text-secondary-500"
832
+ ],
833
+ dark: ["tw-text-neutral-800 [&_svg]:tw-text-neutral-400"],
834
+ danger: ["tw-text-error-500 [&_svg]:tw-text-error-500"],
835
+ muted: ["tw-text-muted-foreground [&_svg]:tw-text-muted-foreground"],
836
+ custom: []
837
+ },
838
+ variant: {
839
+ link: ["tw-underline", "hover:tw-no-underline"],
840
+ "link-reverse": ["tw-no-underline", "", "hover:tw-underline"],
841
+ custom: []
842
+ }
843
+ }
844
+ }
845
+ );
846
+ }
847
+ });
848
+
849
+ // src/components/Button/index.ts
850
+ var init_Button2 = __esm({
851
+ "src/components/Button/index.ts"() {
852
+ init_Button();
853
+ init_ButtonInline();
854
+ }
855
+ });
856
+ var Clipboard;
857
+ var init_Clipboard = __esm({
858
+ "src/components/Clipboard/Clipboard.tsx"() {
859
+ init_utils();
860
+ Clipboard = ({
861
+ ref,
862
+ text: textProp,
863
+ children,
864
+ tooltip = "Copy to Clipboard",
865
+ tooltipPlacement = "top",
866
+ tooltipVariant: tooltipVariantProp = "action",
867
+ asChild = false,
868
+ onClick,
869
+ className,
870
+ ...restButtonProps
871
+ }) => {
872
+ const [isTooltipOpen, setIsTooltipOpen] = react.useState(false);
873
+ const [state, setState] = react.useState("ready");
874
+ const text = typeof textProp === "function" ? textProp() : textProp;
875
+ const copy = async (text2) => {
876
+ try {
877
+ if (!document.hasFocus()) window.focus();
878
+ await copyToClipboard(text2);
879
+ setState("copied");
880
+ } catch {
881
+ setState("error");
882
+ }
883
+ };
884
+ const handleOnClick = (event) => {
885
+ if (text && state === "ready") void copy(text);
886
+ onClick?.(event);
887
+ };
888
+ const handleOnOpenChange = (open) => {
889
+ if (!open && state !== "ready") setState("ready");
890
+ setIsTooltipOpen(open);
891
+ };
892
+ const tooltipContent = (() => {
893
+ if (!text) return "Nothing to copy";
894
+ if (state === "error") return "Failed to copy";
895
+ if (state === "copied") return "Copied to Clipboard";
896
+ return tooltip;
897
+ })();
898
+ const tooltipVariant = state === "ready" && !!text ? tooltipVariantProp : "action";
899
+ return /* @__PURE__ */ jsxRuntime.jsxs(design.Tooltip.Root, { open: isTooltipOpen, onOpenChange: handleOnOpenChange, children: [
900
+ /* @__PURE__ */ jsxRuntime.jsx(
901
+ design.Tooltip.Trigger,
902
+ {
903
+ ...restButtonProps,
904
+ asChild,
905
+ keepOpenOnClick: true,
906
+ onClick: handleOnClick,
907
+ className: design.cn("tw-cursor-pointer", className),
908
+ ref,
909
+ children: children ?? text
910
+ }
911
+ ),
912
+ /* @__PURE__ */ jsxRuntime.jsx(
913
+ design.Tooltip.Content,
914
+ {
915
+ keepOpenOnPointerDownOutside: true,
916
+ placement: tooltipPlacement,
917
+ variant: tooltipVariant,
918
+ children: tooltipContent
919
+ }
920
+ )
921
+ ] });
922
+ };
923
+ }
924
+ });
925
+
926
+ // src/components/Clipboard/index.ts
927
+ var init_Clipboard2 = __esm({
928
+ "src/components/Clipboard/index.ts"() {
929
+ init_Clipboard();
930
+ }
931
+ });
932
+ var DEFAULT_ICON, ClipboardButton;
933
+ var init_ClipboardButton = __esm({
934
+ "src/blocks/ClipboardButton/ClipboardButton.tsx"() {
935
+ init_Button2();
936
+ init_Clipboard2();
937
+ init_icons();
938
+ DEFAULT_ICON = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, {});
939
+ ClipboardButton = ({
940
+ // clipboard props
941
+ text,
942
+ tooltip,
943
+ tooltipPlacement,
944
+ tooltipVariant,
945
+ // button props
946
+ icon = DEFAULT_ICON,
947
+ variant = "outline",
948
+ children,
949
+ ...rest
950
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
951
+ Clipboard,
952
+ {
953
+ asChild: true,
954
+ tooltip,
955
+ tooltipPlacement,
956
+ tooltipVariant,
957
+ text,
958
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { ...rest, variant, disabled: !text, children: [
959
+ icon,
960
+ children
961
+ ] })
962
+ }
963
+ );
964
+ }
965
+ });
966
+
967
+ // src/blocks/ClipboardButton/index.ts
968
+ var init_ClipboardButton2 = __esm({
969
+ "src/blocks/ClipboardButton/index.ts"() {
970
+ init_ClipboardButton();
971
+ }
972
+ });
973
+ var MIN_SCALE, MAX_SCALE, ZOOM_STEP, ZoomableSvg;
974
+ var init_ZoomableSvg = __esm({
975
+ "src/components/ZoomableSvg/ZoomableSvg.tsx"() {
976
+ init_ClipboardButton2();
977
+ init_icons();
978
+ init_utils();
979
+ init_Button2();
980
+ init_Tooltip2();
981
+ MIN_SCALE = 0.5;
982
+ MAX_SCALE = 3;
983
+ ZOOM_STEP = 0.1;
984
+ ZoomableSvg = ({ html, copyText, className }) => {
985
+ const containerRef = react.useRef(null);
986
+ const [scale, setScale] = react.useState(1);
987
+ const [translate, setTranslate] = react.useState({ x: 0, y: 0 });
988
+ const [isFullscreen, setIsFullscreen] = react.useState(false);
989
+ react.useEffect(() => {
990
+ if (!isFullscreen) return;
991
+ const onKeyDown = (e) => {
992
+ if (e.key === "Escape") {
993
+ e.stopPropagation();
994
+ setIsFullscreen(false);
995
+ }
996
+ };
997
+ document.addEventListener("keydown", onKeyDown, { capture: true });
998
+ return () => document.removeEventListener("keydown", onKeyDown, { capture: true });
999
+ }, [isFullscreen]);
1000
+ const dragRef = react.useRef(null);
1001
+ react.useEffect(() => {
1002
+ const el = containerRef.current;
1003
+ if (!el) return;
1004
+ const onWheel = (e) => {
1005
+ if (!e.ctrlKey && !e.metaKey) return;
1006
+ e.preventDefault();
1007
+ const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;
1008
+ setScale((s) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s + delta)));
1009
+ };
1010
+ el.addEventListener("wheel", onWheel, { passive: false });
1011
+ return () => el.removeEventListener("wheel", onWheel);
1012
+ }, []);
1013
+ const didDragRef = react.useRef(false);
1014
+ const handleMouseDown = react.useCallback(
1015
+ (e) => {
1016
+ if (e.button !== 0) return;
1017
+ e.preventDefault();
1018
+ didDragRef.current = false;
1019
+ dragRef.current = {
1020
+ startX: e.clientX,
1021
+ startY: e.clientY,
1022
+ startTx: translate.x,
1023
+ startTy: translate.y
1024
+ };
1025
+ },
1026
+ [translate]
1027
+ );
1028
+ const handleMouseMove = react.useCallback((e) => {
1029
+ if (!dragRef.current) return;
1030
+ didDragRef.current = true;
1031
+ setTranslate({
1032
+ x: dragRef.current.startTx + e.clientX - dragRef.current.startX,
1033
+ y: dragRef.current.startTy + e.clientY - dragRef.current.startY
1034
+ });
1035
+ }, []);
1036
+ const handleMouseUp = react.useCallback(() => {
1037
+ dragRef.current = null;
1038
+ }, []);
1039
+ const handleReset = react.useCallback(() => {
1040
+ setScale(1);
1041
+ setTranslate({ x: 0, y: 0 });
1042
+ }, []);
1043
+ const isZoomed = Math.abs(scale - 1) > 1e-3 || translate.x !== 0 || translate.y !== 0;
1044
+ const handleClick = react.useCallback((e) => {
1045
+ if (didDragRef.current) {
1046
+ e.stopPropagation();
1047
+ }
1048
+ }, []);
1049
+ const stopPropagation = react.useCallback((e) => {
1050
+ e.stopPropagation();
1051
+ }, []);
1052
+ const diagramContent = /* @__PURE__ */ jsxRuntime.jsxs(
1053
+ "div",
1054
+ {
1055
+ role: "presentation",
1056
+ className: cn("tw-group/zoom tw-relative", isFullscreen && "tw-h-full"),
1057
+ onClick: handleClick,
1058
+ children: [
1059
+ /* @__PURE__ */ jsxRuntime.jsx(
1060
+ "div",
1061
+ {
1062
+ role: "presentation",
1063
+ ref: containerRef,
1064
+ className: cn(
1065
+ "tw-overflow-hidden tw-cursor-grab active:tw-cursor-grabbing tw-p-3",
1066
+ isFullscreen && "tw-h-full"
1067
+ ),
1068
+ onMouseDown: handleMouseDown,
1069
+ onMouseMove: handleMouseMove,
1070
+ onMouseUp: handleMouseUp,
1071
+ onMouseLeave: handleMouseUp,
1072
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1073
+ "div",
1074
+ {
1075
+ className: cn(
1076
+ "tw-flex tw-justify-center tw-origin-center",
1077
+ isFullscreen && "tw-h-full [&>svg]:tw-h-full"
1078
+ ),
1079
+ style: { transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})` },
1080
+ dangerouslySetInnerHTML: { __html: html }
1081
+ }
1082
+ )
1083
+ }
1084
+ ),
1085
+ /* @__PURE__ */ jsxRuntime.jsxs(
1086
+ "div",
1087
+ {
1088
+ role: "presentation",
1089
+ 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",
1090
+ onClick: stopPropagation,
1091
+ children: [
1092
+ isZoomed && /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { tooltip: "Reset zoom", placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "small", variant: "outline", onClick: handleReset, argo: true, children: "Reset" }) }),
1093
+ copyText && /* @__PURE__ */ jsxRuntime.jsx(
1094
+ ClipboardButton,
1095
+ {
1096
+ text: copyText,
1097
+ tooltip: "Copy code",
1098
+ size: "icon-sm",
1099
+ variant: "outline",
1100
+ argo: true
1101
+ }
1102
+ ),
1103
+ /* @__PURE__ */ jsxRuntime.jsx(
1104
+ Tooltip,
1105
+ {
1106
+ tooltip: isFullscreen ? "Exit fullscreen" : "Fullscreen",
1107
+ placement: "top",
1108
+ triggerAsChild: true,
1109
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1110
+ Button,
1111
+ {
1112
+ size: "icon-sm",
1113
+ variant: "outline",
1114
+ "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
1115
+ onClick: () => setIsFullscreen((f) => !f),
1116
+ argo: true,
1117
+ children: isFullscreen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minimize2, { className: "tw-size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { className: "tw-size-4" })
1118
+ }
1119
+ )
1120
+ }
1121
+ )
1122
+ ]
1123
+ }
1124
+ )
1125
+ ]
1126
+ }
1127
+ );
1128
+ if (isFullscreen) {
1129
+ return /* @__PURE__ */ jsxRuntime.jsx(
1130
+ "div",
1131
+ {
1132
+ role: "presentation",
1133
+ className: "tw-fixed tw-inset-0 tw-z-[1060] tw-bg-neutral-50 tw-p-4",
1134
+ onClick: stopPropagation,
1135
+ children: diagramContent
1136
+ }
1137
+ );
1138
+ }
1139
+ return /* @__PURE__ */ jsxRuntime.jsx(
1140
+ "div",
1141
+ {
1142
+ className: cn(
1143
+ "tw-overflow-hidden tw-rounded-md tw-border tw-border-neutral-150 tw-bg-neutral-50",
1144
+ className
1145
+ ),
1146
+ children: diagramContent
1147
+ }
1148
+ );
1149
+ };
1150
+ }
1151
+ });
1152
+
1153
+ // src/components/ZoomableSvg/index.ts
1154
+ var init_ZoomableSvg2 = __esm({
1155
+ "src/components/ZoomableSvg/index.ts"() {
1156
+ init_ZoomableSvg();
1157
+ }
1158
+ });
1159
+
1160
+ // src/blocks/MermaidDiagram/MermaidDiagram.tsx
1161
+ var MermaidDiagram_exports = {};
1162
+ __export(MermaidDiagram_exports, {
1163
+ MermaidDiagram: () => MermaidDiagram
1164
+ });
1165
+ var mermaidPromise, getMermaid, stripFontImports, tryFastRender, makeResponsive, RENDER_DEBOUNCE_MS, svgCache, MermaidDiagram;
1166
+ var init_MermaidDiagram = __esm({
1167
+ "src/blocks/MermaidDiagram/MermaidDiagram.tsx"() {
1168
+ init_Skeleton();
1169
+ init_ZoomableSvg2();
1170
+ init_utils();
1171
+ mermaidPromise = null;
1172
+ getMermaid = () => {
1173
+ if (!mermaidPromise) {
1174
+ mermaidPromise = import('mermaid').then((m) => {
1175
+ m.default.initialize({
1176
+ startOnLoad: false,
1177
+ securityLevel: "strict",
1178
+ theme: "base",
1179
+ themeVariables: {
1180
+ primaryColor: colors__default.default.secondary[100],
1181
+ primaryTextColor: colors__default.default.neutral[800],
1182
+ primaryBorderColor: colors__default.default.secondary[700],
1183
+ secondaryColor: colors__default.default.white,
1184
+ secondaryTextColor: colors__default.default.neutral[800],
1185
+ secondaryBorderColor: colors__default.default.neutral[150],
1186
+ tertiaryColor: colors__default.default.warning[100],
1187
+ tertiaryTextColor: colors__default.default.neutral[800],
1188
+ tertiaryBorderColor: colors__default.default.warning[500],
1189
+ lineColor: colors__default.default.neutral[300],
1190
+ textColor: colors__default.default.neutral[800],
1191
+ mainBkg: colors__default.default.secondary[100],
1192
+ nodeBorder: colors__default.default.secondary[700],
1193
+ clusterBkg: colors__default.default.white,
1194
+ clusterBorder: colors__default.default.neutral[150],
1195
+ titleColor: colors__default.default.neutral[800],
1196
+ edgeLabelBackground: colors__default.default.white,
1197
+ nodeTextColor: colors__default.default.neutral[800],
1198
+ actorBorder: colors__default.default.secondary[700],
1199
+ actorBkg: colors__default.default.secondary[100],
1200
+ actorTextColor: colors__default.default.neutral[800],
1201
+ actorLineColor: colors__default.default.neutral[300],
1202
+ signalColor: colors__default.default.neutral[800],
1203
+ signalTextColor: colors__default.default.neutral[800],
1204
+ labelBoxBkgColor: colors__default.default.secondary[100],
1205
+ labelBoxBorderColor: colors__default.default.secondary[700],
1206
+ labelTextColor: colors__default.default.neutral[800],
1207
+ loopTextColor: colors__default.default.neutral[800],
1208
+ noteBorderColor: colors__default.default.warning[500],
1209
+ noteBkgColor: colors__default.default.warning[100],
1210
+ noteTextColor: colors__default.default.neutral[800],
1211
+ sectionBkgColor: colors__default.default.secondary[100],
1212
+ altSectionBkgColor: colors__default.default.white,
1213
+ sectionBkgColor2: colors__default.default.neutral[100],
1214
+ taskBorderColor: colors__default.default.secondary[700],
1215
+ taskBkgColor: colors__default.default.secondary[100],
1216
+ taskTextColor: colors__default.default.neutral[800],
1217
+ taskTextDarkColor: colors__default.default.neutral[800],
1218
+ taskTextLightColor: colors__default.default.neutral[800],
1219
+ activeTaskBorderColor: colors__default.default.primary.DEFAULT,
1220
+ activeTaskBkgColor: colors__default.default.secondary[200],
1221
+ doneTaskBorderColor: colors__default.default.primary[600],
1222
+ doneTaskBkgColor: colors__default.default.primary[100],
1223
+ critBorderColor: colors__default.default.error[500],
1224
+ critBkgColor: colors__default.default.error[100],
1225
+ fontFamily: "Inter, system-ui, sans-serif",
1226
+ fontSize: "14px"
1227
+ }
1228
+ });
1229
+ return m;
1230
+ }).catch((err) => {
1231
+ mermaidPromise = null;
1232
+ throw err;
1233
+ });
1234
+ }
1235
+ return mermaidPromise;
1236
+ };
1237
+ stripFontImports = (svg) => svg.replace(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*\);?\s*/g, "");
1238
+ tryFastRender = (code) => {
1239
+ try {
1240
+ return stripFontImports(
1241
+ beautifulMermaid.renderMermaidSVG(code, {
1242
+ bg: colors__default.default.white,
1243
+ fg: colors__default.default.neutral[800],
1244
+ transparent: true,
1245
+ font: "Inter, system-ui, sans-serif"
1246
+ })
1247
+ );
1248
+ } catch {
1249
+ return null;
1250
+ }
1251
+ };
1252
+ makeResponsive = (svgString) => {
1253
+ const viewBoxMatch = svgString.match(/viewBox="[^"]*\s([\d.]+)\s[\d.]+"/);
1254
+ const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : void 0;
1255
+ let result = svgString.replace(/(<svg[^>]*?)\s+width="[^"]*"/i, '$1 width="100%"').replace(/(<svg[^>]*?)\s+height="[^"]*"/i, "$1");
1256
+ if (!vbWidth) return result;
1257
+ const hasStyle = /(<svg[^>]*?)\s+style="([^"]*)"/i.test(result);
1258
+ if (hasStyle) {
1259
+ result = result.replace(/(<svg[^>]*?)\s+style="([^"]*)"/i, (_m, pre, styles) => {
1260
+ const cleaned = styles.replace(/max-width:\s*[^;"]*;?\s*/g, "").trim();
1261
+ const combined = [cleaned, `max-width: ${vbWidth}px`].filter(Boolean).join("; ");
1262
+ return `${pre} style="${combined}"`;
1263
+ });
1264
+ } else {
1265
+ result = result.replace(/<svg/, `<svg style="max-width: ${vbWidth}px"`);
1266
+ }
1267
+ return result;
1268
+ };
1269
+ RENDER_DEBOUNCE_MS = 300;
1270
+ svgCache = /* @__PURE__ */ new Map();
1271
+ MermaidDiagram = ({ code }) => {
1272
+ const id = react.useId();
1273
+ const [svg, setSvg] = react.useState(() => {
1274
+ const cached = svgCache.get(code);
1275
+ if (cached) return cached;
1276
+ const fast = tryFastRender(code);
1277
+ if (fast) {
1278
+ svgCache.set(code, fast);
1279
+ return fast;
1280
+ }
1281
+ return null;
1282
+ });
1283
+ const [renderFailed, setRenderFailed] = react.useState(false);
1284
+ const debounceRef = react.useRef(null);
1285
+ const renderIdRef = react.useRef(0);
1286
+ const [prevCode, setPrevCode] = react.useState(code);
1287
+ if (code !== prevCode) {
1288
+ setPrevCode(code);
1289
+ const cached = svgCache.get(code);
1290
+ const fast = cached ?? tryFastRender(code);
1291
+ if (fast && !cached) svgCache.set(code, fast);
1292
+ setSvg(fast);
1293
+ setRenderFailed(false);
1294
+ }
1295
+ react.useEffect(() => {
1296
+ if (svgCache.has(code)) {
1297
+ setSvg(svgCache.get(code));
1298
+ setRenderFailed(false);
1299
+ return;
1300
+ }
1301
+ const fastResult = tryFastRender(code);
1302
+ if (fastResult) {
1303
+ svgCache.set(code, fastResult);
1304
+ setSvg(fastResult);
1305
+ setRenderFailed(false);
1306
+ return;
1307
+ }
1308
+ setSvg(null);
1309
+ const currentRenderId = ++renderIdRef.current;
1310
+ setRenderFailed(false);
1311
+ if (debounceRef.current) {
1312
+ clearTimeout(debounceRef.current);
1313
+ }
1314
+ debounceRef.current = setTimeout(() => {
1315
+ getMermaid().then(async (mermaidModule) => {
1316
+ if (renderIdRef.current !== currentRenderId) return;
1317
+ const rendererId = `mermaid-${id.replaceAll(":", "")}`;
1318
+ const container = document.createElement("div");
1319
+ container.style.visibility = "hidden";
1320
+ container.style.position = "absolute";
1321
+ container.style.top = "-9999px";
1322
+ container.style.width = "900px";
1323
+ document.body.appendChild(container);
1324
+ try {
1325
+ const result = await mermaidModule.default.render(rendererId, code, container);
1326
+ if (renderIdRef.current === currentRenderId && result) {
1327
+ svgCache.set(code, result.svg);
1328
+ setSvg(result.svg);
1329
+ setRenderFailed(false);
1330
+ }
1331
+ } finally {
1332
+ container.remove();
1333
+ }
1334
+ }).catch((err) => {
1335
+ if (renderIdRef.current === currentRenderId) {
1336
+ console.error("[MermaidDiagram] fallback failed:", err);
1337
+ setSvg(null);
1338
+ setRenderFailed(true);
1339
+ }
1340
+ });
1341
+ }, RENDER_DEBOUNCE_MS);
1342
+ const timer = debounceRef.current;
1343
+ const renderId = renderIdRef;
1344
+ return () => {
1345
+ renderId.current++;
1346
+ if (timer) {
1347
+ clearTimeout(timer);
1348
+ }
1349
+ };
1350
+ }, [code, id]);
1351
+ const processedSvg = svg ? makeResponsive(svg) : null;
1352
+ if (renderFailed) {
1353
+ return /* @__PURE__ */ jsxRuntime.jsx(
1354
+ "pre",
1355
+ {
1356
+ className: cn(
1357
+ "tw-my-3 tw-overflow-auto tw-whitespace-pre-wrap tw-break-all",
1358
+ "tw-py-3 tw-px-4",
1359
+ "tw-bg-neutral-50",
1360
+ "tw-rounded-md tw-text-neutral-400",
1361
+ "tw-text-sm tw-font-mono"
1362
+ ),
1363
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code })
1364
+ }
1365
+ );
1366
+ }
1367
+ if (processedSvg) {
1368
+ return /* @__PURE__ */ jsxRuntime.jsx(
1369
+ ZoomableSvg,
1370
+ {
1371
+ html: processedSvg,
1372
+ copyText: `\`\`\`mermaid
1373
+ ${code}
1374
+ \`\`\``,
1375
+ className: "tw-my-3"
1376
+ },
1377
+ code
1378
+ );
1379
+ }
1380
+ return /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(Skeleton, { className: "tw-h-40" }) });
1381
+ };
1382
+ }
1383
+ });
1384
+
1385
+ // src/components/MarkdownEditor/MarkdownEditor.tsx
1386
+ init_utils();
1387
+ var ImageRendererContext = react.createContext(null);
1388
+ var ImageRendererProvider = ImageRendererContext;
1389
+ var useImageRenderer = () => react.use(ImageRendererContext);
1390
+ var isPlaceholder = (src) => src.startsWith("upload-placeholder-");
1391
+ var ImageNodeComponent = ({ src, alt }) => {
1392
+ const renderer = useImageRenderer();
1393
+ if (isPlaceholder(src)) {
1394
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw-inline-flex tw-items-center tw-gap-1 tw-rounded tw-bg-neutral-100 tw-px-2 tw-py-1 tw-text-xs tw-text-neutral-400", children: "Uploading image\u2026" });
1395
+ }
1396
+ if (renderer) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderer({ src, alt }) });
1397
+ return /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt });
1398
+ };
1399
+ var ImageNode = class _ImageNode extends lexical.DecoratorNode {
1400
+ __src;
1401
+ __altText;
1402
+ static getType() {
1403
+ return "image";
1404
+ }
1405
+ static clone(node) {
1406
+ return new _ImageNode(node.__src, node.__altText, node.__key);
1407
+ }
1408
+ constructor(src, altText, key) {
1409
+ super(key);
1410
+ this.__src = src;
1411
+ this.__altText = altText;
1412
+ }
1413
+ getSrc() {
1414
+ return this.__src;
1415
+ }
1416
+ getAlt() {
1417
+ return this.__altText;
1418
+ }
1419
+ setSrc(src) {
1420
+ const writable = this.getWritable();
1421
+ writable.__src = src;
1422
+ }
1423
+ setAlt(altText) {
1424
+ const writable = this.getWritable();
1425
+ writable.__altText = altText;
1426
+ }
1427
+ createDOM(config) {
1428
+ const span = document.createElement("span");
1429
+ const className = config.theme.image;
1430
+ if (typeof className === "string") {
1431
+ span.className = className;
1432
+ }
1433
+ return span;
1434
+ }
1435
+ updateDOM() {
1436
+ return false;
1437
+ }
1438
+ decorate() {
1439
+ return /* @__PURE__ */ jsxRuntime.jsx(ImageNodeComponent, { src: this.__src, alt: this.__altText });
1440
+ }
1441
+ isInline() {
1442
+ return true;
1443
+ }
1444
+ static importJSON(serializedNode) {
1445
+ return $createImageNode(serializedNode.src, serializedNode.altText);
1446
+ }
1447
+ exportJSON() {
1448
+ return {
1449
+ type: "image",
1450
+ version: 1,
1451
+ src: this.__src,
1452
+ altText: this.__altText
1453
+ };
1454
+ }
1455
+ exportDOM() {
1456
+ const element = document.createElement("img");
1457
+ element.setAttribute("src", this.__src);
1458
+ element.setAttribute("alt", this.__altText);
1459
+ return { element };
1460
+ }
1461
+ static importDOM() {
1462
+ return {
1463
+ img: () => ({
1464
+ conversion: (domNode) => {
1465
+ const src = domNode.getAttribute("src") || "";
1466
+ const alt = domNode.getAttribute("alt") || "";
1467
+ return { node: $createImageNode(src, alt) };
1468
+ },
1469
+ priority: 0
1470
+ })
1471
+ };
1472
+ }
1473
+ };
1474
+ var $createImageNode = (src, altText) => {
1475
+ return new ImageNode(src, altText);
1476
+ };
1477
+ var $isImageNode = (node) => {
1478
+ return node instanceof ImageNode;
1479
+ };
1480
+
1481
+ // src/components/MarkdownEditor/nodes/MermaidNodeComponent.tsx
1482
+ init_Skeleton();
1483
+ var MermaidDiagram2 = react.lazy(
1484
+ () => Promise.resolve().then(() => (init_MermaidDiagram(), MermaidDiagram_exports)).then(
1485
+ (m) => ({ default: m.MermaidDiagram }),
1486
+ (error) => {
1487
+ console.error("[MarkdownEditor] failed to load MermaidDiagram chunk", error);
1488
+ return {
1489
+ default: ({ code }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) })
1490
+ };
1491
+ }
1492
+ )
1493
+ );
1494
+ var MermaidNodeComponent = ({ code }) => {
1495
+ return /* @__PURE__ */ jsxRuntime.jsx(
1496
+ react.Suspense,
1497
+ {
1498
+ fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-my-3 tw-overflow-hidden tw-rounded-card tw-border tw-border-neutral-150 tw-bg-neutral-50 tw-p-6", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "tw-h-40" }) }),
1499
+ children: /* @__PURE__ */ jsxRuntime.jsx(MermaidDiagram2, { code })
1500
+ }
1501
+ );
1502
+ };
1503
+ var MermaidNode = class _MermaidNode extends lexical.DecoratorNode {
1504
+ __code;
1505
+ static getType() {
1506
+ return "mermaid";
1507
+ }
1508
+ static clone(node) {
1509
+ return new _MermaidNode(node.__code, node.__key);
1510
+ }
1511
+ constructor(code, key) {
1512
+ super(key);
1513
+ this.__code = code;
1514
+ }
1515
+ getCode() {
1516
+ return this.__code;
1517
+ }
1518
+ setCode(code) {
1519
+ const writable = this.getWritable();
1520
+ writable.__code = code;
1521
+ }
1522
+ createDOM() {
1523
+ const div = document.createElement("div");
1524
+ div.setAttribute("data-lexical-mermaid", "true");
1525
+ return div;
1526
+ }
1527
+ updateDOM() {
1528
+ return false;
1529
+ }
1530
+ decorate() {
1531
+ return /* @__PURE__ */ jsxRuntime.jsx(MermaidNodeComponent, { code: this.__code });
1532
+ }
1533
+ isInline() {
1534
+ return false;
1535
+ }
1536
+ static importJSON(serializedNode) {
1537
+ return $createMermaidNode(serializedNode.code);
1538
+ }
1539
+ exportJSON() {
1540
+ return {
1541
+ type: "mermaid",
1542
+ version: 1,
1543
+ code: this.__code
1544
+ };
1545
+ }
1546
+ };
1547
+ var $createMermaidNode = (code) => {
1548
+ return new MermaidNode(code);
1549
+ };
1550
+ var $isMermaidNode = (node) => {
1551
+ return node instanceof MermaidNode;
1552
+ };
1553
+
1554
+ // src/components/Toast/toast.tsx
1555
+ init_utils();
1556
+
1557
+ // src/components/Toast/ToastRoot.tsx
1558
+ init_icons();
1559
+ init_utils();
1560
+
1561
+ // src/utils/legacyIcon.tsx
1562
+ init_Icon2();
1563
+ var isFAIconValue = (value) => typeof value === "string" || Array.isArray(value) && value.length === 2 && typeof value[0] === "string" && typeof value[1] === "string";
1564
+ var renderLegacyIcon = (value) => isFAIconValue(value) ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: value }) : value;
1565
+
1566
+ // src/components/Toast/ToastAction.tsx
1567
+ init_utils();
1568
+ var ToastAction = ({
1569
+ ref,
1570
+ className,
1571
+ ...rest
1572
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1573
+ "button",
1574
+ {
1575
+ ...rest,
1576
+ ref,
1577
+ "data-slot": "toast-action",
1578
+ type: "button",
1579
+ className: cn(
1580
+ // layout
1581
+ "tw-col-start-3",
1582
+ "tw-row-start-1",
1583
+ "tw-flex",
1584
+ "tw-items-center",
1585
+ "tw-justify-center",
1586
+ // font
1587
+ "tw-text-xs",
1588
+ "tw-font-medium",
1589
+ "tw-text-primary",
1590
+ // sizing
1591
+ "tw-px-2",
1592
+ "tw-h-6",
1593
+ // styles
1594
+ "tw-bg-primary-foreground",
1595
+ "tw-rounded",
1596
+ className
1597
+ )
1598
+ }
1599
+ );
1600
+
1601
+ // src/components/Toast/ToastDescription.tsx
1602
+ init_utils();
1603
+ var ToastDescription = ({
1604
+ ref,
1605
+ className,
1606
+ children,
1607
+ ...rest
1608
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1609
+ "div",
1610
+ {
1611
+ ref,
1612
+ "data-slot": "toast-description",
1613
+ className: cn(
1614
+ "tw-col-start-2",
1615
+ "tw-font-normal",
1616
+ "tw-break-words",
1617
+ "tw-text-white",
1618
+ "group-data-[variant=default]/toast:tw-text-muted-foreground",
1619
+ className
1620
+ ),
1621
+ ...rest,
1622
+ children
1623
+ }
1624
+ );
1625
+
1626
+ // src/components/Toast/ToastDismiss.tsx
1627
+ init_icons();
1628
+ init_utils();
1629
+ var ToastDismiss = ({
1630
+ ref,
1631
+ className,
1632
+ ...rest
1633
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
1634
+ "button",
1635
+ {
1636
+ ref,
1637
+ "data-slot": "toast-dismiss",
1638
+ className: cn(
1639
+ "tw-flex",
1640
+ "tw-justify-center",
1641
+ "tw-col-start-4",
1642
+ "tw-row-start-1",
1643
+ "tailwindcss-preflight",
1644
+ "[&_svg]:tw-aspect-square",
1645
+ "[&_svg]:tw-size-4",
1646
+ "[&_svg]:tw-m-1",
1647
+ "tw-text-white",
1648
+ "group-data-[variant=default]/toast:[&_svg]:tw-text-popover-foreground",
1649
+ className
1650
+ ),
1651
+ type: "button",
1652
+ ...rest,
1653
+ children: [
1654
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {}),
1655
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw-sr-only", children: "Dismiss" })
1656
+ ]
1657
+ }
1658
+ );
1659
+
1660
+ // src/components/Toast/ToastDuration.tsx
1661
+ init_utils();
1662
+ var ToastDuration = ({
1663
+ ref,
1664
+ duration,
1665
+ className,
1666
+ style,
1667
+ ...rest
1668
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1669
+ "span",
1670
+ {
1671
+ ...rest,
1672
+ ref,
1673
+ className: cn(
1674
+ "tw-bg-white/30",
1675
+ "group-data-[variant=default]/toast:tw-bg-popover-foreground/20",
1676
+ "tw-rounded-bl-lg",
1677
+ "tw-mx-px",
1678
+ // positioning
1679
+ "tw-absolute",
1680
+ "tw-bottom-0",
1681
+ "tw-left-0",
1682
+ // sizing
1683
+ "tw-h-1",
1684
+ // animation
1685
+ "tw-animate-toast-progress",
1686
+ "group-hover/toast:[animation-play-state:paused]",
1687
+ className
1688
+ ),
1689
+ style: {
1690
+ animationDuration: `${duration}ms`,
1691
+ ...style
1692
+ }
1693
+ }
1694
+ );
1695
+
1696
+ // src/components/Toast/ToastTitle.tsx
1697
+ init_utils();
1698
+ var ToastTitle = ({
1699
+ ref,
1700
+ className,
1701
+ children,
1702
+ ...rest
1703
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1704
+ "div",
1705
+ {
1706
+ ref,
1707
+ "data-slot": "toast-title",
1708
+ className: cn(
1709
+ "tw-col-start-2",
1710
+ "tw-text-sm",
1711
+ "tw-leading-6",
1712
+ "tw-min-h-6",
1713
+ "tw-self-center",
1714
+ "tw-text-white",
1715
+ "group-data-[variant=default]/toast:tw-text-popover-foreground",
1716
+ "tw-break-words",
1717
+ "tw-font-medium",
1718
+ className
1719
+ ),
1720
+ ...rest,
1721
+ children
1722
+ }
1723
+ );
1724
+ var variants2 = classVarianceAuthority.cva(
1725
+ [
1726
+ "tailwindcss-preflight",
1727
+ "tw-group/toast",
1728
+ "tw-relative",
1729
+ // layout
1730
+ "tw-grid",
1731
+ "tw-grid-cols-[0_1fr_auto_auto]",
1732
+ "tw-items-start",
1733
+ "has-[[data-slot=toast-description]]:tw-grid-rows-[auto_auto]",
1734
+ "has-[[data-slot=toast-icon]]:tw-grid-cols-[auto_1fr_auto_auto]",
1735
+ "[&_[data-slot=toast-icon]]:tw-mr-2",
1736
+ "[&_[data-slot=toast-title]]:tw-mr-2.5",
1737
+ "[&_[data-slot=toast-description]]:tw-mr-2.5",
1738
+ "[&_[data-slot=toast-action]]:tw-mr-2",
1739
+ "[&_[data-slot=toast-description]]:tw-col-end-3",
1740
+ "tw-gap-y-0",
1741
+ // styles
1742
+ "tw-p-4",
1743
+ "tw-rounded-lg",
1744
+ "tw-shadow-md"
1745
+ ],
1746
+ {
1747
+ defaultVariants: {
1748
+ variant: "info"
1749
+ },
1750
+ variants: {
1751
+ variant: {
1752
+ default: "tw-border tw-border-border tw-bg-popover",
1753
+ error: "tw-bg-error-550",
1754
+ info: "tw-bg-secondary-600",
1755
+ success: "tw-bg-primary-700",
1756
+ warning: "tw-bg-warning-550"
1757
+ }
1758
+ }
1759
+ }
1760
+ );
1761
+ var DEFAULT_VARIANT_ICON = {
1762
+ error: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, {}),
1763
+ info: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, {}),
1764
+ success: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, {}),
1765
+ warning: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, {})
1766
+ };
1767
+ var ToastRoot = ({
1768
+ id,
1769
+ title,
1770
+ description,
1771
+ action,
1772
+ duration = Infinity,
1773
+ variant = "info",
1774
+ loading = false,
1775
+ icon: iconProp
1776
+ }) => {
1777
+ const icon = (() => {
1778
+ if (loading) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "tw-animate-spin" });
1779
+ if (iconProp) return renderLegacyIcon(iconProp);
1780
+ if (variant === "default" || variant === null) return null;
1781
+ return DEFAULT_VARIANT_ICON[variant];
1782
+ })();
1783
+ const handleActionClick = (event) => {
1784
+ sonner.toast.dismiss(id);
1785
+ action?.onClick(event);
1786
+ };
1787
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-variant": variant, className: cn(variants2({ variant })), children: [
1788
+ icon && /* @__PURE__ */ jsxRuntime.jsx(
1789
+ "span",
1790
+ {
1791
+ "data-slot": "toast-icon",
1792
+ className: cn(
1793
+ "tw-inline-flex",
1794
+ "tw-items-center",
1795
+ "tw-justify-center",
1796
+ // styles — container at 20px with no padding so the 20px Lucide
1797
+ // glyph fills the slot (previous tw-size-4 + tw-p-1 clipped a
1798
+ // 16px child into 8px of visible space)
1799
+ "tw-aspect-square",
1800
+ "tw-size-5",
1801
+ "tw-shrink-0",
1802
+ "[&_svg]:tw-size-5",
1803
+ "tw-text-white",
1804
+ "group-data-[variant=default]/toast:tw-text-popover-foreground"
1805
+ ),
1806
+ children: icon
1807
+ }
1808
+ ),
1809
+ /* @__PURE__ */ jsxRuntime.jsx(ToastTitle, { children: title }),
1810
+ description && /* @__PURE__ */ jsxRuntime.jsx(ToastDescription, { children: description }),
1811
+ action && /* @__PURE__ */ jsxRuntime.jsx(ToastAction, { style: action?.actionButtonStyle, onClick: handleActionClick, children: action.label }),
1812
+ /* @__PURE__ */ jsxRuntime.jsx(ToastDismiss, { onClick: () => sonner.toast.dismiss(id) }),
1813
+ duration !== Infinity && /* @__PURE__ */ jsxRuntime.jsx(ToastDuration, { duration })
1814
+ ] });
1815
+ };
1816
+ var toast = ({
1817
+ onAutoClose,
1818
+ onDismiss,
1819
+ testId,
1820
+ toasterId,
1821
+ dismissible = true,
1822
+ position,
1823
+ title: titleProp,
1824
+ ...toast2
1825
+ }) => {
1826
+ const duration = (() => {
1827
+ if (typeof toast2.duration === "number") return toast2.duration;
1828
+ if (toast2.variant === "error" || toast2.variant === "warning") return Infinity;
1829
+ return toast2.duration ?? 5e3;
1830
+ })();
1831
+ const renderCustomToast = (id) => {
1832
+ const title = typeof titleProp === "function" ? titleProp({ dismiss: () => sonner.toast.dismiss(id) }) : titleProp;
1833
+ return /* @__PURE__ */ jsxRuntime.jsx(ToastRoot, { ...toast2, id, title, duration });
1834
+ };
1835
+ return sonner.toast.custom(renderCustomToast, {
1836
+ // toast generated by sonner will always have an id, but we want to allow users to specify their own id if they want to
1837
+ // can not pass undefined, as it will break dismiss
1838
+ ...toast2.id != null ? { id: toast2.id } : {},
1839
+ unstyled: true,
1840
+ position,
1841
+ onAutoClose,
1842
+ onDismiss,
1843
+ testId,
1844
+ toasterId,
1845
+ dismissible,
1846
+ duration,
1847
+ // override defult focus-visible styles to match our design
1848
+ className: cn("tw-rounded-lg", "focus-visible:!tw-ring-4", "focus-visible:!tw-ring-primary/50")
1849
+ });
1850
+ };
1851
+ toast.success = (title, options) => toast({
1852
+ ...options,
1853
+ title,
1854
+ variant: "success"
1855
+ });
1856
+ toast.error = (title, options) => toast({
1857
+ ...options,
1858
+ title,
1859
+ variant: "error",
1860
+ duration: options?.duration ?? Infinity
1861
+ });
1862
+ toast.warning = (title, options) => toast({
1863
+ ...options,
1864
+ title,
1865
+ variant: "warning",
1866
+ duration: options?.duration ?? Infinity
1867
+ });
1868
+ toast.info = (title, options) => toast({
1869
+ ...options,
1870
+ title,
1871
+ variant: "info"
1872
+ });
1873
+ toast.dismiss = (toastId) => sonner.toast.dismiss(toastId);
1874
+ toast.dismissAll = () => sonner.toast.dismiss();
1875
+
1876
+ // src/components/MarkdownEditor/plugins/ImagePastePlugin.tsx
1877
+ var ACCEPTED_IMAGE_TYPES = [
1878
+ "image/png",
1879
+ "image/jpeg",
1880
+ "image/gif",
1881
+ "image/webp",
1882
+ "image/svg+xml"
1883
+ ];
1884
+ var MAX_IMAGE_SIZE = 10 * 1024 * 1024;
1885
+ var PLACEHOLDER_PREFIX = "upload-placeholder-";
1886
+ var generatePlaceholderId = () => {
1887
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1888
+ return crypto.randomUUID();
1889
+ }
1890
+ return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
1891
+ };
1892
+ var isAcceptedImageType = (type) => ACCEPTED_IMAGE_TYPES.includes(type);
1893
+ var getImageFilesFromDataTransfer = (dataTransfer) => {
1894
+ if (!dataTransfer) return [];
1895
+ if (dataTransfer.items.length > 0) {
1896
+ const files = [];
1897
+ for (const item of dataTransfer.items) {
1898
+ if (item.kind === "file" && isAcceptedImageType(item.type)) {
1899
+ const file = item.getAsFile();
1900
+ if (file) files.push(file);
1901
+ }
1902
+ }
1903
+ if (files.length > 0) return files;
1904
+ }
1905
+ return Array.from(dataTransfer.files).filter((file) => isAcceptedImageType(file.type));
1906
+ };
1907
+ var escapeMarkdownAlt = (text) => text.replace(/[[\]()]/g, "");
1908
+ var ImagePastePlugin = ({ onImageUpload }) => {
1909
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
1910
+ const onImageUploadRef = react.useRef(onImageUpload);
1911
+ onImageUploadRef.current = onImageUpload;
1912
+ react.useEffect(() => {
1913
+ const uploadFile = (file) => {
1914
+ const upload = onImageUploadRef.current;
1915
+ if (!upload) return;
1916
+ if (file.size > MAX_IMAGE_SIZE) {
1917
+ toast.error(`Image "${file.name}" is too large. Maximum size is 10 MB.`);
1918
+ return;
1919
+ }
1920
+ let nodeKey = null;
1921
+ editor.update(() => {
1922
+ const placeholderNode = $createImageNode(
1923
+ `${PLACEHOLDER_PREFIX}${generatePlaceholderId()}`,
1924
+ "Uploading image\u2026"
1925
+ );
1926
+ lexical.$insertNodes([placeholderNode]);
1927
+ nodeKey = placeholderNode.getKey();
1928
+ });
1929
+ if (!nodeKey) return;
1930
+ const capturedKey = nodeKey;
1931
+ upload(file).then(({ url }) => {
1932
+ editor.update(() => {
1933
+ const node = lexical.$getNodeByKey(capturedKey);
1934
+ if ($isImageNode(node)) {
1935
+ const altText = escapeMarkdownAlt(file.name.replace(/\.[^.]+$/, "") || "image");
1936
+ node.setSrc(url);
1937
+ node.setAlt(altText);
1938
+ }
1939
+ });
1940
+ }).catch((error) => {
1941
+ console.error("[MarkdownEditor] image upload failed", error);
1942
+ toast.error(`Failed to upload "${file.name}". Please try again.`);
1943
+ editor.update(() => {
1944
+ const node = lexical.$getNodeByKey(capturedKey);
1945
+ if (node) node.remove();
1946
+ });
1947
+ });
1948
+ };
1949
+ const removePaste = editor.registerCommand(
1950
+ lexical.PASTE_COMMAND,
1951
+ (event) => {
1952
+ if (!onImageUploadRef.current) return false;
1953
+ if (!(event instanceof ClipboardEvent)) return false;
1954
+ const files = getImageFilesFromDataTransfer(event.clipboardData);
1955
+ if (files.length === 0) return false;
1956
+ event.preventDefault();
1957
+ Promise.resolve().then(() => files.forEach(uploadFile));
1958
+ return true;
1959
+ },
1960
+ lexical.COMMAND_PRIORITY_CRITICAL
1961
+ );
1962
+ const removeDrop = editor.registerCommand(
1963
+ lexical.DROP_COMMAND,
1964
+ (event) => {
1965
+ if (!onImageUploadRef.current) return false;
1966
+ const files = getImageFilesFromDataTransfer(event.dataTransfer);
1967
+ if (files.length === 0) return false;
1968
+ event.preventDefault();
1969
+ Promise.resolve().then(() => files.forEach(uploadFile));
1970
+ return true;
1971
+ },
1972
+ lexical.COMMAND_PRIORITY_CRITICAL
1973
+ );
1974
+ return () => {
1975
+ removePaste();
1976
+ removeDrop();
1977
+ };
1978
+ }, [editor]);
1979
+ return null;
1980
+ };
1981
+ var KeyboardPlugin = ({
1982
+ onSave,
1983
+ onCancel,
1984
+ singleLine,
1985
+ blurOnEscape,
1986
+ skipBlurSaveRef
1987
+ }) => {
1988
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
1989
+ const onSaveRef = react.useRef(onSave);
1990
+ onSaveRef.current = onSave;
1991
+ const onCancelRef = react.useRef(onCancel);
1992
+ onCancelRef.current = onCancel;
1993
+ const singleLineRef = react.useRef(singleLine);
1994
+ singleLineRef.current = singleLine;
1995
+ const blurOnEscapeRef = react.useRef(blurOnEscape);
1996
+ blurOnEscapeRef.current = blurOnEscape;
1997
+ const skipBlurSaveExternalRef = skipBlurSaveRef;
1998
+ react.useEffect(() => {
1999
+ return editor.registerCommand(
2000
+ lexical.KEY_DOWN_COMMAND,
2001
+ (event) => {
2002
+ if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) {
2003
+ event.preventDefault();
2004
+ onSaveRef.current?.();
2005
+ return true;
2006
+ }
2007
+ if (event.key === "Enter" && !event.shiftKey && !event.altKey && singleLineRef.current) {
2008
+ event.preventDefault();
2009
+ editor.getRootElement()?.blur();
2010
+ return true;
2011
+ }
2012
+ if (event.key === "Escape" && blurOnEscapeRef.current) {
2013
+ if (skipBlurSaveExternalRef) skipBlurSaveExternalRef.current = true;
2014
+ onCancelRef.current?.();
2015
+ editor.getRootElement()?.blur();
2016
+ return true;
2017
+ }
2018
+ return false;
2019
+ },
2020
+ lexical.COMMAND_PRIORITY_HIGH
2021
+ );
2022
+ }, [editor, skipBlurSaveExternalRef]);
2023
+ return null;
2024
+ };
2025
+ var IMAGE = {
2026
+ dependencies: [ImageNode],
2027
+ export: (node) => {
2028
+ if (!$isImageNode(node)) return null;
2029
+ return `![${node.getAlt()}](${node.getSrc()})`;
2030
+ },
2031
+ importRegExp: /!\[([^\]]*)\]\(([^)]+)\)/,
2032
+ regExp: /!\[([^\]]*)\]\(([^)]+)\)$/,
2033
+ replace: (textNode, match) => {
2034
+ const [, alt = "", src = ""] = match;
2035
+ const imageNode = $createImageNode(src, alt);
2036
+ textNode.replace(imageNode);
2037
+ },
2038
+ trigger: ")",
2039
+ type: "text-match"
2040
+ };
2041
+ var HORIZONTAL_RULE = {
2042
+ dependencies: [LexicalHorizontalRuleNode.HorizontalRuleNode],
2043
+ export: (node) => {
2044
+ return LexicalHorizontalRuleNode.$isHorizontalRuleNode(node) ? "---" : null;
2045
+ },
2046
+ regExp: /^(---|\*\*\*|___)$/,
2047
+ replace: (parentNode) => {
2048
+ const node = LexicalHorizontalRuleNode.$createHorizontalRuleNode();
2049
+ parentNode.replace(node);
2050
+ },
2051
+ type: "element"
2052
+ };
2053
+ var MERMAID = {
2054
+ dependencies: [MermaidNode],
2055
+ export: (node) => {
2056
+ if (!$isMermaidNode(node)) return null;
2057
+ return "```mermaid\n" + node.getCode() + "\n```";
2058
+ },
2059
+ regExpStart: /^[ \t]*(`{3,})mermaid(?:\s.*)?$/,
2060
+ regExpEnd: {
2061
+ optional: true,
2062
+ regExp: /^[ \t]*`{3,}$/
2063
+ },
2064
+ replace: (rootNode, _children, _startMatch, _endMatch, linesInBetween) => {
2065
+ if (!linesInBetween) return;
2066
+ const code = linesInBetween.join("\n").trim();
2067
+ if (code) {
2068
+ rootNode.append($createMermaidNode(code));
2069
+ }
2070
+ },
2071
+ handleImportAfterStartMatch: ({
2072
+ lines,
2073
+ rootNode,
2074
+ startLineIndex,
2075
+ startMatch
2076
+ }) => {
2077
+ const fence = startMatch[1];
2078
+ if (!fence) return [false, startLineIndex];
2079
+ const fenceLength = fence.trim().length;
2080
+ const endRegex = new RegExp(`^[ \\t]*\`{${fenceLength},}$`);
2081
+ for (let i = startLineIndex + 1; i < lines.length; i++) {
2082
+ if (endRegex.test(lines[i] ?? "")) {
2083
+ const code2 = lines.slice(startLineIndex + 1, i).join("\n").trim();
2084
+ if (code2) {
2085
+ rootNode.append($createMermaidNode(code2));
2086
+ }
2087
+ return [true, i];
2088
+ }
2089
+ }
2090
+ const code = lines.slice(startLineIndex + 1).join("\n").trim();
2091
+ if (code) {
2092
+ rootNode.append($createMermaidNode(code));
2093
+ }
2094
+ return [true, lines.length - 1];
2095
+ },
2096
+ type: "multiline-element"
2097
+ };
2098
+ var CUSTOM_TRANSFORMERS = [
2099
+ IMAGE,
2100
+ HORIZONTAL_RULE,
2101
+ markdown.CHECK_LIST,
2102
+ MERMAID,
2103
+ ...markdown.TRANSFORMERS
2104
+ ];
2105
+ var SINGLE_LINE_TRANSFORMERS = CUSTOM_TRANSFORMERS.filter(
2106
+ (t) => t.type === "text-format" || t.type === "text-match"
2107
+ );
2108
+ var TABLE_FENCE_LANG = "__kbc_table__";
2109
+ var isTableLine = (line) => {
2110
+ const trimmed = line.trim();
2111
+ return trimmed.startsWith("|") && trimmed.endsWith("|");
2112
+ };
2113
+ var CODE_FENCE_REGEX = /^[ \t]*`{3,}/;
2114
+ var preprocessMarkdown = (markdown) => {
2115
+ const lines = markdown.split("\n");
2116
+ const result = [];
2117
+ let tableLines = [];
2118
+ let insideCodeFence = false;
2119
+ const flushTable = () => {
2120
+ if (tableLines.length >= 2) {
2121
+ result.push(`\`\`\`${TABLE_FENCE_LANG}`);
2122
+ result.push(...tableLines);
2123
+ result.push("```");
2124
+ } else {
2125
+ result.push(...tableLines);
2126
+ }
2127
+ tableLines = [];
2128
+ };
2129
+ for (const line of lines) {
2130
+ if (CODE_FENCE_REGEX.test(line)) {
2131
+ if (tableLines.length > 0) flushTable();
2132
+ insideCodeFence = !insideCodeFence;
2133
+ result.push(line);
2134
+ continue;
2135
+ }
2136
+ if (insideCodeFence) {
2137
+ result.push(line);
2138
+ continue;
2139
+ }
2140
+ if (isTableLine(line)) {
2141
+ tableLines.push(line);
2142
+ } else {
2143
+ if (tableLines.length > 0) flushTable();
2144
+ result.push(line);
2145
+ }
2146
+ }
2147
+ if (tableLines.length > 0) flushTable();
2148
+ return result.join("\n");
2149
+ };
2150
+ var postprocessMarkdown = (markdown) => {
2151
+ const regex = new RegExp(`\`\`\`${TABLE_FENCE_LANG}\\n([\\s\\S]*?)\\n\`\`\``, "g");
2152
+ return markdown.replace(regex, "$1");
2153
+ };
2154
+
2155
+ // src/components/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx
2156
+ var IMPORT_TAG = "markdown-import";
2157
+ var MarkdownSyncPlugin = ({
2158
+ value,
2159
+ editable,
2160
+ onChange,
2161
+ transformers = CUSTOM_TRANSFORMERS
2162
+ }) => {
2163
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
2164
+ const lastExportedRef = react.useRef(value);
2165
+ const onChangeRef = react.useRef(onChange);
2166
+ onChangeRef.current = onChange;
2167
+ const transformersRef = react.useRef(transformers);
2168
+ transformersRef.current = transformers;
2169
+ react.useEffect(() => {
2170
+ editor.setEditable(editable);
2171
+ }, [editor, editable]);
2172
+ react.useEffect(() => {
2173
+ if (value === lastExportedRef.current) return;
2174
+ lastExportedRef.current = value;
2175
+ editor.update(
2176
+ () => {
2177
+ markdown.$convertFromMarkdownString(preprocessMarkdown(value), transformersRef.current);
2178
+ },
2179
+ { tag: IMPORT_TAG }
2180
+ );
2181
+ }, [editor, value]);
2182
+ react.useEffect(() => {
2183
+ return editor.registerUpdateListener(({ tags }) => {
2184
+ if (tags.has(IMPORT_TAG)) return;
2185
+ editor.getEditorState().read(() => {
2186
+ const raw = markdown.$convertToMarkdownString(transformersRef.current);
2187
+ const markdown$1 = postprocessMarkdown(raw);
2188
+ if (markdown$1 !== lastExportedRef.current) {
2189
+ lastExportedRef.current = markdown$1;
2190
+ onChangeRef.current?.(markdown$1);
2191
+ }
2192
+ });
2193
+ });
2194
+ }, [editor]);
2195
+ return null;
2196
+ };
2197
+
2198
+ // src/components/MarkdownEditor/plugins/ToolbarPlugin.tsx
2199
+ init_icons();
2200
+
2201
+ // src/components/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx
2202
+ init_icons();
2203
+ init_utils();
2204
+
2205
+ // src/components/DropdownMenu/DropdownMenuCheckboxItem.tsx
2206
+ init_icons();
2207
+ init_utils();
2208
+
2209
+ // src/components/DropdownMenu/DropdownMenuItemIndicator.tsx
2210
+ init_icons();
2211
+ var variants3 = classVarianceAuthority.cva(
2212
+ [
2213
+ "tailwindcss-preflight",
2214
+ "tw-pointer-events-none",
2215
+ // sizing
2216
+ "tw-size-4",
2217
+ "tw-aspect-square",
2218
+ "tw-shrink-0",
2219
+ // layout
2220
+ "tw-flex",
2221
+ "tw-items-center",
2222
+ "tw-justify-center"
2223
+ ],
2224
+ {
2225
+ variants: {
2226
+ variant: {
2227
+ none: [],
2228
+ radio: [
2229
+ "tw-border",
2230
+ "tw-border-solid",
2231
+ "tw-border-border",
2232
+ "tw-rounded-full",
2233
+ "tw-bg-white",
2234
+ "[&_svg]:tw-size-2",
2235
+ "[&_svg]:data-[state=unchecked]:tw-hidden",
2236
+ // Lucide Circle is stroke-only — force fill to match the stroke
2237
+ // (currentColor) so the indicator reads as a solid dot.
2238
+ "[&_svg]:tw-fill-current",
2239
+ "group-data-[variant=argo]/dropdown-menu-content:[&_svg]:tw-text-primary",
2240
+ "group-data-[variant=default]/dropdown-menu-content:[&_svg]:tw-text-secondary-500"
2241
+ ],
2242
+ check: ["[&_svg]:tw-size-3.5", "[&_svg]:tw-text-primary"],
2243
+ checkbox: [
2244
+ "[&_svg]:tw-text-white",
2245
+ "tw-border",
2246
+ "tw-border-solid",
2247
+ "tw-border-neutral-200",
2248
+ "tw-rounded",
2249
+ "[&_svg]:tw-size-3",
2250
+ "[&_svg]:data-[state=unchecked]:tw-hidden",
2251
+ "group-data-[variant=argo]/dropdown-menu-content:data-[state=checked]:tw-border-primary",
2252
+ "group-data-[variant=argo]/dropdown-menu-content:data-[state=checked]:tw-bg-primary",
2253
+ "group-data-[variant=default]/dropdown-menu-content:data-[state=checked]:tw-border-secondary-500",
2254
+ "group-data-[variant=default]/dropdown-menu-content:data-[state=checked]:tw-bg-secondary-500"
2255
+ ],
2256
+ switch: [
2257
+ "tw-size-5",
2258
+ // Lucide SVGs default to 24×24 — constrain the rendered ToggleRight
2259
+ // to the indicator slot so it doesn't overflow.
2260
+ "[&_svg]:tw-size-5",
2261
+ "tw-text-neutral-400",
2262
+ "data-[state=unchecked]:tw-rotate-180",
2263
+ "group-data-[variant=default]/dropdown-menu-content:data-[state=checked]:tw-text-secondary-500",
2264
+ "group-data-[variant=argo]/dropdown-menu-content:data-[state=checked]:tw-text-primary"
2265
+ ]
2266
+ }
2267
+ }
2268
+ }
2269
+ );
2270
+ var DropdownMenuItemIndicator = ({
2271
+ variant,
2272
+ className,
2273
+ forceMount: forceMountProp,
2274
+ ...rest
2275
+ }) => {
2276
+ const IconComp = (() => {
2277
+ if (variant === "switch") return lucideReact.ToggleRight;
2278
+ if (variant === "radio") return lucideReact.Circle;
2279
+ return lucideReact.Check;
2280
+ })();
2281
+ const forceMount = (() => {
2282
+ if (forceMountProp) return true;
2283
+ return variant === "check" ? void 0 : true;
2284
+ })();
2285
+ if (variant === "none") return null;
2286
+ return /* @__PURE__ */ jsxRuntime.jsx(
2287
+ DropdownMenuPrimitive3__namespace.ItemIndicator,
2288
+ {
2289
+ ...rest,
2290
+ forceMount,
2291
+ className: variants3({ variant, className }),
2292
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconComp, {})
2293
+ }
2294
+ );
2295
+ };
2296
+
2297
+ // src/components/DropdownMenu/ItemIcon.tsx
2298
+ init_utils();
2299
+ var ItemIcon = ({ className, children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2300
+ "span",
2301
+ {
2302
+ ...props,
2303
+ className: cn(
2304
+ "tw-inline-flex",
2305
+ "tw-items-center",
2306
+ "tw-justify-center",
2307
+ "tw-aspect-square",
2308
+ // 20px container fits the 16px Lucide glyph plus 2px breathing room
2309
+ // each side — the previous tw-size-4 + tw-p-0.5 clipped the 16px child.
2310
+ "tw-size-5",
2311
+ "[&_svg]:tw-size-4",
2312
+ "group-data-[variant=default]/dropdown-menu-content:tw-text-neutral-400",
2313
+ "group-data-[variant=argo]/dropdown-menu-content:tw-text-primary",
2314
+ "group-data-[variant=argo]/dropdown-menu-content:group-aria-disabled:tw-text-muted-foreground",
2315
+ "group-data-[variant=default]/dropdown-menu-content:group-hover:tw-text-secondary-500",
2316
+ className
2317
+ ),
2318
+ children
2319
+ }
2320
+ );
2321
+
2322
+ // src/components/DropdownMenu/styles.ts
2323
+ init_utils();
2324
+ var itemVariants = cn(
2325
+ // reset
2326
+ "tailwindcss-preflight",
2327
+ "tw-outline-none",
2328
+ "tw-group",
2329
+ "tw-peer",
2330
+ "tw-relative",
2331
+ // positioning
2332
+ "tw-flex",
2333
+ "tw-flex-1",
2334
+ "tw-items-center",
2335
+ "tw-gap-2",
2336
+ "tw-cursor-pointer",
2337
+ "tw-select-none",
2338
+ "tw-transition-colors",
2339
+ // spacing
2340
+ "tw-p-2",
2341
+ // typography
2342
+ "tw-font-sans",
2343
+ "tw-text-sm",
2344
+ "aria-disabled:tw-pointer-events-none",
2345
+ "aria-disabled:tw-opacity-50",
2346
+ "focus-visible:tw-outline-none",
2347
+ "group-data-[variant=default]/dropdown-menu-content:tw-rounded",
2348
+ "group-data-[variant=default]/dropdown-menu-content:focus:tw-bg-neutral-100",
2349
+ "group-data-[variant=default]/dropdown-menu-content:focus:tw-text-neutral-900",
2350
+ "group-data-[variant=default]/dropdown-menu-content:hover:tw-bg-neutral-100",
2351
+ "group-data-[variant=default]/dropdown-menu-content:hover:tw-text-neutral-900",
2352
+ "group-data-[variant=argo]/dropdown-menu-content:tw-rounded-md",
2353
+ "group-data-[variant=argo]/dropdown-menu-content:tw-text-slate-800",
2354
+ "group-data-[variant=argo]/dropdown-menu-content:focus:tw-text-slate-800",
2355
+ "group-data-[variant=argo]/dropdown-menu-content:focus:tw-bg-sky-100",
2356
+ "group-data-[variant=argo]/dropdown-menu-content:hover:tw-text-slate-800",
2357
+ "group-data-[variant=argo]/dropdown-menu-content:hover:tw-bg-sky-100"
2358
+ );
2359
+ var contentVariants = cn(
2360
+ "tailwindcss-preflight",
2361
+ "tw-group/dropdown-menu-content",
2362
+ "tw-z-[1040]",
2363
+ "tw-bg-white",
2364
+ // positioning
2365
+ "tw-flex",
2366
+ "tw-flex-col",
2367
+ "tw-origin-[--radix-dropdown-menu-content-transform-origin]",
2368
+ // sizing
2369
+ "tw-max-h-[var(--radix-dropdown-menu-content-available-height)]",
2370
+ "tw-min-w-32",
2371
+ // border
2372
+ "tw-border",
2373
+ "tw-shadow-md",
2374
+ "data-[variant=default]:tw-rounded-md",
2375
+ "data-[variant=argo]:tw-rounded-2xl",
2376
+ // animations
2377
+ "data-[state=open]:tw-animate-in",
2378
+ "data-[state=open]:tw-fade-in-0",
2379
+ "data-[state=open]:tw-zoom-in-95",
2380
+ "data-[state=closed]:tw-animate-out",
2381
+ "data-[state=closed]:tw-fade-out-0",
2382
+ "data-[state=closed]:tw-zoom-out-95",
2383
+ "data-[side=bottom]:tw-slide-in-from-top-2",
2384
+ "data-[side=left]:tw-slide-in-from-right-2",
2385
+ "data-[side=right]:tw-slide-in-from-left-2",
2386
+ "data-[side=top]:tw-slide-in-from-bottom-2"
2387
+ );
2388
+ var DropdownMenuCheckboxItem = ({
2389
+ className,
2390
+ children,
2391
+ checked,
2392
+ closeOnSelect = false,
2393
+ onSelect,
2394
+ indicatorAlign = "start",
2395
+ indicator = "checkbox",
2396
+ isLoading = false,
2397
+ ...props
2398
+ }) => {
2399
+ const isAtStart = indicatorAlign === "start";
2400
+ const indicatorEle = isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ItemIcon, { className: isAtStart ? "" : "tw-ml-auto", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "tw-animate-spin" }) }) : /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItemIndicator, { variant: indicator, className: isAtStart ? "" : "tw-ml-auto" });
2401
+ const handleSelect = (event) => {
2402
+ if (!closeOnSelect) event.preventDefault();
2403
+ onSelect?.(event);
2404
+ };
2405
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2406
+ DropdownMenuPrimitive3__namespace.CheckboxItem,
2407
+ {
2408
+ className: cn(itemVariants, className),
2409
+ checked,
2410
+ onSelect: handleSelect,
2411
+ ...props,
2412
+ children: [
2413
+ isAtStart && indicatorEle,
2414
+ children,
2415
+ !isAtStart && indicatorEle
2416
+ ]
2417
+ }
2418
+ );
2419
+ };
2420
+
2421
+ // src/components/DropdownMenu/DropdownMenuContent.tsx
2422
+ init_utils();
2423
+
2424
+ // src/components/ScrollArea/ScrollArea.tsx
2425
+ init_utils();
2426
+
2427
+ // src/components/ScrollArea/ScrollBar.tsx
2428
+ init_utils();
2429
+ var ScrollBar = ({ className, orientation = "vertical", ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2430
+ ScrollAreaPrimitive2__namespace.ScrollAreaScrollbar,
2431
+ {
2432
+ orientation,
2433
+ className: cn(
2434
+ "tw-flex tw-touch-none tw-select-none tw-transition-color",
2435
+ '[data-state="hidden"]:tw-bg-pink-500',
2436
+ {
2437
+ "tw-h-full tw-w-2.5 tw-p-px": orientation === "vertical",
2438
+ "tw-h-2.5 tw-flex-col tw-p-px": orientation === "horizontal"
2439
+ },
2440
+ className
2441
+ ),
2442
+ ...props,
2443
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2444
+ ScrollAreaPrimitive2__namespace.ScrollAreaThumb,
2445
+ {
2446
+ className: cn(
2447
+ "tw-relative",
2448
+ "tw-flex-1",
2449
+ "tw-rounded-full",
2450
+ "tw-bg-neutral-200",
2451
+ "hover:tw-bg-neutral-400"
2452
+ )
2453
+ }
2454
+ )
2455
+ }
2456
+ );
2457
+ var ScrollArea = ({
2458
+ ref,
2459
+ className,
2460
+ children,
2461
+ viewPortClassName,
2462
+ orientation,
2463
+ scrollBarClassName,
2464
+ ...props
2465
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
2466
+ ScrollAreaPrimitive2__namespace.Root,
2467
+ {
2468
+ "data-slot": "scroll-area",
2469
+ className: cn(
2470
+ "tw-peer/scroll-area tw-relative tw-overflow-hidden focus-visible:tw-outline-none",
2471
+ className
2472
+ ),
2473
+ ...props,
2474
+ children: [
2475
+ /* @__PURE__ */ jsxRuntime.jsx(
2476
+ ScrollAreaPrimitive2__namespace.Viewport,
2477
+ {
2478
+ ref,
2479
+ className: cn(
2480
+ "tw-h-full tw-w-full tw-rounded-[inherit] focus-visible:tw-outline-none",
2481
+ viewPortClassName
2482
+ ),
2483
+ children
2484
+ }
2485
+ ),
2486
+ orientation ? /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { className: scrollBarClassName, orientation }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2487
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { className: scrollBarClassName, orientation: "vertical" }),
2488
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { className: scrollBarClassName, orientation: "horizontal" })
2489
+ ] }),
2490
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollAreaPrimitive2__namespace.Corner, {})
2491
+ ]
2492
+ }
2493
+ );
2494
+ var DropdownMenuContext = react.createContext({
2495
+ variant: "default"
2496
+ });
2497
+ var useDropdownMenuContext = () => react.use(DropdownMenuContext);
2498
+ var DropdownMenuContent = ({
2499
+ className,
2500
+ sideOffset = 4,
2501
+ forceMount,
2502
+ children,
2503
+ viewPortClassName,
2504
+ container,
2505
+ ...props
2506
+ }) => {
2507
+ const { variant } = useDropdownMenuContext();
2508
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive3__namespace.Portal, { forceMount: forceMount || void 0, container, children: /* @__PURE__ */ jsxRuntime.jsx(
2509
+ DropdownMenuPrimitive3__namespace.Content,
2510
+ {
2511
+ ...props,
2512
+ "data-variant": variant,
2513
+ sideOffset,
2514
+ className: contentVariants,
2515
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2516
+ ScrollArea,
2517
+ {
2518
+ className,
2519
+ viewPortClassName: cn(
2520
+ "tw-p-2",
2521
+ "tw-max-h-[var(--radix-dropdown-menu-content-available-height)]",
2522
+ viewPortClassName
2523
+ ),
2524
+ scrollBarClassName: "tw-w-1.5",
2525
+ children
2526
+ }
2527
+ )
2528
+ }
2529
+ ) });
2530
+ };
2531
+
2532
+ // src/components/DropdownMenu/DropdownMenuItem.tsx
2533
+ init_icons();
2534
+ init_utils();
2535
+ var DropdownMenuItem = ({
2536
+ ref,
2537
+ className,
2538
+ asModalTrigger = false,
2539
+ onSelect,
2540
+ onPointerLeave,
2541
+ onPointerMove,
2542
+ children,
2543
+ asChild,
2544
+ icon,
2545
+ iconClassName,
2546
+ isLoading = false,
2547
+ ...props
2548
+ }) => {
2549
+ const Comp = asChild ? reactSlot.Root : "div";
2550
+ const adornment = isLoading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "tw-animate-spin" }) : renderLegacyIcon(icon);
2551
+ const handleOnSelect = (event) => {
2552
+ if (asModalTrigger) event.preventDefault();
2553
+ onSelect?.(event);
2554
+ };
2555
+ const handlePointerLeave = (event) => {
2556
+ if (asModalTrigger) event.preventDefault();
2557
+ onPointerLeave?.(event);
2558
+ };
2559
+ const handlePointerMove = (event) => {
2560
+ if (asModalTrigger) event.preventDefault();
2561
+ onPointerMove?.(event);
2562
+ };
2563
+ return /* @__PURE__ */ jsxRuntime.jsx(
2564
+ DropdownMenuPrimitive3__namespace.Item,
2565
+ {
2566
+ ...props,
2567
+ ref,
2568
+ onSelect: handleOnSelect,
2569
+ onPointerLeave: handlePointerLeave,
2570
+ onPointerMove: handlePointerMove,
2571
+ className: cn(itemVariants, className),
2572
+ asChild: true,
2573
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Comp, { children: [
2574
+ adornment && /* @__PURE__ */ jsxRuntime.jsx(ItemIcon, { className: iconClassName, children: adornment }),
2575
+ /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slottable, { children })
2576
+ ] })
2577
+ }
2578
+ );
2579
+ };
2580
+
2581
+ // src/components/DropdownMenu/DropdownMenuItemDescription.tsx
2582
+ init_utils();
2583
+ var descriptionVariants = classVarianceAuthority.cva(
2584
+ [
2585
+ "tw-box-border",
2586
+ "tw-ml-auto",
2587
+ "tw-font-sans",
2588
+ "tw-tracking-normal",
2589
+ "tw-font-normal",
2590
+ "tw-text-xs",
2591
+ "tw-text-muted-foreground"
2592
+ ],
2593
+ {
2594
+ variants: {
2595
+ hideOnHover: {
2596
+ true: ["group-focus-within:tw-hidden", "group-hover:tw-hidden"],
2597
+ false: []
2598
+ }
2599
+ },
2600
+ defaultVariants: {}
2601
+ }
2602
+ );
2603
+ var DropdownMenuItemDescription = ({
2604
+ className,
2605
+ children,
2606
+ hideOnHover = false,
2607
+ ...props
2608
+ }) => {
2609
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, className: cn(descriptionVariants({ hideOnHover }), className), children });
2610
+ };
2611
+
2612
+ // src/components/DropdownMenu/DropdownMenuLabel.tsx
2613
+ init_utils();
2614
+ var DropdownMenuLabel = ({ className, ...props }) => {
2615
+ return /* @__PURE__ */ jsxRuntime.jsx(
2616
+ DropdownMenuPrimitive3__namespace.Label,
2617
+ {
2618
+ className: cn(
2619
+ "tw-p-2",
2620
+ "tw-font-medium",
2621
+ "tw-text-xs",
2622
+ "tw-text-muted-foreground",
2623
+ className
2624
+ ),
2625
+ ...props
2626
+ }
2627
+ );
2628
+ };
2629
+ var DropdownMenuRadioGroup = ({
2630
+ value,
2631
+ defaultValue,
2632
+ onValueChange,
2633
+ ...props
2634
+ }) => {
2635
+ const handleChange = (value2) => {
2636
+ onValueChange?.(value2);
2637
+ };
2638
+ return /* @__PURE__ */ jsxRuntime.jsx(
2639
+ DropdownMenuPrimitive3__namespace.RadioGroup,
2640
+ {
2641
+ ...props,
2642
+ value,
2643
+ defaultValue,
2644
+ onValueChange: handleChange
2645
+ }
2646
+ );
2647
+ };
2648
+
2649
+ // src/components/DropdownMenu/DropdownMenuRadioGroup/DropdownMenuRadioItem.tsx
2650
+ init_icons();
2651
+ init_utils();
2652
+ var DropdownMenuRadioItem = ({
2653
+ className,
2654
+ children,
2655
+ closeOnSelect,
2656
+ onSelect,
2657
+ indicatorAlign = "start",
2658
+ indicator = "radio",
2659
+ icon,
2660
+ iconClassName,
2661
+ isLoading = false,
2662
+ ...props
2663
+ }) => {
2664
+ const isAtStart = indicatorAlign === "start";
2665
+ const indicatorEle = isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ItemIcon, { className: iconClassName, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "tw-animate-spin" }) }) : /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItemIndicator, { variant: indicator });
2666
+ const handleSelect = (event) => {
2667
+ if (!closeOnSelect) event.preventDefault();
2668
+ onSelect?.(event);
2669
+ };
2670
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2671
+ DropdownMenuPrimitive3__namespace.RadioItem,
2672
+ {
2673
+ className: cn(
2674
+ itemVariants,
2675
+ "data-[state=checked]:tw-cursor-default",
2676
+ {
2677
+ "data-[state=checked]:tw-bg-neutral-100": indicator === "none",
2678
+ "group-data-[variant=argo]/dropdown-menu-content:data-[state=checked]:tw-bg-sky-100": indicator === "check"
2679
+ },
2680
+ className
2681
+ ),
2682
+ onSelect: handleSelect,
2683
+ ...props,
2684
+ children: [
2685
+ isAtStart && indicatorEle,
2686
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ItemIcon, { className: iconClassName, children: renderLegacyIcon(icon) }),
2687
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw-flex tw-min-w-0 tw-flex-1 tw-items-center tw-gap-2", children }),
2688
+ !isAtStart && indicatorEle
2689
+ ]
2690
+ }
2691
+ );
2692
+ };
2693
+
2694
+ // src/components/DropdownMenu/DropdownMenuSeparator.tsx
2695
+ init_utils();
2696
+ var DropdownMenuSeparator = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2697
+ DropdownMenuPrimitive3__namespace.Separator,
2698
+ {
2699
+ className: cn(
2700
+ "tw-relative",
2701
+ "tw-z-10",
2702
+ // layout
2703
+ "tw-flex",
2704
+ "tw-items-center",
2705
+ "tw-justify-center",
2706
+ "tw-w-full",
2707
+ // separator line
2708
+ 'before:tw-content-[""]',
2709
+ "before:tw-w-full",
2710
+ "before:tw-h-px",
2711
+ "group-data-[variant=default]/dropdown-menu-content:tw-py-2",
2712
+ "group-data-[variant=default]/dropdown-menu-content:before:tw-bg-neutral-150",
2713
+ "group-data-[variant=argo]/dropdown-menu-content:tw-py-1",
2714
+ "group-data-[variant=argo]/dropdown-menu-content:before:tw-bg-border",
2715
+ className
2716
+ ),
2717
+ ...props
2718
+ }
2719
+ );
2720
+ var DropdownMenuSub = DropdownMenuPrimitive3__namespace.Sub;
2721
+
2722
+ // src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubContent.tsx
2723
+ init_utils();
2724
+ var DropdownMenuSubContent = ({ className, ...props }) => {
2725
+ const { variant } = useDropdownMenuContext();
2726
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive3__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
2727
+ DropdownMenuPrimitive3__namespace.SubContent,
2728
+ {
2729
+ "data-variant": variant,
2730
+ className: cn(contentVariants, "tw-z-[1041]", "tw-p-2", className),
2731
+ ...props
2732
+ }
2733
+ ) });
2734
+ };
2735
+
2736
+ // src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubTrigger.tsx
2737
+ init_icons();
2738
+ init_utils();
2739
+ var DropdownMenuSubTrigger = ({ className, children, ...props }) => {
2740
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuPrimitive3__namespace.SubTrigger, { className: cn(itemVariants, className), ...props, children: [
2741
+ children,
2742
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "tw-ml-auto tw-size-5" })
2743
+ ] });
2744
+ };
2745
+
2746
+ // src/components/DropdownMenu/DropdownMenuTrigger.tsx
2747
+ init_utils();
2748
+ var DropdownMenuTrigger = ({
2749
+ ref,
2750
+ className,
2751
+ ...props
2752
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
2753
+ DropdownMenuPrimitive3.Trigger,
2754
+ {
2755
+ ...props,
2756
+ ref,
2757
+ "data-slot": "dropdown-menu-trigger",
2758
+ className: cn("tw-group/dropdown-menu-trigger", className)
2759
+ }
2760
+ );
2761
+ var DropdownMenu = ({
2762
+ // change a default value to false, for modal property, as it is not used in most cases
2763
+ modal = false,
2764
+ variant = "default",
2765
+ ...props
2766
+ }) => {
2767
+ const contextValue = react.useMemo(() => ({ variant }), [variant]);
2768
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContext, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive3.Root, { ...props, modal }) });
2769
+ };
2770
+ DropdownMenu.Trigger = DropdownMenuTrigger;
2771
+ DropdownMenu.Content = DropdownMenuContent;
2772
+ DropdownMenu.Group = DropdownMenuPrimitive3.Group;
2773
+ DropdownMenu.Sub = DropdownMenuSub;
2774
+ DropdownMenu.SubContent = DropdownMenuSubContent;
2775
+ DropdownMenu.SubTrigger = DropdownMenuSubTrigger;
2776
+ DropdownMenu.Separator = DropdownMenuSeparator;
2777
+ DropdownMenu.Label = DropdownMenuLabel;
2778
+ DropdownMenu.Item = DropdownMenuItem;
2779
+ DropdownMenu.CheckboxItem = DropdownMenuCheckboxItem;
2780
+ DropdownMenu.RadioGroup = DropdownMenuRadioGroup;
2781
+ DropdownMenu.RadioItem = DropdownMenuRadioItem;
2782
+ DropdownMenu.ItemDescription = DropdownMenuItemDescription;
2783
+
2784
+ // src/components/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx
2785
+ init_Tooltip2();
2786
+ var ALIGNMENT_OPTIONS = [
2787
+ { value: "left", label: "Left", icon: lucideReact.AlignLeft },
2788
+ { value: "center", label: "Center", icon: lucideReact.AlignCenter },
2789
+ { value: "right", label: "Right", icon: lucideReact.AlignRight },
2790
+ { value: "justify", label: "Justify", icon: lucideReact.AlignJustify }
2791
+ ];
2792
+ var ALIGNMENT_ICONS = Object.fromEntries(
2793
+ ALIGNMENT_OPTIONS.map(({ value, icon }) => [value, icon])
2794
+ );
2795
+ var AlignmentDropdown = ({
2796
+ editor,
2797
+ alignment
2798
+ }) => {
2799
+ const savedSelectionRef = react.useRef(null);
2800
+ const handleOpenChange = (open) => {
2801
+ if (open) {
2802
+ editor.getEditorState().read(() => {
2803
+ const selection = lexical.$getSelection();
2804
+ savedSelectionRef.current = selection ? selection.clone() : null;
2805
+ });
2806
+ }
2807
+ };
2808
+ const handleSelect = (align) => {
2809
+ editor.update(() => {
2810
+ if (savedSelectionRef.current) {
2811
+ lexical.$setSelection(savedSelectionRef.current);
2812
+ }
2813
+ editor.dispatchCommand(lexical.FORMAT_ELEMENT_COMMAND, align);
2814
+ });
2815
+ };
2816
+ const CurrentAlignmentIcon = ALIGNMENT_ICONS[alignment] ?? lucideReact.AlignLeft;
2817
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { onOpenChange: handleOpenChange, children: [
2818
+ /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { tooltip: "Text alignment", placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2819
+ "button",
2820
+ {
2821
+ type: "button",
2822
+ className: cn(
2823
+ "tw-flex tw-h-7 tw-cursor-pointer tw-items-center tw-gap-1 tw-rounded tw-border-0 tw-bg-transparent tw-px-1.5 tw-text-xs tw-text-neutral-600",
2824
+ "hover:tw-bg-neutral-100"
2825
+ ),
2826
+ children: [
2827
+ /* @__PURE__ */ jsxRuntime.jsx(CurrentAlignmentIcon, { className: "tw-size-4" }),
2828
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "tw-size-3" })
2829
+ ]
2830
+ }
2831
+ ) }) }),
2832
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Content, { align: "start", className: "tw-min-w-32", children: ALIGNMENT_OPTIONS.map(({ value, label, icon: IconComp }) => /* @__PURE__ */ jsxRuntime.jsxs(
2833
+ DropdownMenu.Item,
2834
+ {
2835
+ onSelect: () => handleSelect(value),
2836
+ className: cn(
2837
+ "tw-flex tw-items-center tw-gap-2",
2838
+ alignment === value && "tw-bg-secondary-50 tw-text-secondary-500"
2839
+ ),
2840
+ children: [
2841
+ /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: "tw-size-4" }),
2842
+ label
2843
+ ]
2844
+ },
2845
+ value
2846
+ )) })
2847
+ ] });
2848
+ };
2849
+
2850
+ // src/components/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx
2851
+ init_icons();
2852
+ init_utils();
2853
+ init_Tooltip2();
2854
+ var BLOCK_TYPE_META = {
2855
+ paragraph: { label: "Normal", icon: lucideReact.Type, selectable: true },
2856
+ h1: { label: "Heading 1", icon: lucideReact.Heading1, selectable: true },
2857
+ h2: { label: "Heading 2", icon: lucideReact.Heading2, selectable: true },
2858
+ h3: { label: "Heading 3", icon: lucideReact.Heading3, selectable: true },
2859
+ bullet: { label: "Bullet List", icon: lucideReact.List, selectable: false },
2860
+ number: { label: "Numbered List", icon: lucideReact.ListOrdered, selectable: false },
2861
+ quote: { label: "Quote", icon: lucideReact.Quote, selectable: false },
2862
+ code: { label: "Code Block", icon: lucideReact.SquareCode, selectable: false }
2863
+ };
2864
+ var BLOCK_TYPE_OPTIONS = Object.entries(BLOCK_TYPE_META).filter(([, meta]) => meta.selectable).map(([value, { label, icon }]) => ({ value, label, icon }));
2865
+ var isBlockType = (value) => Object.prototype.hasOwnProperty.call(BLOCK_TYPE_META, value);
2866
+ var BlockTypeDropdown = ({
2867
+ editor,
2868
+ blockType
2869
+ }) => {
2870
+ const savedSelectionRef = react.useRef(null);
2871
+ const currentMeta = isBlockType(blockType) ? BLOCK_TYPE_META[blockType] : null;
2872
+ const CurrentBlockIcon = currentMeta?.icon ?? lucideReact.Type;
2873
+ const handleOpenChange = (open) => {
2874
+ if (open) {
2875
+ editor.getEditorState().read(() => {
2876
+ const selection = lexical.$getSelection();
2877
+ savedSelectionRef.current = selection ? selection.clone() : null;
2878
+ });
2879
+ }
2880
+ };
2881
+ const handleSelect = (type) => {
2882
+ editor.update(() => {
2883
+ if (savedSelectionRef.current) {
2884
+ lexical.$setSelection(savedSelectionRef.current);
2885
+ }
2886
+ const selection = lexical.$getSelection();
2887
+ if (!lexical.$isRangeSelection(selection)) return;
2888
+ if (type === "bullet") {
2889
+ editor.dispatchCommand(list.INSERT_UNORDERED_LIST_COMMAND, void 0);
2890
+ return;
2891
+ }
2892
+ if (type === "number") {
2893
+ editor.dispatchCommand(list.INSERT_ORDERED_LIST_COMMAND, void 0);
2894
+ return;
2895
+ }
2896
+ const anchorNode = selection.anchor.getNode();
2897
+ const element = utils.$getNearestBlockElementAncestorOrThrow(anchorNode);
2898
+ const newNode = type === "h1" || type === "h2" || type === "h3" ? richText.$createHeadingNode(type) : type === "quote" ? richText.$createQuoteNode() : type === "code" ? code.$createCodeNode() : lexical.$createParagraphNode();
2899
+ element.getChildren().forEach((child) => newNode.append(child));
2900
+ element.replace(newNode);
2901
+ });
2902
+ };
2903
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { onOpenChange: handleOpenChange, children: [
2904
+ /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { tooltip: "Change block type", placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2905
+ "button",
2906
+ {
2907
+ type: "button",
2908
+ className: cn(
2909
+ "tw-flex tw-h-7 tw-cursor-pointer tw-items-center tw-gap-1.5 tw-rounded tw-border-0 tw-bg-transparent tw-px-1.5 tw-text-xs tw-text-neutral-600",
2910
+ "hover:tw-bg-neutral-100"
2911
+ ),
2912
+ children: [
2913
+ /* @__PURE__ */ jsxRuntime.jsx(CurrentBlockIcon, { className: "tw-size-4" }),
2914
+ currentMeta?.label ?? "Normal",
2915
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "tw-size-3" })
2916
+ ]
2917
+ }
2918
+ ) }) }),
2919
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Content, { align: "start", className: "tw-min-w-40", children: BLOCK_TYPE_OPTIONS.map(({ value, label, icon: IconComp }) => /* @__PURE__ */ jsxRuntime.jsxs(
2920
+ DropdownMenu.Item,
2921
+ {
2922
+ onSelect: () => handleSelect(value),
2923
+ className: cn(
2924
+ "tw-flex tw-items-center tw-gap-2",
2925
+ blockType === value && "tw-bg-secondary-50 tw-text-secondary-500"
2926
+ ),
2927
+ children: [
2928
+ /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: "tw-size-4" }),
2929
+ label
2930
+ ]
2931
+ },
2932
+ value
2933
+ )) })
2934
+ ] });
2935
+ };
2936
+
2937
+ // src/components/MarkdownEditor/plugins/toolbar/LinkPanel.tsx
2938
+ init_icons();
2939
+ init_Button2();
2940
+ var buttonGroupVariant = classVarianceAuthority.cva(
2941
+ ["tailwindcss-preflight", "tw-inline-flex", "tw-items-center", "tw-group/button-group"],
2942
+ {
2943
+ defaultVariants: {
2944
+ variant: "inline",
2945
+ space: "small"
2946
+ },
2947
+ variants: {
2948
+ variant: {
2949
+ inline: [],
2950
+ block: [
2951
+ "tw-w-full",
2952
+ "tw-flex-col",
2953
+ "sm:tw-flex-row",
2954
+ "[&_a]:tw-flex-1",
2955
+ "[&>button:not([data-icon-only=true])]:tw-flex-1"
2956
+ ]
2957
+ },
2958
+ space: {
2959
+ "extra-small": "tw-gap-1",
2960
+ "little-small": "tw-gap-2",
2961
+ small: "tw-gap-3",
2962
+ medium: "tw-gap-4",
2963
+ large: "tw-gap-6",
2964
+ compact: [
2965
+ "tw-border-collapse",
2966
+ "!tw-gap-0",
2967
+ // ensure that focus visible outline is at the top
2968
+ "[&>*:focus-visible]:!tw-z-10",
2969
+ "[&>*:not(:first-child)]:tw-rounded-l-none",
2970
+ "[&>*:not(:last-child)]:tw-rounded-r-none",
2971
+ "[&>*:not(:last-child)]:tw-border-r-0",
2972
+ "[&>*:not(:first-child)]:tw-border-l-0",
2973
+ // separator
2974
+ "[&>*:not(:first-child)]:before:tw-content",
2975
+ "[&>*:not(:first-child)]:before:tw-absolute",
2976
+ "[&>*:not(:first-child)]:before:tw-left-0",
2977
+ "[&>*:not(:first-child)]:before:tw-h-full",
2978
+ "[&>*:not(:first-child)]:before:tw-w-px",
2979
+ "[&>*:not(:first-child)]:before:tw-bg-black/10"
2980
+ ]
2981
+ }
2982
+ }
2983
+ }
2984
+ );
2985
+ var ButtonGroup = ({
2986
+ ref,
2987
+ children,
2988
+ space = "small",
2989
+ className,
2990
+ variant,
2991
+ ...rest
2992
+ }) => {
2993
+ return /* @__PURE__ */ jsxRuntime.jsx(
2994
+ "div",
2995
+ {
2996
+ ref,
2997
+ ...rest,
2998
+ role: "group",
2999
+ "data-variant": variant,
3000
+ className: buttonGroupVariant({ variant, className, space }),
3001
+ children
3002
+ }
3003
+ );
3004
+ };
3005
+
3006
+ // src/components/FormGroup/FormGroup.tsx
3007
+ init_utils();
3008
+ var FormGroupContext = react.createContext({
3009
+ state: "default"
3010
+ });
3011
+ var FormGroupProvider = FormGroupContext;
3012
+ var useFormGroupContext = () => react.use(FormGroupContext);
3013
+
3014
+ // src/components/InputGroup/InputGroup.tsx
3015
+ init_utils();
3016
+
3017
+ // src/components/InputGroup/InputGroupAddon.tsx
3018
+ init_utils();
3019
+ var addonVariants = classVarianceAuthority.cva(["tw-flex", "tw-items-center", "tw-gap-1"], {
3020
+ defaultVariants: {
3021
+ align: "inline-start"
3022
+ },
3023
+ variants: {
3024
+ align: {
3025
+ "inline-start": ["tw-order-first", "[&:not(:empty)]:tw-pl-4"],
3026
+ "inline-end": ["tw-order-last", "[&:not(:empty)]:tw-pr-4"],
3027
+ "block-start": [
3028
+ "tw-order-first",
3029
+ // `tw-w-full` needs to be empty-conditional too — when the addon
3030
+ // has no content the root stays in flex-row, and a 100%-wide
3031
+ // empty addon would claim half of the input row beside the input.
3032
+ "[&:not(:empty)]:tw-w-full",
3033
+ "[&:not(:empty)]:tw-px-4",
3034
+ "[&:not(:empty)]:tw-py-1.5"
3035
+ ],
3036
+ "block-end": [
3037
+ "tw-order-last",
3038
+ "[&:not(:empty)]:tw-w-full",
3039
+ "[&:not(:empty)]:tw-px-4",
3040
+ "[&:not(:empty)]:tw-py-1.5"
3041
+ ]
3042
+ }
3043
+ }
3044
+ });
3045
+ var InputGroupAddon = ({
3046
+ children,
3047
+ align = "inline-start",
3048
+ className,
3049
+ ...props
3050
+ }) => /* @__PURE__ */ jsxRuntime.jsx("div", { ...props, "data-align": align, className: cn(addonVariants({ align, className })), children });
3051
+
3052
+ // src/components/InputGroup/InputGroupButton.tsx
3053
+ init_utils();
3054
+ init_Button2();
3055
+ var InputGroupButton = ({
3056
+ ref,
3057
+ className,
3058
+ tabIndex = -1,
3059
+ ...props
3060
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
3061
+ Button,
3062
+ {
3063
+ argo: true,
3064
+ ...props,
3065
+ tabIndex,
3066
+ ref,
3067
+ variant: "invisible",
3068
+ size: "icon-sm",
3069
+ className: cn("tw-size-5", "[&_svg]:tw-text-muted-foreground", className)
3070
+ }
3071
+ );
3072
+
3073
+ // src/components/InputGroup/InputGroupInput.tsx
3074
+ init_utils();
3075
+ var InputGroupInput = ({
3076
+ ref,
3077
+ className,
3078
+ ...inputProps
3079
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
3080
+ "input",
3081
+ {
3082
+ ...inputProps,
3083
+ ref,
3084
+ className: cn(
3085
+ "tw-w-full",
3086
+ "tw-bg-transparent",
3087
+ "tw-outline-none",
3088
+ // font
3089
+ "tw-font-sans",
3090
+ "tw-text-sm",
3091
+ // placeholder
3092
+ "placeholder:tw-text-neutral-400",
3093
+ "placeholder:tw-font-normal",
3094
+ // disabled
3095
+ "disabled:tw-cursor-not-allowed",
3096
+ className
3097
+ )
3098
+ }
3099
+ );
3100
+
3101
+ // src/components/InputGroup/InputGroupText.tsx
3102
+ init_utils();
3103
+ var InputGroupText = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
3104
+ "span",
3105
+ {
3106
+ className: cn(
3107
+ "tw-flex",
3108
+ "tw-items-center",
3109
+ "tw-gap-2",
3110
+ "tw-text-sm",
3111
+ "tw-text-muted-foreground",
3112
+ "[&_svg]:tw-pointer-events-none",
3113
+ '[&_svg:not([class*="tw-size-"])]:tw-size-4',
3114
+ className
3115
+ ),
3116
+ ...props
3117
+ }
3118
+ );
3119
+
3120
+ // src/components/InputGroup/InputGroupTextArea.tsx
3121
+ init_utils();
3122
+ var InputGroupTextArea = ({
3123
+ ref,
3124
+ className,
3125
+ onChange,
3126
+ onValueChange,
3127
+ value,
3128
+ defaultValue,
3129
+ onBlur,
3130
+ onValueBlur,
3131
+ disableResize = false,
3132
+ minRows = 1,
3133
+ maxRows = 4,
3134
+ ...props
3135
+ }) => {
3136
+ const handleChange = (event) => {
3137
+ onValueChange?.(event.target.value);
3138
+ onChange?.(event);
3139
+ };
3140
+ const handleBlur = (event) => {
3141
+ onValueBlur?.(event.target.value);
3142
+ onBlur?.(event);
3143
+ };
3144
+ return /* @__PURE__ */ jsxRuntime.jsx(
3145
+ TextareaAutosize__default.default,
3146
+ {
3147
+ ...props,
3148
+ ref,
3149
+ value: value ?? void 0,
3150
+ defaultValue: defaultValue ?? void 0,
3151
+ onChange: handleChange,
3152
+ onBlur: handleBlur,
3153
+ minRows,
3154
+ maxRows: maxRows === "unlimited" ? void 0 : maxRows,
3155
+ className: cn(
3156
+ "tw-w-full",
3157
+ "tw-bg-transparent",
3158
+ "tw-outline-none",
3159
+ "tw-px-4",
3160
+ // font
3161
+ "tw-font-sans",
3162
+ "tw-text-sm",
3163
+ // placeholder
3164
+ "placeholder:tw-text-neutral-400",
3165
+ "placeholder:tw-font-normal",
3166
+ // disabled
3167
+ "disabled:tw-cursor-not-allowed",
3168
+ {
3169
+ "tw-resize-none": disableResize
3170
+ },
3171
+ className
3172
+ )
3173
+ }
3174
+ );
3175
+ };
3176
+ var inputGroupVariants = classVarianceAuthority.cva(
3177
+ [
3178
+ "tailwindcss-preflight",
3179
+ "tw-group",
3180
+ "tw-overflow-hidden",
3181
+ "tw-box-border",
3182
+ // positioning
3183
+ "tw-flex",
3184
+ "tw-items-center",
3185
+ // base
3186
+ "tw-rounded",
3187
+ "tw-border",
3188
+ "tw-border-solid",
3189
+ "tw-border-neutral-200",
3190
+ "tw-text-neutral-800",
3191
+ "tw-transition",
3192
+ // focus
3193
+ "has-[:is(input,textarea):focus]:tw-ring-4",
3194
+ // readonly
3195
+ "has-[:is(input,textarea)[readonly]]:tw-bg-neutral-150",
3196
+ "has-[:is(input,textarea)[readonly]]:focus-within:tw-ring-0",
3197
+ "has-[:is(input,textarea)[readonly]]:tw-border-neutral-150",
3198
+ // disabled cursor (opacity owned by variant)
3199
+ "has-[:is(input,textarea):disabled]:tw-cursor-not-allowed",
3200
+ // textarea: top-align addons, allow vertical expansion, own its y-padding
3201
+ "has-[textarea]:tw-items-start",
3202
+ "has-[[data-align=block-start]:not(:empty)]:tw-flex-wrap",
3203
+ "has-[[data-align=block-end]:not(:empty)]:tw-flex-wrap",
3204
+ "[&>input]:has-[[data-align=block-start]:not(:empty)]:tw-w-auto",
3205
+ "[&>input]:has-[[data-align=block-start]:not(:empty)]:tw-flex-1",
3206
+ "[&>input]:has-[[data-align=block-end]:not(:empty)]:tw-w-auto",
3207
+ "[&>input]:has-[[data-align=block-end]:not(:empty)]:tw-flex-1",
3208
+ "[&>input]:tw-px-4",
3209
+ "[&>input]:has-[[data-align=inline-start]:not(:empty)]:tw-pl-2",
3210
+ "[&>input]:has-[[data-align=inline-end]:not(:empty)]:tw-pr-2"
3211
+ ],
3212
+ {
3213
+ defaultVariants: {
3214
+ variant: "primary",
3215
+ state: "default",
3216
+ sizing: "default",
3217
+ focusVariant: "default"
3218
+ },
3219
+ compoundVariants: [
3220
+ {
3221
+ variant: "secondary",
3222
+ state: "error",
3223
+ className: ["tw-bg-error-100"]
3224
+ },
3225
+ {
3226
+ variant: "secondary",
3227
+ state: "warning",
3228
+ className: ["tw-bg-warning-100"]
3229
+ },
3230
+ {
3231
+ variant: "primary",
3232
+ state: "default",
3233
+ focusVariant: "off",
3234
+ className: ["has-[:is(input,textarea):focus]:tw-border-neutral-200"]
3235
+ },
3236
+ {
3237
+ variant: "secondary",
3238
+ state: "default",
3239
+ focusVariant: "off",
3240
+ className: ["has-[:is(input,textarea):focus]:tw-border-neutral-100"]
3241
+ },
3242
+ {
3243
+ variant: ["primary", "secondary"],
3244
+ state: "error",
3245
+ focusVariant: "on",
3246
+ className: ["!tw-border-error-500", "!tw-ring-error-200"]
3247
+ },
3248
+ {
3249
+ variant: ["primary", "secondary"],
3250
+ state: "warning",
3251
+ focusVariant: "on",
3252
+ className: ["!tw-border-warning-500", "!tw-ring-warning-200"]
3253
+ },
3254
+ // --- argo ---
3255
+ {
3256
+ variant: "argo",
3257
+ state: "default",
3258
+ className: [
3259
+ "has-[:is(input,textarea):focus]:tw-border-primary",
3260
+ "has-[:is(input,textarea):focus]:tw-ring-primary/50"
3261
+ ]
3262
+ },
3263
+ {
3264
+ variant: "argo",
3265
+ state: "error",
3266
+ className: [
3267
+ "tw-border-destructive",
3268
+ "has-[:is(input,textarea):focus]:tw-border-destructive",
3269
+ "has-[:is(input,textarea):focus]:tw-ring-destructive/20"
3270
+ ]
3271
+ },
3272
+ {
3273
+ variant: "argo",
3274
+ focusVariant: "on",
3275
+ className: ["!tw-border-primary", "!tw-ring-primary/50"]
3276
+ },
3277
+ {
3278
+ variant: "argo",
3279
+ state: "error",
3280
+ focusVariant: "on",
3281
+ className: ["!tw-border-destructive", "!tw-ring-destructive/20"]
3282
+ },
3283
+ {
3284
+ variant: "argo",
3285
+ state: "default",
3286
+ focusVariant: "off",
3287
+ className: ["has-[:is(input,textarea):focus]:tw-border-input"]
3288
+ }
3289
+ ],
3290
+ variants: {
3291
+ focusVariant: {
3292
+ default: [],
3293
+ on: ["!tw-border-secondary-500", "!tw-ring-secondary-200", "!tw-ring-4"],
3294
+ off: ["has-[:is(input,textarea):focus]:!tw-ring-0"]
3295
+ },
3296
+ variant: {
3297
+ primary: ["tw-bg-white", "has-[:is(input,textarea):disabled]:tw-opacity-40"],
3298
+ secondary: [
3299
+ "tw-bg-neutral-100",
3300
+ "tw-border-neutral-100",
3301
+ "has-[:is(input,textarea):disabled]:tw-opacity-40"
3302
+ ],
3303
+ argo: [
3304
+ "tw-bg-background",
3305
+ "tw-border-input",
3306
+ "tw-rounded-lg",
3307
+ "tw-text-foreground",
3308
+ "has-[:is(input,textarea):disabled]:tw-opacity-50",
3309
+ // higher specificity than has-[:is(input,textarea):focus] — prevents focus border on readonly
3310
+ "has-[:is(input,textarea)[readonly]:focus]:tw-border-neutral-150"
3311
+ ]
3312
+ },
3313
+ sizing: {
3314
+ default: [
3315
+ "[&>:is(input,textarea)]:tw-py-2.5",
3316
+ "[&>:is(input,textarea)]:tw-leading-[18px]",
3317
+ "[&>textarea]:!tw-min-h-[calc(2.5rem-2px)]"
3318
+ ],
3319
+ small: [
3320
+ "[&>:is(input,textarea)]:tw-py-2",
3321
+ "[&>:is(input,textarea)]:tw-leading-[16px]",
3322
+ "[&>textarea]:!tw-min-h-[calc(2rem-2px)]"
3323
+ ],
3324
+ medium: [
3325
+ "[&>:is(input,textarea)]:tw-py-2",
3326
+ "[&>:is(input,textarea)]:tw-leading-[18px]",
3327
+ "[&>textarea]:!tw-min-h-[calc(2.25rem-2px)]"
3328
+ ]
3329
+ },
3330
+ state: {
3331
+ default: [
3332
+ "has-[:is(input,textarea):focus]:tw-border-secondary-500",
3333
+ "has-[:is(input,textarea):focus]:tw-ring-secondary-200"
3334
+ ],
3335
+ error: [
3336
+ "tw-border-error-500",
3337
+ "has-[:is(input,textarea):focus]:tw-border-error-500",
3338
+ "has-[:is(input,textarea):focus]:tw-ring-error-200"
3339
+ ],
3340
+ warning: [
3341
+ "tw-border-warning-500",
3342
+ "has-[:is(input,textarea):focus]:tw-border-warning-500",
3343
+ "has-[:is(input,textarea):focus]:tw-ring-warning-200"
3344
+ ]
3345
+ }
3346
+ }
3347
+ }
3348
+ );
3349
+ var InputGroupRoot = ({
3350
+ ref,
3351
+ children,
3352
+ state,
3353
+ variant,
3354
+ sizing,
3355
+ focusVariant,
3356
+ className,
3357
+ ...props
3358
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
3359
+ "div",
3360
+ {
3361
+ ...props,
3362
+ ref,
3363
+ className: cn(inputGroupVariants({ state, variant, sizing, focusVariant, className })),
3364
+ children
3365
+ }
3366
+ );
3367
+ var InputGroup = InputGroupRoot;
3368
+ InputGroup.Input = InputGroupInput;
3369
+ InputGroup.Addon = InputGroupAddon;
3370
+ InputGroup.Button = InputGroupButton;
3371
+ InputGroup.TextArea = InputGroupTextArea;
3372
+ InputGroup.Text = InputGroupText;
3373
+
3374
+ // src/blocks/ColorInput/ColorInput.tsx
3375
+ init_icons();
3376
+ init_utils();
3377
+
3378
+ // src/blocks/ColorInput/utils.ts
3379
+ var HEX_CHARSET = /^[0-9a-fA-F]+$/;
3380
+ var COMPLETE_HEX_PATTERN = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
3381
+ var MAX_HEX_BODY_LENGTH = 8;
3382
+ var PICKER_FALLBACK = "#000000";
3383
+ var extractHexBody = (value) => {
3384
+ if (typeof value !== "string") return null;
3385
+ const trimmed = value.trim();
3386
+ if (trimmed === "") return null;
3387
+ return trimmed.startsWith("#") ? trimmed.slice(1) : trimmed;
3388
+ };
3389
+ var isCompleteHexColor = (value) => COMPLETE_HEX_PATTERN.test(value);
3390
+ var showPicker = (input) => {
3391
+ const isShowPickerSupported = "showPicker" in HTMLInputElement.prototype;
3392
+ isShowPickerSupported ? input.showPicker() : input.click();
3393
+ };
3394
+ var coerceHexInputValue = (value) => {
3395
+ const body = extractHexBody(value);
3396
+ if (body === null) return "";
3397
+ const [validBody] = body.match(/^[0-9a-fA-F]+/) ?? [];
3398
+ if (!validBody) return "";
3399
+ return `#${validBody.slice(0, MAX_HEX_BODY_LENGTH)}`;
3400
+ };
3401
+ var coerceColorPickerValue = (value) => {
3402
+ const body = extractHexBody(value);
3403
+ if (body === null || !HEX_CHARSET.test(body)) return PICKER_FALLBACK;
3404
+ if (body.length === 3 || body.length === 4) {
3405
+ const [r, g, b] = body;
3406
+ return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();
3407
+ }
3408
+ if (body.length === 6 || body.length === 8) {
3409
+ return `#${body.slice(0, 6).toLowerCase()}`;
3410
+ }
3411
+ return PICKER_FALLBACK;
3412
+ };
3413
+ var ColorPicker = ({ value, disabled, readOnly, ...props }) => {
3414
+ const pickerRef = react.useRef(null);
3415
+ const handleOpenPicker = () => {
3416
+ if (!pickerRef.current) return;
3417
+ showPicker(pickerRef.current);
3418
+ };
3419
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tw-relative", children: [
3420
+ /* @__PURE__ */ jsxRuntime.jsx(
3421
+ "input",
3422
+ {
3423
+ ...props,
3424
+ ref: pickerRef,
3425
+ type: "color",
3426
+ value: coerceColorPickerValue(value),
3427
+ tabIndex: -1,
3428
+ "aria-hidden": true,
3429
+ className: "tw-pointer-events-none tw-absolute tw-left-0 tw-top-full tw-size-0 tw-opacity-0",
3430
+ disabled,
3431
+ readOnly
3432
+ }
3433
+ ),
3434
+ /* @__PURE__ */ jsxRuntime.jsx(
3435
+ InputGroup.Button,
3436
+ {
3437
+ onMouseDown: (event) => event.preventDefault(),
3438
+ disabled: disabled || readOnly,
3439
+ onClick: handleOpenPicker,
3440
+ "aria-label": "Pick color",
3441
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pipette, { className: "tw-size-4" })
3442
+ }
3443
+ )
3444
+ ] });
3445
+ };
3446
+ var ColorInput = ({
3447
+ ref,
3448
+ // group props
3449
+ state,
3450
+ variant,
3451
+ focusVariant,
3452
+ sizing,
3453
+ className,
3454
+ // own props
3455
+ value: valueProp,
3456
+ onValueChange,
3457
+ onValueBlur,
3458
+ onChange,
3459
+ onBlur,
3460
+ defaultValue,
3461
+ allowClear = false,
3462
+ // input props
3463
+ disabled,
3464
+ readOnly,
3465
+ ...restInputProps
3466
+ }) => {
3467
+ const inputRef = react.useRef(null);
3468
+ const [internalValue, setInternalValue] = react.useState(defaultValue ?? "");
3469
+ const isControlled = valueProp !== void 0;
3470
+ const value = isControlled ? valueProp ?? "" : internalValue;
3471
+ const setValue = (nextValue) => {
3472
+ if (!isControlled) setInternalValue(nextValue);
3473
+ onValueChange?.(nextValue);
3474
+ };
3475
+ const canClear = allowClear && !!value && !disabled && !readOnly;
3476
+ const swatchColor = coerceHexInputValue(value);
3477
+ const isValidSwatch = isCompleteHexColor(swatchColor);
3478
+ const handleChange = (event) => {
3479
+ setValue(event.target.value);
3480
+ onChange?.(event);
3481
+ };
3482
+ const handleBlur = (event) => {
3483
+ const newValue = event.target.value;
3484
+ const sanitizedNewValue = coerceHexInputValue(newValue);
3485
+ if (sanitizedNewValue !== newValue) {
3486
+ if (!isControlled) event.target.value = sanitizedNewValue;
3487
+ setValue(sanitizedNewValue);
3488
+ }
3489
+ onValueBlur?.(sanitizedNewValue);
3490
+ onBlur?.(event);
3491
+ };
3492
+ const handlePickerChange = (event) => {
3493
+ setValue(coerceHexInputValue(event.target.value));
3494
+ onChange?.(event);
3495
+ };
3496
+ const handleClear = () => {
3497
+ if (!inputRef.current) return;
3498
+ inputRef.current.value = "";
3499
+ setValue("");
3500
+ onChange?.(createChangeInputEvent(inputRef.current));
3501
+ };
3502
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3503
+ InputGroup,
3504
+ {
3505
+ state,
3506
+ variant,
3507
+ sizing,
3508
+ focusVariant,
3509
+ className,
3510
+ children: [
3511
+ /* @__PURE__ */ jsxRuntime.jsx(
3512
+ InputGroup.Addon,
3513
+ {
3514
+ align: "inline-start",
3515
+ className: cn(
3516
+ { "-tw-ml-7 tw-opacity-0": !value },
3517
+ "tw-transition-[opacity,margin]",
3518
+ "tw-ease-linear",
3519
+ "tw-duration-200"
3520
+ ),
3521
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3522
+ "div",
3523
+ {
3524
+ style: isValidSwatch ? { background: swatchColor } : void 0,
3525
+ className: cn(
3526
+ "tw-size-5",
3527
+ "tw-shrink-0",
3528
+ "tw-rounded-sm",
3529
+ "tw-border",
3530
+ "tw-border-solid",
3531
+ "tw-border-neutral-300",
3532
+ {
3533
+ "tw-bg-[linear-gradient(to_top_right,transparent_calc(50%_-_1px),theme(colors.red.300)_calc(50%_-_1px),theme(colors.red.300)_calc(50%_+_1px),transparent_calc(50%_+_1px))]": !isValidSwatch
3534
+ }
3535
+ )
3536
+ }
3537
+ )
3538
+ }
3539
+ ),
3540
+ /* @__PURE__ */ jsxRuntime.jsx(
3541
+ InputGroup.Input,
3542
+ {
3543
+ ...restInputProps,
3544
+ type: "text",
3545
+ ref: mergeRefs(ref ?? null, inputRef),
3546
+ value,
3547
+ onChange: handleChange,
3548
+ onBlur: handleBlur,
3549
+ disabled,
3550
+ readOnly
3551
+ }
3552
+ ),
3553
+ /* @__PURE__ */ jsxRuntime.jsxs(InputGroup.Addon, { align: "inline-end", children: [
3554
+ canClear && /* @__PURE__ */ jsxRuntime.jsx(
3555
+ InputGroup.Button,
3556
+ {
3557
+ onMouseDown: (event) => event.preventDefault(),
3558
+ onClick: handleClear,
3559
+ "aria-label": "Clear color",
3560
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "tw-size-4" })
3561
+ }
3562
+ ),
3563
+ /* @__PURE__ */ jsxRuntime.jsx(
3564
+ ColorPicker,
3565
+ {
3566
+ disabled,
3567
+ readOnly,
3568
+ value,
3569
+ onChange: handlePickerChange
3570
+ }
3571
+ )
3572
+ ] })
3573
+ ]
3574
+ }
3575
+ );
3576
+ };
3577
+ var FormGroupColorInput = ({
3578
+ ref,
3579
+ ...props
3580
+ }) => {
3581
+ const { state } = useFormGroupContext();
3582
+ return /* @__PURE__ */ jsxRuntime.jsx(ColorInput, { state, ...props, ref });
3583
+ };
3584
+ var helpVariants = classVarianceAuthority.cva(["tw-m-0", "tw-text-xs"], {
3585
+ defaultVariants: {
3586
+ state: "default"
3587
+ },
3588
+ variants: {
3589
+ state: {
3590
+ default: ["tw-text-neutral-500"],
3591
+ error: ["tw-text-error-500"],
3592
+ warning: ["tw-text-warning-500"]
3593
+ }
3594
+ }
3595
+ });
3596
+ var HelpBlock = ({ children, className, state = "default", testId }) => {
3597
+ if (!children) return null;
3598
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { "data-testid": testId, className: helpVariants({ state, className }), children });
3599
+ };
3600
+ var FormGroupHelp = ({ children, ...rest }) => {
3601
+ const formGroupContext = useFormGroupContext();
3602
+ return /* @__PURE__ */ jsxRuntime.jsx(HelpBlock, { state: formGroupContext.state, ...rest, children });
3603
+ };
3604
+ var toNumberOrNull = (event) => Number.isNaN(event.target.valueAsNumber) ? null : event.target.valueAsNumber;
3605
+ var NumberInput = ({
3606
+ ref,
3607
+ state,
3608
+ variant,
3609
+ focusVariant,
3610
+ sizing,
3611
+ className,
3612
+ value,
3613
+ defaultValue,
3614
+ onValueChange,
3615
+ onValueBlur,
3616
+ onChange,
3617
+ onBlur,
3618
+ prefix,
3619
+ suffix,
3620
+ ...inputProps
3621
+ }) => {
3622
+ const handleChange = (event) => {
3623
+ onValueChange?.(toNumberOrNull(event));
3624
+ onChange?.(event);
3625
+ };
3626
+ const handleBlur = (event) => {
3627
+ onValueBlur?.(toNumberOrNull(event));
3628
+ onBlur?.(event);
3629
+ };
3630
+ const isControlled = value !== void 0;
3631
+ const valueProp = isControlled ? { value: value ?? "" } : { defaultValue: defaultValue ?? "" };
3632
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3633
+ InputGroup,
3634
+ {
3635
+ state,
3636
+ variant,
3637
+ sizing,
3638
+ focusVariant,
3639
+ className,
3640
+ children: [
3641
+ prefix && /* @__PURE__ */ jsxRuntime.jsx(InputGroup.Addon, { align: "inline-start", children: prefix }),
3642
+ /* @__PURE__ */ jsxRuntime.jsx(
3643
+ InputGroup.Input,
3644
+ {
3645
+ ...inputProps,
3646
+ ...valueProp,
3647
+ ref,
3648
+ type: "number",
3649
+ onChange: handleChange,
3650
+ onBlur: handleBlur
3651
+ }
3652
+ ),
3653
+ suffix && /* @__PURE__ */ jsxRuntime.jsx(InputGroup.Addon, { align: "inline-end", children: suffix })
3654
+ ]
3655
+ }
3656
+ );
3657
+ };
3658
+ var FormGroupNumberInput = ({
3659
+ ref,
3660
+ ...props
3661
+ }) => {
3662
+ const { state } = useFormGroupContext();
3663
+ return /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...props, ref, state });
3664
+ };
3665
+ var Textarea = ({
3666
+ ref,
3667
+ containerClassName,
3668
+ // group props
3669
+ state = "default",
3670
+ variant = "primary",
3671
+ sizing,
3672
+ focusVariant,
3673
+ ...rest
3674
+ }) => {
3675
+ return /* @__PURE__ */ jsxRuntime.jsx(
3676
+ InputGroup,
3677
+ {
3678
+ state,
3679
+ sizing,
3680
+ focusVariant,
3681
+ variant,
3682
+ className: containerClassName,
3683
+ children: /* @__PURE__ */ jsxRuntime.jsx(InputGroup.TextArea, { ...rest, ref })
3684
+ }
3685
+ );
3686
+ };
3687
+ var FormGroupTextarea = (props) => {
3688
+ const { state } = useFormGroupContext();
3689
+ return /* @__PURE__ */ jsxRuntime.jsx(Textarea, { state, ...props });
3690
+ };
3691
+
3692
+ // src/components/Input/Input.tsx
3693
+ init_icons();
3694
+ init_utils();
3695
+
3696
+ // src/components/Input/utils.ts
3697
+ init_utils();
3698
+ var genInputTestId = (prefix = "") => {
3699
+ const ps = createPrefixedString(prefix);
3700
+ return {
3701
+ toString: () => prefix,
3702
+ inputWrapper: ps`input-wrapper`,
3703
+ input: ps`input`,
3704
+ clearButton: ps`clear-button`
3705
+ };
3706
+ };
3707
+ var Input = ({
3708
+ ref: forwardedRef,
3709
+ state = "default",
3710
+ sizing = "default",
3711
+ className,
3712
+ prefix = null,
3713
+ rightSuffix = null,
3714
+ rightSuffixVariant = "default",
3715
+ leftSuffix = null,
3716
+ allowClear = false,
3717
+ onClear,
3718
+ disabled = false,
3719
+ testId: prefixTestId = "",
3720
+ autoFocus = false,
3721
+ id,
3722
+ name,
3723
+ variant,
3724
+ readOnly,
3725
+ type = "text",
3726
+ focusVariant = "default",
3727
+ onChange,
3728
+ onBlur,
3729
+ value,
3730
+ defaultValue,
3731
+ ...inputProps
3732
+ }) => {
3733
+ const [hasUncontrolledValue, setHasUncontrolledValue] = react.useState(() => !!defaultValue);
3734
+ const hasValue = !!value || hasUncontrolledValue;
3735
+ const inputRef = react.useRef(null);
3736
+ const testId = genInputTestId(prefixTestId);
3737
+ const isClearButtonVisible = hasValue && !disabled && !readOnly || !!onClear;
3738
+ const handleChange = (event) => {
3739
+ const val = event.target.value;
3740
+ setHasUncontrolledValue(val !== "");
3741
+ onChange?.(event);
3742
+ };
3743
+ const handleBlur = (event) => {
3744
+ const val = event.target.value;
3745
+ setHasUncontrolledValue(val !== "");
3746
+ onBlur?.(event);
3747
+ };
3748
+ const handleClear = () => {
3749
+ if (inputRef.current === null) return;
3750
+ inputRef.current.value = "";
3751
+ inputRef.current.focus();
3752
+ onClear?.();
3753
+ setHasUncontrolledValue(false);
3754
+ onChange?.(createChangeInputEvent(inputRef.current));
3755
+ };
3756
+ const isControlled = value !== void 0;
3757
+ const valueProp = isControlled ? { value: value ?? "" } : { defaultValue: defaultValue ?? "" };
3758
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3759
+ InputGroup,
3760
+ {
3761
+ state,
3762
+ variant,
3763
+ sizing,
3764
+ focusVariant,
3765
+ className,
3766
+ "data-testid": testId.inputWrapper,
3767
+ children: [
3768
+ prefix && /* @__PURE__ */ jsxRuntime.jsx(InputGroup.Addon, { align: "inline-start", children: prefix }),
3769
+ /* @__PURE__ */ jsxRuntime.jsx(
3770
+ InputGroup.Input,
3771
+ {
3772
+ ...inputProps,
3773
+ ...valueProp,
3774
+ autoFocus,
3775
+ type,
3776
+ onChange: handleChange,
3777
+ onBlur: handleBlur,
3778
+ ref: mergeRefs(forwardedRef ?? null, inputRef),
3779
+ disabled,
3780
+ id,
3781
+ name,
3782
+ readOnly,
3783
+ "data-testid": testId.input
3784
+ }
3785
+ ),
3786
+ (leftSuffix || allowClear || rightSuffix) && /* @__PURE__ */ jsxRuntime.jsxs(InputGroup.Addon, { align: "inline-end", children: [
3787
+ leftSuffix,
3788
+ allowClear && isClearButtonVisible && /* @__PURE__ */ jsxRuntime.jsx(
3789
+ InputGroup.Button,
3790
+ {
3791
+ "aria-label": "Clear",
3792
+ onMouseDown: (e) => e.preventDefault(),
3793
+ onClick: handleClear,
3794
+ "data-testid": testId.clearButton,
3795
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "tw-size-4" })
3796
+ }
3797
+ ),
3798
+ rightSuffix && /* @__PURE__ */ jsxRuntime.jsx(
3799
+ "div",
3800
+ {
3801
+ className: cn({
3802
+ "tw-whitespace-nowrap tw-bg-neutral-200 tw-px-4 -tw-mr-4 tw-py-2.5": rightSuffixVariant === "addon"
3803
+ }),
3804
+ children: rightSuffix
3805
+ }
3806
+ )
3807
+ ] })
3808
+ ]
3809
+ }
3810
+ );
3811
+ };
3812
+ var sanitizeTextInputValue = (value) => {
3813
+ if (typeof value === "string" && value.trim() === "") return "";
3814
+ return value;
3815
+ };
3816
+ var TextInput = ({
3817
+ ref,
3818
+ value,
3819
+ defaultValue,
3820
+ type = "text",
3821
+ onValueChange,
3822
+ onChange,
3823
+ onValueBlur,
3824
+ onBlur,
3825
+ ...props
3826
+ }) => {
3827
+ const handleChange = (event) => {
3828
+ onValueChange?.(event.target.value);
3829
+ onChange?.(event);
3830
+ };
3831
+ const handleBlur = (event) => {
3832
+ onValueBlur?.(event.target.value);
3833
+ onBlur?.(event);
3834
+ };
3835
+ return /* @__PURE__ */ jsxRuntime.jsx(
3836
+ Input,
3837
+ {
3838
+ ...props,
3839
+ ref,
3840
+ onChange: handleChange,
3841
+ onBlur: handleBlur,
3842
+ type,
3843
+ value: sanitizeTextInputValue(value),
3844
+ defaultValue: sanitizeTextInputValue(defaultValue)
3845
+ }
3846
+ );
3847
+ };
3848
+ var FormGroupTextInput = ({
3849
+ ref,
3850
+ ...props
3851
+ }) => {
3852
+ const { state } = useFormGroupContext();
3853
+ return /* @__PURE__ */ jsxRuntime.jsx(TextInput, { state, ...props, ref });
3854
+ };
3855
+ var FormGroup = ({ className, children, state, testId }) => {
3856
+ return /* @__PURE__ */ jsxRuntime.jsx(FormGroupProvider, { value: { state }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId, className: cn("tw-flex tw-flex-col tw-gap-1", className), children }) });
3857
+ };
3858
+ FormGroup.Help = FormGroupHelp;
3859
+ FormGroup.TextInput = FormGroupTextInput;
3860
+ FormGroup.NumberInput = FormGroupNumberInput;
3861
+ FormGroup.ColorInput = FormGroupColorInput;
3862
+ FormGroup.Textarea = FormGroupTextarea;
3863
+
3864
+ // src/components/Label/Label.tsx
3865
+ init_utils();
3866
+ var Optional = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("tw-text-neutral-400", className), children: "(optional)" });
3867
+ var Label2 = ({ className, children, id, htmlFor, ...rest }) => {
3868
+ return /* @__PURE__ */ jsxRuntime.jsx(
3869
+ RLabel__namespace.Root,
3870
+ {
3871
+ ...rest,
3872
+ id: id?.toString(),
3873
+ htmlFor: htmlFor?.toString(),
3874
+ className: cn(
3875
+ "tw-m-0 tw-text-neutral-800 tw-font-normal peer-disabled:tw-opacity-50",
3876
+ className
3877
+ ),
3878
+ children
3879
+ }
3880
+ );
3881
+ };
3882
+ Label2.Optional = Optional;
3883
+
3884
+ // src/components/MarkdownEditor/plugins/toolbar/ToolbarButton.tsx
3885
+ init_utils();
3886
+ init_Tooltip2();
3887
+ var ToolbarButton = ({
3888
+ active,
3889
+ disabled,
3890
+ onClick,
3891
+ tooltip,
3892
+ children,
3893
+ className: extraClassName
3894
+ }) => /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { tooltip, placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3895
+ "button",
3896
+ {
3897
+ type: "button",
3898
+ disabled,
3899
+ onClick,
3900
+ className: cn(
3901
+ "tw-flex tw-h-7 tw-min-w-7 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border-0 tw-bg-transparent tw-px-1 tw-text-xs tw-text-neutral-600",
3902
+ "hover:tw-bg-neutral-100 disabled:tw-cursor-not-allowed disabled:tw-opacity-30",
3903
+ active && "tw-bg-secondary-100 tw-text-secondary-500",
3904
+ extraClassName
3905
+ ),
3906
+ children
3907
+ }
3908
+ ) });
3909
+ var insertLink = (editor, url, label, savedSelection) => {
3910
+ editor.update(() => {
3911
+ lexical.$setSelection(savedSelection);
3912
+ const selection = lexical.$getSelection();
3913
+ if (lexical.$isRangeSelection(selection)) {
3914
+ const selectedText = selection.getTextContent();
3915
+ if (selectedText && label === selectedText) {
3916
+ editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, url);
3917
+ return;
3918
+ }
3919
+ }
3920
+ const linkNode = link.$createLinkNode(url);
3921
+ const textNode = lexical.$createTextNode(label || url);
3922
+ linkNode.append(textNode);
3923
+ if (lexical.$isRangeSelection(selection)) {
3924
+ selection.insertNodes([linkNode]);
3925
+ }
3926
+ });
3927
+ };
3928
+ var LinkPanel = ({ editor, isLink }) => {
3929
+ const [open, setOpen] = react.useState(false);
3930
+ const [url, setUrl] = react.useState("");
3931
+ const [label, setLabel] = react.useState("");
3932
+ const savedSelectionRef = react.useRef(null);
3933
+ const panelRef = react.useRef(null);
3934
+ const handleOpen = () => {
3935
+ editor.getEditorState().read(() => {
3936
+ const selection = lexical.$getSelection();
3937
+ savedSelectionRef.current = selection ? selection.clone() : null;
3938
+ if (lexical.$isRangeSelection(selection)) {
3939
+ const text = selection.getTextContent();
3940
+ if (text) setLabel(text);
3941
+ }
3942
+ });
3943
+ setOpen(true);
3944
+ };
3945
+ const handleClose = () => {
3946
+ setOpen(false);
3947
+ setUrl("");
3948
+ setLabel("");
3949
+ savedSelectionRef.current = null;
3950
+ editor.focus();
3951
+ };
3952
+ const handleSubmit = () => {
3953
+ const trimmedUrl = url.trim();
3954
+ if (!trimmedUrl) return;
3955
+ insertLink(editor, trimmedUrl, label.trim(), savedSelectionRef.current);
3956
+ handleClose();
3957
+ };
3958
+ const handleKeyDown = (e) => {
3959
+ if (e.key === "Enter") {
3960
+ e.preventDefault();
3961
+ handleSubmit();
3962
+ }
3963
+ if (e.key === "Escape") {
3964
+ e.preventDefault();
3965
+ handleClose();
3966
+ }
3967
+ };
3968
+ if (isLink) {
3969
+ return /* @__PURE__ */ jsxRuntime.jsx(
3970
+ ToolbarButton,
3971
+ {
3972
+ active: true,
3973
+ onClick: () => editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, null),
3974
+ tooltip: "Remove Link",
3975
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link, { className: "tw-size-4" })
3976
+ }
3977
+ );
3978
+ }
3979
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tw-relative", children: [
3980
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { active: open, onClick: handleOpen, tooltip: "Insert Link", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link, { className: "tw-size-4" }) }),
3981
+ open && /* @__PURE__ */ jsxRuntime.jsx(
3982
+ "div",
3983
+ {
3984
+ ref: panelRef,
3985
+ className: "tw-absolute tw-left-0 tw-top-full tw-z-50 tw-mt-1 tw-w-80 tw-rounded-md tw-border tw-border-neutral-200 tw-bg-white tw-p-3 tw-shadow-lg",
3986
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tw-flex tw-flex-col tw-gap-2", children: [
3987
+ /* @__PURE__ */ jsxRuntime.jsxs(FormGroup, { children: [
3988
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "link-label", className: "tw-mb-1 tw-text-xs", children: "Label" }),
3989
+ /* @__PURE__ */ jsxRuntime.jsx(
3990
+ TextInput,
3991
+ {
3992
+ id: "link-label",
3993
+ autoFocus: true,
3994
+ placeholder: "Link text",
3995
+ value: label,
3996
+ onValueChange: setLabel,
3997
+ onKeyDown: handleKeyDown,
3998
+ variant: "secondary"
3999
+ }
4000
+ )
4001
+ ] }),
4002
+ /* @__PURE__ */ jsxRuntime.jsxs(FormGroup, { children: [
4003
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "link-url", className: "tw-mb-1 tw-text-xs", children: "URL" }),
4004
+ /* @__PURE__ */ jsxRuntime.jsx(
4005
+ TextInput,
4006
+ {
4007
+ id: "link-url",
4008
+ placeholder: "https://\u2026",
4009
+ value: url,
4010
+ onValueChange: setUrl,
4011
+ onKeyDown: handleKeyDown,
4012
+ variant: "secondary"
4013
+ }
4014
+ )
4015
+ ] }),
4016
+ /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { children: [
4017
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "small", variant: "outline", onClick: handleClose, children: "Cancel" }),
4018
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "small", onClick: handleSubmit, disabled: !url.trim(), children: "Add link" })
4019
+ ] })
4020
+ ] })
4021
+ }
4022
+ )
4023
+ ] });
4024
+ };
4025
+ var ToolbarDivider = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-mx-0.5 tw-h-5 tw-w-px tw-bg-neutral-200" });
4026
+ var ELEMENT_FORMAT_TYPES = ["left", "center", "right", "justify", "start", "end", ""];
4027
+ var isElementFormatType = (value) => ELEMENT_FORMAT_TYPES.includes(value);
4028
+ var toElementFormatType = (value) => isElementFormatType(value) ? value : "left";
4029
+ var ToolbarPlugin = () => {
4030
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
4031
+ const [isBold, setIsBold] = react.useState(false);
4032
+ const [isItalic, setIsItalic] = react.useState(false);
4033
+ const [isUnderline, setIsUnderline] = react.useState(false);
4034
+ const [isStrikethrough, setIsStrikethrough] = react.useState(false);
4035
+ const [isCode, setIsCode] = react.useState(false);
4036
+ const [isLink, setIsLink] = react.useState(false);
4037
+ const [blockType, setBlockType] = react.useState("paragraph");
4038
+ const [alignment, setAlignment] = react.useState("left");
4039
+ const [isVisible, setIsVisible] = react.useState(false);
4040
+ const [position, setPosition] = react.useState(null);
4041
+ const toolbarRef = react.useRef(null);
4042
+ const isMouseDownRef = react.useRef(false);
4043
+ const hasSelectionRef = react.useRef(false);
4044
+ const updatePosition = react.useCallback(() => {
4045
+ const nativeSelection = window.getSelection();
4046
+ if (!nativeSelection || nativeSelection.rangeCount === 0) return;
4047
+ const range = nativeSelection.getRangeAt(0);
4048
+ const rect = range.getBoundingClientRect();
4049
+ if (rect.width > 0) {
4050
+ const toolbarWidth = toolbarRef.current?.offsetWidth ?? 300;
4051
+ setPosition({
4052
+ top: rect.top + window.scrollY - 8,
4053
+ left: Math.max(8, rect.left + window.scrollX + rect.width / 2 - toolbarWidth / 2)
4054
+ });
4055
+ }
4056
+ }, []);
4057
+ react.useEffect(() => {
4058
+ const handleMouseDown = () => {
4059
+ isMouseDownRef.current = true;
4060
+ };
4061
+ const handleMouseUp = () => {
4062
+ isMouseDownRef.current = false;
4063
+ if (hasSelectionRef.current) {
4064
+ setIsVisible(true);
4065
+ }
4066
+ };
4067
+ document.addEventListener("mousedown", handleMouseDown);
4068
+ document.addEventListener("mouseup", handleMouseUp);
4069
+ return () => {
4070
+ document.removeEventListener("mousedown", handleMouseDown);
4071
+ document.removeEventListener("mouseup", handleMouseUp);
4072
+ };
4073
+ }, []);
4074
+ const updateToolbar = react.useCallback(() => {
4075
+ const selection = lexical.$getSelection();
4076
+ if (!lexical.$isRangeSelection(selection)) {
4077
+ hasSelectionRef.current = false;
4078
+ setIsVisible(false);
4079
+ return;
4080
+ }
4081
+ const hasSelection = !selection.isCollapsed() && selection.getTextContent().length > 0;
4082
+ hasSelectionRef.current = hasSelection;
4083
+ if (!hasSelection) {
4084
+ setIsVisible(false);
4085
+ } else if (!isMouseDownRef.current) {
4086
+ setIsVisible(true);
4087
+ }
4088
+ if (hasSelection) {
4089
+ updatePosition();
4090
+ }
4091
+ setIsBold(selection.hasFormat("bold"));
4092
+ setIsItalic(selection.hasFormat("italic"));
4093
+ setIsUnderline(selection.hasFormat("underline"));
4094
+ setIsStrikethrough(selection.hasFormat("strikethrough"));
4095
+ setIsCode(selection.hasFormat("code"));
4096
+ const node = selection.anchor.getNode();
4097
+ const parent = node.getParent();
4098
+ setIsLink(link.$isLinkNode(parent) || link.$isLinkNode(node));
4099
+ const blockElement = utils.$getNearestBlockElementAncestorOrThrow(node);
4100
+ if (list.$isListNode(blockElement)) {
4101
+ const listType = blockElement.getListType();
4102
+ setBlockType(listType === "number" ? "number" : "bullet");
4103
+ } else if (richText.$isHeadingNode(blockElement)) {
4104
+ setBlockType(blockElement.getTag());
4105
+ } else if (code.$isCodeNode(blockElement)) {
4106
+ setBlockType("code");
4107
+ } else if (richText.$isQuoteNode(blockElement)) {
4108
+ setBlockType("quote");
4109
+ } else {
4110
+ setBlockType("paragraph");
4111
+ }
4112
+ setAlignment(toElementFormatType(blockElement.getFormatType()));
4113
+ }, [updatePosition]);
4114
+ react.useEffect(() => {
4115
+ const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {
4116
+ editorState.read(() => {
4117
+ updateToolbar();
4118
+ });
4119
+ });
4120
+ return () => {
4121
+ unregisterUpdate();
4122
+ };
4123
+ }, [editor, updateToolbar]);
4124
+ if (!isVisible || !position) return null;
4125
+ return reactDom.createPortal(
4126
+ /* @__PURE__ */ jsxRuntime.jsxs(
4127
+ "div",
4128
+ {
4129
+ ref: toolbarRef,
4130
+ role: "toolbar",
4131
+ "aria-label": "Formatting options",
4132
+ onMouseDown: (e) => e.preventDefault(),
4133
+ style: { top: position.top, left: position.left },
4134
+ className: "tw-absolute tw-z-[1060] tw-flex tw--translate-y-full tw-items-center tw-gap-0.5 tw-rounded-lg tw-border tw-border-neutral-200 tw-bg-white tw-px-1.5 tw-py-1 tw-shadow-lg",
4135
+ children: [
4136
+ /* @__PURE__ */ jsxRuntime.jsx(BlockTypeDropdown, { editor, blockType }),
4137
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarDivider, {}),
4138
+ /* @__PURE__ */ jsxRuntime.jsx(
4139
+ ToolbarButton,
4140
+ {
4141
+ active: isBold,
4142
+ onClick: () => editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "bold"),
4143
+ tooltip: "Bold (Ctrl+B)",
4144
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bold, { className: "tw-size-4" })
4145
+ }
4146
+ ),
4147
+ /* @__PURE__ */ jsxRuntime.jsx(
4148
+ ToolbarButton,
4149
+ {
4150
+ active: isItalic,
4151
+ onClick: () => editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "italic"),
4152
+ tooltip: "Italic (Ctrl+I)",
4153
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Italic, { className: "tw-size-4" })
4154
+ }
4155
+ ),
4156
+ /* @__PURE__ */ jsxRuntime.jsx(
4157
+ ToolbarButton,
4158
+ {
4159
+ active: isUnderline,
4160
+ onClick: () => editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "underline"),
4161
+ tooltip: "Underline (Ctrl+U)",
4162
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Underline, { className: "tw-size-4" })
4163
+ }
4164
+ ),
4165
+ /* @__PURE__ */ jsxRuntime.jsx(
4166
+ ToolbarButton,
4167
+ {
4168
+ active: isStrikethrough,
4169
+ onClick: () => editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "strikethrough"),
4170
+ tooltip: "Strikethrough",
4171
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Strikethrough, { className: "tw-size-4" })
4172
+ }
4173
+ ),
4174
+ /* @__PURE__ */ jsxRuntime.jsx(
4175
+ ToolbarButton,
4176
+ {
4177
+ active: isCode,
4178
+ onClick: () => editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "code"),
4179
+ tooltip: "Inline Code",
4180
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { className: "tw-size-4" })
4181
+ }
4182
+ ),
4183
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarDivider, {}),
4184
+ /* @__PURE__ */ jsxRuntime.jsx(LinkPanel, { editor, isLink }),
4185
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarDivider, {}),
4186
+ /* @__PURE__ */ jsxRuntime.jsx(
4187
+ ToolbarButton,
4188
+ {
4189
+ active: blockType === "bullet",
4190
+ onClick: () => {
4191
+ if (blockType === "bullet") {
4192
+ editor.dispatchCommand(list.REMOVE_LIST_COMMAND, void 0);
4193
+ } else {
4194
+ editor.dispatchCommand(list.INSERT_UNORDERED_LIST_COMMAND, void 0);
4195
+ }
4196
+ },
4197
+ tooltip: "Bullet List",
4198
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "tw-size-4" })
4199
+ }
4200
+ ),
4201
+ /* @__PURE__ */ jsxRuntime.jsx(
4202
+ ToolbarButton,
4203
+ {
4204
+ active: blockType === "number",
4205
+ onClick: () => {
4206
+ if (blockType === "number") {
4207
+ editor.dispatchCommand(list.REMOVE_LIST_COMMAND, void 0);
4208
+ } else {
4209
+ editor.dispatchCommand(list.INSERT_ORDERED_LIST_COMMAND, void 0);
4210
+ }
4211
+ },
4212
+ tooltip: "Numbered List",
4213
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrdered, { className: "tw-size-4" })
4214
+ }
4215
+ ),
4216
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarDivider, {}),
4217
+ /* @__PURE__ */ jsxRuntime.jsx(AlignmentDropdown, { editor, alignment }),
4218
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarDivider, {}),
4219
+ /* @__PURE__ */ jsxRuntime.jsx(
4220
+ ToolbarButton,
4221
+ {
4222
+ active: blockType === "quote",
4223
+ onClick: () => {
4224
+ editor.update(() => {
4225
+ const selection = lexical.$getSelection();
4226
+ if (!lexical.$isRangeSelection(selection)) return;
4227
+ const anchorNode = selection.anchor.getNode();
4228
+ const element = utils.$getNearestBlockElementAncestorOrThrow(anchorNode);
4229
+ const newNode = blockType === "quote" ? lexical.$createParagraphNode() : richText.$createQuoteNode();
4230
+ element.getChildren().forEach((child) => newNode.append(child));
4231
+ element.replace(newNode);
4232
+ });
4233
+ },
4234
+ tooltip: "Quote",
4235
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Quote, { className: "tw-size-4" })
4236
+ }
4237
+ ),
4238
+ /* @__PURE__ */ jsxRuntime.jsx(
4239
+ ToolbarButton,
4240
+ {
4241
+ active: blockType === "code",
4242
+ onClick: () => {
4243
+ editor.update(() => {
4244
+ const selection = lexical.$getSelection();
4245
+ if (!lexical.$isRangeSelection(selection)) return;
4246
+ const anchorNode = selection.anchor.getNode();
4247
+ const element = utils.$getNearestBlockElementAncestorOrThrow(anchorNode);
4248
+ const newNode = blockType === "code" ? lexical.$createParagraphNode() : code.$createCodeNode();
4249
+ element.getChildren().forEach((child) => newNode.append(child));
4250
+ element.replace(newNode);
4251
+ });
4252
+ },
4253
+ tooltip: "Code Block",
4254
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquareCode, { className: "tw-size-4" })
4255
+ }
4256
+ )
4257
+ ]
4258
+ }
4259
+ ),
4260
+ document.body
4261
+ );
4262
+ };
4263
+
4264
+ // src/components/MarkdownEditor/theme.ts
4265
+ var editorTheme = {
4266
+ link: "tw-cursor-pointer !tw-text-secondary-500 tw-underline",
4267
+ text: {
4268
+ bold: "tw-font-bold",
4269
+ italic: "tw-italic",
4270
+ strikethrough: "tw-line-through",
4271
+ underline: "tw-underline",
4272
+ code: "tw-rounded tw-bg-neutral-100 tw-px-1 tw-py-0.5 tw-font-mono tw-text-[0.85em]"
4273
+ },
4274
+ list: {
4275
+ ol: "!tw-list-decimal",
4276
+ ul: "!tw-list-disc",
4277
+ checklist: "!tw-list-none !tw-pl-0",
4278
+ listitemChecked: [
4279
+ "tw-relative !tw-pl-6 tw-list-none tw-outline-none tw-line-through tw-text-neutral-400",
4280
+ 'before:tw-content-[""] before:tw-absolute before:tw-left-0 before:tw-top-[3px]',
4281
+ "before:tw-size-4 before:tw-rounded before:tw-border before:tw-border-solid",
4282
+ "before:tw-bg-secondary-500 before:tw-border-secondary-500 before:tw-cursor-pointer",
4283
+ 'after:tw-content-[""] after:tw-absolute after:tw-left-[5.5px] after:tw-top-[5.5px]',
4284
+ "after:tw-w-1 after:tw-h-2 after:tw-border-white after:tw-border-solid",
4285
+ "after:tw-border-r-[1.5px] after:tw-border-b-[1.5px] after:tw-border-t-0 after:tw-border-l-0",
4286
+ "after:tw-rotate-45"
4287
+ ].join(" "),
4288
+ listitemUnchecked: [
4289
+ "tw-relative !tw-pl-6 tw-list-none tw-outline-none",
4290
+ 'before:tw-content-[""] before:tw-absolute before:tw-left-0 before:tw-top-[3px]',
4291
+ "before:tw-size-4 before:tw-rounded before:tw-border before:tw-border-solid",
4292
+ "before:tw-border-neutral-200 before:tw-bg-white before:tw-cursor-pointer"
4293
+ ].join(" ")
4294
+ }
4295
+ };
4296
+ var EDITOR_NODES = [
4297
+ ImageNode,
4298
+ MermaidNode,
4299
+ richText.HeadingNode,
4300
+ richText.QuoteNode,
4301
+ list.ListNode,
4302
+ list.ListItemNode,
4303
+ code.CodeNode,
4304
+ link.LinkNode,
4305
+ LexicalHorizontalRuleNode.HorizontalRuleNode
4306
+ ];
4307
+ var MarkdownEditor = ({
4308
+ value,
4309
+ onChange,
4310
+ readOnly = false,
4311
+ placeholder,
4312
+ autoFocus = false,
4313
+ disabled = false,
4314
+ onSave,
4315
+ onCancel,
4316
+ onImageUpload,
4317
+ className,
4318
+ imageRenderer,
4319
+ showToolbar = false,
4320
+ compact = false,
4321
+ saveOnBlur = false,
4322
+ singleLine = false,
4323
+ clampDisplay = false
4324
+ }) => {
4325
+ const editable = !readOnly && !disabled;
4326
+ const transformers = singleLine ? SINGLE_LINE_TRANSFORMERS : CUSTOM_TRANSFORMERS;
4327
+ const [initialConfig] = react.useState(() => ({
4328
+ namespace: "MarkdownEditor",
4329
+ theme: editorTheme,
4330
+ nodes: EDITOR_NODES,
4331
+ onError: (error) => {
4332
+ console.error("[MarkdownEditor] uncaught editor error", error);
4333
+ },
4334
+ editable,
4335
+ editorState: () => {
4336
+ markdown.$convertFromMarkdownString(preprocessMarkdown(value), transformers);
4337
+ }
4338
+ }));
4339
+ const skipBlurSaveRef = react.useRef(false);
4340
+ const handleBlur = saveOnBlur && onSave ? (event) => {
4341
+ if (skipBlurSaveRef.current) {
4342
+ skipBlurSaveRef.current = false;
4343
+ return;
4344
+ }
4345
+ if (!event.currentTarget.contains(event.relatedTarget)) {
4346
+ onSave();
4347
+ }
4348
+ } : void 0;
4349
+ return /* @__PURE__ */ jsxRuntime.jsx(LexicalComposer.LexicalComposer, { initialConfig, children: /* @__PURE__ */ jsxRuntime.jsx(ImageRendererProvider, { value: imageRenderer ?? null, children: /* @__PURE__ */ jsxRuntime.jsxs(
4350
+ "div",
4351
+ {
4352
+ className: cn(
4353
+ !compact && "tw-prose",
4354
+ // Compact mode drops `tw-prose`, so Lexical's <p> wrappers fall back to the browser
4355
+ // default `margin: 1em 0` — visually huge at heading sizes. Zero them, and use the
4356
+ // adjacent-sibling selector for paragraph spacing so single-paragraph blocks (titles,
4357
+ // short descriptions) stay tight while multi-paragraph blocks still breathe.
4358
+ compact && "[&_p]:tw-m-0 [&_p+p]:tw-mt-2",
4359
+ // Display-state clamp: 2 lines + bottom fade. Drops in focus-within so editing
4360
+ // expands to full height. Fade replaces ellipsis per the pattern spec — the
4361
+ // mask gradient overlays line-clamp's default ellipsis so it's invisible.
4362
+ clampDisplay && "[&:not(:focus-within)]:tw-line-clamp-2 [&:not(:focus-within)]:[mask-image:linear-gradient(to_bottom,black_50%,transparent)]",
4363
+ className
4364
+ ),
4365
+ onBlur: handleBlur,
4366
+ children: [
4367
+ showToolbar && editable && /* @__PURE__ */ jsxRuntime.jsx(ToolbarPlugin, {}),
4368
+ /* @__PURE__ */ jsxRuntime.jsx(
4369
+ "div",
4370
+ {
4371
+ className: cn(
4372
+ "tw-relative tw-rounded-md tw-transition-colors",
4373
+ // In compact mode the padding lets the hover bg / focus ring extend past the text,
4374
+ // but a matching negative margin shifts the wrapper outward so the text itself stays
4375
+ // aligned with the parent's content edge (i.e. with where static text would render).
4376
+ compact ? "tw-px-1.5 tw-py-0.5 -tw-mx-1.5 -tw-my-0.5" : "tw-p-2",
4377
+ editable && "tw-cursor-text hover:tw-bg-neutral-50 focus-within:tw-ring-2 focus-within:tw-ring-secondary-500/40"
4378
+ ),
4379
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4380
+ LexicalRichTextPlugin.RichTextPlugin,
4381
+ {
4382
+ contentEditable: /* @__PURE__ */ jsxRuntime.jsx(
4383
+ LexicalContentEditable.ContentEditable,
4384
+ {
4385
+ className: cn("tw-outline-none", !compact && "tw-min-h-[100px]"),
4386
+ "aria-placeholder": placeholder ?? "",
4387
+ placeholder: placeholder ? /* @__PURE__ */ jsxRuntime.jsx(
4388
+ "div",
4389
+ {
4390
+ className: cn(
4391
+ "tw-pointer-events-none tw-absolute tw-select-none tw-text-neutral-400",
4392
+ compact ? "tw-left-1.5 tw-top-0.5" : "tw-left-2 tw-top-[calc(0.5rem+0.35em)]"
4393
+ ),
4394
+ children: placeholder
4395
+ }
4396
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", {})
4397
+ }
4398
+ ),
4399
+ ErrorBoundary: LexicalErrorBoundary.LexicalErrorBoundary
4400
+ }
4401
+ )
4402
+ }
4403
+ ),
4404
+ /* @__PURE__ */ jsxRuntime.jsx(LexicalHistoryPlugin.HistoryPlugin, {}),
4405
+ /* @__PURE__ */ jsxRuntime.jsx(LexicalLinkPlugin.LinkPlugin, {}),
4406
+ /* @__PURE__ */ jsxRuntime.jsx(LexicalClickableLinkPlugin.ClickableLinkPlugin, { newTab: true }),
4407
+ !singleLine && /* @__PURE__ */ jsxRuntime.jsx(LexicalListPlugin.ListPlugin, {}),
4408
+ !singleLine && /* @__PURE__ */ jsxRuntime.jsx(LexicalCheckListPlugin.CheckListPlugin, {}),
4409
+ !singleLine && /* @__PURE__ */ jsxRuntime.jsx(LexicalHorizontalRulePlugin.HorizontalRulePlugin, {}),
4410
+ /* @__PURE__ */ jsxRuntime.jsx(LexicalTabIndentationPlugin.TabIndentationPlugin, {}),
4411
+ /* @__PURE__ */ jsxRuntime.jsx(LexicalMarkdownShortcutPlugin.MarkdownShortcutPlugin, { transformers }),
4412
+ /* @__PURE__ */ jsxRuntime.jsx(
4413
+ MarkdownSyncPlugin,
4414
+ {
4415
+ value,
4416
+ editable,
4417
+ onChange,
4418
+ transformers
4419
+ }
4420
+ ),
4421
+ /* @__PURE__ */ jsxRuntime.jsx(ImagePastePlugin, { onImageUpload }),
4422
+ /* @__PURE__ */ jsxRuntime.jsx(
4423
+ KeyboardPlugin,
4424
+ {
4425
+ onSave,
4426
+ onCancel,
4427
+ singleLine,
4428
+ blurOnEscape: singleLine || saveOnBlur,
4429
+ skipBlurSaveRef
4430
+ }
4431
+ ),
4432
+ autoFocus && /* @__PURE__ */ jsxRuntime.jsx(LexicalAutoFocusPlugin.AutoFocusPlugin, {})
4433
+ ]
4434
+ }
4435
+ ) }) });
4436
+ };
4437
+
4438
+ exports.MarkdownEditor = MarkdownEditor;
4439
+ //# sourceMappingURL=markdown-editor.cjs.map
4440
+ //# sourceMappingURL=markdown-editor.cjs.map