@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.
- package/README.md +4 -2
- package/dist/components/BlockTypePicker.d.ts +1 -1
- package/dist/components/BlockTypePicker.d.ts.map +1 -1
- package/dist/components/Lex4Editor.d.ts.map +1 -1
- package/dist/components/PageView.d.ts.map +1 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/context/document-context.d.ts +1 -1
- package/dist/context/document-context.d.ts.map +1 -1
- package/dist/context/document-provider.d.ts.map +1 -1
- package/dist/context/toolbar-style-snapshot.d.ts +4 -0
- package/dist/context/toolbar-style-snapshot.d.ts.map +1 -0
- package/dist/context/toolbar-style-store.d.ts +28 -0
- package/dist/context/toolbar-style-store.d.ts.map +1 -0
- package/dist/lex4-editor.cjs +513 -159
- package/dist/lex4-editor.cjs.map +1 -1
- package/dist/lex4-editor.js +516 -162
- package/dist/lex4-editor.js.map +1 -1
- package/dist/lexical/commands/block-commands.d.ts +1 -1
- package/dist/lexical/commands/block-commands.d.ts.map +1 -1
- package/dist/lexical/commands/block-types.d.ts +2 -0
- package/dist/lexical/commands/block-types.d.ts.map +1 -0
- package/dist/lexical/plugins/active-editor-plugin.d.ts.map +1 -1
- package/dist/style.css +2 -2
- package/dist/utils/document-insert-target.d.ts +12 -0
- package/dist/utils/document-insert-target.d.ts.map +1 -0
- package/dist/utils/text-style.d.ts +6 -0
- package/dist/utils/text-style.d.ts.map +1 -1
- package/dist/variables/variable-formatting.d.ts.map +1 -1
- package/dist/variables/variable-node.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/lex4-editor.js
CHANGED
|
@@ -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,
|
|
6
|
-
import { $
|
|
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
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
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
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
2936
|
-
const
|
|
2937
|
-
const
|
|
2938
|
-
const
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
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
|
-
|
|
2982
|
-
setActiveFontFamily("Calibri");
|
|
2983
|
-
setActiveFontSize(DEFAULT_FONT_SIZE);
|
|
3336
|
+
toolbarStyleStore.getState().reset();
|
|
2984
3337
|
return;
|
|
2985
3338
|
}
|
|
2986
|
-
const updateSelectionState = () => {
|
|
2987
|
-
|
|
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,
|
|
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
|
|
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",
|
|
3793
|
-
|
|
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
|
-
|
|
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
|
|
5728
|
-
|
|
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(
|
|
6093
|
+
inserted = insertDocumentContent(targetEditor, documentToInsert);
|
|
5740
6094
|
}
|
|
5741
6095
|
);
|
|
5742
6096
|
return inserted;
|