@yurikilian/lex4 1.5.9 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,11 +2,11 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
- import React, { createContext, useContext, useMemo, useReducer, useState, useRef, useCallback, useEffect, forwardRef, createElement, useImperativeHandle } from "react";
6
- import { $getRoot, $createRangeSelectionFromDom, $getSelection, $isRangeSelection, $isTextNode, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, $createParagraphNode, $applyNodeReplacement, DecoratorNode, KEY_BACKSPACE_COMMAND, COMMAND_PRIORITY_LOW, KEY_DELETE_COMMAND, $isNodeSelection, $getNodeByKey, $selectAll, SELECTION_CHANGE_COMMAND, KEY_TAB_COMMAND, $isElementNode, $isParagraphNode, $setSelection, FOCUS_COMMAND, $splitNode, $getNearestNodeFromDOMNode, CONTROLLED_TEXT_INSERTION_COMMAND, KEY_DOWN_COMMAND, PASTE_COMMAND, KEY_ENTER_COMMAND, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_CRITICAL, $insertNodes, $createLineBreakNode, $createTextNode, createCommand, COMMAND_PRIORITY_EDITOR } from "lexical";
5
+ import React, { createContext, useContext, useMemo, useRef, useReducer, useState, useCallback, useEffect, forwardRef, createElement, useImperativeHandle } from "react";
6
+ import { $getSelection, $isRangeSelection, $isTextNode, $getRoot, $createRangeSelectionFromDom, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, $applyNodeReplacement, DecoratorNode, KEY_BACKSPACE_COMMAND, COMMAND_PRIORITY_LOW, KEY_DELETE_COMMAND, KEY_DOWN_COMMAND, $isNodeSelection, $getNodeByKey, $setSelection, $createNodeSelection, $isElementNode, $createParagraphNode, $selectAll, SELECTION_CHANGE_COMMAND, KEY_TAB_COMMAND, $isParagraphNode, FOCUS_COMMAND, $splitNode, $getNearestNodeFromDOMNode, CONTROLLED_TEXT_INSERTION_COMMAND, PASTE_COMMAND, KEY_ENTER_COMMAND, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_CRITICAL, $insertNodes, $createLineBreakNode, $createTextNode, createCommand, COMMAND_PRIORITY_EDITOR } from "lexical";
7
7
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
8
8
  import { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, ListNode, ListItemNode, $isListNode, $createListItemNode, $createListNode } from "@lexical/list";
9
- import { $setBlocksType } from "@lexical/selection";
9
+ import { $patchStyleText, $setBlocksType } from "@lexical/selection";
10
10
  import { $createHeadingNode, $isHeadingNode, HeadingNode, QuoteNode, $createQuoteNode } from "@lexical/rich-text";
11
11
  import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
12
12
  import { LexicalComposer } from "@lexical/react/LexicalComposer";
@@ -777,6 +777,115 @@ const TranslationsProvider = ({
777
777
  );
778
778
  return /* @__PURE__ */ jsx(TranslationsContext.Provider, { value: merged, children });
779
779
  };
780
+ const createStoreImpl = (createState) => {
781
+ let state;
782
+ const listeners = /* @__PURE__ */ new Set();
783
+ const setState = (partial, replace) => {
784
+ const nextState = typeof partial === "function" ? partial(state) : partial;
785
+ if (!Object.is(nextState, state)) {
786
+ const previousState = state;
787
+ state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
788
+ listeners.forEach((listener) => listener(state, previousState));
789
+ }
790
+ };
791
+ const getState = () => state;
792
+ const getInitialState = () => initialState;
793
+ const subscribe = (listener) => {
794
+ listeners.add(listener);
795
+ return () => listeners.delete(listener);
796
+ };
797
+ const api = { setState, getState, getInitialState, subscribe };
798
+ const initialState = state = createState(setState, getState, api);
799
+ return api;
800
+ };
801
+ const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
802
+ const identity = (arg) => arg;
803
+ function useStore(api, selector = identity) {
804
+ const slice = React.useSyncExternalStore(
805
+ api.subscribe,
806
+ React.useCallback(() => selector(api.getState()), [api, selector]),
807
+ React.useCallback(() => selector(api.getInitialState()), [api, selector])
808
+ );
809
+ React.useDebugValue(slice);
810
+ return slice;
811
+ }
812
+ const SUPPORTED_FONT_SIZES = [
813
+ 8,
814
+ 9,
815
+ 10,
816
+ 11,
817
+ 12,
818
+ 14,
819
+ 16,
820
+ 18,
821
+ 20,
822
+ 24,
823
+ 28,
824
+ 32,
825
+ 36,
826
+ 48,
827
+ 72
828
+ ];
829
+ const DEFAULT_FONT_SIZE = 12;
830
+ function applyFontSize(editor, size) {
831
+ editor.update(() => {
832
+ const selection = $getSelection();
833
+ if (!$isRangeSelection(selection)) return;
834
+ const nodes = selection.getNodes();
835
+ for (const node of nodes) {
836
+ if ($isTextNode(node)) {
837
+ const existing = node.getStyle();
838
+ const updated = mergeFontSize(existing, size);
839
+ node.setStyle(updated);
840
+ }
841
+ }
842
+ });
843
+ }
844
+ function mergeFontSize(existingStyle, size) {
845
+ const stripped = existingStyle.replace(/font-size:\s*[^;]+;?\s*/g, "").trim();
846
+ const sizeDecl = `font-size: ${size}pt`;
847
+ return stripped ? `${stripped}; ${sizeDecl}` : sizeDecl;
848
+ }
849
+ const DEFAULT_TOOLBAR_STYLE_SNAPSHOT = {
850
+ blockType: "paragraph",
851
+ fontFamily: "Calibri",
852
+ fontSize: DEFAULT_FONT_SIZE,
853
+ alignment: "left",
854
+ isBold: false,
855
+ isItalic: false,
856
+ isUnderline: false,
857
+ isStrikethrough: false,
858
+ hasSelectedVariable: false
859
+ };
860
+ function createToolbarStyleStore(initialSnapshot = DEFAULT_TOOLBAR_STYLE_SNAPSHOT) {
861
+ return createStore((set) => ({
862
+ ...initialSnapshot,
863
+ setSnapshot: (snapshot) => set(snapshot),
864
+ reset: () => set(DEFAULT_TOOLBAR_STYLE_SNAPSHOT)
865
+ }));
866
+ }
867
+ const ToolbarStyleStoreContext = createContext(null);
868
+ const ToolbarStyleStoreProvider = ({ children }) => {
869
+ const storeRef = useRef(null);
870
+ if (!storeRef.current) {
871
+ storeRef.current = createToolbarStyleStore();
872
+ }
873
+ return /* @__PURE__ */ jsx(ToolbarStyleStoreContext.Provider, { value: storeRef.current, children });
874
+ };
875
+ function useToolbarStyleStore(selector) {
876
+ const store = useContext(ToolbarStyleStoreContext);
877
+ if (!store) {
878
+ throw new Error("useToolbarStyleStore must be used within a ToolbarStyleStoreProvider");
879
+ }
880
+ return useStore(store, selector);
881
+ }
882
+ function useToolbarStyleStoreApi() {
883
+ const store = useContext(ToolbarStyleStoreContext);
884
+ if (!store) {
885
+ throw new Error("useToolbarStyleStoreApi must be used within a ToolbarStyleStoreProvider");
886
+ }
887
+ return store;
888
+ }
780
889
  const HISTORY_RESTORE_SUPPRESSION_MS = 100;
