@mieweb/ui 0.11.0-dev.24 → 0.11.0-dev.26
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-4W3QJWG2.cjs → chunk-45VC3ZMF.cjs} +32 -3
- package/dist/chunk-45VC3ZMF.cjs.map +1 -0
- package/dist/{chunk-HKLTJYRU.cjs → chunk-DUTEYAKL.cjs} +4 -4
- package/dist/{chunk-HKLTJYRU.cjs.map → chunk-DUTEYAKL.cjs.map} +1 -1
- package/dist/{chunk-IYY7NKA3.js → chunk-OEJ4TCXY.js} +304 -11
- package/dist/chunk-OEJ4TCXY.js.map +1 -0
- package/dist/{chunk-VEPARPUE.cjs → chunk-PIE6M2MT.cjs} +303 -10
- package/dist/chunk-PIE6M2MT.cjs.map +1 -0
- package/dist/{chunk-GTZUG646.js → chunk-SEE4ZPQS.js} +3 -3
- package/dist/{chunk-GTZUG646.js.map → chunk-SEE4ZPQS.js.map} +1 -1
- package/dist/{chunk-V43ZWRBT.js → chunk-YJ7MKZTI.js} +32 -3
- package/dist/chunk-YJ7MKZTI.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 +58 -5
- package/dist/components/RichTextEditor/index.d.ts +58 -5
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/index.cjs +41 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +79 -5
- package/dist/index.d.ts +79 -5
- package/dist/index.js +27 -4
- package/dist/index.js.map +1 -1
- 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-IYY7NKA3.js.map +0 -1
- package/dist/chunk-V43ZWRBT.js.map +0 -1
- package/dist/chunk-VEPARPUE.cjs.map +0 -1
|
@@ -6,7 +6,7 @@ import { X, Search, History, BookOpen, ChevronRight, ChevronDown, Plus } from '.
|
|
|
6
6
|
import { Button } from './chunk-WFBUBT54.js';
|
|
7
7
|
import { cn } from './chunk-TQONQSJO.js';
|
|
8
8
|
import * as React2 from 'react';
|
|
9
|
-
import { Bold, Italic, Underline, List, ListOrdered, AlignLeft, AlignCenter, AlignRight, Braces, Replace, MicOff, Mic, BookOpen as BookOpen$1 } from 'lucide-react';
|
|
9
|
+
import { Bold, Italic, Underline, List, ListOrdered, AlignLeft, AlignCenter, AlignRight, Braces, Replace, MicOff, Mic, BookOpen as BookOpen$1, Plus as Plus$1 } from 'lucide-react';
|
|
10
10
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
11
11
|
|
|
12
12
|
var DEFAULT_LABELS = {
|
|
@@ -520,6 +520,17 @@ var MARKDOWN_BLOCK_RULES = {
|
|
|
520
520
|
"1.": { command: "insertOrderedList" },
|
|
521
521
|
">": { command: "formatBlock", value: "blockquote" }
|
|
522
522
|
};
|
|
523
|
+
function nodeRect(node) {
|
|
524
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
525
|
+
return node.getBoundingClientRect();
|
|
526
|
+
}
|
|
527
|
+
if (node.nodeType === Node.TEXT_NODE && (node.textContent ?? "").length > 0) {
|
|
528
|
+
const range = document.createRange();
|
|
529
|
+
range.selectNodeContents(node);
|
|
530
|
+
return range.getBoundingClientRect();
|
|
531
|
+
}
|
|
532
|
+
return null;
|
|
533
|
+
}
|
|
523
534
|
function lastTextWithin(node) {
|
|
524
535
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
525
536
|
return (node.textContent ?? "").length > 0 ? node : null;
|
|
@@ -566,8 +577,13 @@ var RichTextEditor = React2.forwardRef(
|
|
|
566
577
|
defaultMacrosOpen = false,
|
|
567
578
|
macroLabels,
|
|
568
579
|
onCreateMacro,
|
|
569
|
-
toolbar
|
|
580
|
+
toolbar,
|
|
581
|
+
defaultToolbar = "visible",
|
|
582
|
+
onToolbarChange,
|
|
583
|
+
blockMenu = false,
|
|
584
|
+
blockMenuLabels,
|
|
570
585
|
markdownShortcuts = false,
|
|
586
|
+
chromeless = false,
|
|
571
587
|
"aria-label": ariaLabel
|
|
572
588
|
}, ref) => {
|
|
573
589
|
const editorRef = React2.useRef(null);
|
|
@@ -582,8 +598,46 @@ var RichTextEditor = React2.forwardRef(
|
|
|
582
598
|
const hasVariables = Boolean(variableGroups && variableGroups.length > 0);
|
|
583
599
|
const hasMacros = Boolean(macros);
|
|
584
600
|
const isEmpty = isHtmlEmpty(value);
|
|
585
|
-
const
|
|
601
|
+
const [uncontrolledToolbar, setUncontrolledToolbar] = React2.useState(defaultToolbar);
|
|
602
|
+
const toolbarVisible = (toolbar ?? uncontrolledToolbar) !== "hidden";
|
|
603
|
+
const setToolbarVisibility = (next) => {
|
|
604
|
+
if (toolbar === void 0) setUncontrolledToolbar(next);
|
|
605
|
+
onToolbarChange?.(next);
|
|
606
|
+
};
|
|
586
607
|
const toolbarVisibleRef = React2.useRef(toolbarVisible);
|
|
608
|
+
const [blockMenuOpen, setBlockMenuOpen] = React2.useState(false);
|
|
609
|
+
const [gutterTop, setGutterTop] = React2.useState(chromeless ? 7 : 16);
|
|
610
|
+
const gutterWrapperRef = React2.useRef(null);
|
|
611
|
+
const measureRestGutterTop = React2.useCallback(() => {
|
|
612
|
+
const fallback = chromeless ? 7 : 16;
|
|
613
|
+
if (!editorRef.current) return fallback;
|
|
614
|
+
const padding = parseFloat(
|
|
615
|
+
getComputedStyle(editorRef.current).paddingTop
|
|
616
|
+
);
|
|
617
|
+
return Number.isNaN(padding) ? fallback : Math.round(padding);
|
|
618
|
+
}, [chromeless]);
|
|
619
|
+
React2.useLayoutEffect(() => {
|
|
620
|
+
if (!blockMenu || !editorRef.current) return;
|
|
621
|
+
setGutterTop((current) => {
|
|
622
|
+
const next = measureRestGutterTop();
|
|
623
|
+
return current === next ? current : next;
|
|
624
|
+
});
|
|
625
|
+
}, [blockMenu, measureRestGutterTop]);
|
|
626
|
+
const hoverBlockNodeRef = React2.useRef(null);
|
|
627
|
+
const resetGutter = React2.useCallback(() => {
|
|
628
|
+
hoverBlockNodeRef.current = null;
|
|
629
|
+
const next = measureRestGutterTop();
|
|
630
|
+
setGutterTop((current) => current === next ? current : next);
|
|
631
|
+
}, [measureRestGutterTop]);
|
|
632
|
+
const reconcileGutterWithContent = React2.useCallback(() => {
|
|
633
|
+
if (!blockMenu || !editorRef.current) return;
|
|
634
|
+
const hovered = hoverBlockNodeRef.current;
|
|
635
|
+
if (hovered && !editorRef.current.contains(hovered) || !editorRef.current.hasChildNodes()) {
|
|
636
|
+
resetGutter();
|
|
637
|
+
}
|
|
638
|
+
}, [blockMenu, resetGutter]);
|
|
639
|
+
const blockTargetRangeRef = React2.useRef(null);
|
|
640
|
+
const firstBlockItemRef = React2.useRef(null);
|
|
587
641
|
React2.useImperativeHandle(ref, () => editorRef.current);
|
|
588
642
|
React2.useEffect(() => {
|
|
589
643
|
setSpeechSupported(Boolean(getSpeechRecognition()));
|
|
@@ -610,10 +664,12 @@ var RichTextEditor = React2.forwardRef(
|
|
|
610
664
|
React2.useEffect(() => {
|
|
611
665
|
if (editorRef.current && editorRef.current.innerHTML !== value) {
|
|
612
666
|
editorRef.current.innerHTML = value;
|
|
667
|
+
reconcileGutterWithContent();
|
|
613
668
|
}
|
|
614
|
-
}, [value]);
|
|
669
|
+
}, [value, reconcileGutterWithContent]);
|
|
615
670
|
const updateContent = () => {
|
|
616
671
|
if (editorRef.current) onChange(editorRef.current.innerHTML);
|
|
672
|
+
reconcileGutterWithContent();
|
|
617
673
|
};
|
|
618
674
|
const insertSanitized = (html) => {
|
|
619
675
|
if (!sanitizeHtml) return false;
|
|
@@ -829,13 +885,108 @@ var RichTextEditor = React2.forwardRef(
|
|
|
829
885
|
return true;
|
|
830
886
|
};
|
|
831
887
|
const handleEditorKeyDown = (event) => {
|
|
832
|
-
if (disabled
|
|
888
|
+
if (disabled) return;
|
|
889
|
+
if (blockMenu && event.key === "/" && (event.ctrlKey || event.metaKey) && !event.altKey) {
|
|
890
|
+
event.preventDefault();
|
|
891
|
+
openBlockMenuAtCaret();
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
if (event.key !== " " || // Space during IME composition selects/converts a candidate; never
|
|
833
895
|
// hijack it for shortcut expansion.
|
|
834
896
|
event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey)
|
|
835
897
|
return;
|
|
836
898
|
if (markdownShortcuts && applyMarkdownShortcut(event)) return;
|
|
837
899
|
expandTypedShortcut(event);
|
|
838
900
|
};
|
|
901
|
+
const handleGutterMouseMove = (event) => {
|
|
902
|
+
if (blockMenuOpen || !editorRef.current || !gutterWrapperRef.current)
|
|
903
|
+
return;
|
|
904
|
+
let target = null;
|
|
905
|
+
let top = null;
|
|
906
|
+
for (const child of Array.from(editorRef.current.childNodes)) {
|
|
907
|
+
const rect = nodeRect(child);
|
|
908
|
+
if (!rect) continue;
|
|
909
|
+
if (rect.width === 0 && rect.height === 0) continue;
|
|
910
|
+
if (target === null || rect.top <= event.clientY) {
|
|
911
|
+
target = child;
|
|
912
|
+
top = rect.top;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
if (!target || top === null) {
|
|
916
|
+
resetGutter();
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
hoverBlockNodeRef.current = target;
|
|
920
|
+
const wrapperTop = gutterWrapperRef.current.getBoundingClientRect().top;
|
|
921
|
+
const next = Math.max(Math.round(top - wrapperTop), 4);
|
|
922
|
+
setGutterTop((current) => current === next ? current : next);
|
|
923
|
+
};
|
|
924
|
+
const rangeAtStartOf = (node) => {
|
|
925
|
+
const range = document.createRange();
|
|
926
|
+
range.setStart(node, 0);
|
|
927
|
+
range.collapse(true);
|
|
928
|
+
return range;
|
|
929
|
+
};
|
|
930
|
+
const handleBlockMenuOpenChange = (open) => {
|
|
931
|
+
if (open) {
|
|
932
|
+
const block = hoverBlockNodeRef.current ?? editorRef.current?.firstChild ?? null;
|
|
933
|
+
blockTargetRangeRef.current = block ? rangeAtStartOf(block) : null;
|
|
934
|
+
} else if (editorRef.current && document.activeElement?.closest('[role="menu"]')) {
|
|
935
|
+
const editor = editorRef.current;
|
|
936
|
+
editor.focus();
|
|
937
|
+
const target = blockTargetRangeRef.current;
|
|
938
|
+
const selection = window.getSelection();
|
|
939
|
+
if (target && selection && editor.contains(target.startContainer)) {
|
|
940
|
+
selection.removeAllRanges();
|
|
941
|
+
selection.addRange(target);
|
|
942
|
+
saveSelection();
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
setBlockMenuOpen(open);
|
|
946
|
+
};
|
|
947
|
+
const openBlockMenuAtCaret = () => {
|
|
948
|
+
const selection = window.getSelection();
|
|
949
|
+
if (selection && selection.rangeCount > 0 && editorRef.current?.contains(selection.getRangeAt(0).startContainer)) {
|
|
950
|
+
const caret = selection.getRangeAt(0);
|
|
951
|
+
blockTargetRangeRef.current = caret.cloneRange();
|
|
952
|
+
let node = caret.startContainer;
|
|
953
|
+
while (node.parentNode && node.parentNode !== editorRef.current) {
|
|
954
|
+
node = node.parentNode;
|
|
955
|
+
}
|
|
956
|
+
const rect = nodeRect(node);
|
|
957
|
+
const wrapperRect = gutterWrapperRef.current?.getBoundingClientRect();
|
|
958
|
+
if (rect && wrapperRect) {
|
|
959
|
+
setGutterTop(Math.max(Math.round(rect.top - wrapperRect.top), 4));
|
|
960
|
+
}
|
|
961
|
+
} else {
|
|
962
|
+
blockTargetRangeRef.current = null;
|
|
963
|
+
}
|
|
964
|
+
setBlockMenuOpen(true);
|
|
965
|
+
};
|
|
966
|
+
const applyBlockFormat = (command, value2) => {
|
|
967
|
+
if (disabled || !editorRef.current) return;
|
|
968
|
+
setBlockMenuOpen(false);
|
|
969
|
+
editorRef.current.focus();
|
|
970
|
+
const target = blockTargetRangeRef.current;
|
|
971
|
+
const selection = window.getSelection();
|
|
972
|
+
if (target && selection && editorRef.current.contains(target.startContainer)) {
|
|
973
|
+
selection.removeAllRanges();
|
|
974
|
+
selection.addRange(target);
|
|
975
|
+
}
|
|
976
|
+
try {
|
|
977
|
+
document.execCommand(command, false, value2);
|
|
978
|
+
} catch {
|
|
979
|
+
}
|
|
980
|
+
saveSelection();
|
|
981
|
+
updateContent();
|
|
982
|
+
};
|
|
983
|
+
React2.useEffect(() => {
|
|
984
|
+
if (!blockMenuOpen) return;
|
|
985
|
+
const frame = requestAnimationFrame(
|
|
986
|
+
() => firstBlockItemRef.current?.focus()
|
|
987
|
+
);
|
|
988
|
+
return () => cancelAnimationFrame(frame);
|
|
989
|
+
}, [blockMenuOpen]);
|
|
839
990
|
const toggleDictation = async () => {
|
|
840
991
|
const SpeechRecognition = getSpeechRecognition();
|
|
841
992
|
if (!SpeechRecognition) return;
|
|
@@ -934,12 +1085,51 @@ var RichTextEditor = React2.forwardRef(
|
|
|
934
1085
|
}
|
|
935
1086
|
};
|
|
936
1087
|
const iconButtonClass = "h-8 w-8 p-0";
|
|
1088
|
+
const blockFormatItems = [
|
|
1089
|
+
{ key: "text", label: "Text", command: "formatBlock", value: "p" },
|
|
1090
|
+
{
|
|
1091
|
+
key: "heading1",
|
|
1092
|
+
label: "Heading 1",
|
|
1093
|
+
command: "formatBlock",
|
|
1094
|
+
value: "h1"
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
key: "heading2",
|
|
1098
|
+
label: "Heading 2",
|
|
1099
|
+
command: "formatBlock",
|
|
1100
|
+
value: "h2"
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
key: "heading3",
|
|
1104
|
+
label: "Heading 3",
|
|
1105
|
+
command: "formatBlock",
|
|
1106
|
+
value: "h3"
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
key: "bulletList",
|
|
1110
|
+
label: "Bullet list",
|
|
1111
|
+
command: "insertUnorderedList"
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
key: "numberedList",
|
|
1115
|
+
label: "Numbered list",
|
|
1116
|
+
command: "insertOrderedList"
|
|
1117
|
+
},
|
|
1118
|
+
{
|
|
1119
|
+
key: "quote",
|
|
1120
|
+
label: "Quote",
|
|
1121
|
+
command: "formatBlock",
|
|
1122
|
+
value: "blockquote"
|
|
1123
|
+
}
|
|
1124
|
+
];
|
|
937
1125
|
return /* @__PURE__ */ jsxs(
|
|
938
1126
|
"div",
|
|
939
1127
|
{
|
|
940
1128
|
"data-slot": "rich-text-editor",
|
|
1129
|
+
"data-chromeless": chromeless || void 0,
|
|
941
1130
|
className: cn(
|
|
942
|
-
"
|
|
1131
|
+
"bg-background flex flex-col",
|
|
1132
|
+
!chromeless && "border-border overflow-hidden rounded-lg border",
|
|
943
1133
|
className
|
|
944
1134
|
),
|
|
945
1135
|
children: [
|
|
@@ -1171,16 +1361,103 @@ var RichTextEditor = React2.forwardRef(
|
|
|
1171
1361
|
/* @__PURE__ */ jsxs(
|
|
1172
1362
|
"div",
|
|
1173
1363
|
{
|
|
1364
|
+
ref: gutterWrapperRef,
|
|
1174
1365
|
className: cn(
|
|
1175
1366
|
"relative flex-1",
|
|
1367
|
+
blockMenu && "group/rte-body",
|
|
1176
1368
|
hasMacros && macrosOpen && "md:me-72"
|
|
1177
1369
|
),
|
|
1370
|
+
onMouseMove: blockMenu && !disabled ? handleGutterMouseMove : void 0,
|
|
1178
1371
|
children: [
|
|
1372
|
+
blockMenu && !disabled && /* @__PURE__ */ jsx(
|
|
1373
|
+
"div",
|
|
1374
|
+
{
|
|
1375
|
+
"data-slot": "rich-text-editor-block-gutter",
|
|
1376
|
+
className: "absolute start-1 z-10",
|
|
1377
|
+
style: { top: gutterTop },
|
|
1378
|
+
children: /* @__PURE__ */ jsxs(
|
|
1379
|
+
Dropdown,
|
|
1380
|
+
{
|
|
1381
|
+
open: blockMenuOpen,
|
|
1382
|
+
onOpenChange: handleBlockMenuOpenChange,
|
|
1383
|
+
placement: "bottom-start",
|
|
1384
|
+
trigger: /* @__PURE__ */ jsx(
|
|
1385
|
+
Button,
|
|
1386
|
+
{
|
|
1387
|
+
type: "button",
|
|
1388
|
+
variant: "ghost",
|
|
1389
|
+
size: "sm",
|
|
1390
|
+
className: cn(
|
|
1391
|
+
"h-6 w-6 p-0",
|
|
1392
|
+
// Revealed on hover/focus; always visible on touch,
|
|
1393
|
+
// which has no hover to reveal it with.
|
|
1394
|
+
"opacity-0 transition-opacity",
|
|
1395
|
+
"group-hover/rte-body:opacity-100",
|
|
1396
|
+
"focus-visible:opacity-100",
|
|
1397
|
+
"[@media(hover:none)]:opacity-100",
|
|
1398
|
+
blockMenuOpen && "opacity-100"
|
|
1399
|
+
),
|
|
1400
|
+
"aria-label": blockMenuLabels?.blockMenu ?? "Block menu",
|
|
1401
|
+
title: blockMenuLabels?.blockMenu ?? "Block menu",
|
|
1402
|
+
children: /* @__PURE__ */ jsx(Plus$1, { className: "h-4 w-4" })
|
|
1403
|
+
}
|
|
1404
|
+
),
|
|
1405
|
+
children: [
|
|
1406
|
+
blockFormatItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1407
|
+
DropdownItem,
|
|
1408
|
+
{
|
|
1409
|
+
ref: index === 0 ? firstBlockItemRef : void 0,
|
|
1410
|
+
onClick: () => applyBlockFormat(item.command, item.value),
|
|
1411
|
+
children: blockMenuLabels?.[item.key] ?? item.label
|
|
1412
|
+
},
|
|
1413
|
+
item.key
|
|
1414
|
+
)),
|
|
1415
|
+
/* @__PURE__ */ jsx(DropdownSeparator, {}),
|
|
1416
|
+
hasMacros && /* @__PURE__ */ jsx(
|
|
1417
|
+
DropdownItem,
|
|
1418
|
+
{
|
|
1419
|
+
onClick: () => {
|
|
1420
|
+
setBlockMenuOpen(false);
|
|
1421
|
+
if (blockTargetRangeRef.current) {
|
|
1422
|
+
savedRangeRef.current = blockTargetRangeRef.current;
|
|
1423
|
+
}
|
|
1424
|
+
setMacrosOpen(true);
|
|
1425
|
+
focusRestoringSelection();
|
|
1426
|
+
},
|
|
1427
|
+
children: blockMenuLabels?.insertMacro ?? "Insert macro\u2026"
|
|
1428
|
+
}
|
|
1429
|
+
),
|
|
1430
|
+
/* @__PURE__ */ jsx(
|
|
1431
|
+
DropdownItem,
|
|
1432
|
+
{
|
|
1433
|
+
onClick: () => {
|
|
1434
|
+
setBlockMenuOpen(false);
|
|
1435
|
+
setToolbarVisibility(
|
|
1436
|
+
toolbarVisible ? "hidden" : "visible"
|
|
1437
|
+
);
|
|
1438
|
+
editorRef.current?.focus();
|
|
1439
|
+
},
|
|
1440
|
+
children: toolbarVisible ? blockMenuLabels?.hideToolbar ?? "Hide toolbar" : blockMenuLabels?.showToolbar ?? "Show toolbar"
|
|
1441
|
+
}
|
|
1442
|
+
)
|
|
1443
|
+
]
|
|
1444
|
+
}
|
|
1445
|
+
)
|
|
1446
|
+
}
|
|
1447
|
+
),
|
|
1179
1448
|
isEmpty && placeholder && /* @__PURE__ */ jsx(
|
|
1180
1449
|
"div",
|
|
1181
1450
|
{
|
|
1182
1451
|
"aria-hidden": "true",
|
|
1183
|
-
className:
|
|
1452
|
+
className: cn(
|
|
1453
|
+
"text-muted-foreground pointer-events-none absolute start-0 top-0",
|
|
1454
|
+
// Chromeless hosts drop the wrapper's clipping, so a long
|
|
1455
|
+
// placeholder must stay a single ellipsized line (as a
|
|
1456
|
+
// native textarea clips its own) instead of wrapping out
|
|
1457
|
+
// of the one-row field.
|
|
1458
|
+
chromeless ? "end-0 truncate px-3 py-[7px] text-base" : "p-4",
|
|
1459
|
+
blockMenu && "ps-10"
|
|
1460
|
+
),
|
|
1184
1461
|
children: placeholder
|
|
1185
1462
|
}
|
|
1186
1463
|
),
|
|
@@ -1192,17 +1469,33 @@ var RichTextEditor = React2.forwardRef(
|
|
|
1192
1469
|
"aria-multiline": "true",
|
|
1193
1470
|
"aria-label": ariaLabel ?? placeholder,
|
|
1194
1471
|
contentEditable: !disabled,
|
|
1472
|
+
"data-macros-open": hasMacros && macrosOpen ? "" : void 0,
|
|
1195
1473
|
tabIndex: disabled ? -1 : 0,
|
|
1196
1474
|
onInput: updateContent,
|
|
1197
1475
|
onPaste: handlePaste,
|
|
1198
1476
|
onDrop: handleDrop,
|
|
1199
1477
|
onBlur: hasMacros ? saveSelection : void 0,
|
|
1200
|
-
onKeyDown: hasMacros || markdownShortcuts ? handleEditorKeyDown : void 0,
|
|
1478
|
+
onKeyDown: hasMacros || markdownShortcuts || blockMenu ? handleEditorKeyDown : void 0,
|
|
1201
1479
|
onKeyUp: hasMacros ? saveSelection : void 0,
|
|
1202
1480
|
onMouseUp: hasMacros ? saveSelection : void 0,
|
|
1203
1481
|
className: cn(
|
|
1204
|
-
"
|
|
1482
|
+
"overflow-y-auto focus:outline-none",
|
|
1483
|
+
// Chromeless surfaces start one Input row tall (Textarea md
|
|
1484
|
+
// metrics: 24px line + 7px padding + the host's 1px borders
|
|
1485
|
+
// = h-10) and auto-grow with content.
|
|
1486
|
+
chromeless ? "min-h-[38px] px-3 py-[7px] text-base" : "min-h-[250px] p-4",
|
|
1205
1487
|
"prose prose-sm max-w-none",
|
|
1488
|
+
// Baseline block styles: Tailwind preflight strips heading,
|
|
1489
|
+
// list and quote styling, and the `prose` classes above only
|
|
1490
|
+
// work when the host installs @tailwindcss/typography —
|
|
1491
|
+
// without these, block formats would apply invisibly.
|
|
1492
|
+
"[&_h1]:my-3 [&_h1]:text-2xl [&_h1]:font-bold",
|
|
1493
|
+
"[&_h2]:my-3 [&_h2]:text-xl [&_h2]:font-bold",
|
|
1494
|
+
"[&_h3]:my-2 [&_h3]:text-lg [&_h3]:font-semibold",
|
|
1495
|
+
"[&_ul]:my-2 [&_ul]:list-disc [&_ul]:ps-6",
|
|
1496
|
+
"[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:ps-6",
|
|
1497
|
+
"[&_blockquote]:border-border [&_blockquote]:text-muted-foreground [&_blockquote]:my-2 [&_blockquote]:border-s-4 [&_blockquote]:ps-3",
|
|
1498
|
+
blockMenu && "ps-10",
|
|
1206
1499
|
hasMacros && macrosOpen && "md:min-h-[400px]",
|
|
1207
1500
|
disabled && "bg-muted/20 cursor-not-allowed text-neutral-700 dark:text-neutral-300"
|
|
1208
1501
|
),
|
|
@@ -1237,5 +1530,5 @@ var RichTextEditor = React2.forwardRef(
|
|
|
1237
1530
|
RichTextEditor.displayName = "RichTextEditor";
|
|
1238
1531
|
|
|
1239
1532
|
export { MacroLibrary, RichTextEditor, convertAngleBracketsToMustache, processDictation };
|
|
1240
|
-
//# sourceMappingURL=chunk-
|
|
1241
|
-
//# sourceMappingURL=chunk-
|
|
1533
|
+
//# sourceMappingURL=chunk-OEJ4TCXY.js.map
|
|
1534
|
+
//# sourceMappingURL=chunk-OEJ4TCXY.js.map
|