@mieweb/ui 0.11.0-dev.29 → 0.11.0-dev.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/MIGRATION.md +67 -0
  2. package/README.md +10 -0
  3. package/dist/EncounterMdyEditor-3SQY4MK2.js +286 -0
  4. package/dist/EncounterMdyEditor-3SQY4MK2.js.map +1 -0
  5. package/dist/EncounterMdyEditor-73PTTIRY.cjs +288 -0
  6. package/dist/EncounterMdyEditor-73PTTIRY.cjs.map +1 -0
  7. package/dist/chunk-25MPUVTM.js +339 -0
  8. package/dist/chunk-25MPUVTM.js.map +1 -0
  9. package/dist/{chunk-2VISTX7O.js → chunk-3NOVISM6.js} +3 -3
  10. package/dist/{chunk-2VISTX7O.js.map → chunk-3NOVISM6.js.map} +1 -1
  11. package/dist/{chunk-6GKIISNZ.cjs → chunk-3Y3ZCDNF.cjs} +176 -63
  12. package/dist/chunk-3Y3ZCDNF.cjs.map +1 -0
  13. package/dist/{chunk-AK4LHJPC.js → chunk-4JXO5JTE.js} +84 -3
  14. package/dist/chunk-4JXO5JTE.js.map +1 -0
  15. package/dist/chunk-4NB4WOGU.cjs +666 -0
  16. package/dist/chunk-4NB4WOGU.cjs.map +1 -0
  17. package/dist/{chunk-434L5RYF.js → chunk-4P27Y52M.js} +3 -3
  18. package/dist/{chunk-434L5RYF.js.map → chunk-4P27Y52M.js.map} +1 -1
  19. package/dist/{chunk-PRA2V5BP.cjs → chunk-5KGYTNOA.cjs} +7 -7
  20. package/dist/{chunk-PRA2V5BP.cjs.map → chunk-5KGYTNOA.cjs.map} +1 -1
  21. package/dist/chunk-5LNLB2XT.js +634 -0
  22. package/dist/chunk-5LNLB2XT.js.map +1 -0
  23. package/dist/chunk-5YOT4DVH.js +31 -0
  24. package/dist/chunk-5YOT4DVH.js.map +1 -0
  25. package/dist/chunk-7HFZL5V5.js +2425 -0
  26. package/dist/chunk-7HFZL5V5.js.map +1 -0
  27. package/dist/{chunk-XZNHS7YQ.cjs → chunk-7XC6E4BT.cjs} +3 -3
  28. package/dist/{chunk-XZNHS7YQ.cjs.map → chunk-7XC6E4BT.cjs.map} +1 -1
  29. package/dist/{chunk-JM4YFLO4.js → chunk-AIJYZP7M.js} +3 -3
  30. package/dist/{chunk-JM4YFLO4.js.map → chunk-AIJYZP7M.js.map} +1 -1
  31. package/dist/chunk-BBLEGF5L.js +66 -0
  32. package/dist/chunk-BBLEGF5L.js.map +1 -0
  33. package/dist/{chunk-MBDT2MGR.js → chunk-BIQIE3VW.js} +4 -4
  34. package/dist/{chunk-MBDT2MGR.js.map → chunk-BIQIE3VW.js.map} +1 -1
  35. package/dist/chunk-FSLI5IKP.cjs +54 -0
  36. package/dist/chunk-FSLI5IKP.cjs.map +1 -0
  37. package/dist/chunk-GADJASST.js +3 -0
  38. package/dist/chunk-GADJASST.js.map +1 -0
  39. package/dist/chunk-IXUIOR4K.cjs +2457 -0
  40. package/dist/chunk-IXUIOR4K.cjs.map +1 -0
  41. package/dist/chunk-K2BY7YPJ.cjs +4 -0
  42. package/dist/chunk-K2BY7YPJ.cjs.map +1 -0
  43. package/dist/{chunk-H3P7POFC.cjs → chunk-MA3Y6AYA.cjs} +3 -3
  44. package/dist/{chunk-H3P7POFC.cjs.map → chunk-MA3Y6AYA.cjs.map} +1 -1
  45. package/dist/chunk-QO4A6U73.cjs +342 -0
  46. package/dist/chunk-QO4A6U73.cjs.map +1 -0
  47. package/dist/{chunk-43QBEF6N.js → chunk-QR7B6UPR.js} +176 -63
  48. package/dist/chunk-QR7B6UPR.js.map +1 -0
  49. package/dist/chunk-SMPLM6K3.js +4107 -0
  50. package/dist/chunk-SMPLM6K3.js.map +1 -0
  51. package/dist/chunk-SV6YGK4U.cjs +88 -0
  52. package/dist/chunk-SV6YGK4U.cjs.map +1 -0
  53. package/dist/{chunk-MQ5WJ3NO.js → chunk-UDUYZDTA.js} +14 -72
  54. package/dist/chunk-UDUYZDTA.js.map +1 -0
  55. package/dist/{chunk-ZLBNYCYT.cjs → chunk-XPVQI3MM.cjs} +84 -3
  56. package/dist/chunk-XPVQI3MM.cjs.map +1 -0
  57. package/dist/{chunk-AQUHEKXL.cjs → chunk-XQHDQ64G.cjs} +4 -4
  58. package/dist/{chunk-AQUHEKXL.cjs.map → chunk-XQHDQ64G.cjs.map} +1 -1
  59. package/dist/chunk-Z2OOJGHL.cjs +4155 -0
  60. package/dist/chunk-Z2OOJGHL.cjs.map +1 -0
  61. package/dist/{chunk-QKW2QCGI.cjs → chunk-ZK2R6UGF.cjs} +13 -72
  62. package/dist/chunk-ZK2R6UGF.cjs.map +1 -0
  63. package/dist/components/ActionPlan/index.cjs +4 -4
  64. package/dist/components/ActionPlan/index.js +2 -2
  65. package/dist/components/AlertDialog/index.d.cts +1 -1
  66. package/dist/components/AlertDialog/index.d.ts +1 -1
  67. package/dist/components/EmailEditor/index.cjs +13 -12
  68. package/dist/components/EmailEditor/index.js +4 -3
  69. package/dist/components/MediaEditor/index.cjs +7 -7
  70. package/dist/components/MediaEditor/index.js +2 -2
  71. package/dist/components/RichTextEditor/index.cjs +5 -4
  72. package/dist/components/RichTextEditor/index.d.cts +34 -0
  73. package/dist/components/RichTextEditor/index.d.ts +34 -0
  74. package/dist/components/RichTextEditor/index.js +2 -1
  75. package/dist/components/SuperChat/index.cjs +10 -9
  76. package/dist/components/SuperChat/index.cjs.map +1 -1
  77. package/dist/components/SuperChat/index.js +2 -1
  78. package/dist/components/SuperChat/index.js.map +1 -1
  79. package/dist/components/Textarea/index.cjs +6 -5
  80. package/dist/components/Textarea/index.js +3 -2
  81. package/dist/esheet.cjs +4237 -25
  82. package/dist/esheet.cjs.map +1 -1
  83. package/dist/esheet.d.cts +753 -6
  84. package/dist/esheet.d.ts +753 -6
  85. package/dist/esheet.js +4099 -21
  86. package/dist/esheet.js.map +1 -1
  87. package/dist/index.cjs +204 -3072
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.d.cts +71 -9
  90. package/dist/index.d.ts +71 -9
  91. package/dist/index.js +38 -2968
  92. package/dist/index.js.map +1 -1
  93. package/dist/kerebron.cjs +7 -268
  94. package/dist/kerebron.cjs.map +1 -1
  95. package/dist/kerebron.d.cts +7 -1
  96. package/dist/kerebron.d.ts +7 -1
  97. package/dist/kerebron.js +6 -270
  98. package/dist/kerebron.js.map +1 -1
  99. package/dist/model-WFFZRQMY.js +18 -0
  100. package/dist/model-WFFZRQMY.js.map +1 -0
  101. package/dist/model-Y7WRIGGA.cjs +79 -0
  102. package/dist/model-Y7WRIGGA.cjs.map +1 -0
  103. package/dist/styles.css +1 -1
  104. package/dist/tailwind-preset.cjs +4 -4
  105. package/dist/tailwind-preset.js +1 -1
  106. package/package.json +30 -9
  107. package/dist/chunk-43QBEF6N.js.map +0 -1
  108. package/dist/chunk-6GKIISNZ.cjs.map +0 -1
  109. package/dist/chunk-AK4LHJPC.js.map +0 -1
  110. package/dist/chunk-MQ5WJ3NO.js.map +0 -1
  111. package/dist/chunk-QKW2QCGI.cjs.map +0 -1
  112. package/dist/chunk-SFSBYC46.js +0 -1596
  113. package/dist/chunk-SFSBYC46.js.map +0 -1
  114. package/dist/chunk-ZIJMLRI3.cjs +0 -1633
  115. package/dist/chunk-ZIJMLRI3.cjs.map +0 -1
  116. package/dist/chunk-ZLBNYCYT.cjs.map +0 -1
