@mieweb/ui 0.11.0-dev.22 → 0.11.0-dev.24
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/{chunk-N6XBE47W.js → chunk-3E7C5N2G.js} +3 -3
- package/dist/{chunk-N6XBE47W.js.map → chunk-3E7C5N2G.js.map} +1 -1
- package/dist/{chunk-XWNTCOC7.cjs → chunk-4W3QJWG2.cjs} +18 -2
- package/dist/chunk-4W3QJWG2.cjs.map +1 -0
- package/dist/{chunk-BSDBI6H7.cjs → chunk-BUN6RUJ5.cjs} +100 -8
- package/dist/chunk-BUN6RUJ5.cjs.map +1 -0
- package/dist/{chunk-H3YO5GBM.js → chunk-CPG7SDON.js} +100 -8
- package/dist/chunk-CPG7SDON.js.map +1 -0
- package/dist/{chunk-UQPNO5YC.js → chunk-GTZUG646.js} +4 -4
- package/dist/{chunk-UQPNO5YC.js.map → chunk-GTZUG646.js.map} +1 -1
- package/dist/{chunk-GFP3BUVC.cjs → chunk-HKLTJYRU.cjs} +7 -7
- package/dist/{chunk-GFP3BUVC.cjs.map → chunk-HKLTJYRU.cjs.map} +1 -1
- package/dist/{chunk-5EOW6AP3.js → chunk-IYY7NKA3.js} +97 -19
- package/dist/chunk-IYY7NKA3.js.map +1 -0
- package/dist/{chunk-MC467GS4.js → chunk-V43ZWRBT.js} +18 -2
- package/dist/chunk-V43ZWRBT.js.map +1 -0
- package/dist/{chunk-7BA7ENN5.cjs → chunk-VEPARPUE.cjs} +97 -19
- package/dist/chunk-VEPARPUE.cjs.map +1 -0
- package/dist/{chunk-5VA2HJ5B.cjs → chunk-ZWKC4JML.cjs} +9 -9
- package/dist/{chunk-5VA2HJ5B.cjs.map → chunk-ZWKC4JML.cjs.map} +1 -1
- package/dist/components/EmailEditor/index.cjs +12 -12
- package/dist/components/EmailEditor/index.js +3 -3
- package/dist/components/RichTextEditor/index.cjs +4 -4
- package/dist/components/RichTextEditor/index.d.cts +14 -0
- package/dist/components/RichTextEditor/index.d.ts +14 -0
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/Textarea/index.cjs +3 -3
- package/dist/components/Textarea/index.d.cts +7 -1
- package/dist/components/Textarea/index.d.ts +7 -1
- package/dist/components/Textarea/index.js +1 -1
- package/dist/esheet.cjs +5 -5
- package/dist/esheet.js +2 -2
- package/dist/index.cjs +64 -64
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +7 -7
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5EOW6AP3.js.map +0 -1
- package/dist/chunk-7BA7ENN5.cjs.map +0 -1
- package/dist/chunk-BSDBI6H7.cjs.map +0 -1
- package/dist/chunk-H3YO5GBM.js.map +0 -1
- package/dist/chunk-MC467GS4.js.map +0 -1
- package/dist/chunk-XWNTCOC7.cjs.map +0 -1
|
@@ -511,6 +511,15 @@ function getSpeechRecognition() {
|
|
|
511
511
|
return w.SpeechRecognition || w.webkitSpeechRecognition;
|
|
512
512
|
}
|
|
513
513
|
var BLOCK_BOUNDARY = /^(BR|DIV|P|LI|UL|OL|TABLE|TR|TD|TH|H[1-6]|BLOCKQUOTE|PRE|HR)$/;
|
|
514
|
+
var MARKDOWN_BLOCK_RULES = {
|
|
515
|
+
"#": { command: "formatBlock", value: "h1" },
|
|
516
|
+
"##": { command: "formatBlock", value: "h2" },
|
|
517
|
+
"###": { command: "formatBlock", value: "h3" },
|
|
518
|
+
"-": { command: "insertUnorderedList" },
|
|
519
|
+
"*": { command: "insertUnorderedList" },
|
|
520
|
+
"1.": { command: "insertOrderedList" },
|
|
521
|
+
">": { command: "formatBlock", value: "blockquote" }
|
|
522
|
+
};
|
|
514
523
|
function lastTextWithin(node) {
|
|
515
524
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
516
525
|
return (node.textContent ?? "").length > 0 ? node : null;
|
|
@@ -557,6 +566,8 @@ var RichTextEditor = React2.forwardRef(
|
|
|
557
566
|
defaultMacrosOpen = false,
|
|
558
567
|
macroLabels,
|
|
559
568
|
onCreateMacro,
|
|
569
|
+
toolbar = "visible",
|
|
570
|
+
markdownShortcuts = false,
|
|
560
571
|
"aria-label": ariaLabel
|
|
561
572
|
}, ref) => {
|
|
562
573
|
const editorRef = React2.useRef(null);
|
|
@@ -571,6 +582,8 @@ var RichTextEditor = React2.forwardRef(
|
|
|
571
582
|
const hasVariables = Boolean(variableGroups && variableGroups.length > 0);
|
|
572
583
|
const hasMacros = Boolean(macros);
|
|
573
584
|
const isEmpty = isHtmlEmpty(value);
|
|
585
|
+
const toolbarVisible = toolbar !== "hidden";
|
|
586
|
+
const toolbarVisibleRef = React2.useRef(toolbarVisible);
|
|
574
587
|
React2.useImperativeHandle(ref, () => editorRef.current);
|
|
575
588
|
React2.useEffect(() => {
|
|
576
589
|
setSpeechSupported(Boolean(getSpeechRecognition()));
|
|
@@ -584,6 +597,16 @@ var RichTextEditor = React2.forwardRef(
|
|
|
584
597
|
}
|
|
585
598
|
};
|
|
586
599
|
}, []);
|
|
600
|
+
React2.useEffect(() => {
|
|
601
|
+
toolbarVisibleRef.current = toolbarVisible;
|
|
602
|
+
if (toolbarVisible) return;
|
|
603
|
+
if (recognitionRef.current && isListeningRef.current) {
|
|
604
|
+
shouldRestartRef.current = false;
|
|
605
|
+
isListeningRef.current = false;
|
|
606
|
+
recognitionRef.current.stop();
|
|
607
|
+
setIsListening(false);
|
|
608
|
+
}
|
|
609
|
+
}, [toolbarVisible]);
|
|
587
610
|
React2.useEffect(() => {
|
|
588
611
|
if (editorRef.current && editorRef.current.innerHTML !== value) {
|
|
589
612
|
editorRef.current.innerHTML = value;
|
|
@@ -722,22 +745,18 @@ var RichTextEditor = React2.forwardRef(
|
|
|
722
745
|
saveSelection();
|
|
723
746
|
updateContent();
|
|
724
747
|
};
|
|
725
|
-
const
|
|
726
|
-
if (disabled || event.key !== " " || // Space during IME composition selects/converts a candidate; never
|
|
727
|
-
// hijack it for macro expansion.
|
|
728
|
-
event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey || !macros)
|
|
729
|
-
return;
|
|
748
|
+
const collectTokenBeforeCaret = () => {
|
|
730
749
|
const selection = window.getSelection();
|
|
731
750
|
if (!selection || selection.rangeCount === 0 || !selection.isCollapsed)
|
|
732
|
-
return;
|
|
751
|
+
return null;
|
|
733
752
|
const caret = selection.getRangeAt(0);
|
|
734
753
|
const node = caret.startContainer;
|
|
735
754
|
if (node.nodeType !== Node.TEXT_NODE || !editorRef.current?.contains(node))
|
|
736
|
-
return;
|
|
755
|
+
return null;
|
|
737
756
|
const typed = /(\S+)$/.exec(
|
|
738
757
|
(node.textContent ?? "").slice(0, caret.startOffset)
|
|
739
758
|
);
|
|
740
|
-
if (!typed) return;
|
|
759
|
+
if (!typed) return null;
|
|
741
760
|
let token = typed[1];
|
|
742
761
|
let startNode = node;
|
|
743
762
|
let startOffset = caret.startOffset - typed[1].length;
|
|
@@ -751,17 +770,72 @@ var RichTextEditor = React2.forwardRef(
|
|
|
751
770
|
startNode = prev;
|
|
752
771
|
startOffset = text.length - continued[1].length;
|
|
753
772
|
}
|
|
754
|
-
const
|
|
773
|
+
const atLineStart = startOffset === 0 && !previousVisibleText(startNode, editorRef.current);
|
|
774
|
+
return {
|
|
775
|
+
token,
|
|
776
|
+
startNode,
|
|
777
|
+
startOffset,
|
|
778
|
+
caretNode: node,
|
|
779
|
+
caretOffset: caret.startOffset,
|
|
780
|
+
atLineStart,
|
|
781
|
+
selection
|
|
782
|
+
};
|
|
783
|
+
};
|
|
784
|
+
const selectCollectedToken = (collected) => {
|
|
785
|
+
const replaceRange = document.createRange();
|
|
786
|
+
replaceRange.setStart(collected.startNode, collected.startOffset);
|
|
787
|
+
replaceRange.setEnd(collected.caretNode, collected.caretOffset);
|
|
788
|
+
collected.selection.removeAllRanges();
|
|
789
|
+
collected.selection.addRange(replaceRange);
|
|
790
|
+
return replaceRange;
|
|
791
|
+
};
|
|
792
|
+
const expandTypedShortcut = (event) => {
|
|
793
|
+
if (!macros) return;
|
|
794
|
+
const collected = collectTokenBeforeCaret();
|
|
795
|
+
if (!collected) return;
|
|
796
|
+
const lowered = collected.token.toLowerCase();
|
|
755
797
|
const macro = macros.flatMap((group) => group.macros).find((candidate) => candidate.shortcut?.toLowerCase() === lowered);
|
|
756
798
|
if (!macro) return;
|
|
757
799
|
event.preventDefault();
|
|
758
|
-
|
|
759
|
-
replaceRange.setStart(startNode, startOffset);
|
|
760
|
-
replaceRange.setEnd(node, caret.startOffset);
|
|
761
|
-
selection.removeAllRanges();
|
|
762
|
-
selection.addRange(replaceRange);
|
|
800
|
+
selectCollectedToken(collected);
|
|
763
801
|
insertTextAtSelection(macro.content);
|
|
764
802
|
};
|
|
803
|
+
const applyMarkdownShortcut = (event) => {
|
|
804
|
+
const collected = collectTokenBeforeCaret();
|
|
805
|
+
if (!collected || !collected.atLineStart) return false;
|
|
806
|
+
if (!Object.hasOwn(MARKDOWN_BLOCK_RULES, collected.token)) return false;
|
|
807
|
+
const rule = MARKDOWN_BLOCK_RULES[collected.token];
|
|
808
|
+
event.preventDefault();
|
|
809
|
+
const replaceRange = selectCollectedToken(collected);
|
|
810
|
+
let deleted = false;
|
|
811
|
+
try {
|
|
812
|
+
deleted = document.execCommand("delete", false);
|
|
813
|
+
} catch {
|
|
814
|
+
deleted = false;
|
|
815
|
+
}
|
|
816
|
+
if (!deleted) {
|
|
817
|
+
replaceRange.deleteContents();
|
|
818
|
+
replaceRange.collapse(true);
|
|
819
|
+
collected.selection.removeAllRanges();
|
|
820
|
+
collected.selection.addRange(replaceRange);
|
|
821
|
+
}
|
|
822
|
+
try {
|
|
823
|
+
document.execCommand(rule.command, false, rule.value);
|
|
824
|
+
} catch {
|
|
825
|
+
}
|
|
826
|
+
editorRef.current?.focus();
|
|
827
|
+
saveSelection();
|
|
828
|
+
updateContent();
|
|
829
|
+
return true;
|
|
830
|
+
};
|
|
831
|
+
const handleEditorKeyDown = (event) => {
|
|
832
|
+
if (disabled || event.key !== " " || // Space during IME composition selects/converts a candidate; never
|
|
833
|
+
// hijack it for shortcut expansion.
|
|
834
|
+
event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey)
|
|
835
|
+
return;
|
|
836
|
+
if (markdownShortcuts && applyMarkdownShortcut(event)) return;
|
|
837
|
+
expandTypedShortcut(event);
|
|
838
|
+
};
|
|
765
839
|
const toggleDictation = async () => {
|
|
766
840
|
const SpeechRecognition = getSpeechRecognition();
|
|
767
841
|
if (!SpeechRecognition) return;
|
|
@@ -783,6 +857,7 @@ var RichTextEditor = React2.forwardRef(
|
|
|
783
857
|
);
|
|
784
858
|
return;
|
|
785
859
|
}
|
|
860
|
+
if (!toolbarVisibleRef.current) return;
|
|
786
861
|
const recognition = new SpeechRecognition();
|
|
787
862
|
recognition.continuous = true;
|
|
788
863
|
recognition.interimResults = true;
|
|
@@ -868,7 +943,7 @@ var RichTextEditor = React2.forwardRef(
|
|
|
868
943
|
className
|
|
869
944
|
),
|
|
870
945
|
children: [
|
|
871
|
-
/* @__PURE__ */ jsxs(
|
|
946
|
+
toolbarVisible && /* @__PURE__ */ jsxs(
|
|
872
947
|
"div",
|
|
873
948
|
{
|
|
874
949
|
"data-slot": "rich-text-editor-toolbar",
|
|
@@ -1056,7 +1131,10 @@ var RichTextEditor = React2.forwardRef(
|
|
|
1056
1131
|
size: "sm",
|
|
1057
1132
|
onClick: toggleDictation,
|
|
1058
1133
|
disabled: disabled || !speechSupported,
|
|
1059
|
-
className: cn(
|
|
1134
|
+
className: cn(
|
|
1135
|
+
"h-8 gap-1 px-2",
|
|
1136
|
+
isListening && "animate-pulse"
|
|
1137
|
+
),
|
|
1060
1138
|
title: !speechSupported ? "Speech recognition not supported in this browser" : isListening ? "Stop dictation" : "Start dictation",
|
|
1061
1139
|
children: [
|
|
1062
1140
|
isListening ? /* @__PURE__ */ jsx(MicOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4" }),
|
|
@@ -1119,7 +1197,7 @@ var RichTextEditor = React2.forwardRef(
|
|
|
1119
1197
|
onPaste: handlePaste,
|
|
1120
1198
|
onDrop: handleDrop,
|
|
1121
1199
|
onBlur: hasMacros ? saveSelection : void 0,
|
|
1122
|
-
onKeyDown: hasMacros ?
|
|
1200
|
+
onKeyDown: hasMacros || markdownShortcuts ? handleEditorKeyDown : void 0,
|
|
1123
1201
|
onKeyUp: hasMacros ? saveSelection : void 0,
|
|
1124
1202
|
onMouseUp: hasMacros ? saveSelection : void 0,
|
|
1125
1203
|
className: cn(
|
|
@@ -1159,5 +1237,5 @@ var RichTextEditor = React2.forwardRef(
|
|
|
1159
1237
|
RichTextEditor.displayName = "RichTextEditor";
|
|
1160
1238
|
|
|
1161
1239
|
export { MacroLibrary, RichTextEditor, convertAngleBracketsToMustache, processDictation };
|
|
1162
|
-
//# sourceMappingURL=chunk-
|
|
1163
|
-
//# sourceMappingURL=chunk-
|
|
1240
|
+
//# sourceMappingURL=chunk-IYY7NKA3.js.map
|
|
1241
|
+
//# sourceMappingURL=chunk-IYY7NKA3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/MacroLibrary/MacroLibrary.tsx","../src/components/RichTextEditor/processDictation.ts","../src/components/RichTextEditor/RichTextEditor.tsx"],"names":["React","MacroLibrary","jsxs","jsx","Fragment","BookOpen"],"mappings":"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","file":"chunk-IYY7NKA3.js","sourcesContent":["import * as React from 'react';\nimport {\n SearchIcon,\n HistoryIcon,\n BookOpenIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n CloseIcon,\n PlusIcon,\n} from '../Icons';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\n\nexport interface Macro {\n /** Stable identifier. */\n id: string;\n /** Human-readable name shown in the list. */\n label: string;\n /** Plain text inserted into the editor. `\\n` is preserved. */\n content: string;\n /** Optional shortcut identifier shown as a badge (e.g. `.b`). */\n shortcut?: string;\n /** Extra search terms that are not displayed. */\n keywords?: string[];\n}\n\nexport interface MacroGroup {\n /** Stable identifier. */\n id: string;\n /** Group heading (e.g. \"Default library\"). */\n label: string;\n /**\n * `previous` renders the group visually distinct from library macros\n * (history icon, muted header) so prior values are never mistaken for\n * predefined content. Defaults to `library`.\n */\n kind?: 'library' | 'previous';\n /** Macros belonging to the group. */\n macros: Macro[];\n}\n\nexport interface MacroLibraryProps {\n /** Grouped macros supplied by the application. */\n groups: MacroGroup[];\n /** Called with the chosen macro. The caller performs the insertion. */\n onSelect: (macro: Macro) => void;\n /** Id for the panel root (e.g. the target of a toggle's aria-controls). */\n id?: string;\n /**\n * Name of the insertion target shown in the header (e.g. the editor's\n * label), rendered as \"Insert into <target>\".\n */\n targetLabel?: string;\n /** When provided, renders a close button and enables Escape-to-close. */\n onClose?: () => void;\n /** When provided, renders a \"Save as macro\" action in the footer. */\n onCreateMacro?: () => void;\n /** Autofocus the search input on mount. Defaults to false. */\n autoFocusSearch?: boolean;\n /** Additional class for the panel root. */\n className?: string;\n /** Overridable labels for i18n. */\n labels?: Partial<typeof DEFAULT_LABELS>;\n}\n\nconst DEFAULT_LABELS = {\n insertInto: 'Insert into',\n macros: 'Macros',\n searchPlaceholder: 'Search macros…',\n searchLabel: 'Search macros',\n close: 'Close macros',\n createMacro: 'Save as macro',\n empty: 'No macros available',\n emptyHint: 'The application has not provided a macro list.',\n noResults: 'No macros match',\n clearSearch: 'Clear search',\n showFullContent: 'Show full content',\n hideFullContent: 'Hide full content',\n more: 'more',\n less: 'less',\n};\n\n/** Case-insensitive match across label, shortcut, keywords and content. */\nfunction matchesQuery(macro: Macro, query: string): boolean {\n const q = query.toLowerCase();\n return (\n macro.label.toLowerCase().includes(q) ||\n (macro.shortcut ?? '').toLowerCase().includes(q) ||\n (macro.keywords ?? []).some((k) => k.toLowerCase().includes(q)) ||\n macro.content.toLowerCase().includes(q)\n );\n}\n\n/** Query is a prefix of the macro's shortcut identifier. */\nfunction isShortcutHit(macro: Macro, query: string): boolean {\n return (\n query.length > 0 &&\n (macro.shortcut ?? '').toLowerCase().startsWith(query.toLowerCase())\n );\n}\n\n/** Shortcut-prefix matches rank before everything else. */\nfunction rankMacros(macros: Macro[], query: string): Macro[] {\n return [...macros].sort(\n (a, b) => Number(isShortcutHit(b, query)) - Number(isShortcutHit(a, query))\n );\n}\n\ninterface MacroRowProps {\n macro: Macro;\n isPrevious: boolean;\n isPeeked: boolean;\n peekId: string;\n labels: typeof DEFAULT_LABELS;\n onSelect: (macro: Macro) => void;\n onTogglePeek: () => void;\n onRowKeyDown: (event: React.KeyboardEvent) => void;\n}\n\n/**\n * One macro row. The two-line preview measures its own clamping so the\n * \"more\" toggle only appears when content is actually truncated.\n */\nfunction MacroRow({\n macro,\n isPrevious,\n isPeeked,\n peekId,\n labels,\n onSelect,\n onTogglePeek,\n onRowKeyDown,\n}: MacroRowProps) {\n const [truncated, setTruncated] = React.useState(false);\n const rowRef = React.useRef<HTMLButtonElement>(null);\n const lessRef = React.useRef<HTMLButtonElement>(null);\n // Toggling unmounts the activated control; move focus to its replacement\n // (\"less\" on expand, the row on collapse — the \"more\" chip is hidden until\n // hover/focus) so keyboard focus never drops to <body> and Escape keeps\n // closing the panel.\n const focusAfterToggle = React.useRef(false);\n React.useEffect(() => {\n if (!focusAfterToggle.current) return;\n focusAfterToggle.current = false;\n (isPeeked ? lessRef.current : rowRef.current)?.focus();\n }, [isPeeked]);\n const handleToggle = () => {\n focusAfterToggle.current = true;\n onTogglePeek();\n };\n // Remeasure on resize: docking/undocking or narrowing the panel can clamp\n // content without a React render.\n const previewObserver = React.useRef<ResizeObserver | null>(null);\n const measurePreview = (el: HTMLSpanElement | null) => {\n previewObserver.current?.disconnect();\n previewObserver.current = null;\n if (!el) return;\n const measure = () => setTruncated(el.scrollHeight > el.clientHeight);\n measure();\n if (typeof ResizeObserver !== 'undefined') {\n previewObserver.current = new ResizeObserver(measure);\n previewObserver.current.observe(el);\n }\n };\n return (\n <div\n data-slot=\"macro-library-item\"\n className=\"group/macro hover:bg-muted/60 relative rounded-md\"\n >\n <button\n type=\"button\"\n data-macro-row\n ref={rowRef}\n className=\"focus-visible:ring-ring text-foreground hover:text-primary flex w-full cursor-pointer flex-col items-stretch gap-0.5 rounded-md px-2 py-1.5 text-start focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => onSelect(macro)}\n onKeyDown={onRowKeyDown}\n >\n <span className=\"flex items-center gap-2\">\n {macro.shortcut && (\n <span\n // Shortcuts are typed sequences; keep them LTR in RTL locales.\n dir=\"ltr\"\n className={cn(\n 'border-border bg-background text-muted-foreground rounded border px-1 font-mono text-[11px]',\n isPrevious &&\n 'border-warning-300 bg-warning-50 text-warning-800 dark:border-warning-700 dark:bg-warning-950 dark:text-warning-300'\n )}\n >\n {macro.shortcut}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {macro.label}\n </span>\n </span>\n {!isPeeked && (\n <span\n ref={measurePreview}\n className=\"text-muted-foreground line-clamp-2 text-xs break-words\"\n >\n {macro.content}\n </span>\n )}\n </button>\n {isPeeked && (\n <div\n id={peekId}\n data-slot=\"macro-library-peek\"\n className=\"text-muted-foreground px-2 pb-1 text-xs break-words whitespace-pre-line\"\n >\n {macro.content}\n </div>\n )}\n {truncated && !isPeeked && (\n // Overlays the end of the clamped second line; revealed on row\n // hover or keyboard focus so short rows stay entirely clean. Always\n // visible on devices without hover (touch).\n <button\n type=\"button\"\n className=\"bg-muted text-muted-foreground hover:text-primary focus-visible:ring-ring invisible absolute end-1.5 bottom-1.5 flex cursor-pointer items-center rounded-sm px-1 text-[11px] leading-4 group-focus-within/macro:visible group-hover/macro:visible hover:underline focus-visible:ring-2 focus-visible:outline-none [@media(hover:none)]:visible\"\n aria-expanded={false}\n aria-label={`${labels.showFullContent}: ${macro.label}`}\n onClick={handleToggle}\n >\n {labels.more}\n <ChevronRightIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3 rtl:-scale-x-100\"\n />\n </button>\n )}\n {isPeeked && (\n <span className=\"-mt-1 flex justify-end px-2 pb-1\">\n <button\n type=\"button\"\n ref={lessRef}\n className=\"text-muted-foreground hover:text-primary focus-visible:ring-ring cursor-pointer rounded text-[11px] hover:underline focus-visible:ring-2 focus-visible:outline-none\"\n aria-expanded\n aria-controls={peekId}\n aria-label={`${labels.hideFullContent}: ${macro.label}`}\n onClick={handleToggle}\n >\n {labels.less}\n </button>\n </span>\n )}\n </div>\n );\n}\n\n/**\n * A searchable, grouped macro browser designed to dock inside an editor's\n * chrome. Editor-agnostic: selecting a macro calls `onSelect` and the host\n * performs the insertion. Previous-value groups (`kind: 'previous'`) are\n * rendered distinctly from library macros. All rows and controls are real\n * buttons with roving arrow-key focus from the search input.\n */\nexport const MacroLibrary = React.forwardRef<HTMLDivElement, MacroLibraryProps>(\n function MacroLibrary(\n {\n groups,\n onSelect,\n id,\n targetLabel,\n onClose,\n onCreateMacro,\n autoFocusSearch = false,\n className,\n labels: labelOverrides,\n },\n ref\n ) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides };\n const [query, setQuery] = React.useState('');\n const [collapsed, setCollapsed] = React.useState<Record<string, boolean>>(\n {}\n );\n const [peeked, setPeeked] = React.useState<string | null>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const searchRef = React.useRef<HTMLInputElement>(null);\n const panelId = React.useId();\n\n React.useEffect(() => {\n if (autoFocusSearch) searchRef.current?.focus();\n }, [autoFocusSearch]);\n\n const trimmed = query.trim();\n const searching = trimmed.length > 0;\n\n const visibleGroups = groups\n .map((group) => ({\n ...group,\n macros: searching\n ? rankMacros(\n group.macros.filter((m) => matchesQuery(m, trimmed)),\n trimmed\n )\n : group.macros,\n }))\n .filter((group) => group.macros.length > 0)\n // Groups containing shortcut-prefix hits rank first so \".c\" reaches\n // the macro with that shortcut before incidental content matches in\n // earlier groups; the stable sort keeps group context otherwise.\n .sort(\n (a, b) =>\n Number(b.macros.some((m) => isShortcutHit(m, trimmed))) -\n Number(a.macros.some((m) => isShortcutHit(m, trimmed)))\n );\n\n const hasMacros = groups.some((g) => g.macros.length > 0);\n const noResults = hasMacros && searching && visibleGroups.length === 0;\n\n /** Roving focus across visible macro-row buttons. */\n const moveFocus = (delta: 1 | -1) => {\n const rows = Array.from(\n listRef.current?.querySelectorAll<HTMLButtonElement>(\n '[data-macro-row]'\n ) ?? []\n );\n if (rows.length === 0) return;\n const index = rows.findIndex((row) => row === document.activeElement);\n if (index === -1) {\n rows[delta === 1 ? 0 : rows.length - 1].focus();\n return;\n }\n const next = index + delta;\n if (next < 0) {\n searchRef.current?.focus();\n return;\n }\n rows[Math.min(next, rows.length - 1)].focus();\n };\n\n const handlePanelKeyDown = (event: React.KeyboardEvent) => {\n // Escape during IME composition cancels the composition; never close.\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'Escape' && onClose) {\n event.stopPropagation();\n onClose();\n }\n };\n\n const handleSearchKeyDown = (event: React.KeyboardEvent) => {\n // ArrowDown during IME composition navigates conversion candidates.\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n moveFocus(1);\n }\n };\n\n const handleRowKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n moveFocus(1);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n moveFocus(-1);\n }\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- keydown only delegates Escape-to-close from focusable children\n <div\n ref={ref}\n id={id}\n role=\"group\"\n aria-label={\n targetLabel ? `${labels.insertInto} ${targetLabel}` : labels.macros\n }\n data-slot=\"macro-library\"\n className={cn('bg-muted/20 flex min-h-0 flex-col', className)}\n onKeyDown={handlePanelKeyDown}\n >\n <div\n data-slot=\"macro-library-header\"\n className=\"border-border flex items-center justify-between gap-2 border-b px-3 py-2\"\n >\n <span className=\"text-muted-foreground min-w-0 truncate text-xs\">\n {targetLabel ? (\n <>\n {labels.insertInto}{' '}\n <span className=\"text-foreground font-semibold\">\n {targetLabel}\n </span>\n </>\n ) : (\n labels.macros\n )}\n </span>\n {onClose && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 shrink-0 p-0\"\n onClick={onClose}\n aria-label={labels.close}\n >\n <CloseIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n\n {hasMacros ? (\n <>\n <div className=\"px-3 pt-2\">\n <div className=\"relative\">\n <SearchIcon\n aria-hidden=\"true\"\n className=\"text-muted-foreground pointer-events-none absolute start-2.5 top-1/2 z-10 h-3.5 w-3.5 -translate-y-1/2\"\n />\n <Input\n ref={searchRef}\n label={labels.searchLabel}\n hideLabel\n size=\"sm\"\n type=\"search\"\n placeholder={labels.searchPlaceholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={handleSearchKeyDown}\n className=\"ps-8\"\n aria-controls={`${panelId}-list`}\n />\n </div>\n </div>\n\n {/* Persistent polite region so a failed search is announced. */}\n <div role=\"status\" className=\"sr-only\">\n {noResults ? `${labels.noResults} “${trimmed}”` : ''}\n </div>\n\n <div\n ref={listRef}\n id={`${panelId}-list`}\n data-slot=\"macro-library-list\"\n className=\"min-h-0 flex-1 overflow-y-auto p-1.5\"\n >\n {noResults && (\n <div className=\"text-muted-foreground px-2 py-8 text-center text-sm\">\n <p>\n {labels.noResults} “{trimmed}”\n </p>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={() => {\n setQuery('');\n searchRef.current?.focus();\n }}\n >\n {labels.clearSearch}\n </Button>\n </div>\n )}\n\n {visibleGroups.map((group) => {\n const isPrevious = group.kind === 'previous';\n // Strict check: ids like \"constructor\" must not read\n // inherited Object.prototype members as collapsed state.\n const isCollapsed = !searching && collapsed[group.id] === true;\n const GroupIcon = isPrevious ? HistoryIcon : BookOpenIcon;\n return (\n <div\n key={group.id}\n data-slot=\"macro-library-group\"\n data-kind={group.kind ?? 'library'}\n >\n <button\n type=\"button\"\n className={cn(\n 'text-muted-foreground hover:text-foreground flex w-full items-center gap-1.5 rounded px-2 pt-2.5 pb-1 text-start text-[11px] font-semibold tracking-wide uppercase',\n isPrevious && 'text-warning-700 dark:text-warning-400'\n )}\n aria-expanded={!isCollapsed}\n disabled={searching}\n onClick={() =>\n setCollapsed((prev) => ({\n ...prev,\n [group.id]: prev[group.id] !== true,\n }))\n }\n >\n <GroupIcon aria-hidden=\"true\" className=\"h-3 w-3\" />\n <span className=\"min-w-0 flex-1 truncate\">\n {group.label}\n </span>\n {!searching &&\n (isCollapsed ? (\n <ChevronRightIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n />\n ) : (\n <ChevronDownIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n />\n ))}\n </button>\n\n {!isCollapsed &&\n group.macros.map((macro) => {\n const isPeeked = peeked === macro.id;\n return (\n <MacroRow\n key={macro.id}\n macro={macro}\n isPrevious={isPrevious}\n isPeeked={isPeeked}\n peekId={`${panelId}-peek-${macro.id}`}\n labels={labels}\n onSelect={onSelect}\n onTogglePeek={() =>\n setPeeked(isPeeked ? null : macro.id)\n }\n onRowKeyDown={handleRowKeyDown}\n />\n );\n })}\n </div>\n );\n })}\n </div>\n </>\n ) : (\n <div className=\"text-muted-foreground flex flex-1 flex-col items-center justify-center gap-1 px-4 py-10 text-center text-sm\">\n <BookOpenIcon aria-hidden=\"true\" className=\"mb-1 h-5 w-5\" />\n <p className=\"text-foreground font-medium\">{labels.empty}</p>\n <p className=\"text-xs\">{labels.emptyHint}</p>\n </div>\n )}\n\n {onCreateMacro && (\n <div\n data-slot=\"macro-library-footer\"\n className=\"border-border border-t px-2 py-1.5\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start gap-1.5\"\n onClick={onCreateMacro}\n >\n <PlusIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {labels.createMacro}\n </Button>\n </div>\n )}\n </div>\n );\n }\n);\n","/**\n * Converts spoken punctuation words (e.g. \"period\", \"comma\") into the\n * corresponding characters, using lightweight context heuristics so that words\n * like \"time period\" or \"the colon\" are left intact. Pure and side-effect free\n * so it can be unit tested independently of the editor.\n */\nexport function processDictation(text: string): string {\n let result = text;\n\n // \"period\" as a word vs. as punctuation.\n result = result.replace(\n /\\b(the|a|this|that|each|every|same|time|grace|trial|waiting|probationary|pay|billing|accounting)\\s+period\\b/gi,\n '$1 period'\n );\n result = result.replace(\n /\\bperiod\\s+(of|in|for|from|to|during|between|after|before|when|where|is|was|will|has|had)\\b/gi,\n 'period $1'\n );\n result = result.replace(/\\s+period(\\s*$)/gi, '.$1');\n result = result.replace(/\\s+period\\s+(?=[A-Z])/g, '. ');\n\n // \"comma\"\n result = result.replace(/\\bcomma\\s+(separated|delimited)/gi, 'comma $1');\n result = result.replace(/\\s+comma\\b/gi, ',');\n\n // \"colon\"\n result = result.replace(\n /\\b(the|a|my|your|his|her|their|semicolon|ascending|descending|transverse|sigmoid)\\s+colon\\b/gi,\n '$1 colon'\n );\n result = result.replace(\n /\\bcolon\\s+(cancer|surgery|health|polyp|scope|oscopy)/gi,\n 'colon $1'\n );\n result = result.replace(/\\s+colon\\b/gi, ':');\n\n // \"dash\"\n result = result.replace(\n /\\b(yard|meter|hundred|mad|quick|wild)\\s+dash\\b/gi,\n '$1 dash'\n );\n result = result.replace(/\\bdash\\s+(to|for|of)\\b/gi, 'dash $1');\n result = result.replace(/\\s+dash\\b/gi, ' -');\n\n const simplePunctuation: Record<string, string> = {\n ' full stop': '.',\n ' question mark': '?',\n ' exclamation point': '!',\n ' exclamation mark': '!',\n ' semicolon': ';',\n ' semi colon': ';',\n ' hyphen': '-',\n ' open parenthesis': ' (',\n ' close parenthesis': ')',\n ' open bracket': ' [',\n ' close bracket': ']',\n ' open quote': ' \"',\n ' close quote': '\"',\n ' quote': '\"',\n ' apostrophe': \"'\",\n ' new line': '\\n',\n ' newline': '\\n',\n ' new paragraph': '\\n\\n',\n ' tab': '\\t',\n };\n\n for (const [spoken, punctuation] of Object.entries(simplePunctuation)) {\n const regex = new RegExp(spoken, 'gi');\n result = result.replace(regex, punctuation);\n }\n\n // Capitalize after sentence-ending punctuation.\n result = result.replace(\n /([.!?])\\s+([a-z])/g,\n (_match, punct: string, letter: string) =>\n `${punct} ${letter.toUpperCase()}`\n );\n\n return result;\n}\n\n/**\n * Converts `<<field>>` (and the HTML-encoded `<<field>>`) syntax\n * into mustache `{{field}}` syntax. Pure helper operating on an HTML string.\n */\nexport function convertAngleBracketsToMustache(html: string): string {\n return html\n .replace(\n /<<([^&]*)>>/g,\n (_m, field: string) => `{{${field.trim()}}}`\n )\n .replace(/<<([^>]*)>>/g, (_m, field: string) => `{{${field.trim()}}}`);\n}\n\n/**\n * Returns true when an HTML string has no visible text content.\n * Note: This is a visibility check, not a sanitizer. It strips tags to inspect\n * remaining text — do NOT use this for XSS prevention.\n */\nexport { isHtmlEmpty } from '../../utils/html';\n","import * as React from 'react';\nimport {\n Bold,\n Italic,\n Underline,\n List,\n ListOrdered,\n AlignLeft,\n AlignCenter,\n AlignRight,\n Braces,\n Replace,\n Mic,\n MicOff,\n BookOpen,\n} from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Separator } from '../Separator';\nimport {\n MacroLibrary,\n type Macro,\n type MacroGroup,\n type MacroLibraryProps,\n} from '../MacroLibrary';\nimport {\n Dropdown,\n DropdownItem,\n DropdownLabel,\n DropdownSeparator,\n} from '../Dropdown';\nimport {\n processDictation,\n convertAngleBracketsToMustache,\n isHtmlEmpty,\n} from './processDictation';\n\nexport interface RichTextVariable {\n /** Human-readable label shown in the variable menu. */\n label: string;\n /** The token displayed for the variable (e.g. `{{employee.name}}`). */\n value: string;\n /** Optional text inserted instead of `value` (e.g. an expanded group). */\n insertValue?: string;\n}\n\nexport interface RichTextVariableGroup {\n /** Group heading shown in the variable menu. */\n label: string;\n /** Variables belonging to the group. */\n variables: RichTextVariable[];\n}\n\nexport interface RichTextEditorProps {\n /** Current HTML value of the editor. */\n value: string;\n /** Called with the updated HTML whenever the content changes. */\n onChange: (value: string) => void;\n /** Placeholder shown when the editor is empty. */\n placeholder?: string;\n /** Additional class for the editor wrapper. */\n className?: string;\n /**\n * Variable groups for the \"Insert variable\" menu. When omitted the variable\n * menu and the `<< >>` → `{{ }}` convert button are hidden.\n */\n variableGroups?: RichTextVariableGroup[];\n /** Enable the speech-to-text dictation button. Defaults to true. */\n enableDictation?: boolean;\n /** Called when dictation cannot start (replaces native alerts). */\n onDictationError?: (message: string) => void;\n /** Disable editing and toolbar actions. */\n disabled?: boolean;\n /**\n * Sanitises HTML introduced by paste or drop before it reaches the editable\n * DOM. Without it, pasted markup is inserted as the browser provides it.\n */\n sanitizeHtml?: (html: string) => string;\n /**\n * Grouped macros for the optional macro addon. When omitted the editor is\n * unchanged. When provided, a \"Macros\" toolbar toggle docks a searchable\n * macro panel inside the editor; selecting a macro inserts its content at\n * the retained caret position. Typing a macro shortcut (e.g. `.b`)\n * followed by a space expands it in place, panel open or not.\n */\n macros?: MacroGroup[];\n /** Open the macro panel initially. Defaults to false. */\n defaultMacrosOpen?: boolean;\n /**\n * Overridable labels for the macro addon (i18n). Panel labels are\n * forwarded to the docked `MacroLibrary`; `macros` doubles as the toolbar\n * toggle text, and `showMacros`/`hideMacros` set the toggle's title.\n */\n macroLabels?: MacroLibraryProps['labels'] & {\n /** Toggle title while the panel is closed. Defaults to \"Show macros\". */\n showMacros?: string;\n /** Toggle title while the panel is open. Defaults to \"Hide macros\". */\n hideMacros?: string;\n };\n /** Forwarded to the macro panel's \"Save as macro\" action. */\n onCreateMacro?: () => void;\n /**\n * Toolbar visibility. `'hidden'` removes the toolbar entirely for\n * chromeless surfaces (typed shortcuts keep working; pair with\n * `markdownShortcuts` so formatting stays reachable). Defaults to\n * `'visible'` — existing consumers are unchanged.\n */\n toolbar?: 'visible' | 'hidden';\n /**\n * Expand markdown-style block shortcuts typed at the start of a line and\n * followed by a space: `#`/`##`/`###` → headings, `-`/`*` → bullet list,\n * `1.` → numbered list, `>` → block quote. Inline rules (`**bold**`) are\n * not interpreted. Defaults to false.\n */\n markdownShortcuts?: boolean;\n /** Accessible label for the editable region. */\n 'aria-label'?: string;\n}\n\n// --- Minimal Web Speech API typings (absent from the standard DOM lib) ---\ninterface SpeechRecognitionAlternativeLike {\n transcript: string;\n}\ninterface SpeechRecognitionResultLike {\n isFinal: boolean;\n [index: number]: SpeechRecognitionAlternativeLike;\n}\ninterface SpeechRecognitionResultListLike {\n length: number;\n [index: number]: SpeechRecognitionResultLike;\n}\ninterface SpeechRecognitionEventLike {\n resultIndex: number;\n results: SpeechRecognitionResultListLike;\n}\ninterface SpeechRecognitionErrorEventLike {\n error: string;\n}\ninterface SpeechRecognitionLike {\n continuous: boolean;\n interimResults: boolean;\n lang: string;\n maxAlternatives: number;\n onstart: (() => void) | null;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;\n onend: (() => void) | null;\n start: () => void;\n stop: () => void;\n}\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\ninterface SpeechWindow {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n}\n\nfunction getSpeechRecognition(): SpeechRecognitionCtor | undefined {\n const w = window as unknown as SpeechWindow;\n return w.SpeechRecognition || w.webkitSpeechRecognition;\n}\n\n/** Elements that end a visible word, equivalent to whitespace. */\nconst BLOCK_BOUNDARY =\n /^(BR|DIV|P|LI|UL|OL|TABLE|TR|TD|TH|H[1-6]|BLOCKQUOTE|PRE|HR)$/;\n\n/**\n * Markdown-style block tokens expanded on space at the start of a line.\n * Values feed `document.execCommand`; block rules only — inline markdown\n * (e.g. `**bold**`) is intentionally not interpreted.\n */\nconst MARKDOWN_BLOCK_RULES: Record<\n string,\n { command: string; value?: string }\n> = {\n '#': { command: 'formatBlock', value: 'h1' },\n '##': { command: 'formatBlock', value: 'h2' },\n '###': { command: 'formatBlock', value: 'h3' },\n '-': { command: 'insertUnorderedList' },\n '*': { command: 'insertUnorderedList' },\n '1.': { command: 'insertOrderedList' },\n '>': { command: 'formatBlock', value: 'blockquote' },\n};\n\n/**\n * Last non-empty text node rendered inside `node`, or 'boundary' when it\n * ends with a line break or block element.\n */\nfunction lastTextWithin(node: Node): Text | 'boundary' | null {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').length > 0 ? (node as Text) : null;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return null;\n if (BLOCK_BOUNDARY.test((node as HTMLElement).tagName)) return 'boundary';\n for (let child = node.lastChild; child; child = child.previousSibling) {\n const found = lastTextWithin(child);\n if (found) return found;\n }\n return null;\n}\n\n/**\n * Previous visible text node before `node`, looking across adjacent inline\n * elements (e.g. the \".\" in `.<b>c</b>` precedes the \"c\"). Returns null at\n * a block/line-break boundary or the editor root, where a word cannot\n * continue.\n */\nfunction previousVisibleText(node: Node, root: HTMLElement): Text | null {\n let current: Node = node;\n while (current !== root) {\n let sibling: Node | null = current.previousSibling;\n while (sibling) {\n const found = lastTextWithin(sibling);\n if (found === 'boundary') return null;\n if (found) return found;\n sibling = sibling.previousSibling;\n }\n const parent: Node | null = current.parentNode;\n if (!parent) return null;\n if (\n parent !== root &&\n parent.nodeType === Node.ELEMENT_NODE &&\n BLOCK_BOUNDARY.test((parent as HTMLElement).tagName)\n ) {\n return null;\n }\n current = parent;\n }\n return null;\n}\n\n/**\n * A presentational rich-text editor with formatting, template-variable\n * insertion and optional speech-to-text dictation. Content is supplied and\n * surfaced via `value`/`onChange` so it can be wired to any store. The variable\n * menu is data-agnostic — pass `variableGroups` to populate it.\n */\nconst RichTextEditor = React.forwardRef<HTMLDivElement, RichTextEditorProps>(\n (\n {\n value,\n onChange,\n placeholder,\n className,\n variableGroups,\n enableDictation = true,\n onDictationError,\n disabled = false,\n sanitizeHtml,\n macros,\n defaultMacrosOpen = false,\n macroLabels,\n onCreateMacro,\n toolbar = 'visible',\n markdownShortcuts = false,\n 'aria-label': ariaLabel,\n },\n ref\n ) => {\n const editorRef = React.useRef<HTMLDivElement>(null);\n const [isListening, setIsListening] = React.useState(false);\n const [speechSupported, setSpeechSupported] = React.useState(false);\n const recognitionRef = React.useRef<SpeechRecognitionLike | null>(null);\n const isListeningRef = React.useRef(false);\n const shouldRestartRef = React.useRef(false);\n const [macrosOpen, setMacrosOpen] = React.useState(defaultMacrosOpen);\n // Last caret/selection inside the editable region, retained while the\n // macro panel has focus so insertion lands where the clinician left off.\n const savedRangeRef = React.useRef<Range | null>(null);\n const macroPanelId = React.useId();\n\n const hasVariables = Boolean(variableGroups && variableGroups.length > 0);\n const hasMacros = Boolean(macros);\n const isEmpty = isHtmlEmpty(value);\n const toolbarVisible = toolbar !== 'hidden';\n // Mirrored into a ref so async dictation code can read the live value\n // after awaiting microphone permission.\n const toolbarVisibleRef = React.useRef(toolbarVisible);\n\n React.useImperativeHandle(ref, () => editorRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n setSpeechSupported(Boolean(getSpeechRecognition()));\n }, []);\n\n React.useEffect(() => {\n return () => {\n if (recognitionRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n }\n };\n }, []);\n\n // Hiding the toolbar removes the Stop control and listening indicator,\n // so a running dictation must not keep inserting text (and restarting\n // through onend) with no way to stop it.\n React.useEffect(() => {\n toolbarVisibleRef.current = toolbarVisible;\n if (toolbarVisible) return;\n if (recognitionRef.current && isListeningRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n setIsListening(false);\n }\n }, [toolbarVisible]);\n\n React.useEffect(() => {\n if (editorRef.current && editorRef.current.innerHTML !== value) {\n editorRef.current.innerHTML = value;\n }\n }, [value]);\n\n const updateContent = () => {\n if (editorRef.current) onChange(editorRef.current.innerHTML);\n };\n\n // Pasted/dropped HTML otherwise lands in the live DOM unfiltered, where\n // hostile markup (position:fixed overlays, host CSS classes) is active.\n const insertSanitized = (html: string) => {\n if (!sanitizeHtml) return false;\n document.execCommand('insertHTML', false, sanitizeHtml(html));\n updateContent();\n return true;\n };\n const handlePaste = (e: React.ClipboardEvent) => {\n const html = e.clipboardData.getData('text/html');\n if (html && sanitizeHtml) {\n e.preventDefault();\n insertSanitized(html);\n }\n };\n const handleDrop = (e: React.DragEvent) => {\n const html = e.dataTransfer.getData('text/html');\n if (!html || !sanitizeHtml) return;\n e.preventDefault();\n const caret = (\n document as Document & {\n caretRangeFromPoint?: (\n x: number,\n y: number\n ) => ReturnType<Document['createRange']> | null;\n }\n ).caretRangeFromPoint?.(e.clientX, e.clientY);\n if (caret) {\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(caret);\n }\n editorRef.current?.focus();\n insertSanitized(html);\n };\n\n const execCommand = (command: string) => {\n if (disabled) return;\n document.execCommand(command, false);\n editorRef.current?.focus();\n updateContent();\n };\n\n const handleConvertToMustache = () => {\n if (disabled || !editorRef.current) return;\n editorRef.current.innerHTML = convertAngleBracketsToMustache(\n editorRef.current.innerHTML\n );\n updateContent();\n };\n\n const insertVariable = (variable: RichTextVariable) => {\n if (disabled || !editorRef.current) return;\n editorRef.current.focus();\n const textToInsert = variable.insertValue ?? variable.value;\n\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents();\n if (textToInsert.includes('\\n')) {\n const fragment = document.createDocumentFragment();\n const lines = textToInsert.split('\\n');\n lines.forEach((line, index) => {\n fragment.appendChild(document.createTextNode(line));\n if (index < lines.length - 1) {\n fragment.appendChild(document.createElement('br'));\n }\n });\n range.insertNode(fragment);\n range.collapse(false);\n } else {\n const textNode = document.createTextNode(textToInsert);\n range.insertNode(textNode);\n range.setStartAfter(textNode);\n range.setEndAfter(textNode);\n }\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n editorRef.current.innerHTML += textToInsert.replace(/\\n/g, '<br>');\n }\n updateContent();\n };\n\n const reportError = (message: string) => {\n if (onDictationError) onDictationError(message);\n else if (typeof console !== 'undefined') console.warn(message);\n };\n\n /** Bookmark the selection whenever it lives inside the editable region. */\n const saveSelection = () => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !editorRef.current)\n return;\n const range = selection.getRangeAt(0);\n if (editorRef.current.contains(range.commonAncestorContainer)) {\n savedRangeRef.current = range.cloneRange();\n }\n };\n\n /** Focus the editor and restore the bookmarked selection if still valid. */\n const focusRestoringSelection = () => {\n if (!editorRef.current) return;\n editorRef.current.focus();\n const saved = savedRangeRef.current;\n const selection = window.getSelection();\n if (\n saved &&\n selection &&\n editorRef.current.contains(saved.commonAncestorContainer)\n ) {\n selection.removeAllRanges();\n selection.addRange(saved);\n }\n };\n\n const insertMacro = (macro: Macro) => {\n if (disabled || !editorRef.current) return;\n focusRestoringSelection();\n insertTextAtSelection(macro.content);\n };\n\n /**\n * Replace the current selection with plain text. execCommand participates\n * in the browser's native undo stack, so an insertion can be reverted\n * with a single undo.\n */\n const insertTextAtSelection = (content: string) => {\n let inserted = false;\n try {\n inserted = document.execCommand('insertText', false, content);\n } catch {\n inserted = false;\n }\n if (!inserted) {\n // Fallback (and jsdom path): manual range insertion. Content is\n // always inserted as text nodes, never parsed as HTML.\n const fragment = document.createDocumentFragment();\n const lines = content.split('\\n');\n lines.forEach((line, index) => {\n fragment.appendChild(document.createTextNode(line));\n if (index < lines.length - 1) {\n fragment.appendChild(document.createElement('br'));\n }\n });\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n const range = sel.getRangeAt(0);\n range.deleteContents();\n range.insertNode(fragment);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n } else if (editorRef.current) {\n editorRef.current.appendChild(fragment);\n }\n }\n saveSelection();\n updateContent();\n };\n\n /**\n * The visible word immediately before the collapsed caret, spanning\n * adjacent inline nodes (`.<b>c</b>` is \".c\"). Returns the token, the\n * range coordinates to replace it, and whether it sits at the start of\n * its line (nothing but a block boundary before it).\n */\n const collectTokenBeforeCaret = () => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !selection.isCollapsed)\n return null;\n const caret = selection.getRangeAt(0);\n const node = caret.startContainer;\n if (\n node.nodeType !== Node.TEXT_NODE ||\n !editorRef.current?.contains(node)\n )\n return null;\n const typed = /(\\S+)$/.exec(\n (node.textContent ?? '').slice(0, caret.startOffset)\n );\n if (!typed) return null;\n let token = typed[1];\n let startNode: Node = node;\n let startOffset = caret.startOffset - typed[1].length;\n while (startOffset === 0) {\n const prev = previousVisibleText(startNode, editorRef.current);\n if (!prev) break;\n const text = prev.textContent ?? '';\n const continued = /(\\S+)$/.exec(text);\n if (!continued) break;\n token = continued[1] + token;\n startNode = prev;\n startOffset = text.length - continued[1].length;\n }\n const atLineStart =\n startOffset === 0 && !previousVisibleText(startNode, editorRef.current);\n return {\n token,\n startNode,\n startOffset,\n caretNode: node,\n caretOffset: caret.startOffset,\n atLineStart,\n selection,\n };\n };\n\n /** Select `collected`'s token so the next editing command replaces it. */\n const selectCollectedToken = (\n collected: NonNullable<ReturnType<typeof collectTokenBeforeCaret>>\n ) => {\n const replaceRange = document.createRange();\n replaceRange.setStart(collected.startNode, collected.startOffset);\n replaceRange.setEnd(collected.caretNode, collected.caretOffset);\n collected.selection.removeAllRanges();\n collected.selection.addRange(replaceRange);\n return replaceRange;\n };\n\n /**\n * Expand a typed macro shortcut (dot phrase). When the word immediately\n * before the caret matches a macro shortcut and the user presses space,\n * the shortcut is replaced with the macro content in a single undoable\n * edit; the triggering space is consumed.\n */\n const expandTypedShortcut = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n if (!macros) return;\n const collected = collectTokenBeforeCaret();\n if (!collected) return;\n const lowered = collected.token.toLowerCase();\n const macro = macros\n .flatMap((group) => group.macros)\n .find((candidate) => candidate.shortcut?.toLowerCase() === lowered);\n if (!macro) return;\n\n event.preventDefault();\n selectCollectedToken(collected);\n insertTextAtSelection(macro.content);\n };\n\n /**\n * Apply a markdown block rule when the token before the caret starts its\n * line and matches `MARKDOWN_BLOCK_RULES` (`##` + space → heading). The\n * token removal and the block command both run through execCommand so\n * the expansion stays natively undoable. Returns true when handled.\n */\n const applyMarkdownShortcut = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n const collected = collectTokenBeforeCaret();\n if (!collected || !collected.atLineStart) return false;\n // Own-property check: tokens like \"constructor\" or \"toString\" resolve\n // inherited object members and must not be treated as rules.\n if (!Object.hasOwn(MARKDOWN_BLOCK_RULES, collected.token)) return false;\n const rule = MARKDOWN_BLOCK_RULES[collected.token];\n\n event.preventDefault();\n const replaceRange = selectCollectedToken(collected);\n let deleted = false;\n try {\n deleted = document.execCommand('delete', false);\n } catch {\n deleted = false;\n }\n if (!deleted) {\n // Fallback (and jsdom path): manual removal, caret at the line start.\n replaceRange.deleteContents();\n replaceRange.collapse(true);\n collected.selection.removeAllRanges();\n collected.selection.addRange(replaceRange);\n }\n try {\n document.execCommand(rule.command, false, rule.value);\n } catch {\n // jsdom: no execCommand — the token is still consumed.\n }\n editorRef.current?.focus();\n saveSelection();\n updateContent();\n return true;\n };\n\n /** Space-keydown pipeline: markdown block rules, then macro shortcuts. */\n const handleEditorKeyDown = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n if (\n disabled ||\n event.key !== ' ' ||\n // Space during IME composition selects/converts a candidate; never\n // hijack it for shortcut expansion.\n event.nativeEvent.isComposing ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey\n )\n return;\n if (markdownShortcuts && applyMarkdownShortcut(event)) return;\n expandTypedShortcut(event);\n };\n\n const toggleDictation = async () => {\n const SpeechRecognition = getSpeechRecognition();\n if (!SpeechRecognition) return;\n\n if (isListening && recognitionRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n setIsListening(false);\n return;\n }\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n stream.getTracks().forEach((track) => track.stop());\n } catch {\n reportError(\n 'Microphone access is required for dictation. Please allow microphone access in your browser settings and try again.'\n );\n return;\n }\n\n // The toolbar (and its Stop control) may have been hidden while\n // awaiting microphone permission — do not start an unstoppable session.\n if (!toolbarVisibleRef.current) return;\n\n const recognition = new SpeechRecognition();\n recognition.continuous = true;\n recognition.interimResults = true;\n recognition.lang = 'en-US';\n recognition.maxAlternatives = 1;\n\n recognition.onstart = () => {\n setIsListening(true);\n isListeningRef.current = true;\n shouldRestartRef.current = true;\n };\n\n recognition.onresult = (event) => {\n let finalTranscript = '';\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const result = event.results[i];\n if (result.isFinal) finalTranscript += result[0].transcript;\n }\n\n if (finalTranscript && editorRef.current) {\n const processedText = processDictation(finalTranscript);\n editorRef.current.focus();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents();\n const textNode = document.createTextNode(processedText + ' ');\n range.insertNode(textNode);\n range.setStartAfter(textNode);\n range.setEndAfter(textNode);\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n editorRef.current.innerHTML += processedText + ' ';\n }\n updateContent();\n }\n };\n\n recognition.onerror = (event) => {\n if (event.error === 'no-speech' || event.error === 'aborted') return;\n if (event.error === 'not-allowed') {\n reportError(\n 'Microphone access was denied. Please allow microphone access in your browser settings and try again.'\n );\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n return;\n }\n if (event.error === 'network') return;\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n };\n\n recognition.onend = () => {\n if (shouldRestartRef.current && isListeningRef.current) {\n setTimeout(() => {\n if (shouldRestartRef.current && isListeningRef.current) {\n try {\n recognition.start();\n } catch {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n }\n }\n }, 100);\n } else {\n setIsListening(false);\n }\n };\n\n recognitionRef.current = recognition;\n try {\n recognition.start();\n } catch {\n reportError('Failed to start speech recognition. Please try again.');\n }\n };\n\n const iconButtonClass = 'h-8 w-8 p-0';\n\n return (\n <div\n data-slot=\"rich-text-editor\"\n className={cn(\n 'border-border bg-background flex flex-col overflow-hidden rounded-lg border',\n className\n )}\n >\n {toolbarVisible && (\n <div\n data-slot=\"rich-text-editor-toolbar\"\n className=\"border-border bg-muted/30 sticky top-0 z-10 flex flex-wrap items-center gap-1 border-b p-2\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('bold')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Bold\"\n title=\"Bold\"\n >\n <Bold className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('italic')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Italic\"\n title=\"Italic\"\n >\n <Italic className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('underline')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Underline\"\n title=\"Underline\"\n >\n <Underline className=\"h-4 w-4\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('insertUnorderedList')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Bullet list\"\n title=\"Bullet list\"\n >\n <List className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('insertOrderedList')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Numbered list\"\n title=\"Numbered list\"\n >\n <ListOrdered className=\"h-4 w-4\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyLeft')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align left\"\n title=\"Align left\"\n >\n <AlignLeft className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyCenter')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align center\"\n title=\"Align center\"\n >\n <AlignCenter className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyRight')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align right\"\n title=\"Align right\"\n >\n <AlignRight className=\"h-4 w-4\" />\n </Button>\n\n {hasVariables && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Dropdown\n placement=\"bottom-start\"\n width={240}\n searchable\n searchPlaceholder=\"Search variables…\"\n searchAriaLabel=\"Search template variables\"\n disabled={disabled}\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 gap-1 px-2\"\n disabled={disabled}\n title=\"Insert variable\"\n >\n <Braces className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">Variables</span>\n </Button>\n }\n >\n {variableGroups!.map((group, groupIndex) => (\n <React.Fragment key={group.label}>\n {groupIndex > 0 && <DropdownSeparator />}\n <DropdownLabel>{group.label}</DropdownLabel>\n {group.variables.map((variable) => (\n <DropdownItem\n key={variable.value}\n onClick={() => insertVariable(variable)}\n >\n {variable.label}\n </DropdownItem>\n ))}\n </React.Fragment>\n ))}\n </Dropdown>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleConvertToMustache}\n disabled={disabled}\n className=\"h-8 gap-1 px-2\"\n title=\"Convert <<field>> to {{field}}\"\n >\n <Replace className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">{'<< >> to {{ }}'}</span>\n </Button>\n </>\n )}\n\n {enableDictation && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant={isListening ? 'danger' : 'ghost'}\n size=\"sm\"\n onClick={toggleDictation}\n disabled={disabled || !speechSupported}\n className={cn(\n 'h-8 gap-1 px-2',\n isListening && 'animate-pulse'\n )}\n title={\n !speechSupported\n ? 'Speech recognition not supported in this browser'\n : isListening\n ? 'Stop dictation'\n : 'Start dictation'\n }\n >\n {isListening ? (\n <MicOff className=\"h-4 w-4\" />\n ) : (\n <Mic className=\"h-4 w-4\" />\n )}\n <span className=\"ms-1 text-xs\">\n {isListening ? 'Stop' : 'Dictate'}\n </span>\n </Button>\n </>\n )}\n\n {hasMacros && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setMacrosOpen((open) => !open)}\n disabled={disabled}\n className={cn('h-8 gap-1 px-2', macrosOpen && 'bg-muted')}\n aria-expanded={macrosOpen}\n aria-controls={macrosOpen ? macroPanelId : undefined}\n title={\n macrosOpen\n ? (macroLabels?.hideMacros ?? 'Hide macros')\n : (macroLabels?.showMacros ?? 'Show macros')\n }\n >\n <BookOpen className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">\n {macroLabels?.macros ?? 'Macros'}\n </span>\n </Button>\n </>\n )}\n </div>\n )}\n\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n className={cn(\n 'relative flex-1',\n hasMacros && macrosOpen && 'md:me-72'\n )}\n >\n {isEmpty && placeholder && (\n <div\n aria-hidden=\"true\"\n className=\"text-muted-foreground pointer-events-none absolute start-0 top-0 p-4\"\n >\n {placeholder}\n </div>\n )}\n <div\n ref={editorRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel ?? placeholder}\n contentEditable={!disabled}\n tabIndex={disabled ? -1 : 0}\n onInput={updateContent}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onBlur={hasMacros ? saveSelection : undefined}\n onKeyDown={\n hasMacros || markdownShortcuts ? handleEditorKeyDown : undefined\n }\n onKeyUp={hasMacros ? saveSelection : undefined}\n onMouseUp={hasMacros ? saveSelection : undefined}\n className={cn(\n 'min-h-[250px] overflow-y-auto p-4 focus:outline-none',\n 'prose prose-sm max-w-none',\n hasMacros && macrosOpen && 'md:min-h-[400px]',\n disabled &&\n 'bg-muted/20 cursor-not-allowed text-neutral-700 dark:text-neutral-300'\n )}\n suppressContentEditableWarning\n />\n </div>\n\n {hasMacros && macrosOpen && (\n <MacroLibrary\n id={macroPanelId}\n groups={macros!}\n onSelect={insertMacro}\n targetLabel={ariaLabel ?? placeholder}\n onClose={() => {\n setMacrosOpen(false);\n // Selecting text in the panel moves the document selection;\n // put the caret back where the user left it.\n focusRestoringSelection();\n }}\n onCreateMacro={onCreateMacro}\n labels={macroLabels}\n 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\"\n />\n )}\n </div>\n </div>\n );\n }\n);\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport { RichTextEditor };\n"]}
|
|
@@ -1026,6 +1026,22 @@ var miewebUISafelist = [
|
|
|
1026
1026
|
"min-h-[76px]",
|
|
1027
1027
|
"min-h-[96px]",
|
|
1028
1028
|
"min-h-[120px]",
|
|
1029
|
+
// Textarea auto-grow default (ui#632) — single-line baselines matching the
|
|
1030
|
+
// Input heights, tuned padding so one line + padding + borders equals the
|
|
1031
|
+
// Input size token, floating-label single-line minimums, and the resize
|
|
1032
|
+
// handle variants. (min-h-8 is safelisted above.)
|
|
1033
|
+
"min-h-10",
|
|
1034
|
+
"min-h-12",
|
|
1035
|
+
"py-[5px]",
|
|
1036
|
+
"py-[7px]",
|
|
1037
|
+
"py-[9px]",
|
|
1038
|
+
"min-h-[50px]",
|
|
1039
|
+
"min-h-[58px]",
|
|
1040
|
+
"min-h-[66px]",
|
|
1041
|
+
"resize-none",
|
|
1042
|
+
"resize-y",
|
|
1043
|
+
"resize-x",
|
|
1044
|
+
"resize",
|
|
1029
1045
|
// Floating-group field boxes (labelVariant="floating" on RadioGroup /
|
|
1030
1046
|
// CheckboxGroup) share the floating input heights as min-heights. sr-only
|
|
1031
1047
|
// visually hides the group legend (and the hideLabel input label) while
|
|
@@ -1760,5 +1776,5 @@ var miewebUIPreset = {
|
|
|
1760
1776
|
var tailwind_preset_default = miewebUIPreset;
|
|
1761
1777
|
|
|
1762
1778
|
export { miewebUIPreset, miewebUISafelist, tailwind_preset_default };
|
|
1763
|
-
//# sourceMappingURL=chunk-
|
|
1764
|
-
//# sourceMappingURL=chunk-
|
|
1779
|
+
//# sourceMappingURL=chunk-V43ZWRBT.js.map
|
|
1780
|
+
//# sourceMappingURL=chunk-V43ZWRBT.js.map
|