781
890
  const HISTORY_BATCH_FLUSH_MS = 16;
782
891
  function cloneDocumentSnapshot(document2) {
@@ -1024,7 +1133,11 @@ const DocumentProvider = ({
1024
1133
  register: (pageId, editor) => {
1025
1134
  editorMapRef.current.set(pageId, editor);
1026
1135
  },
1027
- unregister: (pageId) => {
1136
+ unregister: (pageId, editor) => {
1137
+ const currentEditor = editorMapRef.current.get(pageId);
1138
+ if (editor && currentEditor && currentEditor !== editor) {
1139
+ return;
1140
+ }
1028
1141
  editorMapRef.current.delete(pageId);
1029
1142
  },
1030
1143
  get: (pageId) => editorMapRef.current.get(pageId),
@@ -1329,7 +1442,7 @@ const DocumentProvider = ({
1329
1442
  undo,
1330
1443
  redo,
1331
1444
  editorRegistry
1332
- }, children });
1445
+ }, children: /* @__PURE__ */ jsx(ToolbarStyleStoreProvider, { children }) });
1333
1446
  };
1334
1447
  /**
1335
1448
  * @license lucide-react v1.8.0 - ISC
@@ -2077,43 +2190,6 @@ function applyFontFamily(editor, fontFamily) {
2077
2190
  }
2078
2191
  });
2079
2192
  }
2080
- const SUPPORTED_FONT_SIZES = [
2081
- 8,
2082
- 9,
2083
- 10,
2084
- 11,
2085
- 12,
2086
- 14,
2087
- 16,
2088
- 18,
2089
- 20,
2090
- 24,
2091
- 28,
2092
- 32,
2093
- 36,
2094
- 48,
2095
- 72
2096
- ];
2097
- const DEFAULT_FONT_SIZE = 12;
2098
- function applyFontSize(editor, size) {
2099
- editor.update(() => {
2100
- const selection = $getSelection();
2101
- if (!$isRangeSelection(selection)) return;
2102
- const nodes = selection.getNodes();
2103
- for (const node of nodes) {
2104
- if ($isTextNode(node)) {
2105
- const existing = node.getStyle();
2106
- const updated = mergeFontSize(existing, size);
2107
- node.setStyle(updated);
2108
- }
2109
- }
2110
- });
2111
- }
2112
- function mergeFontSize(existingStyle, size) {
2113
- const stripped = existingStyle.replace(/font-size:\s*[^;]+;?\s*/g, "").trim();
2114
- const sizeDecl = `font-size: ${size}pt`;
2115
- return stripped ? `${stripped}; ${sizeDecl}` : sizeDecl;
2116
- }
2117
2193
  function toggleFormat(editor, format) {
2118
2194
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);
2119
2195
  }
