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