@@ -1,9 +1,11 @@
1
+ import { useMessages } from './chunk-5YOT4DVH.js';
1
2
  import { Separator } from './chunk-OQWZYKJM.js';
2
3
  import { Dropdown, DropdownSeparator, DropdownLabel, DropdownItem, DropdownSubmenu } from './chunk-OYUIEJPN.js';
3
4
  import { Input } from './chunk-3IMM2PM4.js';
4
5
  import { isHtmlEmpty } from './chunk-ERLPVXOV.js';
5
6
  import { X, Search, History, BookOpen, ChevronRight, ChevronDown, Plus } from './chunk-BKSPDTX4.js';
6
7
  import { Button } from './chunk-WFBUBT54.js';
8
+ import { AnimatedPresence, Animated } from './chunk-F4N67NAF.js';
7
9
  import { cn } from './chunk-TQONQSJO.js';
8
10
  import * as React2 from 'react';
9
11
  import { Bold, Italic, Underline, List, ListOrdered, AlignLeft, AlignCenter, AlignRight, Braces, Replace, MicOff, Mic, BookOpen as BookOpen$1, Plus as Plus$1 } from 'lucide-react';
@@ -19,8 +21,10 @@ var DEFAULT_LABELS = {
19
21
  empty: "No macros available",
20
22
  emptyHint: "The application has not provided a macro list.",
21
23
  noResults: "No macros match",
22
- clearSearch: "Clear search"
24
+ clearSearch: "Clear search",
25
+ showMore: "Show {count} more"
23
26
  };