@@ -2145,48 +2221,77 @@ function indentContent(editor) {
2145
2221
  function outdentContent(editor) {
2146
2222
  editor.dispatchCommand(OUTDENT_CONTENT_COMMAND, void 0);
2147
2223
  }
2148
- function setBlockType(editor, blockType) {
2149
- editor.update(() => {
2150
- const selection = $getSelection();
2151
- if (!$isRangeSelection(selection)) {
2152
- return;
2153
- }
2154
- if (blockType === "paragraph") {
2155
- $setBlocksType(selection, () => $createParagraphNode());
2156
- return;
2157
- }
2158
- $setBlocksType(selection, () => $createHeadingNode(blockType));
2159
- });
2224
+ const INLINE_BLOCK_STYLE_PROPERTY = "--lex4-block-type";
2225
+ const INLINE_BLOCK_STYLE_PRESETS = {
2226
+ paragraph: {
2227
+ [INLINE_BLOCK_STYLE_PROPERTY]: "paragraph",
2228
+ "font-size": "12pt",
2229
+ "font-weight": "400"
2230
+ },
2231
+ h1: {
2232
+ [INLINE_BLOCK_STYLE_PROPERTY]: "h1",
2233
+ "font-size": "22.5pt",
2234
+ "font-weight": "700"
2235
+ },
2236
+ h2: {
2237
+ [INLINE_BLOCK_STYLE_PROPERTY]: "h2",
2238
+ "font-size": "18pt",
2239
+ "font-weight": "700"
2240
+ },
2241
+ h3: {
2242
+ [INLINE_BLOCK_STYLE_PROPERTY]: "h3",
2243
+ "font-size": "15pt",
2244
+ "font-weight": "600"
2245
+ },
2246
+ h4: {
2247
+ [INLINE_BLOCK_STYLE_PROPERTY]: "h4",
2248
+ "font-size": "13.5pt",
2249
+ "font-weight": "600"
2250
+ },
2251
+ h5: {
2252
+ [INLINE_BLOCK_STYLE_PROPERTY]: "h5",
2253
+ "font-size": "12pt",
2254
+ "font-weight": "500"
2255
+ },
2256
+ h6: {
2257
+ [INLINE_BLOCK_STYLE_PROPERTY]: "h6",
2258
+ "font-size": "11.25pt",
2259
+ "font-weight": "500"
2260
+ }
2261
+ };
2262
+ function escapeStyleProperty(property) {
2263
+ const escapedProperty = property.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2264
+ return escapedProperty;
2160
2265
  }
2161
- function getActiveBlockType(editor) {
2162
- let blockType = "paragraph";
2163
- editor.getEditorState().read(() => {
2164
- const selection = $getSelection();
2165
- if (!$isRangeSelection(selection)) {
2166
- return;
2167
- }
2168
- const anchorNode = selection.anchor.getNode();
2169
- const topLevelElement = anchorNode.getTopLevelElementOrThrow();
2170
- if ($isHeadingNode(topLevelElement)) {
2171
- blockType = topLevelElement.getTag();
2172
- }
2173
- });
2174
- return blockType;
2266
+ function stripStyleDeclaration(existingStyle, property) {
2267
+ const escapedProperty = escapeStyleProperty(property);
2268
+ return existingStyle.replace(
2269
+ new RegExp(`${escapedProperty}:\\s*[^;]+;?\\s*`, "g"),
2270
+ ""
2271
+ ).trim();
2272
+ }
2273
+ function isSupportedInlineBlockType(value) {
2274
+ return value === "paragraph" || value === "h1" || value === "h2" || value === "h3" || value === "h4" || value === "h5" || value === "h6";
2175
2275
  }
2176
2276
  function extractStyleValue(style, property) {
2177
- const escapedProperty = property.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2277
+ const escapedProperty = escapeStyleProperty(property);
2178
2278
  const match = style.match(new RegExp(`${escapedProperty}:\\s*([^;]+)`));
2179
2279
  return match ? match[1].trim().replace(/['"]/g, "") : void 0;
2180
2280
  }
2281
+ function removeStyleDeclaration(existingStyle, property) {
2282
+ return stripStyleDeclaration(existingStyle, property);
2283
+ }
2181
2284
  function mergeStyleDeclaration(existingStyle, property, value) {
2182
- const escapedProperty = property.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2183
- const stripped = existingStyle.replace(
2184
- new RegExp(`${escapedProperty}:\\s*[^;]+;?\\s*`, "g"),
2185
- ""
2186
- ).trim();
2285
+ const stripped = stripStyleDeclaration(existingStyle, property);
2187
2286
  const declaration = `${property}: ${value}`;
2188
2287
  return stripped ? `${stripped}; ${declaration}` : declaration;
2189
2288
  }
2289
+ function mergeStyleDeclarations(existingStyle, declarations) {
2290
+ return Object.entries(declarations).reduce(
2291
+ (style, [property, value]) => mergeStyleDeclaration(style, property, value),
2292
+ existingStyle
2293
+ );
2294
+ }
2190
2295
  function extractFontFamilyFromStyle(style) {
2191
2296
  return extractStyleValue(style, "font-family");
2192
2297
  }
@@ -2204,6 +2309,21 @@ function mergeFontFamilyStyle(existingStyle, fontFamily) {
2204
2309
  function mergeFontSizeStyle(existingStyle, size) {
2205
2310
  return mergeStyleDeclaration(existingStyle, "font-size", `${size}pt`);
2206
2311
  }
2312
+ function extractInlineBlockTypeFromStyle(style) {
2313
+ const value = extractStyleValue(style, INLINE_BLOCK_STYLE_PROPERTY);
2314
+ return isSupportedInlineBlockType(value) ? value : void 0;
2315
+ }
2316
+ function createInlineBlockTypeStylePatch(blockType) {
2317
+ return INLINE_BLOCK_STYLE_PRESETS[blockType];
2318
+ }
2319
+ function mergeInlineBlockTypeStyle(existingStyle, blockType) {
2320
+ const baseStyle = [
2321
+ INLINE_BLOCK_STYLE_PROPERTY,
2322
+ "font-size",
2323
+ "font-weight"
2324
+ ].reduce((style, property) => removeStyleDeclaration(style, property), existingStyle);
2325
+ return mergeStyleDeclarations(baseStyle, createInlineBlockTypeStylePatch(blockType));
2326
+ }
2207
2327
  const EMPTY_CONTEXT = {
2208
2328
  definitions: [],
2209
2329
  refreshDefinitions: () => {
@@ -2345,9 +2465,11 @@ function VariableChip({
2345
2465
  const style = useMemo(() => {
2346
2466
  const fontFamily = extractFontFamilyFromStyle(styleValue);
2347
2467
  const fontSize = extractFontSizePtFromStyle(styleValue);
2468
+ const fontWeight = extractStyleValue(styleValue, "font-weight");
2348
2469
  return {
2349
2470
  ...fontFamily ? { fontFamily } : {},
2350
- ...fontSize ? { fontSize: `${fontSize}pt` } : {}
2471
+ ...fontSize ? { fontSize: `${fontSize}pt` } : {},
2472
+ ...fontWeight ? { fontWeight } : {}
2351
2473
  };
2352
2474
  }, [styleValue]);
2353
2475
  const className = [
@@ -2405,9 +2527,43 @@ function VariableChip({
2405
2527
  },
2406
2528
  COMMAND_PRIORITY_LOW
2407
2529
  );
2530
+ const moveCaretFromSelectedNode = (direction) => {
2531
+ editor.update(() => {
2532
+ const node = $getNodeByKey(nodeKey);
2533
+ if (!$isVariableNode(node)) {
2534
+ return;
2535
+ }
2536
+ if (direction === "backward") {
2537
+ node.selectPrevious();
2538
+ } else {
2539
+ node.selectNext();
2540
+ }
2541
+ });
2542
+ };
2543
+ const unregisterArrowNavigation = editor.registerCommand(
2544
+ KEY_DOWN_COMMAND,
2545
+ (event) => {
2546
+ if (!isSelected || event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {
2547
+ return false;
2548
+ }
2549
+ if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
2550
+ event.preventDefault();
2551
+ moveCaretFromSelectedNode("backward");
2552
+ return true;
2553
+ }
2554
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") {
2555
+ event.preventDefault();
2556
+ moveCaretFromSelectedNode("forward");
2557
+ return true;
2558
+ }
2559
+ return false;
2560
+ },
2561
+ COMMAND_PRIORITY_LOW
2562
+ );
2408
2563
  return () => {
2409
2564
  unregisterBackspace();
2410
2565
  unregisterDelete();
2566
+ unregisterArrowNavigation();
2411
2567
  };
2412
2568
  }, [editor, isSelected, nodeKey]);
2413
2569
  return /* @__PURE__ */ jsx(
@@ -2430,7 +2586,126 @@ function $createVariableNode(variableKey, format = 0, style = "") {
2430
2586
  function $isVariableNode(node) {
2431
2587
  return node instanceof VariableNode;
2432
2588
  }
2433
- const FORMAT_MASKS = {
2589
+ function getElementBlockType$1(element) {
2590
+ if ($isHeadingNode(element)) {
2591
+ return element.getTag();
2592
+ }
2593
+ return "paragraph";
2594
+ }
2595
+ function getVariableTopLevelElement(variable) {
2596
+ const topLevelElement = variable.getTopLevelElementOrThrow();
2597
+ return $isElementNode(topLevelElement) ? topLevelElement : null;
2598
+ }
2599
+ function replaceTopLevelBlockType(element, blockType) {
2600
+ const currentType = getElementBlockType$1(element);
2601
+ if (currentType === blockType) {
2602
+ return;
2603
+ }
2604
+ const nextElement = blockType === "paragraph" ? $createParagraphNode() : $createHeadingNode(blockType);
2605
+ nextElement.setFormat(element.getFormatType());
2606
+ nextElement.setIndent(element.getIndent());
2607
+ const children = element.getChildren();
2608
+ for (const child of children) {
2609
+ nextElement.append(child);
2610
+ }
2611
+ element.replace(nextElement);
2612
+ }
2613
+ function isPartialSingleBlockSelection(selection) {
2614
+ if (selection.isCollapsed()) {
2615
+ return false;
2616
+ }
2617
+ const anchorTopLevel = selection.anchor.getNode().getTopLevelElementOrThrow();
2618
+ const focusTopLevel = selection.focus.getNode().getTopLevelElementOrThrow();
2619
+ if (!anchorTopLevel.is(focusTopLevel)) {
2620
+ return false;
2621
+ }
2622
+ const selectedText = selection.getTextContent().trim();
2623
+ const blockText = anchorTopLevel.getTextContent().trim();
2624
+ return selectedText.length > 0 && selectedText.length < blockText.length;
2625
+ }
2626
+ function applySemanticBlockType(selection, blockType) {
2627
+ if (blockType === "paragraph") {
2628
+ $setBlocksType(selection, () => $createParagraphNode());
2629
+ return;
2630
+ }
2631
+ $setBlocksType(selection, () => $createHeadingNode(blockType));
2632
+ }
2633
+ function selectedVariablesOccupyEntireBlock(variables, topLevelElement) {
2634
+ const selectedKeys = new Set(variables.map((variable) => variable.getKey()));
2635
+ const meaningfulChildren = topLevelElement.getChildren().filter(
2636
+ (child) => !($isTextNode(child) && child.getTextContent().trim() === "")
2637
+ );
2638
+ if (meaningfulChildren.length === 0) {
2639
+ return false;
2640
+ }
2641
+ return meaningfulChildren.every(
2642
+ (child) => $isVariableNode(child) && selectedKeys.has(child.getKey())
2643
+ );
2644
+ }
2645
+ function getStandaloneVariableChildren(topLevelElement) {
2646
+ const meaningfulChildren = topLevelElement.getChildren().filter(
2647
+ (child) => !($isTextNode(child) && child.getTextContent().trim() === "")
2648
+ );
2649
+ if (meaningfulChildren.length === 0 || !meaningfulChildren.every($isVariableNode)) {
2650
+ return null;
2651
+ }
2652
+ return meaningfulChildren;
2653
+ }
2654
+ function setBlockType(editor, blockType) {
2655
+ editor.update(() => {
2656
+ const currentSelection = $getSelection();
2657
+ const selection = $isNodeSelection(currentSelection) ? currentSelection : $createRangeSelectionFromDom(window.getSelection(), editor) ?? currentSelection;
2658
+ if ($isRangeSelection(selection)) {
2659
+ $setSelection(selection);
2660
+ }
2661
+ if ($isNodeSelection(selection)) {
2662
+ const variables = selection.getNodes().filter($isVariableNode);
2663
+ if (variables.length === 0) {
2664
+ return;
2665
+ }
2666
+ const firstTopLevelElement = getVariableTopLevelElement(variables[0]);
2667
+ if (!firstTopLevelElement) {
2668
+ return;
2669
+ }
2670
+ const sameTopLevelElement = variables.every(
2671
+ (variable) => {
2672
+ var _a;
2673
+ return ((_a = getVariableTopLevelElement(variable)) == null ? void 0 : _a.is(firstTopLevelElement)) ?? false;
2674
+ }
2675
+ );
2676
+ if (sameTopLevelElement && selectedVariablesOccupyEntireBlock(variables, firstTopLevelElement)) {
2677
+ for (const variable of variables) {
2678
+ variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));
2679
+ }
2680
+ replaceTopLevelBlockType(firstTopLevelElement, blockType);
2681
+ const nextSelection = $createNodeSelection();
2682
+ for (const variable of variables) {
2683
+ nextSelection.add(variable.getKey());
2684
+ }
2685
+ $setSelection(nextSelection);
2686
+ return;
2687
+ }
2688
+ for (const variable of variables) {
2689
+ variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));
2690
+ }
2691
+ return;
2692
+ }
2693
+ if (!$isRangeSelection(selection)) {
2694
+ return;
2695
+ }
2696
+ const anchorTopLevel = selection.anchor.getNode().getTopLevelElementOrThrow();
2697
+ const standaloneVariables = $isElementNode(anchorTopLevel) ? getStandaloneVariableChildren(anchorTopLevel) : null;
2698
+ if (isPartialSingleBlockSelection(selection)) {
2699
+ $patchStyleText(selection, createInlineBlockTypeStylePatch(blockType));
2700
+ return;
2701
+ }
2702
+ for (const variable of standaloneVariables ?? []) {
2703
+ variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));
2704
+ }
2705
+ applySemanticBlockType(selection, blockType);
2706
+ });
2707
+ }
2708
+ const FORMAT_MASKS$1 = {
2434
2709
  bold: 1,
2435
2710
  italic: 2,
2436
2711
  strikethrough: 4,
@@ -2452,19 +2727,8 @@ function withSelectedVariableNodes(editor, updater) {
2452
2727
  });
2453
2728
  return updated;
2454
2729
  }
2455
- function getSelectedVariableNodes(editor) {
2456
- let nodes = [];
2457
- editor.getEditorState().read(() => {
2458
- const selection = $getSelection();
2459
- if (!$isNodeSelection(selection)) {
2460
- return;
2461
- }
2462
- nodes = selection.getNodes().filter($isVariableNode);
2463
- });
2464
- return nodes;
2465
- }
2466
2730
  function toggleSelectedVariableFormat(editor, format) {
2467
- const mask = FORMAT_MASKS[format];
2731
+ const mask = FORMAT_MASKS$1[format];
2468
2732
  if (!mask) {
2469
2733
  return false;
2470
2734
  }
@@ -2490,17 +2754,6 @@ function applyFontSizeToSelectedVariables(editor, size) {
2490
2754
  }
2491
2755
  });
2492
2756
  }
2493
- function readSelectedVariableFormatting(editor) {
2494
- const firstNode = getSelectedVariableNodes(editor)[0];
2495
- if (!firstNode) {
2496
- return {};
2497
- }
2498
- const style = firstNode.getStyle();
2499
- return {
2500
- fontFamily: extractFontFamilyFromStyle(style),
2501
- fontSize: extractFontSizePtFromStyle(style)
2502
- };
2503
- }
2504
2757
  const BLOCK_TYPE_OPTIONS = [
2505
2758
  { value: "paragraph", shortLabel: "P" },
2506
2759
  { value: "h1", shortLabel: "H1" },
@@ -2916,6 +3169,108 @@ const CanvasControls = () => {
2916
3169
  )
2917
3170
  ] });
