hazo_ui 2.3.1 → 2.4.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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import * as React23 from 'react';
2
- import React23__default, { useRef, useState, useCallback, useEffect, useMemo, Fragment } from 'react';
1
+ import * as React27 from 'react';
2
+ import React27__default, { useRef, useState, useCallback, useEffect, useMemo, Fragment } from 'react';
3
3
  import { Slot } from '@radix-ui/react-slot';
4
4
  import { cva } from 'class-variance-authority';
5
5
  import { clsx } from 'clsx';
@@ -52,6 +52,7 @@ import { LuUndo2, LuRedo2, LuMinus, LuPlus, LuBold, LuItalic, LuUnderline, LuStr
52
52
  import { RxDividerHorizontal } from 'react-icons/rx';
53
53
  import { Extension, Node, mergeAttributes } from '@tiptap/core';
54
54
  import * as TabsPrimitive from '@radix-ui/react-tabs';
55
+ import Suggestion from '@tiptap/suggestion';
55
56
 
56
57
  var __create = Object.create;
57
58
  var __defProp = Object.defineProperty;
@@ -138,7 +139,7 @@ var buttonVariants = cva(
138
139
  }
139
140
  }
140
141
  );
141
- var Button = React23.forwardRef(
142
+ var Button = React27.forwardRef(
142
143
  ({ className, variant, size, asChild = false, ...props }, ref) => {
143
144
  const Comp = asChild ? Slot : "button";
144
145
  return /* @__PURE__ */ jsx(
@@ -155,7 +156,7 @@ Button.displayName = "Button";
155
156
  var Dialog = DialogPrimitive.Root;
156
157
  var DialogTrigger = DialogPrimitive.Trigger;
157
158
  var DialogPortal = DialogPrimitive.Portal;
158
- var DialogOverlay = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
159
+ var DialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
159
160
  DialogPrimitive.Overlay,
160
161
  {
161
162
  ref,
@@ -167,7 +168,7 @@ var DialogOverlay = React23.forwardRef(({ className, ...props }, ref) => /* @__P
167
168
  }
168
169
  ));
169
170
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
170
- var DialogContent = React23.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
171
+ var DialogContent = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
171
172
  /* @__PURE__ */ jsx(DialogOverlay, {}),
172
173
  /* @__PURE__ */ jsxs(
173
174
  DialogPrimitive.Content,
@@ -217,7 +218,7 @@ var DialogFooter = ({
217
218
  }
218
219
  );
219
220
  DialogFooter.displayName = "DialogFooter";
220
- var DialogTitle = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
221
+ var DialogTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
221
222
  DialogPrimitive.Title,
222
223
  {
223
224
  ref,
@@ -229,7 +230,7 @@ var DialogTitle = React23.forwardRef(({ className, ...props }, ref) => /* @__PUR
229
230
  }
230
231
  ));
231
232
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
232
- var DialogDescription = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
233
+ var DialogDescription = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
233
234
  DialogPrimitive.Description,
234
235
  {
235
236
  ref,
@@ -238,7 +239,7 @@ var DialogDescription = React23.forwardRef(({ className, ...props }, ref) => /*
238
239
  }
239
240
  ));
240
241
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
241
- var Command = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
242
+ var Command = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
242
243
  "div",
243
244
  {
244
245
  ref,
@@ -250,7 +251,7 @@ var Command = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__
250
251
  }
251
252
  ));
252
253
  Command.displayName = "Command";
253
- var CommandInput = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
254
+ var CommandInput = React27.forwardRef(({ className, onValueChange, onChange, ...props }, ref) => /* @__PURE__ */ jsx(
254
255
  "input",
255
256
  {
256
257
  ref,
@@ -258,11 +259,15 @@ var CommandInput = React23.forwardRef(({ className, ...props }, ref) => /* @__PU
258
259
  "flex h-11 w-full rounded-md border border-input bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 px-3",
259
260
  className
260
261
  ),
262
+ onChange: (e) => {
263
+ onChange?.(e);
264
+ onValueChange?.(e.target.value);
265
+ },
261
266
  ...props
262
267
  }
263
268
  ));
264
269
  CommandInput.displayName = "CommandInput";
265
- var CommandList = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
270
+ var CommandList = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
266
271
  "div",
267
272
  {
268
273
  ref,
@@ -271,7 +276,7 @@ var CommandList = React23.forwardRef(({ className, ...props }, ref) => /* @__PUR
271
276
  }
272
277
  ));
273
278
  CommandList.displayName = "CommandList";
274
- var CommandEmpty = React23.forwardRef((props, ref) => /* @__PURE__ */ jsx(
279
+ var CommandEmpty = React27.forwardRef((props, ref) => /* @__PURE__ */ jsx(
275
280
  "div",
276
281
  {
277
282
  ref,
@@ -280,19 +285,23 @@ var CommandEmpty = React23.forwardRef((props, ref) => /* @__PURE__ */ jsx(
280
285
  }
281
286
  ));
282
287
  CommandEmpty.displayName = "CommandEmpty";
283
- var CommandGroup = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
288
+ var CommandGroup = React27.forwardRef(({ className, heading, children, ...props }, ref) => /* @__PURE__ */ jsxs(
284
289
  "div",
285
290
  {
286
291
  ref,
287
292
  className: cn(
288
- "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
293
+ "overflow-hidden p-1 text-foreground",
289
294
  className
290
295
  ),
291
- ...props
296
+ ...props,
297
+ children: [
298
+ heading && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground", children: heading }),
299
+ children
300
+ ]
292
301
  }
293
302
  ));
294
303
  CommandGroup.displayName = "CommandGroup";
295
- var CommandItem = React23.forwardRef(({ className, onSelect, value, ...props }, ref) => {
304
+ var CommandItem = React27.forwardRef(({ className, onSelect, value, ...props }, ref) => {
296
305
  const handleClick = () => {
297
306
  if (onSelect && value) {
298
307
  onSelect(value);
@@ -314,7 +323,7 @@ var CommandItem = React23.forwardRef(({ className, onSelect, value, ...props },
314
323
  CommandItem.displayName = "CommandItem";
315
324
  var Popover = PopoverPrimitive.Root;
316
325
  var PopoverTrigger = PopoverPrimitive.Trigger;
317
- var PopoverContent = React23.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
326
+ var PopoverContent = React27.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
318
327
  PopoverPrimitive.Content,
319
328
  {
320
329
  ref,
@@ -328,7 +337,7 @@ var PopoverContent = React23.forwardRef(({ className, align = "center", sideOffs
328
337
  }
329
338
  ) }));
330
339
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
331
- var Input = React23.forwardRef(
340
+ var Input = React27.forwardRef(
332
341
  ({ className, type, ...props }, ref) => {
333
342
  return /* @__PURE__ */ jsx(
334
343
  "input",
@@ -347,7 +356,7 @@ var Input = React23.forwardRef(
347
356
  Input.displayName = "Input";
348
357
  var Select = SelectPrimitive.Root;
349
358
  var SelectValue = SelectPrimitive.Value;
350
- var SelectTrigger = React23.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
359
+ var SelectTrigger = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
351
360
  SelectPrimitive.Trigger,
352
361
  {
353
362
  ref,
@@ -363,7 +372,7 @@ var SelectTrigger = React23.forwardRef(({ className, children, ...props }, ref)
363
372
  }
364
373
  ));
365
374
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
366
- var SelectScrollUpButton = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
375
+ var SelectScrollUpButton = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
367
376
  SelectPrimitive.ScrollUpButton,
368
377
  {
369
378
  ref,
@@ -376,7 +385,7 @@ var SelectScrollUpButton = React23.forwardRef(({ className, ...props }, ref) =>
376
385
  }
377
386
  ));
378
387
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
379
- var SelectScrollDownButton = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
388
+ var SelectScrollDownButton = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
380
389
  SelectPrimitive.ScrollDownButton,
381
390
  {
382
391
  ref,
@@ -389,7 +398,7 @@ var SelectScrollDownButton = React23.forwardRef(({ className, ...props }, ref) =
389
398
  }
390
399
  ));
391
400
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
392
- var SelectContent = React23.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
401
+ var SelectContent = React27.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
393
402
  SelectPrimitive.Content,
394
403
  {
395
404
  ref,
@@ -417,7 +426,7 @@ var SelectContent = React23.forwardRef(({ className, children, position = "poppe
417
426
  }
418
427
  ) }));
419
428
  SelectContent.displayName = SelectPrimitive.Content.displayName;
420
- var SelectLabel = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
429
+ var SelectLabel = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
421
430
  SelectPrimitive.Label,
422
431
  {
423
432
  ref,
@@ -426,7 +435,7 @@ var SelectLabel = React23.forwardRef(({ className, ...props }, ref) => /* @__PUR
426
435
  }
427
436
  ));
428
437
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
429
- var SelectItem = React23.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
438
+ var SelectItem = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
430
439
  SelectPrimitive.Item,
431
440
  {
432
441
  ref,
@@ -442,7 +451,7 @@ var SelectItem = React23.forwardRef(({ className, children, ...props }, ref) =>
442
451
  }
443
452
  ));
444
453
  SelectItem.displayName = SelectPrimitive.Item.displayName;
445
- var SelectSeparator = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
454
+ var SelectSeparator = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
446
455
  SelectPrimitive.Separator,
447
456
  {
448
457
  ref,
@@ -454,7 +463,7 @@ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
454
463
  var TooltipProvider = TooltipPrimitive.Provider;
455
464
  var Tooltip = TooltipPrimitive.Root;
456
465
  var TooltipTrigger = TooltipPrimitive.Trigger;
457
- var TooltipContent = React23.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
466
+ var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
458
467
  TooltipPrimitive.Content,
459
468
  {
460
469
  ref,
@@ -925,7 +934,7 @@ function HazoUiMultiFilterDialog({
925
934
  ] })
926
935
  ] });
927
936
  }
928
- var Switch = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
937
+ var Switch = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
929
938
  SwitchPrimitives.Root,
930
939
  {
931
940
  className: cn(
@@ -945,7 +954,7 @@ var Switch = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
945
954
  }
946
955
  ));
947
956
  Switch.displayName = SwitchPrimitives.Root.displayName;
948
- var Label2 = React23.forwardRef(
957
+ var Label2 = React27.forwardRef(
949
958
  ({ className, ...props }, ref) => {
950
959
  return /* @__PURE__ */ jsx(
951
960
  "label",
@@ -1239,7 +1248,7 @@ function HazoUiMultiSortDialog({
1239
1248
  ] })
1240
1249
  ] });
1241
1250
  }
1242
- var RadioGroup = React23.forwardRef(({ className, ...props }, ref) => {
1251
+ var RadioGroup = React27.forwardRef(({ className, ...props }, ref) => {
1243
1252
  return /* @__PURE__ */ jsx(
1244
1253
  RadioGroupPrimitive.Root,
1245
1254
  {
@@ -1250,7 +1259,7 @@ var RadioGroup = React23.forwardRef(({ className, ...props }, ref) => {
1250
1259
  );
1251
1260
  });
1252
1261
  RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
1253
- var RadioGroupItem = React23.forwardRef(({ className, ...props }, ref) => {
1262
+ var RadioGroupItem = React27.forwardRef(({ className, ...props }, ref) => {
1254
1263
  return /* @__PURE__ */ jsx(
1255
1264
  RadioGroupPrimitive.Item,
1256
1265
  {
@@ -1604,7 +1613,7 @@ function filterInputValue(value, input_type, num_decimals) {
1604
1613
  }
1605
1614
  }
1606
1615
  }
1607
- var HazoUiFlexInput = React23.forwardRef(
1616
+ var HazoUiFlexInput = React27.forwardRef(
1608
1617
  ({
1609
1618
  className,
1610
1619
  input_type = "mixed",
@@ -1621,13 +1630,13 @@ var HazoUiFlexInput = React23.forwardRef(
1621
1630
  onBlur,
1622
1631
  ...props
1623
1632
  }, ref) => {
1624
- const [internalValue, setInternalValue] = React23.useState(
1633
+ const [internalValue, setInternalValue] = React27.useState(
1625
1634
  typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
1626
1635
  );
1627
- const [errorMessage, setErrorMessage] = React23.useState();
1636
+ const [errorMessage, setErrorMessage] = React27.useState();
1628
1637
  const isControlled = controlledValue !== void 0;
1629
1638
  const currentValue = isControlled ? typeof controlledValue === "string" ? controlledValue : String(controlledValue || "") : internalValue;
1630
- React23.useEffect(() => {
1639
+ React27.useEffect(() => {
1631
1640
  if (isControlled) {
1632
1641
  const newValue = typeof controlledValue === "string" ? controlledValue : String(controlledValue || "");
1633
1642
  if (newValue !== internalValue) {
@@ -1707,7 +1716,7 @@ var HazoUiFlexInput = React23.forwardRef(
1707
1716
  }
1708
1717
  );
1709
1718
  HazoUiFlexInput.displayName = "HazoUiFlexInput";
1710
- var ToolbarButton = React23.forwardRef(
1719
+ var ToolbarButton = React27.forwardRef(
1711
1720
  ({ onClick, is_active = false, disabled = false, tooltip, className, children }, ref) => {
1712
1721
  const button = /* @__PURE__ */ jsx(
1713
1722
  "button",
@@ -2026,7 +2035,7 @@ var getRelativePosition = (node, event) => {
2026
2035
  };
2027
2036
  };
2028
2037
  var _excluded = ["prefixCls", "className", "onMove", "onDown"];
2029
- var Interactive = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2038
+ var Interactive = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2030
2039
  var {
2031
2040
  prefixCls = "w-color-interactive",
2032
2041
  className,
@@ -2125,7 +2134,7 @@ var Pointer = (_ref) => {
2125
2134
  }), [top, left, color2, className, prefixCls]);
2126
2135
  };
2127
2136
  var _excluded2 = ["prefixCls", "radius", "pointer", "className", "hue", "style", "hsva", "onChange"];
2128
- var Saturation = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2137
+ var Saturation = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2129
2138
  var _hsva$h;
2130
2139
  var {
2131
2140
  prefixCls = "w-color-saturation",
@@ -2277,7 +2286,7 @@ var Pointer2 = (_ref) => {
2277
2286
  };
2278
2287
  var _excluded4 = ["prefixCls", "className", "hsva", "background", "bgProps", "innerProps", "pointerProps", "radius", "width", "height", "direction", "style", "onChange", "pointer"];
2279
2288
  var BACKGROUND_IMG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==";
2280
- var Alpha = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2289
+ var Alpha = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2281
2290
  var {
2282
2291
  prefixCls = "w-color-alpha",
2283
2292
  className,
@@ -2411,7 +2420,7 @@ var import_objectWithoutPropertiesLoose5 = __toESM(require_objectWithoutProperti
2411
2420
  var _excluded5 = ["prefixCls", "placement", "label", "value", "className", "style", "labelStyle", "inputStyle", "onChange", "onBlur", "renderInput"];
2412
2421
  var validHex2 = (hex) => /^#?([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);
2413
2422
  var getNumberValue = (value) => Number(String(value).replace(/%/g, ""));
2414
- var EditableInput = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2423
+ var EditableInput = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2415
2424
  var {
2416
2425
  prefixCls = "w-color-editable-input",
2417
2426
  placement = "bottom",
@@ -2516,7 +2525,7 @@ var esm_default4 = EditableInput;
2516
2525
  var import_extends7 = __toESM(require_extends());
2517
2526
  var import_objectWithoutPropertiesLoose6 = __toESM(require_objectWithoutPropertiesLoose());
2518
2527
  var _excluded6 = ["prefixCls", "hsva", "placement", "rProps", "gProps", "bProps", "aProps", "className", "style", "onChange"];
2519
- var EditableInputRGBA = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2528
+ var EditableInputRGBA = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2520
2529
  var {
2521
2530
  prefixCls = "w-color-editable-input-rgba",
2522
2531
  hsva,
@@ -2639,7 +2648,7 @@ var esm_default5 = EditableInputRGBA;
2639
2648
  var import_extends8 = __toESM(require_extends());
2640
2649
  var import_objectWithoutPropertiesLoose7 = __toESM(require_objectWithoutPropertiesLoose());
2641
2650
  var _excluded7 = ["prefixCls", "className", "hue", "onChange", "direction"];
2642
- var Hue = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2651
+ var Hue = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2643
2652
  var {
2644
2653
  prefixCls = "w-color-hue",
2645
2654
  className,
@@ -2673,7 +2682,7 @@ var esm_default6 = Hue;
2673
2682
  var import_extends9 = __toESM(require_extends());
2674
2683
  var import_objectWithoutPropertiesLoose8 = __toESM(require_objectWithoutPropertiesLoose());
2675
2684
  var _excluded8 = ["prefixCls", "className", "color", "colors", "style", "rectProps", "onChange", "addonAfter", "addonBefore", "rectRender"];
2676
- var Swatch = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2685
+ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2677
2686
  var {
2678
2687
  prefixCls = "w-color-swatch",
2679
2688
  className,
@@ -2710,7 +2719,7 @@ var Swatch = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2710
2719
  flexWrap: "wrap",
2711
2720
  position: "relative"
2712
2721
  }, style),
2713
- children: [addonBefore && /* @__PURE__ */ React23__default.isValidElement(addonBefore) && addonBefore, colors && Array.isArray(colors) && colors.map((item, idx) => {
2722
+ children: [addonBefore && /* @__PURE__ */ React27__default.isValidElement(addonBefore) && addonBefore, colors && Array.isArray(colors) && colors.map((item, idx) => {
2714
2723
  var title = "";
2715
2724
  var background = "";
2716
2725
  if (typeof item === "string") {
@@ -2736,7 +2745,7 @@ var Swatch = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2736
2745
  children: render
2737
2746
  }, idx);
2738
2747
  }
2739
- var child = rectProps.children && /* @__PURE__ */ React23__default.isValidElement(rectProps.children) ? /* @__PURE__ */ React23__default.cloneElement(rectProps.children, {
2748
+ var child = rectProps.children && /* @__PURE__ */ React27__default.isValidElement(rectProps.children) ? /* @__PURE__ */ React27__default.cloneElement(rectProps.children, {
2740
2749
  color: background,
2741
2750
  checked
2742
2751
  }) : null;
@@ -2750,7 +2759,7 @@ var Swatch = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2750
2759
  background
2751
2760
  })
2752
2761
  }), idx);
2753
- }), addonAfter && /* @__PURE__ */ React23__default.isValidElement(addonAfter) && addonAfter]
2762
+ }), addonAfter && /* @__PURE__ */ React27__default.isValidElement(addonAfter) && addonAfter]
2754
2763
  }));
2755
2764
  });
2756
2765
  Swatch.displayName = "Swatch";
@@ -2769,7 +2778,7 @@ var Bar = (props) => /* @__PURE__ */ jsx("div", {
2769
2778
  backgroundColor: "#fff"
2770
2779
  }
2771
2780
  });
2772
- var Sketch = /* @__PURE__ */ React23__default.forwardRef((props, ref) => {
2781
+ var Sketch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2773
2782
  var {
2774
2783
  prefixCls = "w-color-sketch",
2775
2784
  className,
@@ -3020,19 +3029,19 @@ var Toolbar = ({
3020
3029
  on_attachments_change,
3021
3030
  disabled = false
3022
3031
  }) => {
3023
- const [link_url, set_link_url] = React23.useState("https://");
3024
- const [link_popover_open, set_link_popover_open] = React23.useState(false);
3025
- const [text_color_open, set_text_color_open] = React23.useState(false);
3026
- const [highlight_color_open, set_highlight_color_open] = React23.useState(false);
3027
- const [variables_menu_open, set_variables_menu_open] = React23.useState(false);
3028
- const [table_menu_open, set_table_menu_open] = React23.useState(false);
3029
- const [text_color, set_text_color] = React23.useState("#000000");
3030
- const [highlight_color, set_highlight_color] = React23.useState("#ffff00");
3031
- const [table_rows, set_table_rows] = React23.useState(3);
3032
- const [table_cols, set_table_cols] = React23.useState(3);
3033
- const [hovered_cell, set_hovered_cell] = React23.useState(null);
3034
- const file_input_ref = React23.useRef(null);
3035
- const image_input_ref = React23.useRef(null);
3032
+ const [link_url, set_link_url] = React27.useState("https://");
3033
+ const [link_popover_open, set_link_popover_open] = React27.useState(false);
3034
+ const [text_color_open, set_text_color_open] = React27.useState(false);
3035
+ const [highlight_color_open, set_highlight_color_open] = React27.useState(false);
3036
+ const [variables_menu_open, set_variables_menu_open] = React27.useState(false);
3037
+ const [table_menu_open, set_table_menu_open] = React27.useState(false);
3038
+ const [text_color, set_text_color] = React27.useState("#000000");
3039
+ const [highlight_color, set_highlight_color] = React27.useState("#ffff00");
3040
+ const [table_rows, set_table_rows] = React27.useState(3);
3041
+ const [table_cols, set_table_cols] = React27.useState(3);
3042
+ const [hovered_cell, set_hovered_cell] = React27.useState(null);
3043
+ const file_input_ref = React27.useRef(null);
3044
+ const image_input_ref = React27.useRef(null);
3036
3045
  if (!editor) {
3037
3046
  return null;
3038
3047
  }
@@ -3965,7 +3974,7 @@ var VariableExtension = Node.create({
3965
3974
  }
3966
3975
  });
3967
3976
  var Tabs = TabsPrimitive.Root;
3968
- var TabsList = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3977
+ var TabsList = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3969
3978
  TabsPrimitive.List,
3970
3979
  {
3971
3980
  ref,
@@ -3977,7 +3986,7 @@ var TabsList = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__
3977
3986
  }
3978
3987
  ));
3979
3988
  TabsList.displayName = TabsPrimitive.List.displayName;
3980
- var TabsTrigger = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3989
+ var TabsTrigger = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3981
3990
  TabsPrimitive.Trigger,
3982
3991
  {
3983
3992
  ref,
@@ -3989,7 +3998,7 @@ var TabsTrigger = React23.forwardRef(({ className, ...props }, ref) => /* @__PUR
3989
3998
  }
3990
3999
  ));
3991
4000
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
3992
- var TabsContent = React23.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4001
+ var TabsContent = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3993
4002
  TabsPrimitive.Content,
3994
4003
  {
3995
4004
  ref,
@@ -4024,14 +4033,14 @@ var HazoUiRte = ({
4024
4033
  className,
4025
4034
  show_output_viewer = false
4026
4035
  }) => {
4027
- const [attachments, set_attachments] = React23.useState(
4036
+ const [attachments, set_attachments] = React27.useState(
4028
4037
  initial_attachments
4029
4038
  );
4030
- const [active_tab, set_active_tab] = React23.useState("html");
4039
+ const [active_tab, set_active_tab] = React27.useState("html");
4031
4040
  const is_view_only = active_tab !== "html";
4032
- const attachments_ref = React23.useRef(attachments);
4041
+ const attachments_ref = React27.useRef(attachments);
4033
4042
  attachments_ref.current = attachments;
4034
- const debounced_on_change = React23.useMemo(
4043
+ const debounced_on_change = React27.useMemo(
4035
4044
  () => debounce_fn((output) => {
4036
4045
  if (on_change) {
4037
4046
  on_change(output);
@@ -4130,7 +4139,7 @@ var HazoUiRte = ({
4130
4139
  debounced_on_change(output);
4131
4140
  }
4132
4141
  });
4133
- React23.useEffect(() => {
4142
+ React27.useEffect(() => {
4134
4143
  if (editor && html !== void 0) {
4135
4144
  const current_html = editor.getHTML();
4136
4145
  if (html !== current_html && !editor.isFocused) {
@@ -4138,21 +4147,21 @@ var HazoUiRte = ({
4138
4147
  }
4139
4148
  }
4140
4149
  }, [html, editor]);
4141
- React23.useEffect(() => {
4150
+ React27.useEffect(() => {
4142
4151
  if (editor) {
4143
4152
  editor.setEditable(!disabled);
4144
4153
  }
4145
4154
  }, [disabled, editor]);
4146
- const attachments_from_props_ref = React23.useRef(false);
4147
- const prev_initial_attachments_ref = React23.useRef(initial_attachments);
4148
- React23.useEffect(() => {
4155
+ const attachments_from_props_ref = React27.useRef(false);
4156
+ const prev_initial_attachments_ref = React27.useRef(initial_attachments);
4157
+ React27.useEffect(() => {
4149
4158
  if (JSON.stringify(initial_attachments) !== JSON.stringify(prev_initial_attachments_ref.current)) {
4150
4159
  prev_initial_attachments_ref.current = initial_attachments;
4151
4160
  attachments_from_props_ref.current = true;
4152
4161
  set_attachments(initial_attachments);
4153
4162
  }
4154
4163
  }, [initial_attachments]);
4155
- React23.useEffect(() => {
4164
+ React27.useEffect(() => {
4156
4165
  if (attachments_from_props_ref.current) {
4157
4166
  attachments_from_props_ref.current = false;
4158
4167
  return;
@@ -4246,7 +4255,1583 @@ var HazoUiRte = ({
4246
4255
  );
4247
4256
  };
4248
4257
  HazoUiRte.displayName = "HazoUiRte";
4258
+ var generate_command_id = () => {
4259
+ return `cmd_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
4260
+ };
4261
+ var get_variant_classes = (variant = "default") => {
4262
+ switch (variant) {
4263
+ case "outline":
4264
+ return "bg-transparent border-primary/40 text-primary";
4265
+ case "subtle":
4266
+ return "bg-muted border-transparent text-muted-foreground";
4267
+ case "default":
4268
+ default:
4269
+ return "bg-primary/10 text-primary border-primary/20";
4270
+ }
4271
+ };
4272
+ var CommandPillView = ({ node, selected, editor }) => {
4273
+ const { prefix, action, action_label, id, variant } = node.attrs;
4274
+ const handle_click = () => {
4275
+ const event = new CustomEvent("command-pill-click", {
4276
+ detail: {
4277
+ id,
4278
+ prefix,
4279
+ action,
4280
+ action_label,
4281
+ node_pos: editor.state.selection.from - 1
4282
+ },
4283
+ bubbles: true
4284
+ });
4285
+ document.dispatchEvent(event);
4286
+ };
4287
+ return /* @__PURE__ */ jsx(NodeViewWrapper, { as: "span", className: "inline", children: /* @__PURE__ */ jsxs(
4288
+ "span",
4289
+ {
4290
+ className: cn(
4291
+ "cls_command_pill",
4292
+ "inline-flex items-center",
4293
+ "px-1.5 py-0.5 mx-0.5",
4294
+ "rounded-md",
4295
+ "text-sm font-medium",
4296
+ "border",
4297
+ "cursor-pointer select-none",
4298
+ "transition-all duration-150",
4299
+ get_variant_classes(variant),
4300
+ selected && "ring-2 ring-ring ring-offset-1",
4301
+ "hover:opacity-80"
4302
+ ),
4303
+ contentEditable: false,
4304
+ "data-command-id": id,
4305
+ "data-command-prefix": prefix,
4306
+ "data-command-action": action,
4307
+ onClick: handle_click,
4308
+ children: [
4309
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground opacity-70", children: prefix }),
4310
+ /* @__PURE__ */ jsx("span", { children: action_label })
4311
+ ]
4312
+ }
4313
+ ) });
4314
+ };
4315
+ var CommandNodeExtension = Node.create({
4316
+ name: "commandNode",
4317
+ group: "inline",
4318
+ inline: true,
4319
+ // Atomic means the node cannot be split or merged
4320
+ atom: true,
4321
+ // Draggable in the editor
4322
+ draggable: true,
4323
+ // Selectable as a whole unit
4324
+ selectable: true,
4325
+ addAttributes() {
4326
+ return {
4327
+ id: {
4328
+ default: null,
4329
+ parseHTML: (element) => element.getAttribute("data-command-id"),
4330
+ renderHTML: (attributes) => ({
4331
+ "data-command-id": attributes.id
4332
+ })
4333
+ },
4334
+ prefix: {
4335
+ default: "",
4336
+ parseHTML: (element) => element.getAttribute("data-command-prefix"),
4337
+ renderHTML: (attributes) => ({
4338
+ "data-command-prefix": attributes.prefix
4339
+ })
4340
+ },
4341
+ action: {
4342
+ default: "",
4343
+ parseHTML: (element) => element.getAttribute("data-command-action"),
4344
+ renderHTML: (attributes) => ({
4345
+ "data-command-action": attributes.action
4346
+ })
4347
+ },
4348
+ action_label: {
4349
+ default: "",
4350
+ parseHTML: (element) => element.getAttribute("data-command-label"),
4351
+ renderHTML: (attributes) => ({
4352
+ "data-command-label": attributes.action_label
4353
+ })
4354
+ },
4355
+ variant: {
4356
+ default: "default",
4357
+ parseHTML: (element) => element.getAttribute("data-command-variant") || "default",
4358
+ renderHTML: (attributes) => ({
4359
+ "data-command-variant": attributes.variant
4360
+ })
4361
+ }
4362
+ };
4363
+ },
4364
+ parseHTML() {
4365
+ return [
4366
+ {
4367
+ tag: "span[data-command-id]"
4368
+ }
4369
+ ];
4370
+ },
4371
+ renderHTML({ HTMLAttributes }) {
4372
+ return [
4373
+ "span",
4374
+ mergeAttributes(HTMLAttributes, {
4375
+ class: "cls_command_pill",
4376
+ contenteditable: "false"
4377
+ }),
4378
+ `${HTMLAttributes["data-command-prefix"]}${HTMLAttributes["data-command-label"]}`
4379
+ ];
4380
+ },
4381
+ // Output format: prefix + action (e.g., "@user_123", "/due_date")
4382
+ renderText({ node }) {
4383
+ return `${node.attrs.prefix}${node.attrs.action}`;
4384
+ },
4385
+ addNodeView() {
4386
+ return ReactNodeViewRenderer(CommandPillView);
4387
+ },
4388
+ addCommands() {
4389
+ return {
4390
+ insertCommand: (attrs) => ({ commands }) => {
4391
+ return commands.insertContent({
4392
+ type: this.name,
4393
+ attrs: {
4394
+ ...attrs,
4395
+ id: generate_command_id()
4396
+ }
4397
+ });
4398
+ },
4399
+ updateCommand: (id, attrs) => ({ tr, state }) => {
4400
+ let updated = false;
4401
+ state.doc.descendants((node, pos) => {
4402
+ if (node.type.name === this.name && node.attrs.id === id) {
4403
+ tr.setNodeMarkup(pos, void 0, {
4404
+ ...node.attrs,
4405
+ ...attrs
4406
+ });
4407
+ updated = true;
4408
+ return false;
4409
+ }
4410
+ });
4411
+ return updated;
4412
+ }
4413
+ };
4414
+ },
4415
+ // Keyboard behavior - delete entire node on backspace
4416
+ addKeyboardShortcuts() {
4417
+ return {
4418
+ Backspace: () => this.editor.commands.command(({ tr, state }) => {
4419
+ let is_command = false;
4420
+ const { selection } = state;
4421
+ const { empty, anchor } = selection;
4422
+ if (!empty) {
4423
+ return false;
4424
+ }
4425
+ state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
4426
+ if (node.type.name === this.name) {
4427
+ is_command = true;
4428
+ tr.insertText("", pos, pos + node.nodeSize);
4429
+ return false;
4430
+ }
4431
+ });
4432
+ return is_command;
4433
+ })
4434
+ };
4435
+ }
4436
+ });
4437
+ var create_suggestion_config = (prefix_config, on_suggestion_change, on_insert_command) => {
4438
+ return {
4439
+ char: prefix_config.char,
4440
+ allowSpaces: false,
4441
+ startOfLine: false,
4442
+ items: ({ query }) => {
4443
+ if (!query) return prefix_config.commands;
4444
+ const lower_query = query.toLowerCase();
4445
+ return prefix_config.commands.filter(
4446
+ (cmd) => cmd.action_label.toLowerCase().includes(lower_query) || cmd.action.toLowerCase().includes(lower_query) || cmd.action_description?.toLowerCase().includes(lower_query)
4447
+ );
4448
+ },
4449
+ render: () => {
4450
+ return {
4451
+ onStart: (props) => {
4452
+ on_suggestion_change({
4453
+ is_active: true,
4454
+ query: props.query,
4455
+ prefix: prefix_config.char,
4456
+ client_rect: props.clientRect,
4457
+ commands: prefix_config.commands,
4458
+ range: props.range
4459
+ });
4460
+ },
4461
+ onUpdate: (props) => {
4462
+ on_suggestion_change({
4463
+ is_active: true,
4464
+ query: props.query,
4465
+ prefix: prefix_config.char,
4466
+ client_rect: props.clientRect,
4467
+ commands: prefix_config.commands,
4468
+ range: props.range
4469
+ });
4470
+ },
4471
+ onKeyDown: (props) => {
4472
+ if (props.event.key === "Escape") {
4473
+ on_suggestion_change(null);
4474
+ return true;
4475
+ }
4476
+ if (props.event.key === "ArrowUp" || props.event.key === "ArrowDown" || props.event.key === "Enter") {
4477
+ return true;
4478
+ }
4479
+ return false;
4480
+ },
4481
+ onExit: () => {
4482
+ on_suggestion_change(null);
4483
+ }
4484
+ };
4485
+ },
4486
+ command: ({ range, props }) => {
4487
+ const command = props;
4488
+ on_insert_command(command, prefix_config.char, range);
4489
+ }
4490
+ };
4491
+ };
4492
+ var create_command_suggestion_extension = (config) => {
4493
+ const { prefixes, on_suggestion_change, on_insert_command } = config;
4494
+ return prefixes.map((prefix_config, index) => {
4495
+ return Extension.create({
4496
+ name: `commandSuggestion_${prefix_config.char}_${index}`,
4497
+ addProseMirrorPlugins() {
4498
+ return [
4499
+ Suggestion({
4500
+ editor: this.editor,
4501
+ ...create_suggestion_config(
4502
+ prefix_config,
4503
+ on_suggestion_change,
4504
+ on_insert_command
4505
+ )
4506
+ })
4507
+ ];
4508
+ }
4509
+ });
4510
+ });
4511
+ };
4512
+ var insert_command_at_position = (editor, command, prefix, range, variant = "default") => {
4513
+ editor.chain().focus().deleteRange(range).insertCommand({
4514
+ prefix,
4515
+ action: command.action,
4516
+ action_label: command.action_label,
4517
+ variant
4518
+ }).run();
4519
+ };
4520
+ var get_variant_classes2 = (variant = "default") => {
4521
+ switch (variant) {
4522
+ case "outline":
4523
+ return "bg-transparent border-primary/40 text-primary hover:bg-primary/5";
4524
+ case "subtle":
4525
+ return "bg-muted border-transparent text-muted-foreground hover:bg-muted/80";
4526
+ case "default":
4527
+ default:
4528
+ return "bg-primary/10 text-primary border-primary/20 hover:bg-primary/15";
4529
+ }
4530
+ };
4531
+ var CommandPill = ({
4532
+ prefix,
4533
+ action,
4534
+ action_label,
4535
+ id,
4536
+ selected = false,
4537
+ variant = "default",
4538
+ on_click
4539
+ }) => {
4540
+ return /* @__PURE__ */ jsxs(
4541
+ "span",
4542
+ {
4543
+ className: cn(
4544
+ "cls_command_pill_standalone",
4545
+ "inline-flex items-center",
4546
+ "px-1.5 py-0.5",
4547
+ "rounded-md",
4548
+ "text-sm font-medium",
4549
+ "border",
4550
+ "transition-all duration-150",
4551
+ get_variant_classes2(variant),
4552
+ selected && "ring-2 ring-ring ring-offset-1",
4553
+ on_click && "cursor-pointer"
4554
+ ),
4555
+ "data-command-id": id,
4556
+ "data-command-prefix": prefix,
4557
+ "data-command-action": action,
4558
+ onClick: on_click,
4559
+ role: on_click ? "button" : void 0,
4560
+ tabIndex: on_click ? 0 : void 0,
4561
+ onKeyDown: (e) => {
4562
+ if (on_click && (e.key === "Enter" || e.key === " ")) {
4563
+ e.preventDefault();
4564
+ on_click();
4565
+ }
4566
+ },
4567
+ children: [
4568
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground opacity-70", children: prefix }),
4569
+ /* @__PURE__ */ jsx("span", { children: action_label })
4570
+ ]
4571
+ }
4572
+ );
4573
+ };
4574
+ CommandPill.displayName = "CommandPill";
4575
+ var group_commands = (commands) => {
4576
+ const groups = /* @__PURE__ */ new Map();
4577
+ for (const cmd of commands) {
4578
+ const group_name = cmd.group || "";
4579
+ if (!groups.has(group_name)) {
4580
+ groups.set(group_name, []);
4581
+ }
4582
+ groups.get(group_name).push(cmd);
4583
+ }
4584
+ return groups;
4585
+ };
4586
+ var CommandPopover = ({
4587
+ is_open,
4588
+ commands,
4589
+ prefix,
4590
+ query,
4591
+ selected_index,
4592
+ position,
4593
+ on_select,
4594
+ on_close,
4595
+ on_selection_change: _on_selection_change
4596
+ }) => {
4597
+ const container_ref = React27.useRef(null);
4598
+ const grouped_commands = React27.useMemo(
4599
+ () => group_commands(commands),
4600
+ [commands]
4601
+ );
4602
+ React27.useEffect(() => {
4603
+ const handle_click_outside = (e) => {
4604
+ if (container_ref.current && !container_ref.current.contains(e.target)) {
4605
+ on_close();
4606
+ }
4607
+ };
4608
+ if (is_open) {
4609
+ document.addEventListener("mousedown", handle_click_outside);
4610
+ return () => {
4611
+ document.removeEventListener("mousedown", handle_click_outside);
4612
+ };
4613
+ }
4614
+ }, [is_open, on_close]);
4615
+ if (!is_open) return null;
4616
+ return /* @__PURE__ */ jsx(
4617
+ "div",
4618
+ {
4619
+ ref: container_ref,
4620
+ className: cn(
4621
+ "cls_command_popover",
4622
+ "absolute z-[9999]",
4623
+ "w-64 min-w-[200px] max-w-[300px]",
4624
+ "rounded-md border bg-popover text-popover-foreground shadow-lg",
4625
+ "animate-in fade-in-0 zoom-in-95"
4626
+ ),
4627
+ style: {
4628
+ top: position.top,
4629
+ left: position.left
4630
+ },
4631
+ children: /* @__PURE__ */ jsxs(Command, { className: "rounded-md", children: [
4632
+ query && /* @__PURE__ */ jsxs("div", { className: "px-3 py-2 text-xs text-muted-foreground border-b", children: [
4633
+ "Searching: ",
4634
+ /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
4635
+ prefix,
4636
+ query
4637
+ ] })
4638
+ ] }),
4639
+ /* @__PURE__ */ jsxs(CommandList, { className: "max-h-[200px]", children: [
4640
+ commands.length === 0 && /* @__PURE__ */ jsx(CommandEmpty, { children: "No commands found." }),
4641
+ Array.from(grouped_commands.entries()).map(([group_name, group_commands2]) => /* @__PURE__ */ jsx(
4642
+ CommandGroup,
4643
+ {
4644
+ heading: group_name || void 0,
4645
+ children: group_commands2.map((cmd, idx) => {
4646
+ let flat_idx = 0;
4647
+ for (const [g, cmds] of grouped_commands.entries()) {
4648
+ if (g === group_name) {
4649
+ flat_idx += idx;
4650
+ break;
4651
+ }
4652
+ flat_idx += cmds.length;
4653
+ }
4654
+ return /* @__PURE__ */ jsx(
4655
+ CommandItem,
4656
+ {
4657
+ value: cmd.action,
4658
+ onSelect: () => on_select(cmd),
4659
+ className: cn(
4660
+ flat_idx === selected_index && "bg-accent"
4661
+ ),
4662
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
4663
+ cmd.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-muted-foreground", children: cmd.icon }),
4664
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
4665
+ /* @__PURE__ */ jsxs("div", { className: "font-medium truncate", children: [
4666
+ prefix,
4667
+ cmd.action_label
4668
+ ] }),
4669
+ cmd.action_description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: cmd.action_description })
4670
+ ] })
4671
+ ] })
4672
+ },
4673
+ cmd.action
4674
+ );
4675
+ })
4676
+ },
4677
+ group_name || "default"
4678
+ ))
4679
+ ] })
4680
+ ] })
4681
+ }
4682
+ );
4683
+ };
4684
+ CommandPopover.displayName = "CommandPopover";
4685
+
4686
+ // src/components/hazo_ui_command/index.tsx
4687
+ var parse_commands_from_text = (text, prefixes) => {
4688
+ const result = [];
4689
+ const action_to_label = /* @__PURE__ */ new Map();
4690
+ for (const prefix_config of prefixes) {
4691
+ for (const cmd of prefix_config.commands) {
4692
+ action_to_label.set(`${prefix_config.char}${cmd.action}`, {
4693
+ label: cmd.action_label,
4694
+ prefix: prefix_config.char
4695
+ });
4696
+ }
4697
+ }
4698
+ const prefix_chars = prefixes.map((p) => escape_regex(p.char)).join("|");
4699
+ const pattern = new RegExp(`(${prefix_chars})(\\w+)`, "g");
4700
+ let match;
4701
+ while ((match = pattern.exec(text)) !== null) {
4702
+ const full_match = match[0];
4703
+ const prefix = match[1];
4704
+ const action = match[2];
4705
+ const lookup_key = `${prefix}${action}`;
4706
+ const info = action_to_label.get(lookup_key);
4707
+ if (info) {
4708
+ result.push({
4709
+ action,
4710
+ action_label: info.label,
4711
+ prefix,
4712
+ position: match.index,
4713
+ length: full_match.length
4714
+ });
4715
+ }
4716
+ }
4717
+ return result;
4718
+ };
4719
+ var escape_regex = (str) => {
4720
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4721
+ };
4722
+ var text_to_tiptap_content = (text, prefixes, variant = "default") => {
4723
+ const commands = parse_commands_from_text(text, prefixes);
4724
+ if (commands.length === 0) {
4725
+ return {
4726
+ type: "doc",
4727
+ content: [
4728
+ {
4729
+ type: "paragraph",
4730
+ content: text ? [{ type: "text", text }] : []
4731
+ }
4732
+ ]
4733
+ };
4734
+ }
4735
+ commands.sort((a, b) => a.position - b.position);
4736
+ const content = [];
4737
+ let last_end = 0;
4738
+ for (const cmd of commands) {
4739
+ if (cmd.position > last_end) {
4740
+ content.push({
4741
+ type: "text",
4742
+ text: text.slice(last_end, cmd.position)
4743
+ });
4744
+ }
4745
+ content.push({
4746
+ type: "commandNode",
4747
+ attrs: {
4748
+ id: `cmd_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
4749
+ prefix: cmd.prefix,
4750
+ action: cmd.action,
4751
+ action_label: cmd.action_label,
4752
+ variant
4753
+ }
4754
+ });
4755
+ last_end = cmd.position + cmd.length;
4756
+ }
4757
+ if (last_end < text.length) {
4758
+ content.push({
4759
+ type: "text",
4760
+ text: text.slice(last_end)
4761
+ });
4762
+ }
4763
+ return {
4764
+ type: "doc",
4765
+ content: [
4766
+ {
4767
+ type: "paragraph",
4768
+ content
4769
+ }
4770
+ ]
4771
+ };
4772
+ };
4773
+ var Document = Node.create({
4774
+ name: "doc",
4775
+ topNode: true,
4776
+ content: "block+",
4777
+ renderMarkdown: (node, h) => {
4778
+ if (!node.content) {
4779
+ return "";
4780
+ }
4781
+ return h.renderChildren(node.content, "\n\n");
4782
+ }
4783
+ });
4784
+ var index_default = Document;
4785
+ var Paragraph = Node.create({
4786
+ name: "paragraph",
4787
+ priority: 1e3,
4788
+ addOptions() {
4789
+ return {
4790
+ HTMLAttributes: {}
4791
+ };
4792
+ },
4793
+ group: "block",
4794
+ content: "inline*",
4795
+ parseHTML() {
4796
+ return [{ tag: "p" }];
4797
+ },
4798
+ renderHTML({ HTMLAttributes }) {
4799
+ return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
4800
+ },
4801
+ parseMarkdown: (token, helpers) => {
4802
+ const tokens = token.tokens || [];
4803
+ if (tokens.length === 1 && tokens[0].type === "image") {
4804
+ return helpers.parseChildren([tokens[0]]);
4805
+ }
4806
+ return helpers.createNode(
4807
+ "paragraph",
4808
+ void 0,
4809
+ // no attributes for paragraph
4810
+ helpers.parseInline(tokens)
4811
+ );
4812
+ },
4813
+ renderMarkdown: (node, h) => {
4814
+ if (!node || !Array.isArray(node.content)) {
4815
+ return "";
4816
+ }
4817
+ return h.renderChildren(node.content);
4818
+ },
4819
+ addCommands() {
4820
+ return {
4821
+ setParagraph: () => ({ commands }) => {
4822
+ return commands.setNode(this.name);
4823
+ }
4824
+ };
4825
+ },
4826
+ addKeyboardShortcuts() {
4827
+ return {
4828
+ "Mod-Alt-0": () => this.editor.commands.setParagraph()
4829
+ };
4830
+ }
4831
+ });
4832
+ var index_default2 = Paragraph;
4833
+ var Text = Node.create({
4834
+ name: "text",
4835
+ group: "inline",
4836
+ parseMarkdown: (token) => {
4837
+ return {
4838
+ type: "text",
4839
+ text: token.text || ""
4840
+ };
4841
+ },
4842
+ renderMarkdown: (node) => node.text || ""
4843
+ });
4844
+ var index_default3 = Text;
4845
+ var SingleLineDocument = index_default.extend({
4846
+ content: "paragraph"
4847
+ });
4848
+ var get_editor_output = (editor) => {
4849
+ if (!editor) {
4850
+ return { plain_text: "", display_text: "", commands: [] };
4851
+ }
4852
+ const plain_text = editor.getText();
4853
+ const commands = [];
4854
+ let display_text = "";
4855
+ let position = 0;
4856
+ editor.state.doc.descendants((node, _pos) => {
4857
+ if (node.type.name === "text") {
4858
+ display_text += node.text || "";
4859
+ position += (node.text || "").length;
4860
+ } else if (node.type.name === "commandNode") {
4861
+ const { id, prefix, action, action_label } = node.attrs;
4862
+ const cmd_plain_text = `${prefix}${action}`;
4863
+ const cmd_display_text = `${prefix}${action_label}`;
4864
+ commands.push({
4865
+ id,
4866
+ prefix,
4867
+ action,
4868
+ action_label,
4869
+ position,
4870
+ length: cmd_plain_text.length
4871
+ });
4872
+ display_text += cmd_display_text;
4873
+ position += cmd_plain_text.length;
4874
+ }
4875
+ });
4876
+ return { plain_text, display_text, commands };
4877
+ };
4878
+ var HazoUiTextbox = ({
4879
+ value,
4880
+ default_value,
4881
+ prefixes,
4882
+ placeholder = "Type here...",
4883
+ disabled = false,
4884
+ className,
4885
+ pill_variant = "default",
4886
+ on_change,
4887
+ on_submit,
4888
+ on_command_insert,
4889
+ on_command_change,
4890
+ on_command_remove
4891
+ }) => {
4892
+ const [suggestion_state, set_suggestion_state] = React27.useState(null);
4893
+ const [selected_index, set_selected_index] = React27.useState(0);
4894
+ const [popover_position, set_popover_position] = React27.useState({ top: 0, left: 0 });
4895
+ const [edit_context, set_edit_context] = React27.useState(null);
4896
+ const [edit_selected_index, set_edit_selected_index] = React27.useState(0);
4897
+ const is_controlled = value !== void 0;
4898
+ const editor_container_ref = React27.useRef(null);
4899
+ const edit_popover_ref = React27.useRef(null);
4900
+ const suggestion_extensions = React27.useMemo(() => {
4901
+ return create_command_suggestion_extension({
4902
+ prefixes,
4903
+ on_suggestion_change: (state) => {
4904
+ set_suggestion_state(state);
4905
+ set_selected_index(0);
4906
+ },
4907
+ on_insert_command: (_command, _prefix, _range) => {
4908
+ }
4909
+ });
4910
+ }, [prefixes]);
4911
+ const editor = useEditor({
4912
+ extensions: [
4913
+ SingleLineDocument,
4914
+ index_default2,
4915
+ index_default3,
4916
+ Placeholder.configure({
4917
+ placeholder
4918
+ }),
4919
+ CommandNodeExtension.configure({}),
4920
+ ...suggestion_extensions
4921
+ ],
4922
+ content: is_controlled ? text_to_tiptap_content(value || "", prefixes, pill_variant) : text_to_tiptap_content(default_value || "", prefixes, pill_variant),
4923
+ editable: !disabled,
4924
+ immediatelyRender: false,
4925
+ editorProps: {
4926
+ attributes: {
4927
+ class: cn(
4928
+ "cls_textbox_editor",
4929
+ "w-full outline-none",
4930
+ "whitespace-nowrap overflow-x-auto"
4931
+ )
4932
+ },
4933
+ handleKeyDown: (_view, event) => {
4934
+ if (event.key === "Enter" && !suggestion_state?.is_active) {
4935
+ event.preventDefault();
4936
+ if (on_submit && editor) {
4937
+ on_submit(get_editor_output(editor));
4938
+ }
4939
+ return true;
4940
+ }
4941
+ return false;
4942
+ }
4943
+ },
4944
+ onUpdate: ({ editor: editor2 }) => {
4945
+ if (on_change) {
4946
+ on_change(get_editor_output(editor2));
4947
+ }
4948
+ }
4949
+ });
4950
+ React27.useEffect(() => {
4951
+ if (suggestion_state?.is_active && editor && editor_container_ref.current) {
4952
+ requestAnimationFrame(() => {
4953
+ const container = editor_container_ref.current;
4954
+ if (!container) return;
4955
+ const container_rect = container.getBoundingClientRect();
4956
+ const { from } = suggestion_state.range;
4957
+ try {
4958
+ const coords = editor.view.coordsAtPos(from);
4959
+ if (coords) {
4960
+ set_popover_position({
4961
+ top: coords.bottom - container_rect.top + 4,
4962
+ left: coords.left - container_rect.left
4963
+ });
4964
+ }
4965
+ } catch {
4966
+ const rect = suggestion_state.client_rect?.();
4967
+ if (rect) {
4968
+ set_popover_position({
4969
+ top: rect.bottom - container_rect.top + 4,
4970
+ left: rect.left - container_rect.left
4971
+ });
4972
+ }
4973
+ }
4974
+ });
4975
+ }
4976
+ }, [suggestion_state, editor]);
4977
+ React27.useEffect(() => {
4978
+ if (is_controlled && editor && !editor.isFocused) {
4979
+ const current_text = editor.getText();
4980
+ if (value !== current_text) {
4981
+ const content = text_to_tiptap_content(value || "", prefixes, pill_variant);
4982
+ editor.commands.setContent(content, { emitUpdate: false });
4983
+ }
4984
+ }
4985
+ }, [value, editor, is_controlled, prefixes, pill_variant]);
4986
+ React27.useEffect(() => {
4987
+ if (editor) {
4988
+ editor.setEditable(!disabled);
4989
+ }
4990
+ }, [disabled, editor]);
4991
+ const handle_command_select = React27.useCallback(
4992
+ (command) => {
4993
+ if (!editor || !suggestion_state) return;
4994
+ insert_command_at_position(
4995
+ editor,
4996
+ command,
4997
+ suggestion_state.prefix,
4998
+ suggestion_state.range,
4999
+ pill_variant
5000
+ );
5001
+ if (on_command_insert) {
5002
+ on_command_insert(command, suggestion_state.prefix);
5003
+ }
5004
+ set_suggestion_state(null);
5005
+ },
5006
+ [editor, suggestion_state, pill_variant, on_command_insert]
5007
+ );
5008
+ const handle_popover_close = React27.useCallback(() => {
5009
+ set_suggestion_state(null);
5010
+ editor?.commands.focus();
5011
+ }, [editor]);
5012
+ const handle_edit_close = React27.useCallback(() => {
5013
+ set_edit_context(null);
5014
+ editor?.commands.focus();
5015
+ }, [editor]);
5016
+ const handle_command_update = React27.useCallback(
5017
+ (new_command) => {
5018
+ if (!editor || !edit_context) return;
5019
+ const old_command = edit_context.command;
5020
+ editor.commands.updateCommand(old_command.id, {
5021
+ action: new_command.action,
5022
+ action_label: new_command.action_label
5023
+ });
5024
+ if (on_command_change) {
5025
+ on_command_change(old_command, new_command);
5026
+ }
5027
+ set_edit_context(null);
5028
+ editor.commands.focus();
5029
+ },
5030
+ [editor, edit_context, on_command_change]
5031
+ );
5032
+ const handle_command_remove = React27.useCallback(() => {
5033
+ if (!editor || !edit_context) return;
5034
+ const command = edit_context.command;
5035
+ editor.state.doc.descendants((node, pos) => {
5036
+ if (node.type.name === "commandNode" && node.attrs.id === command.id) {
5037
+ editor.chain().focus().deleteRange({ from: pos, to: pos + node.nodeSize }).run();
5038
+ return false;
5039
+ }
5040
+ });
5041
+ if (on_command_remove) {
5042
+ on_command_remove(command);
5043
+ }
5044
+ set_edit_context(null);
5045
+ }, [editor, edit_context, on_command_remove]);
5046
+ const filtered_commands = React27.useMemo(() => {
5047
+ if (!suggestion_state) return [];
5048
+ const query = suggestion_state.query.toLowerCase();
5049
+ if (!query) return suggestion_state.commands;
5050
+ return suggestion_state.commands.filter(
5051
+ (cmd) => cmd.action_label.toLowerCase().includes(query) || cmd.action.toLowerCase().includes(query) || cmd.action_description?.toLowerCase().includes(query)
5052
+ );
5053
+ }, [suggestion_state]);
5054
+ React27.useEffect(() => {
5055
+ if (!suggestion_state?.is_active) return;
5056
+ const handle_keydown = (e) => {
5057
+ switch (e.key) {
5058
+ case "ArrowDown":
5059
+ e.preventDefault();
5060
+ set_selected_index(
5061
+ (prev) => Math.min(prev + 1, filtered_commands.length - 1)
5062
+ );
5063
+ break;
5064
+ case "ArrowUp":
5065
+ e.preventDefault();
5066
+ set_selected_index((prev) => Math.max(prev - 1, 0));
5067
+ break;
5068
+ case "Enter":
5069
+ e.preventDefault();
5070
+ if (filtered_commands[selected_index]) {
5071
+ handle_command_select(filtered_commands[selected_index]);
5072
+ }
5073
+ break;
5074
+ case "Escape":
5075
+ e.preventDefault();
5076
+ handle_popover_close();
5077
+ break;
5078
+ }
5079
+ };
5080
+ window.addEventListener("keydown", handle_keydown);
5081
+ return () => window.removeEventListener("keydown", handle_keydown);
5082
+ }, [
5083
+ suggestion_state?.is_active,
5084
+ filtered_commands,
5085
+ selected_index,
5086
+ handle_command_select,
5087
+ handle_popover_close
5088
+ ]);
5089
+ React27.useEffect(() => {
5090
+ if (!edit_context) return;
5091
+ const handle_click_outside = (e) => {
5092
+ if (edit_popover_ref.current && !edit_popover_ref.current.contains(e.target)) {
5093
+ set_edit_context(null);
5094
+ }
5095
+ };
5096
+ const timeout = setTimeout(() => {
5097
+ document.addEventListener("mousedown", handle_click_outside);
5098
+ }, 100);
5099
+ return () => {
5100
+ clearTimeout(timeout);
5101
+ document.removeEventListener("mousedown", handle_click_outside);
5102
+ };
5103
+ }, [edit_context]);
5104
+ const edit_commands = React27.useMemo(() => {
5105
+ if (!edit_context) return [];
5106
+ const prefix_config = prefixes.find((p) => p.char === edit_context.command.prefix);
5107
+ return prefix_config?.commands || [];
5108
+ }, [edit_context, prefixes]);
5109
+ React27.useEffect(() => {
5110
+ if (!edit_context) return;
5111
+ const handle_keydown = (e) => {
5112
+ switch (e.key) {
5113
+ case "ArrowDown":
5114
+ e.preventDefault();
5115
+ set_edit_selected_index(
5116
+ (prev) => Math.min(prev + 1, edit_commands.length)
5117
+ );
5118
+ break;
5119
+ case "ArrowUp":
5120
+ e.preventDefault();
5121
+ set_edit_selected_index((prev) => Math.max(prev - 1, 0));
5122
+ break;
5123
+ case "Enter":
5124
+ e.preventDefault();
5125
+ if (edit_selected_index === edit_commands.length) {
5126
+ handle_command_remove();
5127
+ } else if (edit_commands[edit_selected_index]) {
5128
+ handle_command_update(edit_commands[edit_selected_index]);
5129
+ }
5130
+ break;
5131
+ case "Escape":
5132
+ e.preventDefault();
5133
+ handle_edit_close();
5134
+ break;
5135
+ }
5136
+ };
5137
+ window.addEventListener("keydown", handle_keydown);
5138
+ return () => window.removeEventListener("keydown", handle_keydown);
5139
+ }, [
5140
+ edit_context,
5141
+ edit_commands,
5142
+ edit_selected_index,
5143
+ handle_command_update,
5144
+ handle_command_remove,
5145
+ handle_edit_close
5146
+ ]);
5147
+ React27.useEffect(() => {
5148
+ const handle_pill_click = (e) => {
5149
+ const detail = e.detail;
5150
+ const { id, prefix, action, action_label, node_pos } = detail;
5151
+ if (editor && editor_container_ref.current) {
5152
+ const container_rect = editor_container_ref.current.getBoundingClientRect();
5153
+ try {
5154
+ const coords = editor.view.coordsAtPos(node_pos);
5155
+ if (coords) {
5156
+ const prefix_config = prefixes.find((p) => p.char === prefix);
5157
+ const current_index = prefix_config?.commands.findIndex(
5158
+ (cmd) => cmd.action === action
5159
+ ) ?? 0;
5160
+ set_edit_context({
5161
+ command: {
5162
+ id,
5163
+ prefix,
5164
+ action,
5165
+ action_label,
5166
+ position: node_pos,
5167
+ length: 0
5168
+ },
5169
+ node_pos,
5170
+ rect: new DOMRect(
5171
+ coords.left - container_rect.left,
5172
+ coords.bottom - container_rect.top + 4,
5173
+ 0,
5174
+ 0
5175
+ )
5176
+ });
5177
+ set_edit_selected_index(Math.max(0, current_index));
5178
+ }
5179
+ } catch {
5180
+ }
5181
+ }
5182
+ };
5183
+ document.addEventListener("command-pill-click", handle_pill_click);
5184
+ return () => document.removeEventListener("command-pill-click", handle_pill_click);
5185
+ }, [editor, prefixes]);
5186
+ return /* @__PURE__ */ jsxs(
5187
+ "div",
5188
+ {
5189
+ ref: editor_container_ref,
5190
+ className: cn(
5191
+ "cls_hazo_ui_textbox",
5192
+ "relative flex h-10 w-full rounded-md border border-input bg-background px-3 py-2",
5193
+ "text-sm ring-offset-background",
5194
+ "focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
5195
+ disabled && "cursor-not-allowed opacity-50",
5196
+ className
5197
+ ),
5198
+ children: [
5199
+ /* @__PURE__ */ jsx(
5200
+ EditorContent,
5201
+ {
5202
+ editor,
5203
+ className: cn(
5204
+ "cls_textbox_content",
5205
+ "flex-1 min-w-0",
5206
+ "[&_.ProseMirror]:outline-none",
5207
+ "[&_.ProseMirror_p]:m-0",
5208
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]",
5209
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:text-muted-foreground",
5210
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:pointer-events-none",
5211
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:float-left",
5212
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:h-0"
5213
+ )
5214
+ }
5215
+ ),
5216
+ suggestion_state?.is_active && /* @__PURE__ */ jsx(
5217
+ CommandPopover,
5218
+ {
5219
+ is_open: true,
5220
+ commands: filtered_commands,
5221
+ prefix: suggestion_state.prefix,
5222
+ query: suggestion_state.query,
5223
+ selected_index,
5224
+ position: popover_position,
5225
+ on_query_change: () => {
5226
+ },
5227
+ on_select: handle_command_select,
5228
+ on_close: handle_popover_close,
5229
+ on_selection_change: set_selected_index
5230
+ }
5231
+ ),
5232
+ edit_context && /* @__PURE__ */ jsx(
5233
+ "div",
5234
+ {
5235
+ ref: edit_popover_ref,
5236
+ className: cn(
5237
+ "cls_edit_popover",
5238
+ "absolute z-[9999]",
5239
+ "w-64 min-w-[200px] max-w-[300px]",
5240
+ "rounded-md border bg-popover text-popover-foreground shadow-lg",
5241
+ "animate-in fade-in-0 zoom-in-95"
5242
+ ),
5243
+ style: {
5244
+ top: edit_context.rect.y,
5245
+ left: edit_context.rect.x
5246
+ },
5247
+ children: /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
5248
+ /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground border-b", children: "Change command" }),
5249
+ /* @__PURE__ */ jsxs("div", { className: "max-h-[200px] overflow-y-auto", children: [
5250
+ edit_commands.map((cmd, idx) => /* @__PURE__ */ jsxs(
5251
+ "div",
5252
+ {
5253
+ className: cn(
5254
+ "px-3 py-2 cursor-pointer flex items-center gap-2",
5255
+ "hover:bg-accent",
5256
+ idx === edit_selected_index && "bg-accent",
5257
+ cmd.action === edit_context.command.action && "font-medium"
5258
+ ),
5259
+ onClick: () => handle_command_update(cmd),
5260
+ children: [
5261
+ cmd.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-muted-foreground", children: cmd.icon }),
5262
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
5263
+ /* @__PURE__ */ jsxs("div", { className: "truncate", children: [
5264
+ edit_context.command.prefix,
5265
+ cmd.action_label
5266
+ ] }),
5267
+ cmd.action_description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: cmd.action_description })
5268
+ ] }),
5269
+ cmd.action === edit_context.command.action && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "current" })
5270
+ ]
5271
+ },
5272
+ cmd.action
5273
+ )),
5274
+ /* @__PURE__ */ jsx(
5275
+ "div",
5276
+ {
5277
+ className: cn(
5278
+ "px-3 py-2 cursor-pointer flex items-center gap-2 text-destructive border-t",
5279
+ "hover:bg-destructive/10",
5280
+ edit_selected_index === edit_commands.length && "bg-destructive/10"
5281
+ ),
5282
+ onClick: handle_command_remove,
5283
+ children: /* @__PURE__ */ jsx("span", { children: "Remove" })
5284
+ }
5285
+ )
5286
+ ] })
5287
+ ] })
5288
+ }
5289
+ )
5290
+ ]
5291
+ }
5292
+ );
5293
+ };
5294
+ HazoUiTextbox.displayName = "HazoUiTextbox";
5295
+ var HardBreak = Node.create({
5296
+ name: "hardBreak",
5297
+ markdownTokenName: "br",
5298
+ addOptions() {
5299
+ return {
5300
+ keepMarks: true,
5301
+ HTMLAttributes: {}
5302
+ };
5303
+ },
5304
+ inline: true,
5305
+ group: "inline",
5306
+ selectable: false,
5307
+ linebreakReplacement: true,
5308
+ parseHTML() {
5309
+ return [{ tag: "br" }];
5310
+ },
5311
+ renderHTML({ HTMLAttributes }) {
5312
+ return ["br", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
5313
+ },
5314
+ renderText() {
5315
+ return "\n";
5316
+ },
5317
+ renderMarkdown: () => `
5318
+ `,
5319
+ parseMarkdown: () => {
5320
+ return {
5321
+ type: "hardBreak"
5322
+ };
5323
+ },
5324
+ addCommands() {
5325
+ return {
5326
+ setHardBreak: () => ({ commands, chain, state, editor }) => {
5327
+ return commands.first([
5328
+ () => commands.exitCode(),
5329
+ () => commands.command(() => {
5330
+ const { selection, storedMarks } = state;
5331
+ if (selection.$from.parent.type.spec.isolating) {
5332
+ return false;
5333
+ }
5334
+ const { keepMarks } = this.options;
5335
+ const { splittableMarks } = editor.extensionManager;
5336
+ const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
5337
+ return chain().insertContent({ type: this.name }).command(({ tr, dispatch }) => {
5338
+ if (dispatch && marks && keepMarks) {
5339
+ const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
5340
+ tr.ensureMarks(filteredMarks);
5341
+ }
5342
+ return true;
5343
+ }).run();
5344
+ })
5345
+ ]);
5346
+ }
5347
+ };
5348
+ },
5349
+ addKeyboardShortcuts() {
5350
+ return {
5351
+ "Mod-Enter": () => this.editor.commands.setHardBreak(),
5352
+ "Shift-Enter": () => this.editor.commands.setHardBreak()
5353
+ };
5354
+ }
5355
+ });
5356
+ var index_default4 = HardBreak;
5357
+ var get_editor_output2 = (editor) => {
5358
+ if (!editor) {
5359
+ return { plain_text: "", display_text: "", commands: [] };
5360
+ }
5361
+ const plain_text = editor.getText();
5362
+ const commands = [];
5363
+ let display_text = "";
5364
+ let position = 0;
5365
+ editor.state.doc.descendants((node, _pos) => {
5366
+ if (node.type.name === "text") {
5367
+ display_text += node.text || "";
5368
+ position += (node.text || "").length;
5369
+ } else if (node.type.name === "commandNode") {
5370
+ const { id, prefix, action, action_label } = node.attrs;
5371
+ const cmd_plain_text = `${prefix}${action}`;
5372
+ const cmd_display_text = `${prefix}${action_label}`;
5373
+ commands.push({
5374
+ id,
5375
+ prefix,
5376
+ action,
5377
+ action_label,
5378
+ position,
5379
+ length: cmd_plain_text.length
5380
+ });
5381
+ display_text += cmd_display_text;
5382
+ position += cmd_plain_text.length;
5383
+ } else if (node.type.name === "hardBreak") {
5384
+ display_text += "\n";
5385
+ position += 1;
5386
+ }
5387
+ });
5388
+ return { plain_text, display_text, commands };
5389
+ };
5390
+ var multiline_text_to_tiptap_content = (text, prefixes, variant = "default") => {
5391
+ const lines = text.split("\n");
5392
+ const paragraphs = [];
5393
+ for (const line of lines) {
5394
+ const line_content = text_to_tiptap_content(line, prefixes, variant);
5395
+ const para = line_content.content?.[0];
5396
+ if (para) {
5397
+ paragraphs.push(para);
5398
+ } else {
5399
+ paragraphs.push({ type: "paragraph", content: [] });
5400
+ }
5401
+ }
5402
+ return {
5403
+ type: "doc",
5404
+ content: paragraphs.length > 0 ? paragraphs : [{ type: "paragraph", content: [] }]
5405
+ };
5406
+ };
5407
+ var HazoUiTextarea = ({
5408
+ value,
5409
+ default_value,
5410
+ prefixes,
5411
+ placeholder = "Type here...",
5412
+ disabled = false,
5413
+ className,
5414
+ pill_variant = "default",
5415
+ min_height = "80px",
5416
+ max_height = "200px",
5417
+ rows,
5418
+ on_change,
5419
+ on_submit,
5420
+ on_command_insert,
5421
+ on_command_change,
5422
+ on_command_remove
5423
+ }) => {
5424
+ const [suggestion_state, set_suggestion_state] = React27.useState(null);
5425
+ const [selected_index, set_selected_index] = React27.useState(0);
5426
+ const [popover_position, set_popover_position] = React27.useState({ top: 0, left: 0 });
5427
+ const [edit_context, set_edit_context] = React27.useState(null);
5428
+ const [edit_selected_index, set_edit_selected_index] = React27.useState(0);
5429
+ const is_controlled = value !== void 0;
5430
+ const editor_container_ref = React27.useRef(null);
5431
+ const edit_popover_ref = React27.useRef(null);
5432
+ const calculated_min_height = rows ? `${rows * 1.5}em` : min_height;
5433
+ const suggestion_extensions = React27.useMemo(() => {
5434
+ return create_command_suggestion_extension({
5435
+ prefixes,
5436
+ on_suggestion_change: (state) => {
5437
+ set_suggestion_state(state);
5438
+ set_selected_index(0);
5439
+ },
5440
+ on_insert_command: (_command, _prefix, _range) => {
5441
+ }
5442
+ });
5443
+ }, [prefixes]);
5444
+ const editor = useEditor({
5445
+ extensions: [
5446
+ index_default,
5447
+ index_default2,
5448
+ index_default3,
5449
+ index_default4,
5450
+ Placeholder.configure({
5451
+ placeholder
5452
+ }),
5453
+ CommandNodeExtension.configure({}),
5454
+ ...suggestion_extensions
5455
+ ],
5456
+ content: is_controlled ? multiline_text_to_tiptap_content(value || "", prefixes, pill_variant) : multiline_text_to_tiptap_content(default_value || "", prefixes, pill_variant),
5457
+ editable: !disabled,
5458
+ immediatelyRender: false,
5459
+ editorProps: {
5460
+ attributes: {
5461
+ class: cn("cls_textarea_editor", "w-full outline-none"),
5462
+ style: `min-height: ${calculated_min_height}; max-height: ${max_height}`
5463
+ },
5464
+ handleKeyDown: (_view, event) => {
5465
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey) && !suggestion_state?.is_active) {
5466
+ event.preventDefault();
5467
+ if (on_submit && editor) {
5468
+ on_submit(get_editor_output2(editor));
5469
+ }
5470
+ return true;
5471
+ }
5472
+ return false;
5473
+ }
5474
+ },
5475
+ onUpdate: ({ editor: editor2 }) => {
5476
+ if (on_change) {
5477
+ on_change(get_editor_output2(editor2));
5478
+ }
5479
+ }
5480
+ });
5481
+ React27.useEffect(() => {
5482
+ if (suggestion_state?.is_active && editor && editor_container_ref.current) {
5483
+ requestAnimationFrame(() => {
5484
+ const container = editor_container_ref.current;
5485
+ if (!container) return;
5486
+ const container_rect = container.getBoundingClientRect();
5487
+ const { from } = suggestion_state.range;
5488
+ try {
5489
+ const coords = editor.view.coordsAtPos(from);
5490
+ if (coords) {
5491
+ set_popover_position({
5492
+ top: coords.bottom - container_rect.top + 4,
5493
+ left: coords.left - container_rect.left
5494
+ });
5495
+ }
5496
+ } catch {
5497
+ const rect = suggestion_state.client_rect?.();
5498
+ if (rect) {
5499
+ set_popover_position({
5500
+ top: rect.bottom - container_rect.top + 4,
5501
+ left: rect.left - container_rect.left
5502
+ });
5503
+ }
5504
+ }
5505
+ });
5506
+ }
5507
+ }, [suggestion_state, editor]);
5508
+ React27.useEffect(() => {
5509
+ if (is_controlled && editor && !editor.isFocused) {
5510
+ const current_text = editor.getText();
5511
+ if (value !== current_text) {
5512
+ const content = multiline_text_to_tiptap_content(
5513
+ value || "",
5514
+ prefixes,
5515
+ pill_variant
5516
+ );
5517
+ editor.commands.setContent(content, { emitUpdate: false });
5518
+ }
5519
+ }
5520
+ }, [value, editor, is_controlled, prefixes, pill_variant]);
5521
+ React27.useEffect(() => {
5522
+ if (editor) {
5523
+ editor.setEditable(!disabled);
5524
+ }
5525
+ }, [disabled, editor]);
5526
+ const handle_command_select = React27.useCallback(
5527
+ (command) => {
5528
+ if (!editor || !suggestion_state) return;
5529
+ insert_command_at_position(
5530
+ editor,
5531
+ command,
5532
+ suggestion_state.prefix,
5533
+ suggestion_state.range,
5534
+ pill_variant
5535
+ );
5536
+ if (on_command_insert) {
5537
+ on_command_insert(command, suggestion_state.prefix);
5538
+ }
5539
+ set_suggestion_state(null);
5540
+ },
5541
+ [editor, suggestion_state, pill_variant, on_command_insert]
5542
+ );
5543
+ const handle_popover_close = React27.useCallback(() => {
5544
+ set_suggestion_state(null);
5545
+ editor?.commands.focus();
5546
+ }, [editor]);
5547
+ const handle_edit_close = React27.useCallback(() => {
5548
+ set_edit_context(null);
5549
+ editor?.commands.focus();
5550
+ }, [editor]);
5551
+ const handle_command_update = React27.useCallback(
5552
+ (new_command) => {
5553
+ if (!editor || !edit_context) return;
5554
+ const old_command = edit_context.command;
5555
+ editor.commands.updateCommand(old_command.id, {
5556
+ action: new_command.action,
5557
+ action_label: new_command.action_label
5558
+ });
5559
+ if (on_command_change) {
5560
+ on_command_change(old_command, new_command);
5561
+ }
5562
+ set_edit_context(null);
5563
+ editor.commands.focus();
5564
+ },
5565
+ [editor, edit_context, on_command_change]
5566
+ );
5567
+ const handle_command_remove = React27.useCallback(() => {
5568
+ if (!editor || !edit_context) return;
5569
+ const command = edit_context.command;
5570
+ editor.state.doc.descendants((node, pos) => {
5571
+ if (node.type.name === "commandNode" && node.attrs.id === command.id) {
5572
+ editor.chain().focus().deleteRange({ from: pos, to: pos + node.nodeSize }).run();
5573
+ return false;
5574
+ }
5575
+ });
5576
+ if (on_command_remove) {
5577
+ on_command_remove(command);
5578
+ }
5579
+ set_edit_context(null);
5580
+ }, [editor, edit_context, on_command_remove]);
5581
+ const filtered_commands = React27.useMemo(() => {
5582
+ if (!suggestion_state) return [];
5583
+ const query = suggestion_state.query.toLowerCase();
5584
+ if (!query) return suggestion_state.commands;
5585
+ return suggestion_state.commands.filter(
5586
+ (cmd) => cmd.action_label.toLowerCase().includes(query) || cmd.action.toLowerCase().includes(query) || cmd.action_description?.toLowerCase().includes(query)
5587
+ );
5588
+ }, [suggestion_state]);
5589
+ React27.useEffect(() => {
5590
+ if (!suggestion_state?.is_active) return;
5591
+ const handle_keydown = (e) => {
5592
+ switch (e.key) {
5593
+ case "ArrowDown":
5594
+ e.preventDefault();
5595
+ set_selected_index(
5596
+ (prev) => Math.min(prev + 1, filtered_commands.length - 1)
5597
+ );
5598
+ break;
5599
+ case "ArrowUp":
5600
+ e.preventDefault();
5601
+ set_selected_index((prev) => Math.max(prev - 1, 0));
5602
+ break;
5603
+ case "Enter":
5604
+ e.preventDefault();
5605
+ if (filtered_commands[selected_index]) {
5606
+ handle_command_select(filtered_commands[selected_index]);
5607
+ }
5608
+ break;
5609
+ case "Escape":
5610
+ e.preventDefault();
5611
+ handle_popover_close();
5612
+ break;
5613
+ }
5614
+ };
5615
+ window.addEventListener("keydown", handle_keydown);
5616
+ return () => window.removeEventListener("keydown", handle_keydown);
5617
+ }, [
5618
+ suggestion_state?.is_active,
5619
+ filtered_commands,
5620
+ selected_index,
5621
+ handle_command_select,
5622
+ handle_popover_close
5623
+ ]);
5624
+ React27.useEffect(() => {
5625
+ if (!edit_context) return;
5626
+ const handle_click_outside = (e) => {
5627
+ if (edit_popover_ref.current && !edit_popover_ref.current.contains(e.target)) {
5628
+ set_edit_context(null);
5629
+ }
5630
+ };
5631
+ const timeout = setTimeout(() => {
5632
+ document.addEventListener("mousedown", handle_click_outside);
5633
+ }, 100);
5634
+ return () => {
5635
+ clearTimeout(timeout);
5636
+ document.removeEventListener("mousedown", handle_click_outside);
5637
+ };
5638
+ }, [edit_context]);
5639
+ const edit_commands = React27.useMemo(() => {
5640
+ if (!edit_context) return [];
5641
+ const prefix_config = prefixes.find((p) => p.char === edit_context.command.prefix);
5642
+ return prefix_config?.commands || [];
5643
+ }, [edit_context, prefixes]);
5644
+ React27.useEffect(() => {
5645
+ if (!edit_context) return;
5646
+ const handle_keydown = (e) => {
5647
+ switch (e.key) {
5648
+ case "ArrowDown":
5649
+ e.preventDefault();
5650
+ set_edit_selected_index(
5651
+ (prev) => Math.min(prev + 1, edit_commands.length)
5652
+ );
5653
+ break;
5654
+ case "ArrowUp":
5655
+ e.preventDefault();
5656
+ set_edit_selected_index((prev) => Math.max(prev - 1, 0));
5657
+ break;
5658
+ case "Enter":
5659
+ e.preventDefault();
5660
+ if (edit_selected_index === edit_commands.length) {
5661
+ handle_command_remove();
5662
+ } else if (edit_commands[edit_selected_index]) {
5663
+ handle_command_update(edit_commands[edit_selected_index]);
5664
+ }
5665
+ break;
5666
+ case "Escape":
5667
+ e.preventDefault();
5668
+ handle_edit_close();
5669
+ break;
5670
+ }
5671
+ };
5672
+ window.addEventListener("keydown", handle_keydown);
5673
+ return () => window.removeEventListener("keydown", handle_keydown);
5674
+ }, [
5675
+ edit_context,
5676
+ edit_commands,
5677
+ edit_selected_index,
5678
+ handle_command_update,
5679
+ handle_command_remove,
5680
+ handle_edit_close
5681
+ ]);
5682
+ React27.useEffect(() => {
5683
+ const handle_pill_click = (e) => {
5684
+ const detail = e.detail;
5685
+ const { id, prefix, action, action_label, node_pos } = detail;
5686
+ if (editor && editor_container_ref.current) {
5687
+ const container_rect = editor_container_ref.current.getBoundingClientRect();
5688
+ try {
5689
+ const coords = editor.view.coordsAtPos(node_pos);
5690
+ if (coords) {
5691
+ const prefix_config = prefixes.find((p) => p.char === prefix);
5692
+ const current_index = prefix_config?.commands.findIndex(
5693
+ (cmd) => cmd.action === action
5694
+ ) ?? 0;
5695
+ set_edit_context({
5696
+ command: {
5697
+ id,
5698
+ prefix,
5699
+ action,
5700
+ action_label,
5701
+ position: node_pos,
5702
+ length: 0
5703
+ },
5704
+ node_pos,
5705
+ rect: new DOMRect(
5706
+ coords.left - container_rect.left,
5707
+ coords.bottom - container_rect.top + 4,
5708
+ 0,
5709
+ 0
5710
+ )
5711
+ });
5712
+ set_edit_selected_index(Math.max(0, current_index));
5713
+ }
5714
+ } catch {
5715
+ }
5716
+ }
5717
+ };
5718
+ document.addEventListener("command-pill-click", handle_pill_click);
5719
+ return () => document.removeEventListener("command-pill-click", handle_pill_click);
5720
+ }, [editor, prefixes]);
5721
+ return /* @__PURE__ */ jsxs(
5722
+ "div",
5723
+ {
5724
+ ref: editor_container_ref,
5725
+ className: cn(
5726
+ "cls_hazo_ui_textarea",
5727
+ "relative flex w-full rounded-md border border-input bg-background px-3 py-2",
5728
+ "text-sm ring-offset-background",
5729
+ "focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
5730
+ disabled && "cursor-not-allowed opacity-50",
5731
+ className
5732
+ ),
5733
+ style: {
5734
+ minHeight: calculated_min_height,
5735
+ maxHeight: max_height
5736
+ },
5737
+ children: [
5738
+ /* @__PURE__ */ jsx(
5739
+ EditorContent,
5740
+ {
5741
+ editor,
5742
+ className: cn(
5743
+ "cls_textarea_content",
5744
+ "flex-1 min-w-0 overflow-y-auto",
5745
+ "[&_.ProseMirror]:outline-none",
5746
+ "[&_.ProseMirror_p]:m-0 [&_.ProseMirror_p]:mb-1",
5747
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]",
5748
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:text-muted-foreground",
5749
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:pointer-events-none",
5750
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:float-left",
5751
+ "[&_.ProseMirror_.is-editor-empty:first-child::before]:h-0"
5752
+ )
5753
+ }
5754
+ ),
5755
+ suggestion_state?.is_active && /* @__PURE__ */ jsx(
5756
+ CommandPopover,
5757
+ {
5758
+ is_open: true,
5759
+ commands: filtered_commands,
5760
+ prefix: suggestion_state.prefix,
5761
+ query: suggestion_state.query,
5762
+ selected_index,
5763
+ position: popover_position,
5764
+ on_query_change: () => {
5765
+ },
5766
+ on_select: handle_command_select,
5767
+ on_close: handle_popover_close,
5768
+ on_selection_change: set_selected_index
5769
+ }
5770
+ ),
5771
+ edit_context && /* @__PURE__ */ jsx(
5772
+ "div",
5773
+ {
5774
+ ref: edit_popover_ref,
5775
+ className: cn(
5776
+ "cls_edit_popover",
5777
+ "absolute z-[9999]",
5778
+ "w-64 min-w-[200px] max-w-[300px]",
5779
+ "rounded-md border bg-popover text-popover-foreground shadow-lg",
5780
+ "animate-in fade-in-0 zoom-in-95"
5781
+ ),
5782
+ style: {
5783
+ top: edit_context.rect.y,
5784
+ left: edit_context.rect.x
5785
+ },
5786
+ children: /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
5787
+ /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground border-b", children: "Change command" }),
5788
+ /* @__PURE__ */ jsxs("div", { className: "max-h-[200px] overflow-y-auto", children: [
5789
+ edit_commands.map((cmd, idx) => /* @__PURE__ */ jsxs(
5790
+ "div",
5791
+ {
5792
+ className: cn(
5793
+ "px-3 py-2 cursor-pointer flex items-center gap-2",
5794
+ "hover:bg-accent",
5795
+ idx === edit_selected_index && "bg-accent",
5796
+ cmd.action === edit_context.command.action && "font-medium"
5797
+ ),
5798
+ onClick: () => handle_command_update(cmd),
5799
+ children: [
5800
+ cmd.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-muted-foreground", children: cmd.icon }),
5801
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
5802
+ /* @__PURE__ */ jsxs("div", { className: "truncate", children: [
5803
+ edit_context.command.prefix,
5804
+ cmd.action_label
5805
+ ] }),
5806
+ cmd.action_description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: cmd.action_description })
5807
+ ] }),
5808
+ cmd.action === edit_context.command.action && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "current" })
5809
+ ]
5810
+ },
5811
+ cmd.action
5812
+ )),
5813
+ /* @__PURE__ */ jsx(
5814
+ "div",
5815
+ {
5816
+ className: cn(
5817
+ "px-3 py-2 cursor-pointer flex items-center gap-2 text-destructive border-t",
5818
+ "hover:bg-destructive/10",
5819
+ edit_selected_index === edit_commands.length && "bg-destructive/10"
5820
+ ),
5821
+ onClick: handle_command_remove,
5822
+ children: /* @__PURE__ */ jsx("span", { children: "Remove" })
5823
+ }
5824
+ )
5825
+ ] })
5826
+ ] })
5827
+ }
5828
+ )
5829
+ ]
5830
+ }
5831
+ );
5832
+ };
5833
+ HazoUiTextarea.displayName = "HazoUiTextarea";
4249
5834
 
4250
- export { HazoUiFlexInput, HazoUiFlexRadio, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiRte };
5835
+ export { CommandNodeExtension, CommandPill, CommandPopover, HazoUiFlexInput, HazoUiFlexRadio, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiRte, HazoUiTextarea, HazoUiTextbox, create_command_suggestion_extension, parse_commands_from_text, text_to_tiptap_content };
4251
5836
  //# sourceMappingURL=index.js.map
4252
5837
  //# sourceMappingURL=index.js.map