27
+ var PREVIEW_COUNT = 4;
24
28
  function matchesQuery(macro, query) {
25
29
  const q = query.toLowerCase();
26
30
  return macro.label.toLowerCase().includes(q) || (macro.shortcut ?? "").toLowerCase().includes(q) || (macro.keywords ?? []).some((k) => k.toLowerCase().includes(q)) || macro.content.toLowerCase().includes(q);
@@ -42,6 +46,7 @@ var MacroLibrary = React2.forwardRef(
42
46
  onClose,
43
47
  onCreateMacro,
44
48
  autoFocusSearch = false,
49
+ compact = false,
45
50
  className,
46
51
  labels: labelOverrides
47
52
  }, ref) {
@@ -50,6 +55,7 @@ var MacroLibrary = React2.forwardRef(
50
55
  const [collapsed, setCollapsed] = React2.useState(
51
56
  {}
52
57
  );
58
+ const [expanded, setExpanded] = React2.useState({});
53
59
  const listRef = React2.useRef(null);
54
60
  const searchRef = React2.useRef(null);
55
61
  const panelId = React2.useId();
@@ -112,6 +118,18 @@ var MacroLibrary = React2.forwardRef(
112
118
  moveFocus(-1);
113
119
  }
114
120
  };
121
+ const expandGroup = (groupId) => {
122
+ setExpanded((prev) => ({ ...prev, [groupId]: true }));
123
+ requestAnimationFrame(() => {
124
+ const groupEl = Array.from(
125
+ listRef.current?.querySelectorAll(
126
+ '[data-slot="macro-library-group"]'
127
+ ) ?? []
128
+ ).find((el) => el.dataset.groupId === groupId);
129
+ const rows = groupEl?.querySelectorAll("[data-macro-row]");
130
+ rows?.[PREVIEW_COUNT]?.focus();
131
+ });
132
+ };
115
133
  return (
116
134
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- keydown only delegates Escape-to-close from focusable children
117
135
  /* @__PURE__ */ jsxs(
@@ -125,7 +143,7 @@ var MacroLibrary = React2.forwardRef(
125
143
  className: cn("bg-muted/20 flex min-h-0 flex-col", className),
126
144
  onKeyDown: handlePanelKeyDown,
127
145
  children: [
128
- /* @__PURE__ */ jsxs(
146
+ !compact && /* @__PURE__ */ jsxs(
129
147
  "div",
130
148
  {
131
149
  "data-slot": "macro-library-header",
@@ -152,7 +170,7 @@ var MacroLibrary = React2.forwardRef(
152
170
  }
153
171
  ),
154
172
  hasMacros ? /* @__PURE__ */ jsxs(Fragment, { children: [
155
- /* @__PURE__ */ jsx("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
173
+ !compact && /* @__PURE__ */ jsx("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
156
174
  /* @__PURE__ */ jsx(
157
175
  Search,
158
176
  {
@@ -211,14 +229,17 @@ var MacroLibrary = React2.forwardRef(
211
229
  visibleGroups.map((group) => {
212
230
  const isPrevious = group.kind === "previous";
213
231
  const isCollapsed = !searching && collapsed[group.id] === true;
232
+ const isPreview = !searching && expanded[group.id] !== true && group.macros.length > PREVIEW_COUNT;
233
+ const visibleMacros = isPreview ? group.macros.slice(0, PREVIEW_COUNT) : group.macros;
214
234
  const GroupIcon = isPrevious ? History : BookOpen;
215
235
  return /* @__PURE__ */ jsxs(
216
236
  "div",
217
237
  {
218
238
  "data-slot": "macro-library-group",
239
+ "data-group-id": group.id,
219
240
  "data-kind": group.kind ?? "library",
220
241
  children: [
221
- /* @__PURE__ */ jsxs(
242
+ (!compact || isPrevious) && /* @__PURE__ */ jsxs(
222
243
  "button",
223
244
  {
224
245
  type: "button",
@@ -251,7 +272,7 @@ var MacroLibrary = React2.forwardRef(
251
272
  ]
252
273
  }
253
274
  ),
254
- !isCollapsed && group.macros.map((macro) => /* @__PURE__ */ jsxs(
275
+ !isCollapsed && visibleMacros.map((macro) => /* @__PURE__ */ jsxs(
255
276
  "button",
256
277
  {
257
278
  type: "button",
@@ -276,7 +297,31 @@ var MacroLibrary = React2.forwardRef(
276
297
  ]
277
298
  },
278
299
  macro.id
279
- ))
300
+ )),
301
+ !isCollapsed && isPreview && /* @__PURE__ */ jsxs(
302
+ "button",
303
+ {
304
+ type: "button",
305
+ "data-macro-row": true,
306
+ "data-slot": "macro-library-show-more",
307
+ className: "focus-visible:ring-ring text-muted-foreground hover:bg-muted/60 hover:text-primary flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start text-xs font-medium focus-visible:ring-2 focus-visible:outline-none",
308
+ onClick: () => expandGroup(group.id),
309
+ onKeyDown: handleRowKeyDown,
310
+ children: [
311
+ /* @__PURE__ */ jsx(
312
+ ChevronDown,
313
+ {
314
+ "aria-hidden": "true",
315
+ className: "h-3 w-3"
316
+ }
317
+ ),
318
+ labels.showMore.replace(
319
+ "{count}",
320
+ String(group.macros.length - PREVIEW_COUNT)
321
+ )
322
+ ]
323
+ }
324
+ )
280
325
  ]
281
326
  },
282
327
  group.id
@@ -454,6 +499,9 @@ var RichTextEditor = React2.forwardRef(
454
499
  sanitizeHtml,
455
500
  macros,
456
501
  defaultMacrosOpen = false,
502
+ macrosOnFocus = false,
503
+ compactMacros = false,
504
+ onMacroInsert,
457
505
  macroLabels,
458
506
  onCreateMacro,
459
507
  toolbar,
@@ -473,6 +521,7 @@ var RichTextEditor = React2.forwardRef(
473
521
  "aria-invalid": ariaInvalid,
474
522
  "aria-required": ariaRequired
475
523
  }, ref) => {
524
+ const m = useMessages();
476
525
  const inert = disabled || readOnly;
477
526
  const editorRef = React2.useRef(null);
478
527
  const [isListening, setIsListening] = React2.useState(false);
@@ -480,11 +529,14 @@ var RichTextEditor = React2.forwardRef(
480
529
  const recognitionRef = React2.useRef(null);
481
530
  const isListeningRef = React2.useRef(false);
482
531
  const shouldRestartRef = React2.useRef(false);
483
- const [macrosOpen, setMacrosOpen] = React2.useState(defaultMacrosOpen);
532
+ const [macrosOpen, setMacrosOpen] = React2.useState(
533
+ defaultMacrosOpen && !macrosOnFocus
534
+ );
484
535
  const savedRangeRef = React2.useRef(null);
485
536
  const macroPanelId = React2.useId();
486
537
  const hasVariables = Boolean(variableGroups && variableGroups.length > 0);
487
538
  const hasMacros = Boolean(macros);
539
+ const macrosResting = hasMacros && macrosOnFocus && !macrosOpen;
488
540
  const hasMacroEntries = Boolean(
489
541
  macros?.some((group) => group.macros.length > 0)
490
542
  );
@@ -565,7 +617,17 @@ var RichTextEditor = React2.forwardRef(
565
617
  }, [inert]);
566
618
  React2.useEffect(() => {
567
619
  if (editorRef.current && editorRef.current.innerHTML !== value) {
620
+ const hadFocus = document.activeElement === editorRef.current;
568
621
  editorRef.current.innerHTML = value;
622
+ if (hadFocus) {
623
+ const range = document.createRange();
624
+ range.selectNodeContents(editorRef.current);
625
+ range.collapse(false);
626
+ const selection = window.getSelection();
627
+ selection?.removeAllRanges();
628
+ selection?.addRange(range);
629
+ savedRangeRef.current = range.cloneRange();
630
+ }
569
631
  reconcileGutterWithContent();
570
632
  }
571
633
  }, [value, reconcileGutterWithContent]);
@@ -669,6 +731,7 @@ var RichTextEditor = React2.forwardRef(
669
731
  };
670
732
  const insertMacro = (macro) => {
671
733
  if (inert || !editorRef.current) return;
734
+ if (onMacroInsert?.(macro) === true) return;
672
735
  focusRestoringSelection();
673
736
  insertTextAtSelection(macro.content);
674
737
  };
@@ -747,6 +810,21 @@ var RichTextEditor = React2.forwardRef(
747
810
  collected.selection.addRange(replaceRange);
748
811
  return replaceRange;
749
812
  };
813
+ const deleteSelectedRange = (replaceRange) => {
814
+ let deleted = false;
815
+ try {
816
+ deleted = document.execCommand("delete", false);
817
+ } catch {
818
+ deleted = false;
819
+ }
820
+ if (!deleted) {
821
+ replaceRange.deleteContents();
822
+ replaceRange.collapse(true);
823
+ const selection = window.getSelection();
824
+ selection?.removeAllRanges();
825
+ selection?.addRange(replaceRange);
826
+ }
827
+ };
750
828
  const expandTypedShortcut = (event) => {
751
829
  if (!macros) return;
752
830
  const collected = collectTokenBeforeCaret();
@@ -755,6 +833,14 @@ var RichTextEditor = React2.forwardRef(
755
833
  const macro = macros.flatMap((group) => group.macros).find((candidate) => candidate.shortcut?.toLowerCase() === lowered);
756
834
  if (!macro) return;
757
835
  event.preventDefault();
836
+ if (onMacroInsert) {
837
+ deleteSelectedRange(selectCollectedToken(collected));
838
+ saveSelection();
839
+ updateContent();
840
+ if (onMacroInsert(macro) === true) return;
841
+ insertTextAtSelection(macro.content);
842
+ return;
843
+ }
758
844
  selectCollectedToken(collected);
759
845
  insertTextAtSelection(macro.content);
760
846
  };
@@ -764,19 +850,7 @@ var RichTextEditor = React2.forwardRef(
764
850
  if (!Object.hasOwn(MARKDOWN_BLOCK_RULES, collected.token)) return false;
765
851
  const rule = MARKDOWN_BLOCK_RULES[collected.token];
766
852
  event.preventDefault();
767
- const replaceRange = selectCollectedToken(collected);
768
- let deleted = false;
769
- try {
770
- deleted = document.execCommand("delete", false);
771
- } catch {
772
- deleted = false;
773
- }
774
- if (!deleted) {
775
- replaceRange.deleteContents();
776
- replaceRange.collapse(true);
777
- collected.selection.removeAllRanges();
778
- collected.selection.addRange(replaceRange);
779
- }
853
+ deleteSelectedRange(selectCollectedToken(collected));
780
854
  try {
781
855
  document.execCommand(rule.command, false, rule.value);
782
856
  } catch {
@@ -1030,6 +1104,21 @@ var RichTextEditor = React2.forwardRef(
1030
1104
  {
1031
1105
  "data-slot": "rich-text-editor",
1032
1106
  "data-chromeless": chromeless || void 0,
1107
+ onFocus: hasMacros && macrosOnFocus ? () => setMacrosOpen(true) : void 0,
1108
+ onBlur: hasMacros && macrosOnFocus ? (event) => {
1109
+ const related = event.relatedTarget;
1110
+ if (related && event.currentTarget.contains(related)) return;
1111
+ let menu = related?.closest('[role="menu"]');
1112
+ while (menu && menu.id) {
1113
+ const trigger = document.querySelector(
1114
+ `[aria-controls="${globalThis.CSS.escape(menu.id)}"]`
1115
+ );
1116
+ if (!trigger) break;
1117
+ if (event.currentTarget.contains(trigger)) return;
1118
+ menu = trigger.closest('[role="menu"]');
1119
+ }
1120
+ setMacrosOpen(false);
1121
+ } : void 0,
1033
1122
  className: cn(
1034
1123
  "bg-background flex flex-col",
1035
1124
  !chromeless && "border-border overflow-hidden rounded-lg border",
@@ -1051,8 +1140,8 @@ var RichTextEditor = React2.forwardRef(
1051
1140
  onClick: () => execCommand("bold"),
1052
1141
  disabled,
1053
1142
  className: iconButtonClass,
1054
- "aria-label": "Bold",
1055
- title: "Bold",
1143
+ "aria-label": m("Bold"),
1144
+ title: m("Bold"),
1056
1145
  children: /* @__PURE__ */ jsx(Bold, { className: "h-4 w-4" })
1057
1146
  }
1058
1147
  ),
@@ -1065,8 +1154,8 @@ var RichTextEditor = React2.forwardRef(
1065
1154
  onClick: () => execCommand("italic"),
1066
1155
  disabled,
1067
1156
  className: iconButtonClass,
1068
- "aria-label": "Italic",
1069
- title: "Italic",
1157
+ "aria-label": m("Italic"),
1158
+ title: m("Italic"),
1070
1159
  children: /* @__PURE__ */ jsx(Italic, { className: "h-4 w-4" })
1071
1160
  }
1072
1161
  ),
@@ -1079,8 +1168,8 @@ var RichTextEditor = React2.forwardRef(
1079
1168
  onClick: () => execCommand("underline"),
1080
1169
  disabled,
1081
1170
  className: iconButtonClass,
1082
- "aria-label": "Underline",
1083
- title: "Underline",
1171
+ "aria-label": m("Underline"),
1172
+ title: m("Underline"),
1084
1173
  children: /* @__PURE__ */ jsx(Underline, { className: "h-4 w-4" })
1085
1174
  }
1086
1175
  ),
@@ -1094,8 +1183,8 @@ var RichTextEditor = React2.forwardRef(
1094
1183
  onClick: () => execCommand("insertUnorderedList"),
1095
1184
  disabled,
1096
1185
  className: iconButtonClass,
1097
- "aria-label": "Bullet list",
1098
- title: "Bullet list",
1186
+ "aria-label": m("Bullet list"),
1187
+ title: m("Bullet list"),
1099
1188
  children: /* @__PURE__ */ jsx(List, { className: "h-4 w-4" })
1100
1189
  }
1101
1190
  ),
@@ -1108,8 +1197,8 @@ var RichTextEditor = React2.forwardRef(
1108
1197
  onClick: () => execCommand("insertOrderedList"),
1109
1198
  disabled,
1110
1199
  className: iconButtonClass,
1111
- "aria-label": "Numbered list",
1112
- title: "Numbered list",
1200
+ "aria-label": m("Numbered list"),
1201
+ title: m("Numbered list"),
1113
1202
  children: /* @__PURE__ */ jsx(ListOrdered, { className: "h-4 w-4" })
1114
1203
  }
1115
1204
  ),
@@ -1123,8 +1212,8 @@ var RichTextEditor = React2.forwardRef(
1123
1212
  onClick: () => execCommand("justifyLeft"),
1124
1213
  disabled,
1125
1214
  className: iconButtonClass,
1126
- "aria-label": "Align left",
1127
- title: "Align left",
1215
+ "aria-label": m("Align left"),
1216
+ title: m("Align left"),
1128
1217
  children: /* @__PURE__ */ jsx(AlignLeft, { className: "h-4 w-4" })
1129
1218
  }
1130
1219
  ),
@@ -1137,8 +1226,8 @@ var RichTextEditor = React2.forwardRef(
1137
1226
  onClick: () => execCommand("justifyCenter"),
1138
1227
  disabled,
1139
1228
  className: iconButtonClass,
1140
- "aria-label": "Align center",
1141
- title: "Align center",
1229
+ "aria-label": m("Align center"),
1230
+ title: m("Align center"),
1142
1231
  children: /* @__PURE__ */ jsx(AlignCenter, { className: "h-4 w-4" })
1143
1232
  }
1144
1233
  ),
@@ -1151,8 +1240,8 @@ var RichTextEditor = React2.forwardRef(
1151
1240
  onClick: () => execCommand("justifyRight"),
1152
1241
  disabled,
1153
1242
  className: iconButtonClass,
1154
- "aria-label": "Align right",
1155
- title: "Align right",
1243
+ "aria-label": m("Align right"),
1244
+ title: m("Align right"),
1156
1245
  children: /* @__PURE__ */ jsx(AlignRight, { className: "h-4 w-4" })
1157
1246
  }
1158
1247
  ),
@@ -1175,10 +1264,10 @@ var RichTextEditor = React2.forwardRef(
1175
1264
  size: "sm",
1176
1265
  className: "h-8 gap-1 px-2",
1177
1266
  disabled,
1178
- title: "Insert variable",
1267
+ title: m("Insert variable"),
1179
1268
  children: [
1180
1269
  /* @__PURE__ */ jsx(Braces, { className: "h-4 w-4" }),
1181
- /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs", children: "Variables" })
1270
+ /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs", children: m("Variables") })
1182
1271
  ]
1183
1272
  }
1184
1273
  ),
@@ -1206,10 +1295,10 @@ var RichTextEditor = React2.forwardRef(
1206
1295
  onClick: handleConvertToMustache,
1207
1296
  disabled,
1208
1297
  className: "h-8 gap-1 px-2",
1209
- title: "Convert <<field>> to {{field}}",
1298
+ title: m("Convert <<field>> to {{field}}"),
1210
1299
  children: [
1211
1300
  /* @__PURE__ */ jsx(Replace, { className: "h-4 w-4" }),
1212
- /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs", children: "<< >> to {{ }}" })
1301
+ /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs", children: m("<< >> to {{ }}") })
1213
1302
  ]
1214
1303
  }
1215
1304
  )
@@ -1228,10 +1317,10 @@ var RichTextEditor = React2.forwardRef(
1228
1317
  "h-8 gap-1 px-2",
1229
1318
  isListening && "animate-pulse"
1230
1319
  ),
1231
- title: !speechSupported ? "Speech recognition not supported in this browser" : isListening ? "Stop dictation" : "Start dictation",
1320
+ title: !speechSupported ? m("Speech recognition not supported in this browser") : isListening ? m("Stop dictation") : m("Start dictation"),
1232
1321
  children: [
1233
1322
  isListening ? /* @__PURE__ */ jsx(MicOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4" }),
1234
- /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs", children: isListening ? "Stop" : "Dictate" })
1323
+ /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs", children: isListening ? m("Stop") : m("Dictate") })
1235
1324
  ]
1236
1325
  }
1237
1326
  )
@@ -1272,7 +1361,7 @@ var RichTextEditor = React2.forwardRef(
1272
1361
  ),
1273
1362
  onMouseMove: blockMenu && !disabled ? handleGutterMouseMove : void 0,
1274
1363
  children: [
1275
- blockMenu && !inert && /* @__PURE__ */ jsx(
1364
+ blockMenu && !inert && !macrosResting && /* @__PURE__ */ jsx(
1276
1365
  "div",
1277
1366
  {
1278
1367
  "data-slot": "rich-text-editor-block-gutter",
@@ -1337,6 +1426,7 @@ var RichTextEditor = React2.forwardRef(
1337
1426
  if (blockTargetRangeRef.current) {
1338
1427
  savedRangeRef.current = blockTargetRangeRef.current;
1339
1428
  }
1429
+ focusRestoringSelection();
1340
1430
  insertMacro(macro);
1341
1431
  },
1342
1432
  children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
@@ -1401,7 +1491,7 @@ var RichTextEditor = React2.forwardRef(
1401
1491
  // native textarea clips its own) instead of wrapping out
1402
1492
  // of the one-row field.
1403
1493
  chromeless ? "end-0 truncate px-3 py-[7px] text-base" : "p-4",
1404
- blockMenu && "ps-10",
1494
+ blockMenu && !macrosResting && "ps-10",
1405
1495
  // Keep the placeholder's font in step with the editable
1406
1496
  // when the host restyles it (e.g. Textarea's `size`).
1407
1497
  editorClassName
@@ -1450,8 +1540,15 @@ var RichTextEditor = React2.forwardRef(
1450
1540
  "[&_ul]:my-2 [&_ul]:list-disc [&_ul]:ps-6",
1451
1541
  "[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:ps-6",
1452
1542
  "[&_blockquote]:border-border [&_blockquote]:text-muted-foreground [&_blockquote]:my-2 [&_blockquote]:border-s-4 [&_blockquote]:ps-3",
1453
- blockMenu && "ps-10",
1454
- hasMacros && macrosOpen && "md:min-h-[400px]",
1543
+ blockMenu && !macrosResting && "ps-10",
1544
+ // Tall enough for the docked panel's search plus a few rows
1545
+ // without forcing the host form to scroll; the compact panel
1546
+ // is just rows, so it needs far less.
1547
+ hasMacros && macrosOpen && (compactMacros ? "md:min-h-[140px]" : "md:min-h-[250px]"),
1548
+ // Focus mode grows the field from one row on focus (and, with
1549
+ // the block gutter, indents it) — ease the jump instead of
1550
+ // snapping.
1551
+ hasMacros && macrosOnFocus && "transition-[min-height,padding] duration-200 ease-out motion-reduce:transition-none",
1455
1552
  disabled && "bg-muted/20 cursor-not-allowed text-neutral-700 dark:text-neutral-300",
1456
1553
  editorClassName
1457
1554
  ),
@@ -1462,22 +1559,38 @@ var RichTextEditor = React2.forwardRef(
1462
1559
  ]
1463
1560
  }
1464
1561
  ),
1465
- hasMacros && macrosOpen && /* @__PURE__ */ jsx(
1466
- MacroLibrary,
1562
+ hasMacros && /* @__PURE__ */ jsx(AnimatedPresence, { children: macrosOpen && /* @__PURE__ */ jsx(
1563
+ Animated,
1467
1564
  {
1468
- id: macroPanelId,
1469
- groups: macros,
1470
- onSelect: insertMacro,
1471
- targetLabel: ariaLabel ?? placeholder,
1472
- onClose: () => {
1473
- setMacrosOpen(false);
1474
- focusRestoringSelection();
1475
- },
1476
- onCreateMacro,
1477
- labels: macroLabels,
1478
- className: "border-border max-h-72 border-t md:absolute md:inset-y-0 md:end-0 md:max-h-none md:w-72 md:border-s md:border-t-0"
1479
- }
1480
- )
1565
+ preset: "menu",
1566
+ mode: "presence",
1567
+ custom: typeof document !== "undefined" && document.dir === "rtl" ? "left" : "right",
1568
+ fallbackClassName: "animate-fade-in",
1569
+ className: "border-border flex max-h-72 flex-col border-t md:absolute md:inset-y-0 md:end-0 md:max-h-none md:w-72 md:border-s md:border-t-0",
1570
+ children: /* @__PURE__ */ jsx(
1571
+ MacroLibrary,
1572
+ {
1573
+ id: macroPanelId,
1574
+ groups: macros,
1575
+ onSelect: insertMacro,
1576
+ targetLabel: ariaLabel ?? placeholder,
1577
+ onClose: (
1578
+ // Focus mode: visibility follows focus; a close that
1579
+ // refocuses the editor would just reopen the panel.
1580
+ macrosOnFocus ? void 0 : () => {
1581
+ setMacrosOpen(false);
1582
+ focusRestoringSelection();
1583
+ }
1584
+ ),
1585
+ onCreateMacro,
1586
+ labels: macroLabels,
1587
+ compact: compactMacros,
1588
+ className: "min-h-0 flex-1"
1589
+ }
1590
+ )
1591
+ },
1592
+ "macro-panel"
1593
+ ) })
1481
1594
  ] })
1482
1595
  ]
1483
1596
  }
@@ -1487,5 +1600,5 @@ var RichTextEditor = React2.forwardRef(
1487
1600
  RichTextEditor.displayName = "RichTextEditor";
1488
1601
 
1489
1602
  export { MacroLibrary, RichTextEditor, convertAngleBracketsToMustache, processDictation };
1490
- //# sourceMappingURL=chunk-43QBEF6N.js.map
1491
- //# sourceMappingURL=chunk-43QBEF6N.js.map
1603
+ //# sourceMappingURL=chunk-QR7B6UPR.js.map
1604
+ //# sourceMappingURL=chunk-QR7B6UPR.js.map