2918
3171
  };
3172
+ const FORMAT_MASKS = {
3173
+ bold: 1,
3174
+ italic: 2,
3175
+ strikethrough: 4,
3176
+ underline: 8
3177
+ };
3178
+ function normalizeFontFamily(fontFamily) {
3179
+ if (fontFamily && SUPPORTED_FONTS.includes(fontFamily)) {
3180
+ return fontFamily;
3181
+ }
3182
+ return "Calibri";
3183
+ }
3184
+ function normalizeAlignment(alignment) {
3185
+ if (alignment === "center" || alignment === "right" || alignment === "justify") {
3186
+ return alignment;
3187
+ }
3188
+ return "left";
3189
+ }
3190
+ function getElementBlockType(node) {
3191
+ const topLevelElement = node.getTopLevelElementOrThrow();
3192
+ if ($isHeadingNode(topLevelElement)) {
3193
+ return topLevelElement.getTag();
3194
+ }
3195
+ return "paragraph";
3196
+ }
3197
+ function getElementAlignment(node) {
3198
+ const topLevelElement = node.getTopLevelElementOrThrow();
3199
+ if ($isElementNode(topLevelElement)) {
3200
+ return normalizeAlignment(topLevelElement.getFormatType());
3201
+ }
3202
+ return "left";
3203
+ }
3204
+ function getInlineStyleTarget(nodes, anchorNode) {
3205
+ if ($isTextNode(anchorNode) || $isVariableNode(anchorNode)) {
3206
+ return anchorNode;
3207
+ }
3208
+ return nodes.find((node) => $isTextNode(node) || $isVariableNode(node)) ?? null;
3209
+ }
3210
+ function getInlineStyleFromNode(node) {
3211
+ if ($isTextNode(node) || $isVariableNode(node)) {
3212
+ return node.getStyle();
3213
+ }
3214
+ return "";
3215
+ }
3216
+ function hasInlineFormat(node, format) {
3217
+ if ($isVariableNode(node)) {
3218
+ return (node.getFormat() & FORMAT_MASKS[format]) !== 0;
3219
+ }
3220
+ if ($isTextNode(node) && "hasFormat" in node && typeof node.hasFormat === "function") {
3221
+ return node.hasFormat(format);
3222
+ }
3223
+ if ($isTextNode(node) && "getFormat" in node && typeof node.getFormat === "function") {
3224
+ return (node.getFormat() & FORMAT_MASKS[format]) !== 0;
3225
+ }
3226
+ return false;
3227
+ }
3228
+ function readToolbarStyleSnapshot(editor, editorState = editor.getEditorState()) {
3229
+ let snapshot = DEFAULT_TOOLBAR_STYLE_SNAPSHOT;
3230
+ editorState.read(() => {
3231
+ const currentSelection = $getSelection();
3232
+ const selection = $isNodeSelection(currentSelection) ? currentSelection : $createRangeSelectionFromDom(window.getSelection(), editor) ?? currentSelection;
3233
+ if ($isNodeSelection(selection)) {
3234
+ const variableNodes = selection.getNodes().filter($isVariableNode);
3235
+ if (variableNodes.length === 0) {
3236
+ return;
3237
+ }
3238
+ const firstVariableNode = variableNodes[0];
3239
+ const style2 = firstVariableNode.getStyle();
3240
+ snapshot = {
3241
+ blockType: extractInlineBlockTypeFromStyle(style2) ?? getElementBlockType(firstVariableNode),
3242
+ fontFamily: normalizeFontFamily(extractFontFamilyFromStyle(style2)),
3243
+ fontSize: extractFontSizePtFromStyle(style2) ?? DEFAULT_FONT_SIZE,
3244
+ alignment: getElementAlignment(firstVariableNode),
3245
+ isBold: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.bold) !== 0),
3246
+ isItalic: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.italic) !== 0),
3247
+ isUnderline: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.underline) !== 0),
3248
+ isStrikethrough: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.strikethrough) !== 0),
3249
+ hasSelectedVariable: true
3250
+ };
3251
+ return;
3252
+ }
3253
+ if (!$isRangeSelection(selection)) {
3254
+ return;
3255
+ }
3256
+ const anchorNode = selection.anchor.getNode();
3257
+ const inlineStyleTarget = getInlineStyleTarget(selection.getNodes(), anchorNode);
3258
+ const style = selection.style || getInlineStyleFromNode(inlineStyleTarget);
3259
+ const isCollapsed = selection.isCollapsed();
3260
+ snapshot = {
3261
+ blockType: extractInlineBlockTypeFromStyle(style) ?? getElementBlockType(anchorNode),
3262
+ fontFamily: normalizeFontFamily(extractFontFamilyFromStyle(style)),
3263
+ fontSize: extractFontSizePtFromStyle(style) ?? DEFAULT_FONT_SIZE,
3264
+ alignment: getElementAlignment(anchorNode),
3265
+ isBold: selection.hasFormat("bold") || isCollapsed && hasInlineFormat(inlineStyleTarget, "bold"),
3266
+ isItalic: selection.hasFormat("italic") || isCollapsed && hasInlineFormat(inlineStyleTarget, "italic"),
3267
+ isUnderline: selection.hasFormat("underline") || isCollapsed && hasInlineFormat(inlineStyleTarget, "underline"),
3268
+ isStrikethrough: selection.hasFormat("strikethrough") || isCollapsed && hasInlineFormat(inlineStyleTarget, "strikethrough"),
3269
+ hasSelectedVariable: false
3270
+ };
3271
+ });
3272
+ return snapshot;
3273
+ }
2919
3274
  const Toolbar = () => {
2920
3275
  const {
2921
3276
  activeEditor,
@@ -2932,15 +3287,15 @@ const Toolbar = () => {
2932
3287
  const { toolbarItems, toolbarEndItems } = useExtensions();
2933
3288
  const toolbarConfig = useToolbarConfig();
2934
3289
  const t = useTranslations();
2935
- const [activeBlockType, setActiveBlockType] = useState("paragraph");
2936
- const [activeFontFamily, setActiveFontFamily] = useState("Calibri");
2937
- const [activeFontSize, setActiveFontSize] = useState(DEFAULT_FONT_SIZE);
2938
- const normalizeFontFamily = useCallback((fontFamily) => {
2939
- if (fontFamily && SUPPORTED_FONTS.includes(fontFamily)) {
2940
- return fontFamily;
2941
- }
2942
- return "Calibri";
2943
- }, []);
3290
+ const toolbarStyleStore = useToolbarStyleStoreApi();
3291
+ const activeBlockType = useToolbarStyleStore((state) => state.blockType);
3292
+ const activeFontFamily = useToolbarStyleStore((state) => state.fontFamily);
3293
+ const activeFontSize = useToolbarStyleStore((state) => state.fontSize);
3294
+ const activeAlignment = useToolbarStyleStore((state) => state.alignment);
3295
+ const isBoldActive = useToolbarStyleStore((state) => state.isBold);
3296
+ const isItalicActive = useToolbarStyleStore((state) => state.isItalic);
3297
+ const isUnderlineActive = useToolbarStyleStore((state) => state.isUnderline);
3298
+ const isStrikethroughActive = useToolbarStyleStore((state) => state.isStrikethrough);
2944
3299
  const withBodySelection = useCallback(
2945
3300
  (editor, action) => {
2946
3301
  editor.update(() => {
@@ -2978,38 +3333,11 @@ const Toolbar = () => {
2978
3333
  );
2979
3334
  useEffect(() => {
2980
3335
  if (!activeEditor) {
2981
- setActiveBlockType("paragraph");
2982
- setActiveFontFamily("Calibri");
2983
- setActiveFontSize(DEFAULT_FONT_SIZE);
3336
+ toolbarStyleStore.getState().reset();
2984
3337
  return;
2985
3338
  }
2986
- const updateSelectionState = () => {
2987
- const selectedVariables = getSelectedVariableNodes(activeEditor);
2988
- if (selectedVariables.length > 0) {
2989
- const formatting = readSelectedVariableFormatting(activeEditor);
2990
- setActiveBlockType("paragraph");
2991
- setActiveFontFamily(normalizeFontFamily(formatting.fontFamily));
2992
- setActiveFontSize(formatting.fontSize ?? DEFAULT_FONT_SIZE);
2993
- return;
2994
- }
2995
- setActiveBlockType(getActiveBlockType(activeEditor));
2996
- let nextFontFamily = "Calibri";
2997
- let nextFontSize = DEFAULT_FONT_SIZE;
2998
- activeEditor.getEditorState().read(() => {
2999
- const selection = $getSelection();
3000
- if (!$isRangeSelection(selection)) {
3001
- return;
3002
- }
3003
- const textNode = selection.getNodes().find($isTextNode);
3004
- if (!textNode) {
3005
- return;
3006
- }
3007
- const style = textNode.getStyle();
3008
- nextFontFamily = normalizeFontFamily(extractFontFamilyFromStyle(style));
3009
- nextFontSize = extractFontSizePtFromStyle(style) ?? DEFAULT_FONT_SIZE;
3010
- });
3011
- setActiveFontFamily(nextFontFamily);
3012
- setActiveFontSize(nextFontSize);
3339
+ const updateSelectionState = (editorState = activeEditor.getEditorState()) => {
3340
+ toolbarStyleStore.getState().setSnapshot(readToolbarStyleSnapshot(activeEditor, editorState));
3013
3341
  };
3014
3342
  updateSelectionState();
3015
3343
  const unregisterSelectionChange = activeEditor.registerCommand(
@@ -3020,14 +3348,14 @@ const Toolbar = () => {
3020
3348
  },
3021
3349
  COMMAND_PRIORITY_LOW
3022
3350
  );
3023
- const unregisterUpdateListener = activeEditor.registerUpdateListener(() => {
3024
- updateSelectionState();
3351
+ const unregisterUpdateListener = activeEditor.registerUpdateListener(({ editorState }) => {
3352
+ updateSelectionState(editorState);
3025
3353
  });
3026
3354
  return () => {
3027
3355
  unregisterSelectionChange();
3028
3356
  unregisterUpdateListener();
3029
3357
  };
3030
- }, [activeEditor, normalizeFontFamily]);
3358
+ }, [activeEditor, toolbarStyleStore]);
3031
3359
  const handleBold = useCallback(() => {
3032
3360
  debug("toolbar", `bold (globalSelection=${globalSelectionActive}, editors=${editorRegistry.all().length}, hasEditor=${!!activeEditor})`);
3033
3361
  runToolbarAction(t.history.actions.boldApplied, () => {
@@ -3212,17 +3540,17 @@ const Toolbar = () => {
3212
3540
  ] }),
3213
3541
  /* @__PURE__ */ jsx(Divider, {}),
3214
3542
  /* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "format-group", children: [
3215
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.bold, testId: "btn-bold", onClick: handleBold, children: /* @__PURE__ */ jsx(Bold, { size: 15 }) }),
3216
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.italic, testId: "btn-italic", onClick: handleItalic, children: /* @__PURE__ */ jsx(Italic, { size: 15 }) }),
3217
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.underline, testId: "btn-underline", onClick: handleUnderline, children: /* @__PURE__ */ jsx(Underline, { size: 15 }) }),
3218
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.strikethrough, testId: "btn-strike", onClick: handleStrikethrough, children: /* @__PURE__ */ jsx(Strikethrough, { size: 15 }) })
3543
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.bold, testId: "btn-bold", active: isBoldActive, onClick: handleBold, children: /* @__PURE__ */ jsx(Bold, { size: 15 }) }),
3544
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.italic, testId: "btn-italic", active: isItalicActive, onClick: handleItalic, children: /* @__PURE__ */ jsx(Italic, { size: 15 }) }),
3545
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.underline, testId: "btn-underline", active: isUnderlineActive, onClick: handleUnderline, children: /* @__PURE__ */ jsx(Underline, { size: 15 }) }),
3546
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.strikethrough, testId: "btn-strike", active: isStrikethroughActive, onClick: handleStrikethrough, children: /* @__PURE__ */ jsx(Strikethrough, { size: 15 }) })
3219
3547
  ] }),
