@keboola/design 1.0.0 → 1.2.0

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