@mieweb/ui 0.11.0-dev.23 → 0.11.0-dev.25
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-7BA7ENN5.cjs → chunk-3S5LK2EW.cjs} +346 -20
- package/dist/chunk-3S5LK2EW.cjs.map +1 -0
- package/dist/{chunk-ESXTC5GW.cjs → chunk-CY7ZRKLW.cjs} +4 -4
- package/dist/{chunk-ESXTC5GW.cjs.map → chunk-CY7ZRKLW.cjs.map} +1 -1
- package/dist/{chunk-67REGSKI.js → chunk-JTLOCREL.js} +3 -3
- package/dist/{chunk-67REGSKI.js.map → chunk-JTLOCREL.js.map} +1 -1
- package/dist/{chunk-4W3QJWG2.cjs → chunk-OCRUE3HI.cjs} +26 -3
- package/dist/chunk-OCRUE3HI.cjs.map +1 -0
- package/dist/{chunk-5EOW6AP3.js → chunk-UTSRPQ5B.js} +347 -21
- package/dist/chunk-UTSRPQ5B.js.map +1 -0
- package/dist/{chunk-V43ZWRBT.js → chunk-UY3PIO7F.js} +26 -3
- package/dist/chunk-UY3PIO7F.js.map +1 -0
- package/dist/components/EmailEditor/index.cjs +11 -11
- package/dist/components/EmailEditor/index.js +2 -2
- package/dist/components/RichTextEditor/index.cjs +4 -4
- package/dist/components/RichTextEditor/index.d.cts +61 -1
- package/dist/components/RichTextEditor/index.d.ts +61 -1
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/index.cjs +18 -18
- package/dist/index.d.cts +61 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.js +3 -3
- 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-4W3QJWG2.cjs.map +0 -1
- package/dist/chunk-5EOW6AP3.js.map +0 -1
- package/dist/chunk-7BA7ENN5.cjs.map +0 -1
- package/dist/chunk-V43ZWRBT.js.map +0 -1
|
@@ -533,6 +533,26 @@ function getSpeechRecognition() {
|
|
|
533
533
|
return w.SpeechRecognition || w.webkitSpeechRecognition;
|
|
534
534
|
}
|
|
535
535
|
var BLOCK_BOUNDARY = /^(BR|DIV|P|LI|UL|OL|TABLE|TR|TD|TH|H[1-6]|BLOCKQUOTE|PRE|HR)$/;
|
|
536
|
+
var MARKDOWN_BLOCK_RULES = {
|
|
537
|
+
"#": { command: "formatBlock", value: "h1" },
|
|
538
|
+
"##": { command: "formatBlock", value: "h2" },
|
|
539
|
+
"###": { command: "formatBlock", value: "h3" },
|
|
540
|
+
"-": { command: "insertUnorderedList" },
|
|
541
|
+
"*": { command: "insertUnorderedList" },
|
|
542
|
+
"1.": { command: "insertOrderedList" },
|
|
543
|
+
">": { command: "formatBlock", value: "blockquote" }
|
|
544
|
+
};
|
|
545
|
+
function nodeRect(node) {
|
|
546
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
547
|
+
return node.getBoundingClientRect();
|
|
548
|
+
}
|
|
549
|
+
if (node.nodeType === Node.TEXT_NODE && (node.textContent ?? "").length > 0) {
|
|
550
|
+
const range = document.createRange();
|
|
551
|
+
range.selectNodeContents(node);
|
|
552
|
+
return range.getBoundingClientRect();
|
|
553
|
+
}
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
536
556
|
function lastTextWithin(node) {
|
|
537
557
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
538
558
|
return (node.textContent ?? "").length > 0 ? node : null;
|
|
@@ -579,6 +599,12 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
579
599
|
defaultMacrosOpen = false,
|
|
580
600
|
macroLabels,
|
|
581
601
|
onCreateMacro,
|
|
602
|
+
toolbar,
|
|
603
|
+
defaultToolbar = "visible",
|
|
604
|
+
onToolbarChange,
|
|
605
|
+
blockMenu = false,
|
|
606
|
+
blockMenuLabels,
|
|
607
|
+
markdownShortcuts = false,
|
|
582
608
|
"aria-label": ariaLabel
|
|
583
609
|
}, ref) => {
|
|
584
610
|
const editorRef = React2__namespace.useRef(null);
|
|
@@ -593,6 +619,19 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
593
619
|
const hasVariables = Boolean(variableGroups && variableGroups.length > 0);
|
|
594
620
|
const hasMacros = Boolean(macros);
|
|
595
621
|
const isEmpty = chunkC7RVKV25_cjs.isHtmlEmpty(value);
|
|
622
|
+
const [uncontrolledToolbar, setUncontrolledToolbar] = React2__namespace.useState(defaultToolbar);
|
|
623
|
+
const toolbarVisible = (toolbar ?? uncontrolledToolbar) !== "hidden";
|
|
624
|
+
const setToolbarVisibility = (next) => {
|
|
625
|
+
if (toolbar === void 0) setUncontrolledToolbar(next);
|
|
626
|
+
onToolbarChange?.(next);
|
|
627
|
+
};
|
|
628
|
+
const toolbarVisibleRef = React2__namespace.useRef(toolbarVisible);
|
|
629
|
+
const [blockMenuOpen, setBlockMenuOpen] = React2__namespace.useState(false);
|
|
630
|
+
const [gutterTop, setGutterTop] = React2__namespace.useState(16);
|
|
631
|
+
const gutterWrapperRef = React2__namespace.useRef(null);
|
|
632
|
+
const hoverBlockNodeRef = React2__namespace.useRef(null);
|
|
633
|
+
const blockTargetRangeRef = React2__namespace.useRef(null);
|
|
634
|
+
const firstBlockItemRef = React2__namespace.useRef(null);
|
|
596
635
|
React2__namespace.useImperativeHandle(ref, () => editorRef.current);
|
|
597
636
|
React2__namespace.useEffect(() => {
|
|
598
637
|
setSpeechSupported(Boolean(getSpeechRecognition()));
|
|
@@ -606,6 +645,16 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
606
645
|
}
|
|
607
646
|
};
|
|
608
647
|
}, []);
|
|
648
|
+
React2__namespace.useEffect(() => {
|
|
649
|
+
toolbarVisibleRef.current = toolbarVisible;
|
|
650
|
+
if (toolbarVisible) return;
|
|
651
|
+
if (recognitionRef.current && isListeningRef.current) {
|
|
652
|
+
shouldRestartRef.current = false;
|
|
653
|
+
isListeningRef.current = false;
|
|
654
|
+
recognitionRef.current.stop();
|
|
655
|
+
setIsListening(false);
|
|
656
|
+
}
|
|
657
|
+
}, [toolbarVisible]);
|
|
609
658
|
React2__namespace.useEffect(() => {
|
|
610
659
|
if (editorRef.current && editorRef.current.innerHTML !== value) {
|
|
611
660
|
editorRef.current.innerHTML = value;
|
|
@@ -744,22 +793,18 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
744
793
|
saveSelection();
|
|
745
794
|
updateContent();
|
|
746
795
|
};
|
|
747
|
-
const
|
|
748
|
-
if (disabled || event.key !== " " || // Space during IME composition selects/converts a candidate; never
|
|
749
|
-
// hijack it for macro expansion.
|
|
750
|
-
event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey || !macros)
|
|
751
|
-
return;
|
|
796
|
+
const collectTokenBeforeCaret = () => {
|
|
752
797
|
const selection = window.getSelection();
|
|
753
798
|
if (!selection || selection.rangeCount === 0 || !selection.isCollapsed)
|
|
754
|
-
return;
|
|
799
|
+
return null;
|
|
755
800
|
const caret = selection.getRangeAt(0);
|
|
756
801
|
const node = caret.startContainer;
|
|
757
802
|
if (node.nodeType !== Node.TEXT_NODE || !editorRef.current?.contains(node))
|
|
758
|
-
return;
|
|
803
|
+
return null;
|
|
759
804
|
const typed = /(\S+)$/.exec(
|
|
760
805
|
(node.textContent ?? "").slice(0, caret.startOffset)
|
|
761
806
|
);
|
|
762
|
-
if (!typed) return;
|
|
807
|
+
if (!typed) return null;
|
|
763
808
|
let token = typed[1];
|
|
764
809
|
let startNode = node;
|
|
765
810
|
let startOffset = caret.startOffset - typed[1].length;
|
|
@@ -773,17 +818,164 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
773
818
|
startNode = prev;
|
|
774
819
|
startOffset = text.length - continued[1].length;
|
|
775
820
|
}
|
|
776
|
-
const
|
|
821
|
+
const atLineStart = startOffset === 0 && !previousVisibleText(startNode, editorRef.current);
|
|
822
|
+
return {
|
|
823
|
+
token,
|
|
824
|
+
startNode,
|
|
825
|
+
startOffset,
|
|
826
|
+
caretNode: node,
|
|
827
|
+
caretOffset: caret.startOffset,
|
|
828
|
+
atLineStart,
|
|
829
|
+
selection
|
|
830
|
+
};
|
|
831
|
+
};
|
|
832
|
+
const selectCollectedToken = (collected) => {
|
|
833
|
+
const replaceRange = document.createRange();
|
|
834
|
+
replaceRange.setStart(collected.startNode, collected.startOffset);
|
|
835
|
+
replaceRange.setEnd(collected.caretNode, collected.caretOffset);
|
|
836
|
+
collected.selection.removeAllRanges();
|
|
837
|
+
collected.selection.addRange(replaceRange);
|
|
838
|
+
return replaceRange;
|
|
839
|
+
};
|
|
840
|
+
const expandTypedShortcut = (event) => {
|
|
841
|
+
if (!macros) return;
|
|
842
|
+
const collected = collectTokenBeforeCaret();
|
|
843
|
+
if (!collected) return;
|
|
844
|
+
const lowered = collected.token.toLowerCase();
|
|
777
845
|
const macro = macros.flatMap((group) => group.macros).find((candidate) => candidate.shortcut?.toLowerCase() === lowered);
|
|
778
846
|
if (!macro) return;
|
|
779
847
|
event.preventDefault();
|
|
780
|
-
|
|
781
|
-
replaceRange.setStart(startNode, startOffset);
|
|
782
|
-
replaceRange.setEnd(node, caret.startOffset);
|
|
783
|
-
selection.removeAllRanges();
|
|
784
|
-
selection.addRange(replaceRange);
|
|
848
|
+
selectCollectedToken(collected);
|
|
785
849
|
insertTextAtSelection(macro.content);
|
|
786
850
|
};
|
|
851
|
+
const applyMarkdownShortcut = (event) => {
|
|
852
|
+
const collected = collectTokenBeforeCaret();
|
|
853
|
+
if (!collected || !collected.atLineStart) return false;
|
|
854
|
+
if (!Object.hasOwn(MARKDOWN_BLOCK_RULES, collected.token)) return false;
|
|
855
|
+
const rule = MARKDOWN_BLOCK_RULES[collected.token];
|
|
856
|
+
event.preventDefault();
|
|
857
|
+
const replaceRange = selectCollectedToken(collected);
|
|
858
|
+
let deleted = false;
|
|
859
|
+
try {
|
|
860
|
+
deleted = document.execCommand("delete", false);
|
|
861
|
+
} catch {
|
|
862
|
+
deleted = false;
|
|
863
|
+
}
|
|
864
|
+
if (!deleted) {
|
|
865
|
+
replaceRange.deleteContents();
|
|
866
|
+
replaceRange.collapse(true);
|
|
867
|
+
collected.selection.removeAllRanges();
|
|
868
|
+
collected.selection.addRange(replaceRange);
|
|
869
|
+
}
|
|
870
|
+
try {
|
|
871
|
+
document.execCommand(rule.command, false, rule.value);
|
|
872
|
+
} catch {
|
|
873
|
+
}
|
|
874
|
+
editorRef.current?.focus();
|
|
875
|
+
saveSelection();
|
|
876
|
+
updateContent();
|
|
877
|
+
return true;
|
|
878
|
+
};
|
|
879
|
+
const handleEditorKeyDown = (event) => {
|
|
880
|
+
if (disabled) return;
|
|
881
|
+
if (blockMenu && event.key === "/" && (event.ctrlKey || event.metaKey) && !event.altKey) {
|
|
882
|
+
event.preventDefault();
|
|
883
|
+
openBlockMenuAtCaret();
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
if (event.key !== " " || // Space during IME composition selects/converts a candidate; never
|
|
887
|
+
// hijack it for shortcut expansion.
|
|
888
|
+
event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey)
|
|
889
|
+
return;
|
|
890
|
+
if (markdownShortcuts && applyMarkdownShortcut(event)) return;
|
|
891
|
+
expandTypedShortcut(event);
|
|
892
|
+
};
|
|
893
|
+
const handleGutterMouseMove = (event) => {
|
|
894
|
+
if (blockMenuOpen || !editorRef.current || !gutterWrapperRef.current)
|
|
895
|
+
return;
|
|
896
|
+
let target = null;
|
|
897
|
+
let top = null;
|
|
898
|
+
for (const child of Array.from(editorRef.current.childNodes)) {
|
|
899
|
+
const rect = nodeRect(child);
|
|
900
|
+
if (!rect) continue;
|
|
901
|
+
if (rect.width === 0 && rect.height === 0) continue;
|
|
902
|
+
if (target === null || rect.top <= event.clientY) {
|
|
903
|
+
target = child;
|
|
904
|
+
top = rect.top;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
if (!target || top === null) return;
|
|
908
|
+
hoverBlockNodeRef.current = target;
|
|
909
|
+
const wrapperTop = gutterWrapperRef.current.getBoundingClientRect().top;
|
|
910
|
+
const next = Math.max(Math.round(top - wrapperTop), 4);
|
|
911
|
+
setGutterTop((current) => current === next ? current : next);
|
|
912
|
+
};
|
|
913
|
+
const rangeAtStartOf = (node) => {
|
|
914
|
+
const range = document.createRange();
|
|
915
|
+
range.setStart(node, 0);
|
|
916
|
+
range.collapse(true);
|
|
917
|
+
return range;
|
|
918
|
+
};
|
|
919
|
+
const handleBlockMenuOpenChange = (open) => {
|
|
920
|
+
if (open) {
|
|
921
|
+
const block = hoverBlockNodeRef.current ?? editorRef.current?.firstChild ?? null;
|
|
922
|
+
blockTargetRangeRef.current = block ? rangeAtStartOf(block) : null;
|
|
923
|
+
} else if (editorRef.current && document.activeElement?.closest('[role="menu"]')) {
|
|
924
|
+
const editor = editorRef.current;
|
|
925
|
+
editor.focus();
|
|
926
|
+
const target = blockTargetRangeRef.current;
|
|
927
|
+
const selection = window.getSelection();
|
|
928
|
+
if (target && selection && editor.contains(target.startContainer)) {
|
|
929
|
+
selection.removeAllRanges();
|
|
930
|
+
selection.addRange(target);
|
|
931
|
+
saveSelection();
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
setBlockMenuOpen(open);
|
|
935
|
+
};
|
|
936
|
+
const openBlockMenuAtCaret = () => {
|
|
937
|
+
const selection = window.getSelection();
|
|
938
|
+
if (selection && selection.rangeCount > 0 && editorRef.current?.contains(selection.getRangeAt(0).startContainer)) {
|
|
939
|
+
const caret = selection.getRangeAt(0);
|
|
940
|
+
blockTargetRangeRef.current = caret.cloneRange();
|
|
941
|
+
let node = caret.startContainer;
|
|
942
|
+
while (node.parentNode && node.parentNode !== editorRef.current) {
|
|
943
|
+
node = node.parentNode;
|
|
944
|
+
}
|
|
945
|
+
const rect = nodeRect(node);
|
|
946
|
+
const wrapperRect = gutterWrapperRef.current?.getBoundingClientRect();
|
|
947
|
+
if (rect && wrapperRect) {
|
|
948
|
+
setGutterTop(Math.max(Math.round(rect.top - wrapperRect.top), 4));
|
|
949
|
+
}
|
|
950
|
+
} else {
|
|
951
|
+
blockTargetRangeRef.current = null;
|
|
952
|
+
}
|
|
953
|
+
setBlockMenuOpen(true);
|
|
954
|
+
};
|
|
955
|
+
const applyBlockFormat = (command, value2) => {
|
|
956
|
+
if (disabled || !editorRef.current) return;
|
|
957
|
+
setBlockMenuOpen(false);
|
|
958
|
+
editorRef.current.focus();
|
|
959
|
+
const target = blockTargetRangeRef.current;
|
|
960
|
+
const selection = window.getSelection();
|
|
961
|
+
if (target && selection && editorRef.current.contains(target.startContainer)) {
|
|
962
|
+
selection.removeAllRanges();
|
|
963
|
+
selection.addRange(target);
|
|
964
|
+
}
|
|
965
|
+
try {
|
|
966
|
+
document.execCommand(command, false, value2);
|
|
967
|
+
} catch {
|
|
968
|
+
}
|
|
969
|
+
saveSelection();
|
|
970
|
+
updateContent();
|
|
971
|
+
};
|
|
972
|
+
React2__namespace.useEffect(() => {
|
|
973
|
+
if (!blockMenuOpen) return;
|
|
974
|
+
const frame = requestAnimationFrame(
|
|
975
|
+
() => firstBlockItemRef.current?.focus()
|
|
976
|
+
);
|
|
977
|
+
return () => cancelAnimationFrame(frame);
|
|
978
|
+
}, [blockMenuOpen]);
|
|
787
979
|
const toggleDictation = async () => {
|
|
788
980
|
const SpeechRecognition = getSpeechRecognition();
|
|
789
981
|
if (!SpeechRecognition) return;
|
|
@@ -805,6 +997,7 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
805
997
|
);
|
|
806
998
|
return;
|
|
807
999
|
}
|
|
1000
|
+
if (!toolbarVisibleRef.current) return;
|
|
808
1001
|
const recognition = new SpeechRecognition();
|
|
809
1002
|
recognition.continuous = true;
|
|
810
1003
|
recognition.interimResults = true;
|
|
@@ -881,6 +1074,43 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
881
1074
|
}
|
|
882
1075
|
};
|
|
883
1076
|
const iconButtonClass = "h-8 w-8 p-0";
|
|
1077
|
+
const blockFormatItems = [
|
|
1078
|
+
{ key: "text", label: "Text", command: "formatBlock", value: "p" },
|
|
1079
|
+
{
|
|
1080
|
+
key: "heading1",
|
|
1081
|
+
label: "Heading 1",
|
|
1082
|
+
command: "formatBlock",
|
|
1083
|
+
value: "h1"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
key: "heading2",
|
|
1087
|
+
label: "Heading 2",
|
|
1088
|
+
command: "formatBlock",
|
|
1089
|
+
value: "h2"
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
key: "heading3",
|
|
1093
|
+
label: "Heading 3",
|
|
1094
|
+
command: "formatBlock",
|
|
1095
|
+
value: "h3"
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
key: "bulletList",
|
|
1099
|
+
label: "Bullet list",
|
|
1100
|
+
command: "insertUnorderedList"
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
key: "numberedList",
|
|
1104
|
+
label: "Numbered list",
|
|
1105
|
+
command: "insertOrderedList"
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
key: "quote",
|
|
1109
|
+
label: "Quote",
|
|
1110
|
+
command: "formatBlock",
|
|
1111
|
+
value: "blockquote"
|
|
1112
|
+
}
|
|
1113
|
+
];
|
|
884
1114
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
885
1115
|
"div",
|
|
886
1116
|
{
|
|
@@ -890,7 +1120,7 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
890
1120
|
className
|
|
891
1121
|
),
|
|
892
1122
|
children: [
|
|
893
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1123
|
+
toolbarVisible && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
894
1124
|
"div",
|
|
895
1125
|
{
|
|
896
1126
|
"data-slot": "rich-text-editor-toolbar",
|
|
@@ -1078,7 +1308,10 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
1078
1308
|
size: "sm",
|
|
1079
1309
|
onClick: toggleDictation,
|
|
1080
1310
|
disabled: disabled || !speechSupported,
|
|
1081
|
-
className: chunkS5RVSXDV_cjs.cn(
|
|
1311
|
+
className: chunkS5RVSXDV_cjs.cn(
|
|
1312
|
+
"h-8 gap-1 px-2",
|
|
1313
|
+
isListening && "animate-pulse"
|
|
1314
|
+
),
|
|
1082
1315
|
title: !speechSupported ? "Speech recognition not supported in this browser" : isListening ? "Stop dictation" : "Start dictation",
|
|
1083
1316
|
children: [
|
|
1084
1317
|
isListening ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: "h-4 w-4" }),
|
|
@@ -1115,16 +1348,98 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
1115
1348
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1116
1349
|
"div",
|
|
1117
1350
|
{
|
|
1351
|
+
ref: gutterWrapperRef,
|
|
1118
1352
|
className: chunkS5RVSXDV_cjs.cn(
|
|
1119
1353
|
"relative flex-1",
|
|
1354
|
+
blockMenu && "group/rte-body",
|
|
1120
1355
|
hasMacros && macrosOpen && "md:me-72"
|
|
1121
1356
|
),
|
|
1357
|
+
onMouseMove: blockMenu && !disabled ? handleGutterMouseMove : void 0,
|
|
1122
1358
|
children: [
|
|
1359
|
+
blockMenu && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1360
|
+
"div",
|
|
1361
|
+
{
|
|
1362
|
+
"data-slot": "rich-text-editor-block-gutter",
|
|
1363
|
+
className: "absolute start-1 z-10",
|
|
1364
|
+
style: { top: gutterTop },
|
|
1365
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1366
|
+
chunkPINIBEIU_cjs.Dropdown,
|
|
1367
|
+
{
|
|
1368
|
+
open: blockMenuOpen,
|
|
1369
|
+
onOpenChange: handleBlockMenuOpenChange,
|
|
1370
|
+
placement: "bottom-start",
|
|
1371
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1372
|
+
chunkANMX7YDL_cjs.Button,
|
|
1373
|
+
{
|
|
1374
|
+
type: "button",
|
|
1375
|
+
variant: "ghost",
|
|
1376
|
+
size: "sm",
|
|
1377
|
+
className: chunkS5RVSXDV_cjs.cn(
|
|
1378
|
+
"h-6 w-6 p-0",
|
|
1379
|
+
// Revealed on hover/focus; always visible on touch,
|
|
1380
|
+
// which has no hover to reveal it with.
|
|
1381
|
+
"opacity-0 transition-opacity",
|
|
1382
|
+
"group-hover/rte-body:opacity-100",
|
|
1383
|
+
"focus-visible:opacity-100",
|
|
1384
|
+
"[@media(hover:none)]:opacity-100",
|
|
1385
|
+
blockMenuOpen && "opacity-100"
|
|
1386
|
+
),
|
|
1387
|
+
"aria-label": blockMenuLabels?.blockMenu ?? "Block menu",
|
|
1388
|
+
title: blockMenuLabels?.blockMenu ?? "Block menu",
|
|
1389
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" })
|
|
1390
|
+
}
|
|
1391
|
+
),
|
|
1392
|
+
children: [
|
|
1393
|
+
blockFormatItems.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1394
|
+
chunkPINIBEIU_cjs.DropdownItem,
|
|
1395
|
+
{
|
|
1396
|
+
ref: index === 0 ? firstBlockItemRef : void 0,
|
|
1397
|
+
onClick: () => applyBlockFormat(item.command, item.value),
|
|
1398
|
+
children: blockMenuLabels?.[item.key] ?? item.label
|
|
1399
|
+
},
|
|
1400
|
+
item.key
|
|
1401
|
+
)),
|
|
1402
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPINIBEIU_cjs.DropdownSeparator, {}),
|
|
1403
|
+
hasMacros && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1404
|
+
chunkPINIBEIU_cjs.DropdownItem,
|
|
1405
|
+
{
|
|
1406
|
+
onClick: () => {
|
|
1407
|
+
setBlockMenuOpen(false);
|
|
1408
|
+
if (blockTargetRangeRef.current) {
|
|
1409
|
+
savedRangeRef.current = blockTargetRangeRef.current;
|
|
1410
|
+
}
|
|
1411
|
+
setMacrosOpen(true);
|
|
1412
|
+
focusRestoringSelection();
|
|
1413
|
+
},
|
|
1414
|
+
children: blockMenuLabels?.insertMacro ?? "Insert macro\u2026"
|
|
1415
|
+
}
|
|
1416
|
+
),
|
|
1417
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1418
|
+
chunkPINIBEIU_cjs.DropdownItem,
|
|
1419
|
+
{
|
|
1420
|
+
onClick: () => {
|
|
1421
|
+
setBlockMenuOpen(false);
|
|
1422
|
+
setToolbarVisibility(
|
|
1423
|
+
toolbarVisible ? "hidden" : "visible"
|
|
1424
|
+
);
|
|
1425
|
+
editorRef.current?.focus();
|
|
1426
|
+
},
|
|
1427
|
+
children: toolbarVisible ? blockMenuLabels?.hideToolbar ?? "Hide toolbar" : blockMenuLabels?.showToolbar ?? "Show toolbar"
|
|
1428
|
+
}
|
|
1429
|
+
)
|
|
1430
|
+
]
|
|
1431
|
+
}
|
|
1432
|
+
)
|
|
1433
|
+
}
|
|
1434
|
+
),
|
|
1123
1435
|
isEmpty && placeholder && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1124
1436
|
"div",
|
|
1125
1437
|
{
|
|
1126
1438
|
"aria-hidden": "true",
|
|
1127
|
-
className:
|
|
1439
|
+
className: chunkS5RVSXDV_cjs.cn(
|
|
1440
|
+
"text-muted-foreground pointer-events-none absolute start-0 top-0 p-4",
|
|
1441
|
+
blockMenu && "ps-10"
|
|
1442
|
+
),
|
|
1128
1443
|
children: placeholder
|
|
1129
1444
|
}
|
|
1130
1445
|
),
|
|
@@ -1141,12 +1456,23 @@ var RichTextEditor = React2__namespace.forwardRef(
|
|
|
1141
1456
|
onPaste: handlePaste,
|
|
1142
1457
|
onDrop: handleDrop,
|
|
1143
1458
|
onBlur: hasMacros ? saveSelection : void 0,
|
|
1144
|
-
onKeyDown: hasMacros ?
|
|
1459
|
+
onKeyDown: hasMacros || markdownShortcuts || blockMenu ? handleEditorKeyDown : void 0,
|
|
1145
1460
|
onKeyUp: hasMacros ? saveSelection : void 0,
|
|
1146
1461
|
onMouseUp: hasMacros ? saveSelection : void 0,
|
|
1147
1462
|
className: chunkS5RVSXDV_cjs.cn(
|
|
1148
1463
|
"min-h-[250px] overflow-y-auto p-4 focus:outline-none",
|
|
1149
1464
|
"prose prose-sm max-w-none",
|
|
1465
|
+
// Baseline block styles: Tailwind preflight strips heading,
|
|
1466
|
+
// list and quote styling, and the `prose` classes above only
|
|
1467
|
+
// work when the host installs @tailwindcss/typography —
|
|
1468
|
+
// without these, block formats would apply invisibly.
|
|
1469
|
+
"[&_h1]:my-3 [&_h1]:text-2xl [&_h1]:font-bold",
|
|
1470
|
+
"[&_h2]:my-3 [&_h2]:text-xl [&_h2]:font-bold",
|
|
1471
|
+
"[&_h3]:my-2 [&_h3]:text-lg [&_h3]:font-semibold",
|
|
1472
|
+
"[&_ul]:my-2 [&_ul]:list-disc [&_ul]:ps-6",
|
|
1473
|
+
"[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:ps-6",
|
|
1474
|
+
"[&_blockquote]:border-border [&_blockquote]:text-muted-foreground [&_blockquote]:my-2 [&_blockquote]:border-s-4 [&_blockquote]:ps-3",
|
|
1475
|
+
blockMenu && "ps-10",
|
|
1150
1476
|
hasMacros && macrosOpen && "md:min-h-[400px]",
|
|
1151
1477
|
disabled && "bg-muted/20 cursor-not-allowed text-neutral-700 dark:text-neutral-300"
|
|
1152
1478
|
),
|
|
@@ -1184,5 +1510,5 @@ exports.MacroLibrary = MacroLibrary;
|
|
|
1184
1510
|
exports.RichTextEditor = RichTextEditor;
|
|
1185
1511
|
exports.convertAngleBracketsToMustache = convertAngleBracketsToMustache;
|
|
1186
1512
|
exports.processDictation = processDictation;
|
|
1187
|
-
//# sourceMappingURL=chunk-
|
|
1188
|
-
//# sourceMappingURL=chunk-
|
|
1513
|
+
//# sourceMappingURL=chunk-3S5LK2EW.cjs.map
|
|
1514
|
+
//# sourceMappingURL=chunk-3S5LK2EW.cjs.map
|