3220
3548
  /* @__PURE__ */ jsx(Divider, {}),
3221
3549
  /* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "align-group", children: [
3222
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignLeft, testId: "btn-align-left", onClick: handleAlignLeft, children: /* @__PURE__ */ jsx(TextAlignStart, { size: 15 }) }),
3223
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignCenter, testId: "btn-align-center", onClick: handleAlignCenter, children: /* @__PURE__ */ jsx(TextAlignCenter, { size: 15 }) }),
3224
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignRight, testId: "btn-align-right", onClick: handleAlignRight, children: /* @__PURE__ */ jsx(TextAlignEnd, { size: 15 }) }),
3225
- /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.justify, testId: "btn-align-justify", onClick: handleAlignJustify, children: /* @__PURE__ */ jsx(TextAlignJustify, { size: 15 }) })
3550
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignLeft, testId: "btn-align-left", active: activeAlignment === "left", onClick: handleAlignLeft, children: /* @__PURE__ */ jsx(TextAlignStart, { size: 15 }) }),
3551
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignCenter, testId: "btn-align-center", active: activeAlignment === "center", onClick: handleAlignCenter, children: /* @__PURE__ */ jsx(TextAlignCenter, { size: 15 }) }),
3552
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignRight, testId: "btn-align-right", active: activeAlignment === "right", onClick: handleAlignRight, children: /* @__PURE__ */ jsx(TextAlignEnd, { size: 15 }) }),
3553
+ /* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.justify, testId: "btn-align-justify", active: activeAlignment === "justify", onClick: handleAlignJustify, children: /* @__PURE__ */ jsx(TextAlignJustify, { size: 15 }) })
3226
3554
  ] }),
3227
3555
  /* @__PURE__ */ jsx(Divider, {}),
3228
3556
  /* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "list-group", children: [
@@ -3273,6 +3601,7 @@ const ToolbarIconButton = ({
3273
3601
  type: "button",
3274
3602
  title,
3275
3603
  "aria-label": title,
3604
+ "aria-pressed": active,
3276
3605
  disabled,
3277
3606
  onMouseDown: (e) => e.preventDefault(),
3278
3607
  onClick,
@@ -3783,14 +4112,18 @@ const ActiveEditorPlugin = ({
3783
4112
  ]);
3784
4113
  useEffect(() => {
3785
4114
  const caretPosition = { pageId, region };
3786
- const handleFocusIn = () => {
4115
+ const markEditorActive = () => {
3787
4116
  setActivePageId(pageId);
3788
4117
  setActiveEditor(editor, caretPosition);
3789
4118
  onFocus == null ? void 0 : onFocus(editor);
3790
4119
  };
3791
4120
  return editor.registerRootListener((rootElement, prevRootElement) => {
3792
- prevRootElement == null ? void 0 : prevRootElement.removeEventListener("focusin", handleFocusIn);
3793
- rootElement == null ? void 0 : rootElement.addEventListener("focusin", handleFocusIn);
4121
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("focusin", markEditorActive);
4122
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousedown", markEditorActive);
4123
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("pointerdown", markEditorActive);
4124
+ rootElement == null ? void 0 : rootElement.addEventListener("focusin", markEditorActive);
4125
+ rootElement == null ? void 0 : rootElement.addEventListener("mousedown", markEditorActive);
4126
+ rootElement == null ? void 0 : rootElement.addEventListener("pointerdown", markEditorActive);
3794
4127
  });
3795
4128
  }, [editor, onFocus, pageId, region, setActiveEditor, setActivePageId]);
3796
4129
  useEffect(() => {
@@ -4460,7 +4793,7 @@ const EditorRegistryPlugin = ({ pageId }) => {
4460
4793
  editorRegistry.register(pageId, editor);
4461
4794
  debug("registry", `registered editor for page ${shortId(pageId)}`);
4462
4795
  return () => {
4463
- editorRegistry.unregister(pageId);
4796
+ editorRegistry.unregister(pageId, editor);
4464
4797
  debug("registry", `unregistered editor for page ${shortId(pageId)}`);
4465
4798
  };
4466
4799
  }, [editor, pageId, editorRegistry]);
@@ -4784,7 +5117,7 @@ const PageView = React.memo(({
4784
5117
  onMoveToPreviousPage,
4785
5118
  onMoveToNextPage
4786
5119
  }) => {
4787
- const { document: document2, dispatch, setActivePageId } = useDocument();
5120
+ const { document: document2, dispatch, editorRegistry, setActiveEditor, setActivePageId } = useDocument();
4788
5121
  const t = useTranslations();
4789
5122
  const page = document2.pages.find((p) => p.id === pageId);
4790
5123
  const showHeaderFooter = document2.headerFooterEnabled;
@@ -4814,7 +5147,11 @@ const PageView = React.memo(({
4814
5147
  );
4815
5148
  const handleFocus = useCallback(() => {
4816
5149
  setActivePageId(pageId);
4817
- }, [setActivePageId, pageId]);
5150
+ const editor = editorRegistry.get(pageId);
5151
+ if (editor) {
5152
+ setActiveEditor(editor, { pageId, region: "body" });
5153
+ }
5154
+ }, [editorRegistry, pageId, setActiveEditor, setActivePageId]);
4818
5155
  const handleOverflow = useCallback(
4819
5156
  (overflowContent, cause) => {
4820
5157
  onOverflow == null ? void 0 : onOverflow(overflowContent, cause);
@@ -5474,6 +5811,20 @@ function insertDocumentContent(editor, document2) {
5474
5811
  });
5475
5812
  return inserted;
5476
5813
  }
5814
+ function resolveDocumentInsertTarget({
5815
+ activeEditor,
5816
+ activeCaretPosition,
5817
+ activePageId,
5818
+ editorRegistry
5819
+ }) {
5820
+ if (activeEditor && (activeCaretPosition == null ? void 0 : activeCaretPosition.region) === "body") {
5821
+ return activeEditor;
5822
+ }
5823
+ if (activePageId) {
5824
+ return editorRegistry.get(activePageId) ?? null;
5825
+ }
5826
+ return editorRegistry.all()[0] ?? null;
5827
+ }
5477
5828
  function selectEntireDocument(rootElement, selectionBuffer) {
5478
5829
  if (!rootElement || !selectionBuffer) {
5479
5830
  return;
@@ -5679,8 +6030,10 @@ const EditorChrome = ({
5679
6030
  const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, onSave, className }, ref) => {
5680
6031
  const {
5681
6032
  document: doc,
6033
+ activePageId,
5682
6034
  activeEditor,
5683
6035
  activeCaretPosition,
6036
+ editorRegistry,
5684
6037
  historySidebarOpen,
5685
6038
  runHistoryAction,
5686
6039
  setHistorySidebarOpen
@@ -5689,7 +6042,6 @@ const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, onSave,
5689
6042
  const t = useTranslations();
5690
6043
  const documentRef = useRef(doc);
5691
6044
  const activeEditorRef = useRef(activeEditor);
5692
- const activeCaretRegionRef = useRef(activeCaretPosition == null ? void 0 : activeCaretPosition.region);
5693
6045
  const historySidebarOpenRef = useRef(historySidebarOpen);
5694
6046
  const runHistoryActionRef = useRef(runHistoryAction);
5695
6047
  const insertedDocumentContentLabelRef = useRef(t.history.actions.insertedDocumentContent);
@@ -5699,9 +6051,6 @@ const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, onSave,
5699
6051
  useEffect(() => {
5700
6052
  activeEditorRef.current = activeEditor;
5701
6053
  }, [activeEditor]);
5702
- useEffect(() => {
5703
- activeCaretRegionRef.current = activeCaretPosition == null ? void 0 : activeCaretPosition.region;
5704
- }, [activeCaretPosition == null ? void 0 : activeCaretPosition.region]);
5705
6054
  useEffect(() => {
5706
6055
  historySidebarOpenRef.current = historySidebarOpen;
5707
6056
  }, [historySidebarOpen]);
@@ -5724,8 +6073,13 @@ const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, onSave,
5724
6073
  setHistorySidebarOpen(!historySidebarOpenRef.current);
5725
6074
  };
5726
6075
  handle.insertDocumentContent = (documentToInsert) => {
5727
- const currentActiveEditor = activeEditorRef.current;
5728
- if (!currentActiveEditor || activeCaretRegionRef.current !== "body") {
6076
+ const targetEditor = resolveDocumentInsertTarget({
6077
+ activeEditor: activeEditorRef.current,
6078
+ activeCaretPosition,
6079
+ activePageId,
6080
+ editorRegistry
6081
+ });
6082
+ if (!targetEditor) {
5729
6083
  return false;
5730
6084
  }
5731
6085
  let inserted = false;
@@ -5736,7 +6090,7 @@ const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, onSave,
5736
6090
  region: "document"
5737
6091
  },
5738
6092
  () => {
5739
- inserted = insertDocumentContent(currentActiveEditor, documentToInsert);
6093
+ inserted = insertDocumentContent(targetEditor, documentToInsert);
5740
6094
  }
5741
6095
  );
5742
6096
  return inserted;