@yurikilian/lex4 1.8.0 → 1.11.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/dist/ast/block-mapper.d.ts.map +1 -1
- package/dist/ast/index.d.ts +1 -1
- package/dist/ast/index.d.ts.map +1 -1
- package/dist/ast/inline-mapper.d.ts +7 -1
- package/dist/ast/inline-mapper.d.ts.map +1 -1
- package/dist/ast/types.d.ts +10 -2
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/VariablePanel.d.ts.map +1 -1
- package/dist/context/toolbar-style-snapshot.d.ts.map +1 -1
- package/dist/context/toolbar-style-store.d.ts +4 -0
- package/dist/context/toolbar-style-store.d.ts.map +1 -1
- package/dist/extensions/variables-extension.d.ts.map +1 -1
- package/dist/i18n/defaults.d.ts.map +1 -1
- package/dist/i18n/pt-BR.d.ts.map +1 -1
- package/dist/i18n/types.d.ts +5 -0
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lex4-editor.cjs +538 -39
- package/dist/lex4-editor.cjs.map +1 -1
- package/dist/lex4-editor.js +540 -41
- package/dist/lex4-editor.js.map +1 -1
- package/dist/lexical/commands/list-commands.d.ts +1 -1
- package/dist/lexical/commands/list-commands.d.ts.map +1 -1
- package/dist/lexical/editor-setup.d.ts.map +1 -1
- package/dist/lexical/nodes/alpha-list-node.d.ts +17 -0
- package/dist/lexical/nodes/alpha-list-node.d.ts.map +1 -0
- package/dist/lexical/utils/import-document-content.d.ts.map +1 -1
- package/dist/style.css +133 -16
- package/dist/variables/index.d.ts +3 -0
- package/dist/variables/index.d.ts.map +1 -1
- package/dist/variables/optional-segment-commands.d.ts +24 -0
- package/dist/variables/optional-segment-commands.d.ts.map +1 -0
- package/dist/variables/optional-segment-node.d.ts +32 -0
- package/dist/variables/optional-segment-node.d.ts.map +1 -0
- package/dist/variables/optional-segment-plugin.d.ts +6 -0
- package/dist/variables/optional-segment-plugin.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/lex4-editor.js
CHANGED
|
@@ -3,9 +3,10 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
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
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,
|
|
6
|
+
import { $getSelection, $isRangeSelection, $isTextNode, $getRoot, $createRangeSelectionFromDom, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, $applyNodeReplacement, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, DecoratorNode, $createNodeSelection, $isNodeSelection, $setSelection, KEY_BACKSPACE_COMMAND, COMMAND_PRIORITY_LOW, KEY_DELETE_COMMAND, KEY_DOWN_COMMAND, $getNodeByKey, $isElementNode, $createParagraphNode, ElementNode, createCommand, $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, COMMAND_PRIORITY_EDITOR } from "lexical";
|
|
7
7
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
8
|
-
import { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND,
|
|
8
|
+
import { ListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, $createListNode, $isListNode, ListItemNode, $createListItemNode } from "@lexical/list";
|
|
9
|
+
import { $findMatchingParent } from "@lexical/utils";
|
|
9
10
|
import { $patchStyleText, $setBlocksType } from "@lexical/selection";
|
|
10
11
|
import { $createHeadingNode, $isHeadingNode, HeadingNode, QuoteNode, $createQuoteNode } from "@lexical/rich-text";
|
|
11
12
|
import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
|
|
@@ -471,6 +472,7 @@ const DEFAULT_TRANSLATIONS = {
|
|
|
471
472
|
justify: "Justify",
|
|
472
473
|
numberedList: "Numbered List",
|
|
473
474
|
bulletList: "Bullet List",
|
|
475
|
+
alphabeticList: "Alphabetic List",
|
|
474
476
|
indent: "Indent",
|
|
475
477
|
outdent: "Outdent",
|
|
476
478
|
history: "History",
|
|
@@ -510,12 +512,14 @@ const DEFAULT_TRANSLATIONS = {
|
|
|
510
512
|
justifiedText: "Justified text",
|
|
511
513
|
insertedNumberedList: "Inserted numbered list",
|
|
512
514
|
insertedBulletList: "Inserted bullet list",
|
|
515
|
+
insertedAlphabeticList: "Inserted alphabetic list",
|
|
513
516
|
indentedContent: "Indented content",
|
|
514
517
|
outdentedContent: "Outdented content",
|
|
515
518
|
fontChanged: "Font changed to {{value}}",
|
|
516
519
|
fontSizeChanged: "Font size changed to {{value}}pt",
|
|
517
520
|
blockTypeChanged: "Block type changed to {{value}}",
|
|
518
|
-
insertedDocumentContent: "Inserted document content"
|
|
521
|
+
insertedDocumentContent: "Inserted document content",
|
|
522
|
+
optionalSegmentToggled: "Optional section toggled"
|
|
519
523
|
}
|
|
520
524
|
},
|
|
521
525
|
variables: {
|
|
@@ -536,7 +540,9 @@ const DEFAULT_TRANSLATIONS = {
|
|
|
536
540
|
createVariableSave: "Add variable",
|
|
537
541
|
createVariableCancel: "Cancel",
|
|
538
542
|
createVariableMissingFields: "Label and key are required.",
|
|
539
|
-
createVariableDuplicateKey: "Variable {{key}} already exists."
|
|
543
|
+
createVariableDuplicateKey: "Variable {{key}} already exists.",
|
|
544
|
+
optionalSegmentToggle: "Optional section",
|
|
545
|
+
optionalSegmentTooltip: "Optional section — appears only when all fields have a value"
|
|
540
546
|
},
|
|
541
547
|
header: {
|
|
542
548
|
placeholder: "Header"
|
|
@@ -613,6 +619,7 @@ const PT_BR_TRANSLATIONS = {
|
|
|
613
619
|
justify: "Justificar",
|
|
614
620
|
numberedList: "Lista Numerada",
|
|
615
621
|
bulletList: "Lista com Marcadores",
|
|
622
|
+
alphabeticList: "Lista Alfabética",
|
|
616
623
|
indent: "Aumentar Recuo",
|
|
617
624
|
outdent: "Diminuir Recuo",
|
|
618
625
|
history: "Histórico",
|
|
@@ -652,12 +659,14 @@ const PT_BR_TRANSLATIONS = {
|
|
|
652
659
|
justifiedText: "Texto justificado",
|
|
653
660
|
insertedNumberedList: "Lista numerada inserida",
|
|
654
661
|
insertedBulletList: "Lista com marcadores inserida",
|
|
662
|
+
insertedAlphabeticList: "Lista alfabética inserida",
|
|
655
663
|
indentedContent: "Conteúdo recuado",
|
|
656
664
|
outdentedContent: "Recuo reduzido",
|
|
657
665
|
fontChanged: "Fonte alterada para {{value}}",
|
|
658
666
|
fontSizeChanged: "Tamanho da fonte alterado para {{value}}pt",
|
|
659
667
|
blockTypeChanged: "Tipo de bloco alterado para {{value}}",
|
|
660
|
-
insertedDocumentContent: "Conteúdo do documento inserido"
|
|
668
|
+
insertedDocumentContent: "Conteúdo do documento inserido",
|
|
669
|
+
optionalSegmentToggled: "Seção opcional alternada"
|
|
661
670
|
}
|
|
662
671
|
},
|
|
663
672
|
variables: {
|
|
@@ -678,7 +687,9 @@ const PT_BR_TRANSLATIONS = {
|
|
|
678
687
|
createVariableSave: "Adicionar variável",
|
|
679
688
|
createVariableCancel: "Cancelar",
|
|
680
689
|
createVariableMissingFields: "Rótulo e chave são obrigatórios.",
|
|
681
|
-
createVariableDuplicateKey: "A variável {{key}} já existe."
|
|
690
|
+
createVariableDuplicateKey: "A variável {{key}} já existe.",
|
|
691
|
+
optionalSegmentToggle: "Seção opcional",
|
|
692
|
+
optionalSegmentTooltip: "Seção opcional — aparece apenas quando todos os campos têm valor"
|
|
682
693
|
},
|
|
683
694
|
header: {
|
|
684
695
|
placeholder: "Cabeçalho"
|
|
@@ -851,11 +862,14 @@ const DEFAULT_TOOLBAR_STYLE_SNAPSHOT = {
|
|
|
851
862
|
fontFamily: "Inter",
|
|
852
863
|
fontSize: DEFAULT_FONT_SIZE,
|
|
853
864
|
alignment: "left",
|
|
865
|
+
activeList: "none",
|
|
854
866
|
isBold: false,
|
|
855
867
|
isItalic: false,
|
|
856
868
|
isUnderline: false,
|
|
857
869
|
isStrikethrough: false,
|
|
858
|
-
hasSelectedVariable: false
|
|
870
|
+
hasSelectedVariable: false,
|
|
871
|
+
hasTextSelection: false,
|
|
872
|
+
insideOptionalSegment: false
|
|
859
873
|
};
|
|
860
874
|
function createToolbarStyleStore(initialSnapshot = DEFAULT_TOOLBAR_STYLE_SNAPSHOT) {
|
|
861
875
|
return createStore((set) => ({
|
|
@@ -1571,33 +1585,33 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
1571
1585
|
* This source code is licensed under the ISC license.
|
|
1572
1586
|
* See the LICENSE file in the root directory of this source tree.
|
|
1573
1587
|
*/
|
|
1574
|
-
const __iconNode$
|
|
1588
|
+
const __iconNode$s = [
|
|
1575
1589
|
["path", { d: "m15 16 2.536-7.328a1.02 1.02 1 0 1 1.928 0L22 16", key: "xik6mr" }],
|
|
1576
1590
|
["path", { d: "M15.697 14h5.606", key: "1stdlc" }],
|
|
1577
1591
|
["path", { d: "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", key: "d5nyq2" }],
|
|
1578
1592
|
["path", { d: "M3.304 13h6.392", key: "1q3zxz" }]
|
|
1579
1593
|
];
|
|
1580
|
-
const ALargeSmall = createLucideIcon("a-large-small", __iconNode$
|
|
1594
|
+
const ALargeSmall = createLucideIcon("a-large-small", __iconNode$s);
|
|
1581
1595
|
/**
|
|
1582
1596
|
* @license lucide-react v1.8.0 - ISC
|
|
1583
1597
|
*
|
|
1584
1598
|
* This source code is licensed under the ISC license.
|
|
1585
1599
|
* See the LICENSE file in the root directory of this source tree.
|
|
1586
1600
|
*/
|
|
1587
|
-
const __iconNode$
|
|
1601
|
+
const __iconNode$r = [
|
|
1588
1602
|
[
|
|
1589
1603
|
"path",
|
|
1590
1604
|
{ d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8", key: "mg9rjx" }
|
|
1591
1605
|
]
|
|
1592
1606
|
];
|
|
1593
|
-
const Bold = createLucideIcon("bold", __iconNode$
|
|
1607
|
+
const Bold = createLucideIcon("bold", __iconNode$r);
|
|
1594
1608
|
/**
|
|
1595
1609
|
* @license lucide-react v1.8.0 - ISC
|
|
1596
1610
|
*
|
|
1597
1611
|
* This source code is licensed under the ISC license.
|
|
1598
1612
|
* See the LICENSE file in the root directory of this source tree.
|
|
1599
1613
|
*/
|
|
1600
|
-
const __iconNode$
|
|
1614
|
+
const __iconNode$q = [
|
|
1601
1615
|
[
|
|
1602
1616
|
"path",
|
|
1603
1617
|
{ d: "M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1", key: "ezmyqa" }
|
|
@@ -1610,7 +1624,18 @@ const __iconNode$p = [
|
|
|
1610
1624
|
}
|
|
1611
1625
|
]
|
|
1612
1626
|
];
|
|
1613
|
-
const Braces = createLucideIcon("braces", __iconNode$
|
|
1627
|
+
const Braces = createLucideIcon("braces", __iconNode$q);
|
|
1628
|
+
/**
|
|
1629
|
+
* @license lucide-react v1.8.0 - ISC
|
|
1630
|
+
*
|
|
1631
|
+
* This source code is licensed under the ISC license.
|
|
1632
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1633
|
+
*/
|
|
1634
|
+
const __iconNode$p = [
|
|
1635
|
+
["path", { d: "M16 3h3a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1h-3", key: "1kt8lf" }],
|
|
1636
|
+
["path", { d: "M8 21H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h3", key: "gduv9" }]
|
|
1637
|
+
];
|
|
1638
|
+
const Brackets = createLucideIcon("brackets", __iconNode$p);
|
|
1614
1639
|
/**
|
|
1615
1640
|
* @license lucide-react v1.8.0 - ISC
|
|
1616
1641
|
*
|
|
@@ -2208,13 +2233,145 @@ function toggleStrikethrough(editor) {
|
|
|
2208
2233
|
function setAlignment(editor, alignment) {
|
|
2209
2234
|
editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, alignment);
|
|
2210
2235
|
}
|
|
2236
|
+
function decorateAlphaListDom(dom) {
|
|
2237
|
+
dom.classList.add("lex4-list-alpha");
|
|
2238
|
+
dom.setAttribute("data-lex4-list-variant", "alpha");
|
|
2239
|
+
}
|
|
2240
|
+
class AlphaListNode extends ListNode {
|
|
2241
|
+
static getType() {
|
|
2242
|
+
return "alpha-list";
|
|
2243
|
+
}
|
|
2244
|
+
static clone(node) {
|
|
2245
|
+
return new AlphaListNode(node.getStart(), node.__key);
|
|
2246
|
+
}
|
|
2247
|
+
static importJSON(serializedNode) {
|
|
2248
|
+
const node = $createAlphaListNode(
|
|
2249
|
+
typeof serializedNode.start === "number" ? serializedNode.start : 1
|
|
2250
|
+
);
|
|
2251
|
+
node.setFormat(serializedNode.format);
|
|
2252
|
+
node.setIndent(serializedNode.indent);
|
|
2253
|
+
node.setDirection(serializedNode.direction);
|
|
2254
|
+
return node;
|
|
2255
|
+
}
|
|
2256
|
+
constructor(start = 1, key) {
|
|
2257
|
+
super("number", start, key);
|
|
2258
|
+
}
|
|
2259
|
+
createDOM(config, editor) {
|
|
2260
|
+
const dom = super.createDOM(config, editor);
|
|
2261
|
+
decorateAlphaListDom(dom);
|
|
2262
|
+
return dom;
|
|
2263
|
+
}
|
|
2264
|
+
updateDOM(prevNode, dom, config) {
|
|
2265
|
+
const replaced = super.updateDOM(prevNode, dom, config);
|
|
2266
|
+
if (replaced) {
|
|
2267
|
+
return true;
|
|
2268
|
+
}
|
|
2269
|
+
decorateAlphaListDom(dom);
|
|
2270
|
+
return false;
|
|
2271
|
+
}
|
|
2272
|
+
exportJSON() {
|
|
2273
|
+
return {
|
|
2274
|
+
...super.exportJSON(),
|
|
2275
|
+
type: "alpha-list",
|
|
2276
|
+
markerStyle: "alpha"
|
|
2277
|
+
};
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
function $createAlphaListNode(start = 1) {
|
|
2281
|
+
return $applyNodeReplacement(new AlphaListNode(start));
|
|
2282
|
+
}
|
|
2283
|
+
function $isAlphaListNode(node) {
|
|
2284
|
+
return node instanceof AlphaListNode;
|
|
2285
|
+
}
|
|
2286
|
+
function getNearestListNode$1(node) {
|
|
2287
|
+
if ($isListNode(node)) {
|
|
2288
|
+
return node;
|
|
2289
|
+
}
|
|
2290
|
+
const listNode = $findMatchingParent(node, $isListNode);
|
|
2291
|
+
return $isListNode(listNode) ? listNode : null;
|
|
2292
|
+
}
|
|
2293
|
+
function getSelectedListNodes() {
|
|
2294
|
+
const selection = $getSelection();
|
|
2295
|
+
if (!selection) {
|
|
2296
|
+
return [];
|
|
2297
|
+
}
|
|
2298
|
+
const listNodes = /* @__PURE__ */ new Map();
|
|
2299
|
+
const nodes = selection.getNodes();
|
|
2300
|
+
if ($isRangeSelection(selection)) {
|
|
2301
|
+
nodes.push(selection.anchor.getNode(), selection.focus.getNode());
|
|
2302
|
+
}
|
|
2303
|
+
for (const node of nodes) {
|
|
2304
|
+
const listNode = getNearestListNode$1(node);
|
|
2305
|
+
if (listNode) {
|
|
2306
|
+
listNodes.set(listNode.getKey(), listNode);
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
return Array.from(listNodes.values());
|
|
2310
|
+
}
|
|
2311
|
+
function replaceWithAlphaList(listNode) {
|
|
2312
|
+
if ($isAlphaListNode(listNode) || listNode.getListType() !== "number") {
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
const alphaList = $createAlphaListNode(listNode.getStart());
|
|
2316
|
+
alphaList.setFormat(listNode.getFormatType());
|
|
2317
|
+
alphaList.setIndent(listNode.getIndent());
|
|
2318
|
+
alphaList.setDirection(listNode.getDirection());
|
|
2319
|
+
alphaList.append(...listNode.getChildren());
|
|
2320
|
+
listNode.replace(alphaList);
|
|
2321
|
+
}
|
|
2322
|
+
function replaceWithPlainList(listNode, listType) {
|
|
2323
|
+
if (!$isAlphaListNode(listNode) && listNode.getListType() === listType) {
|
|
2324
|
+
return;
|
|
2325
|
+
}
|
|
2326
|
+
const plainList = $createListNode(
|
|
2327
|
+
listType,
|
|
2328
|
+
listType === "number" ? listNode.getStart() : 1
|
|
2329
|
+
);
|
|
2330
|
+
plainList.setFormat(listNode.getFormatType());
|
|
2331
|
+
plainList.setIndent(listNode.getIndent());
|
|
2332
|
+
plainList.setDirection(listNode.getDirection());
|
|
2333
|
+
plainList.append(...listNode.getChildren());
|
|
2334
|
+
listNode.replace(plainList);
|
|
2335
|
+
}
|
|
2336
|
+
function insertAlphaList(editor) {
|
|
2337
|
+
const hasAlphaListSelection = editor.getEditorState().read(
|
|
2338
|
+
() => getSelectedListNodes().some($isAlphaListNode)
|
|
2339
|
+
);
|
|
2340
|
+
if (hasAlphaListSelection) {
|
|
2341
|
+
removeList(editor);
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
|
|
2345
|
+
editor.update(() => {
|
|
2346
|
+
getSelectedListNodes().forEach(replaceWithAlphaList);
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2349
|
+
function normalizeSelectedAlphaLists(editor, listType) {
|
|
2350
|
+
const hasAlphaListSelection = editor.getEditorState().read(
|
|
2351
|
+
() => getSelectedListNodes().some($isAlphaListNode)
|
|
2352
|
+
);
|
|
2353
|
+
if (!hasAlphaListSelection) {
|
|
2354
|
+
return false;
|
|
2355
|
+
}
|
|
2356
|
+
editor.update(() => {
|
|
2357
|
+
getSelectedListNodes().forEach((listNode) => replaceWithPlainList(listNode, listType));
|
|
2358
|
+
});
|
|
2359
|
+
return true;
|
|
2360
|
+
}
|
|
2211
2361
|
function insertList(editor, type) {
|
|
2212
|
-
if (type === "
|
|
2362
|
+
if (type === "alpha") {
|
|
2363
|
+
insertAlphaList(editor);
|
|
2364
|
+
} else if (normalizeSelectedAlphaLists(editor, type)) {
|
|
2365
|
+
return;
|
|
2366
|
+
} else if (type === "number") {
|
|
2213
2367
|
editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
|
|
2214
2368
|
} else {
|
|
2215
2369
|
editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
|
|
2216
2370
|
}
|
|
2217
2371
|
}
|
|
2372
|
+
function removeList(editor) {
|
|
2373
|
+
editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
|
|
2374
|
+
}
|
|
2218
2375
|
function indentContent(editor) {
|
|
2219
2376
|
editor.dispatchCommand(INDENT_CONTENT_COMMAND, void 0);
|
|
2220
2377
|
}
|
|
@@ -2608,7 +2765,7 @@ function VariableChip({
|
|
|
2608
2765
|
className,
|
|
2609
2766
|
"data-testid": `variable-chip-${variableKey}`,
|
|
2610
2767
|
"data-variable-group": group,
|
|
2611
|
-
title:
|
|
2768
|
+
title: label,
|
|
2612
2769
|
style,
|
|
2613
2770
|
onMouseDown: handleMouseDown,
|
|
2614
2771
|
onMouseUp: handleMouseUp,
|
|
@@ -3269,6 +3426,154 @@ const CanvasControls = () => {
|
|
|
3269
3426
|
)
|
|
3270
3427
|
] });
|
|
3271
3428
|
};
|
|
3429
|
+
class OptionalSegmentNode extends ElementNode {
|
|
3430
|
+
static getType() {
|
|
3431
|
+
return "optional-segment";
|
|
3432
|
+
}
|
|
3433
|
+
static clone(node) {
|
|
3434
|
+
return new OptionalSegmentNode(node.__key);
|
|
3435
|
+
}
|
|
3436
|
+
constructor(key) {
|
|
3437
|
+
super(key);
|
|
3438
|
+
}
|
|
3439
|
+
// -- Serialization --
|
|
3440
|
+
static importJSON(serializedNode) {
|
|
3441
|
+
const node = $createOptionalSegmentNode();
|
|
3442
|
+
node.setFormat(serializedNode.format);
|
|
3443
|
+
node.setIndent(serializedNode.indent);
|
|
3444
|
+
node.setDirection(serializedNode.direction);
|
|
3445
|
+
return node;
|
|
3446
|
+
}
|
|
3447
|
+
exportJSON() {
|
|
3448
|
+
return {
|
|
3449
|
+
...super.exportJSON(),
|
|
3450
|
+
type: "optional-segment",
|
|
3451
|
+
version: 1
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
// -- DOM --
|
|
3455
|
+
createDOM() {
|
|
3456
|
+
const span = document.createElement("span");
|
|
3457
|
+
span.className = "lex4-optional-segment";
|
|
3458
|
+
span.setAttribute("data-lex4-optional-segment", "true");
|
|
3459
|
+
span.setAttribute("data-testid", "optional-segment");
|
|
3460
|
+
return span;
|
|
3461
|
+
}
|
|
3462
|
+
updateDOM() {
|
|
3463
|
+
return false;
|
|
3464
|
+
}
|
|
3465
|
+
exportDOM() {
|
|
3466
|
+
const span = document.createElement("span");
|
|
3467
|
+
span.setAttribute("data-lex4-optional-segment", "true");
|
|
3468
|
+
return { element: span };
|
|
3469
|
+
}
|
|
3470
|
+
static importDOM() {
|
|
3471
|
+
return null;
|
|
3472
|
+
}
|
|
3473
|
+
// -- Behavior --
|
|
3474
|
+
isInline() {
|
|
3475
|
+
return true;
|
|
3476
|
+
}
|
|
3477
|
+
canBeEmpty() {
|
|
3478
|
+
return false;
|
|
3479
|
+
}
|
|
3480
|
+
canInsertTextBefore() {
|
|
3481
|
+
return false;
|
|
3482
|
+
}
|
|
3483
|
+
canInsertTextAfter() {
|
|
3484
|
+
return false;
|
|
3485
|
+
}
|
|
3486
|
+
insertNewAfter(_, restoreSelection = true) {
|
|
3487
|
+
const segment = $createOptionalSegmentNode();
|
|
3488
|
+
this.insertAfter(segment, restoreSelection);
|
|
3489
|
+
return segment;
|
|
3490
|
+
}
|
|
3491
|
+
extractWithChild(_child, selection, _destination) {
|
|
3492
|
+
if (!$isRangeSelection(selection)) {
|
|
3493
|
+
return false;
|
|
3494
|
+
}
|
|
3495
|
+
const anchorNode = selection.anchor.getNode();
|
|
3496
|
+
const focusNode = selection.focus.getNode();
|
|
3497
|
+
return this.isParentOf(anchorNode) && this.isParentOf(focusNode) && selection.getTextContent().length > 0;
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
function $createOptionalSegmentNode() {
|
|
3501
|
+
return $applyNodeReplacement(new OptionalSegmentNode());
|
|
3502
|
+
}
|
|
3503
|
+
function $isOptionalSegmentNode(node) {
|
|
3504
|
+
return node instanceof OptionalSegmentNode;
|
|
3505
|
+
}
|
|
3506
|
+
const TOGGLE_OPTIONAL_SEGMENT_COMMAND = createCommand(
|
|
3507
|
+
"TOGGLE_OPTIONAL_SEGMENT"
|
|
3508
|
+
);
|
|
3509
|
+
function $getAncestorOptionalSegment(node) {
|
|
3510
|
+
let current = node;
|
|
3511
|
+
while (current !== null) {
|
|
3512
|
+
if ($isOptionalSegmentNode(current)) {
|
|
3513
|
+
return current;
|
|
3514
|
+
}
|
|
3515
|
+
current = typeof current.getParent === "function" ? current.getParent() : null;
|
|
3516
|
+
}
|
|
3517
|
+
return null;
|
|
3518
|
+
}
|
|
3519
|
+
function $unwrapOptionalSegment(segment) {
|
|
3520
|
+
for (const child of segment.getChildren()) {
|
|
3521
|
+
segment.insertBefore(child);
|
|
3522
|
+
}
|
|
3523
|
+
segment.remove();
|
|
3524
|
+
}
|
|
3525
|
+
function containsOptionalSegment(node) {
|
|
3526
|
+
if ($isOptionalSegmentNode(node)) {
|
|
3527
|
+
return true;
|
|
3528
|
+
}
|
|
3529
|
+
if ($isElementNode(node)) {
|
|
3530
|
+
return node.getChildren().some(containsOptionalSegment);
|
|
3531
|
+
}
|
|
3532
|
+
return false;
|
|
3533
|
+
}
|
|
3534
|
+
function $toggleOptionalSegment() {
|
|
3535
|
+
const selection = $getSelection();
|
|
3536
|
+
if (!$isRangeSelection(selection)) {
|
|
3537
|
+
return false;
|
|
3538
|
+
}
|
|
3539
|
+
const anchorSegment = $getAncestorOptionalSegment(selection.anchor.getNode());
|
|
3540
|
+
const focusSegment = $getAncestorOptionalSegment(selection.focus.getNode());
|
|
3541
|
+
if (anchorSegment !== null || focusSegment !== null) {
|
|
3542
|
+
if (anchorSegment !== null && focusSegment !== null && anchorSegment !== focusSegment) {
|
|
3543
|
+
return false;
|
|
3544
|
+
}
|
|
3545
|
+
$unwrapOptionalSegment(anchorSegment ?? focusSegment);
|
|
3546
|
+
return true;
|
|
3547
|
+
}
|
|
3548
|
+
if (selection.isCollapsed()) {
|
|
3549
|
+
return false;
|
|
3550
|
+
}
|
|
3551
|
+
const anchorTop = selection.anchor.getNode().getTopLevelElement();
|
|
3552
|
+
const focusTop = selection.focus.getNode().getTopLevelElement();
|
|
3553
|
+
if (anchorTop === null || anchorTop !== focusTop) {
|
|
3554
|
+
return false;
|
|
3555
|
+
}
|
|
3556
|
+
const extracted = selection.extract();
|
|
3557
|
+
const inlineNodes = extracted.filter((node) => {
|
|
3558
|
+
if ($isElementNode(node) && !node.isInline()) {
|
|
3559
|
+
return false;
|
|
3560
|
+
}
|
|
3561
|
+
return !node.getParents().some((parent) => extracted.includes(parent));
|
|
3562
|
+
});
|
|
3563
|
+
if (inlineNodes.length === 0) {
|
|
3564
|
+
return false;
|
|
3565
|
+
}
|
|
3566
|
+
if (inlineNodes.some(containsOptionalSegment)) {
|
|
3567
|
+
return false;
|
|
3568
|
+
}
|
|
3569
|
+
const segment = $createOptionalSegmentNode();
|
|
3570
|
+
inlineNodes[0].insertBefore(segment);
|
|
3571
|
+
for (const node of inlineNodes) {
|
|
3572
|
+
segment.append(node);
|
|
3573
|
+
}
|
|
3574
|
+
segment.selectEnd();
|
|
3575
|
+
return true;
|
|
3576
|
+
}
|
|
3272
3577
|
const FORMAT_MASKS = {
|
|
3273
3578
|
bold: 1,
|
|
3274
3579
|
italic: 2,
|
|
@@ -3301,6 +3606,40 @@ function getElementAlignment(node) {
|
|
|
3301
3606
|
}
|
|
3302
3607
|
return "left";
|
|
3303
3608
|
}
|
|
3609
|
+
function getNearestListNode(node) {
|
|
3610
|
+
if ($isListNode(node)) {
|
|
3611
|
+
return node;
|
|
3612
|
+
}
|
|
3613
|
+
return $findMatchingParent(node, $isListNode);
|
|
3614
|
+
}
|
|
3615
|
+
function getNodeActiveList(node) {
|
|
3616
|
+
const listNode = getNearestListNode(node);
|
|
3617
|
+
if (!$isListNode(listNode)) {
|
|
3618
|
+
return "none";
|
|
3619
|
+
}
|
|
3620
|
+
if ($isAlphaListNode(listNode)) {
|
|
3621
|
+
return "alpha";
|
|
3622
|
+
}
|
|
3623
|
+
return listNode.getListType() === "number" ? "number" : listNode.getListType() === "bullet" ? "bullet" : "none";
|
|
3624
|
+
}
|
|
3625
|
+
function getActiveList(nodes, anchorNode) {
|
|
3626
|
+
const activeLists = /* @__PURE__ */ new Set();
|
|
3627
|
+
const anchorList = getNodeActiveList(anchorNode);
|
|
3628
|
+
if (anchorList !== "none") {
|
|
3629
|
+
activeLists.add(anchorList);
|
|
3630
|
+
}
|
|
3631
|
+
for (const node of nodes) {
|
|
3632
|
+
const activeList = getNodeActiveList(node);
|
|
3633
|
+
if (activeList === "none") {
|
|
3634
|
+
continue;
|
|
3635
|
+
}
|
|
3636
|
+
activeLists.add(activeList);
|
|
3637
|
+
if (activeLists.size > 1) {
|
|
3638
|
+
return "none";
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
return activeLists.values().next().value ?? "none";
|
|
3642
|
+
}
|
|
3304
3643
|
function getInlineStyleTarget(nodes, anchorNode) {
|
|
3305
3644
|
if ($isTextNode(anchorNode) || $isVariableNode(anchorNode)) {
|
|
3306
3645
|
return anchorNode;
|
|
@@ -3328,8 +3667,9 @@ function hasInlineFormat(node, format) {
|
|
|
3328
3667
|
function readToolbarStyleSnapshot(editor, editorState = editor.getEditorState()) {
|
|
3329
3668
|
let snapshot = DEFAULT_TOOLBAR_STYLE_SNAPSHOT;
|
|
3330
3669
|
editorState.read(() => {
|
|
3670
|
+
var _a;
|
|
3331
3671
|
const currentSelection = $getSelection();
|
|
3332
|
-
const selection = $isNodeSelection(currentSelection) ? currentSelection : $createRangeSelectionFromDom(window.getSelection(), editor) ?? currentSelection;
|
|
3672
|
+
const selection = $isNodeSelection(currentSelection) || $isRangeSelection(currentSelection) ? currentSelection : $createRangeSelectionFromDom(window.getSelection(), editor) ?? currentSelection;
|
|
3333
3673
|
if ($isNodeSelection(selection)) {
|
|
3334
3674
|
const variableNodes = selection.getNodes().filter($isVariableNode);
|
|
3335
3675
|
if (variableNodes.length === 0) {
|
|
@@ -3342,11 +3682,14 @@ function readToolbarStyleSnapshot(editor, editorState = editor.getEditorState())
|
|
|
3342
3682
|
fontFamily: normalizeFontFamily(extractFontFamilyFromStyle(style2)),
|
|
3343
3683
|
fontSize: extractFontSizePtFromStyle(style2) ?? DEFAULT_FONT_SIZE,
|
|
3344
3684
|
alignment: getElementAlignment(firstVariableNode),
|
|
3685
|
+
activeList: getActiveList(variableNodes, firstVariableNode),
|
|
3345
3686
|
isBold: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.bold) !== 0),
|
|
3346
3687
|
isItalic: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.italic) !== 0),
|
|
3347
3688
|
isUnderline: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.underline) !== 0),
|
|
3348
3689
|
isStrikethrough: variableNodes.every((node) => (node.getFormat() & FORMAT_MASKS.strikethrough) !== 0),
|
|
3349
|
-
hasSelectedVariable: true
|
|
3690
|
+
hasSelectedVariable: true,
|
|
3691
|
+
hasTextSelection: false,
|
|
3692
|
+
insideOptionalSegment: $getAncestorOptionalSegment(firstVariableNode) !== null
|
|
3350
3693
|
};
|
|
3351
3694
|
return;
|
|
3352
3695
|
}
|
|
@@ -3362,11 +3705,14 @@ function readToolbarStyleSnapshot(editor, editorState = editor.getEditorState())
|
|
|
3362
3705
|
fontFamily: normalizeFontFamily(extractFontFamilyFromStyle(style)),
|
|
3363
3706
|
fontSize: extractFontSizePtFromStyle(style) ?? DEFAULT_FONT_SIZE,
|
|
3364
3707
|
alignment: getElementAlignment(anchorNode),
|
|
3708
|
+
activeList: getActiveList(selection.getNodes(), anchorNode),
|
|
3365
3709
|
isBold: selection.hasFormat("bold") || isCollapsed && hasInlineFormat(inlineStyleTarget, "bold"),
|
|
3366
3710
|
isItalic: selection.hasFormat("italic") || isCollapsed && hasInlineFormat(inlineStyleTarget, "italic"),
|
|
3367
3711
|
isUnderline: selection.hasFormat("underline") || isCollapsed && hasInlineFormat(inlineStyleTarget, "underline"),
|
|
3368
3712
|
isStrikethrough: selection.hasFormat("strikethrough") || isCollapsed && hasInlineFormat(inlineStyleTarget, "strikethrough"),
|
|
3369
|
-
hasSelectedVariable: false
|
|
3713
|
+
hasSelectedVariable: false,
|
|
3714
|
+
hasTextSelection: !isCollapsed,
|
|
3715
|
+
insideOptionalSegment: $getAncestorOptionalSegment(anchorNode) !== null || $getAncestorOptionalSegment(((_a = selection.focus) == null ? void 0 : _a.getNode()) ?? null) !== null
|
|
3370
3716
|
};
|
|
3371
3717
|
});
|
|
3372
3718
|
return snapshot;
|
|
@@ -3392,6 +3738,7 @@ const Toolbar = () => {
|
|
|
3392
3738
|
const activeFontFamily = useToolbarStyleStore((state) => state.fontFamily);
|
|
3393
3739
|
const activeFontSize = useToolbarStyleStore((state) => state.fontSize);
|
|
3394
3740
|
const activeAlignment = useToolbarStyleStore((state) => state.alignment);
|
|
3741
|
+
const activeList = useToolbarStyleStore((state) => state.activeList);
|
|
3395
3742
|
const isBoldActive = useToolbarStyleStore((state) => state.isBold);
|
|
3396
3743
|
const isItalicActive = useToolbarStyleStore((state) => state.isItalic);
|
|
3397
3744
|
const isUnderlineActive = useToolbarStyleStore((state) => state.isUnderline);
|
|
@@ -3420,16 +3767,27 @@ const Toolbar = () => {
|
|
|
3420
3767
|
);
|
|
3421
3768
|
const runToolbarAction = useCallback(
|
|
3422
3769
|
(label, callback) => {
|
|
3770
|
+
const refreshSnapshot = () => {
|
|
3771
|
+
if (!activeEditor) {
|
|
3772
|
+
return;
|
|
3773
|
+
}
|
|
3774
|
+
queueMicrotask(() => {
|
|
3775
|
+
toolbarStyleStore.getState().setSnapshot(readToolbarStyleSnapshot(activeEditor));
|
|
3776
|
+
});
|
|
3777
|
+
};
|
|
3423
3778
|
runHistoryAction(
|
|
3424
3779
|
{
|
|
3425
3780
|
label,
|
|
3426
3781
|
source: "toolbar",
|
|
3427
3782
|
region: "document"
|
|
3428
3783
|
},
|
|
3429
|
-
|
|
3784
|
+
() => {
|
|
3785
|
+
callback();
|
|
3786
|
+
refreshSnapshot();
|
|
3787
|
+
}
|
|
3430
3788
|
);
|
|
3431
3789
|
},
|
|
3432
|
-
[runHistoryAction]
|
|
3790
|
+
[activeEditor, runHistoryAction, toolbarStyleStore]
|
|
3433
3791
|
);
|
|
3434
3792
|
useEffect(() => {
|
|
3435
3793
|
if (!activeEditor) {
|
|
@@ -3522,6 +3880,11 @@ const Toolbar = () => {
|
|
|
3522
3880
|
applyToBodyEditors((editor) => insertList(editor, "bullet"));
|
|
3523
3881
|
});
|
|
3524
3882
|
}, [applyToBodyEditors, runToolbarAction, t.history.actions.insertedBulletList]);
|
|
3883
|
+
const handleListAlpha = useCallback(() => {
|
|
3884
|
+
runToolbarAction(t.history.actions.insertedAlphabeticList, () => {
|
|
3885
|
+
applyToBodyEditors((editor) => insertList(editor, "alpha"));
|
|
3886
|
+
});
|
|
3887
|
+
}, [applyToBodyEditors, runToolbarAction, t.history.actions.insertedAlphabeticList]);
|
|
3525
3888
|
const handleIndent = useCallback(() => {
|
|
3526
3889
|
runToolbarAction(t.history.actions.indentedContent, () => {
|
|
3527
3890
|
applyToBodyEditors(indentContent);
|
|
@@ -3654,8 +4017,9 @@ const Toolbar = () => {
|
|
|
3654
4017
|
] }),
|
|
3655
4018
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
3656
4019
|
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "list-group", children: [
|
|
3657
|
-
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.numberedList, testId: "btn-list-number", onClick: handleListNumber, children: /* @__PURE__ */ jsx(ListOrdered, { size: 15 }) }),
|
|
3658
|
-
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.bulletList, testId: "btn-list-bullet", onClick: handleListBullet, children: /* @__PURE__ */ jsx(List, { size: 15 }) }),
|
|
4020
|
+
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.numberedList, testId: "btn-list-number", active: activeList === "number", onClick: handleListNumber, children: /* @__PURE__ */ jsx(ListOrdered, { size: 15 }) }),
|
|
4021
|
+
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.bulletList, testId: "btn-list-bullet", active: activeList === "bullet", onClick: handleListBullet, children: /* @__PURE__ */ jsx(List, { size: 15 }) }),
|
|
4022
|
+
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alphabeticList, testId: "btn-list-alpha", active: activeList === "alpha", onClick: handleListAlpha, children: /* @__PURE__ */ jsx("span", { className: "lex4-toolbar-text-icon", children: "a)" }) }),
|
|
3659
4023
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.indent, testId: "btn-indent", onClick: handleIndent, children: /* @__PURE__ */ jsx(ListIndentIncrease, { size: 15 }) }),
|
|
3660
4024
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.outdent, testId: "btn-outdent", onClick: handleOutdent, children: /* @__PURE__ */ jsx(ListIndentDecrease, { size: 15 }) })
|
|
3661
4025
|
] }),
|
|
@@ -4046,7 +4410,7 @@ const lexicalTheme = {
|
|
|
4046
4410
|
},
|
|
4047
4411
|
quote: "lex4-quote"
|
|
4048
4412
|
};
|
|
4049
|
-
const DEFAULT_NODES = [HeadingNode, QuoteNode, ListNode, ListItemNode];
|
|
4413
|
+
const DEFAULT_NODES = [HeadingNode, QuoteNode, ListNode, ListItemNode, AlphaListNode];
|
|
4050
4414
|
function createEditorConfig(mode, pageId, extraNodes = [], themeOverrides = {}) {
|
|
4051
4415
|
const namespace = pageId ? `lex4-${mode}-${pageId}` : `lex4-${mode}`;
|
|
4052
4416
|
return {
|
|
@@ -5606,6 +5970,8 @@ function mapInlineNode(node) {
|
|
|
5606
5970
|
return mapVariableNode(node);
|
|
5607
5971
|
case "linebreak":
|
|
5608
5972
|
return mapLineBreak();
|
|
5973
|
+
case "optional-segment":
|
|
5974
|
+
return mapOptionalSegment(node);
|
|
5609
5975
|
default:
|
|
5610
5976
|
return { type: "text", text: "" };
|
|
5611
5977
|
}
|
|
@@ -5629,6 +5995,12 @@ function mapVariableNode(node) {
|
|
|
5629
5995
|
function mapLineBreak() {
|
|
5630
5996
|
return { type: "linebreak" };
|
|
5631
5997
|
}
|
|
5998
|
+
function mapOptionalSegment(node) {
|
|
5999
|
+
return {
|
|
6000
|
+
type: "optional-segment",
|
|
6001
|
+
children: mapInlineNodes(node.children ?? [])
|
|
6002
|
+
};
|
|
6003
|
+
}
|
|
5632
6004
|
function mapInlineNodes(nodes) {
|
|
5633
6005
|
return nodes.map(mapInlineNode);
|
|
5634
6006
|
}
|
|
@@ -5664,6 +6036,7 @@ function mapBlockNode(node) {
|
|
|
5664
6036
|
case "heading":
|
|
5665
6037
|
return mapHeading(node);
|
|
5666
6038
|
case "list":
|
|
6039
|
+
case "alpha-list":
|
|
5667
6040
|
return mapList(node);
|
|
5668
6041
|
case "quote":
|
|
5669
6042
|
return mapBlockQuote(node);
|
|
@@ -5697,7 +6070,7 @@ function mapHeading(node) {
|
|
|
5697
6070
|
};
|
|
5698
6071
|
}
|
|
5699
6072
|
function mapList(node) {
|
|
5700
|
-
const listType = node.listType === "number" ? "ordered" : "unordered";
|
|
6073
|
+
const listType = node.type === "alpha-list" ? "ordered-alpha" : node.listType === "number" ? "ordered" : "unordered";
|
|
5701
6074
|
const items = (node.children ?? []).filter((c) => c.type === "listitem").map(mapListItem);
|
|
5702
6075
|
return {
|
|
5703
6076
|
type: "list",
|
|
@@ -5709,7 +6082,7 @@ function mapListItem(node) {
|
|
|
5709
6082
|
const inlineChildren = [];
|
|
5710
6083
|
let nestedList;
|
|
5711
6084
|
for (const child of node.children ?? []) {
|
|
5712
|
-
if (child.type === "list") {
|
|
6085
|
+
if (child.type === "list" || child.type === "alpha-list") {
|
|
5713
6086
|
nestedList = mapList(child);
|
|
5714
6087
|
} else {
|
|
5715
6088
|
const mapped = mapInlineNodes([child]);
|
|
@@ -5853,6 +6226,13 @@ function buildLexicalNode(serializedNode) {
|
|
|
5853
6226
|
appendChildren(node, serializedNode.children);
|
|
5854
6227
|
return node;
|
|
5855
6228
|
}
|
|
6229
|
+
case "alpha-list": {
|
|
6230
|
+
const node = $createAlphaListNode(
|
|
6231
|
+
typeof serializedNode.start === "number" ? serializedNode.start : 1
|
|
6232
|
+
);
|
|
6233
|
+
appendChildren(node, serializedNode.children);
|
|
6234
|
+
return node;
|
|
6235
|
+
}
|
|
5856
6236
|
case "listitem": {
|
|
5857
6237
|
const node = $createListItemNode();
|
|
5858
6238
|
appendChildren(node, serializedNode.children);
|
|
@@ -5876,6 +6256,11 @@ function buildLexicalNode(serializedNode) {
|
|
|
5876
6256
|
typeof serializedNode.format === "number" ? serializedNode.format : 0,
|
|
5877
6257
|
typeof serializedNode.style === "string" ? serializedNode.style : ""
|
|
5878
6258
|
);
|
|
6259
|
+
case "optional-segment": {
|
|
6260
|
+
const node = $createOptionalSegmentNode();
|
|
6261
|
+
appendChildren(node, serializedNode.children);
|
|
6262
|
+
return node;
|
|
6263
|
+
}
|
|
5879
6264
|
default:
|
|
5880
6265
|
return null;
|
|
5881
6266
|
}
|
|
@@ -6357,13 +6742,53 @@ const VariablePlugin = () => {
|
|
|
6357
6742
|
}, [editor]);
|
|
6358
6743
|
return null;
|
|
6359
6744
|
};
|
|
6745
|
+
const OptionalSegmentPlugin = () => {
|
|
6746
|
+
const [editor] = useLexicalComposerContext();
|
|
6747
|
+
const t = useTranslations();
|
|
6748
|
+
useEffect(() => {
|
|
6749
|
+
return editor.registerCommand(
|
|
6750
|
+
TOGGLE_OPTIONAL_SEGMENT_COMMAND,
|
|
6751
|
+
() => {
|
|
6752
|
+
let handled = false;
|
|
6753
|
+
editor.update(() => {
|
|
6754
|
+
handled = $toggleOptionalSegment();
|
|
6755
|
+
});
|
|
6756
|
+
return handled;
|
|
6757
|
+
},
|
|
6758
|
+
COMMAND_PRIORITY_EDITOR
|
|
6759
|
+
);
|
|
6760
|
+
}, [editor]);
|
|
6761
|
+
useEffect(() => {
|
|
6762
|
+
return editor.registerMutationListener(
|
|
6763
|
+
OptionalSegmentNode,
|
|
6764
|
+
(mutations) => {
|
|
6765
|
+
editor.getEditorState().read(() => {
|
|
6766
|
+
for (const [key, mutation] of mutations) {
|
|
6767
|
+
if (mutation === "created" || mutation === "updated") {
|
|
6768
|
+
const element = editor.getElementByKey(key);
|
|
6769
|
+
if (element) {
|
|
6770
|
+
element.title = t.variables.optionalSegmentTooltip;
|
|
6771
|
+
}
|
|
6772
|
+
}
|
|
6773
|
+
}
|
|
6774
|
+
});
|
|
6775
|
+
},
|
|
6776
|
+
{ skipInitialization: false }
|
|
6777
|
+
);
|
|
6778
|
+
}, [editor, t.variables.optionalSegmentTooltip]);
|
|
6779
|
+
return null;
|
|
6780
|
+
};
|
|
6360
6781
|
const VariablePanel = ({ open, onClose }) => {
|
|
6361
6782
|
const { definitions, refreshDefinitions } = useVariables();
|
|
6362
6783
|
const { activeEditor, runHistoryAction } = useDocument();
|
|
6363
6784
|
const t = useTranslations();
|
|
6364
6785
|
const [filter, setFilter] = useState("");
|
|
6786
|
+
const [collapsedGroups, setCollapsedGroups] = useState({});
|
|
6365
6787
|
const [creating, setCreating] = useState(false);
|
|
6366
6788
|
const [createError, setCreateError] = useState(null);
|
|
6789
|
+
const toggleGroup = useCallback((group) => {
|
|
6790
|
+
setCollapsedGroups((current) => ({ ...current, [group]: !current[group] }));
|
|
6791
|
+
}, []);
|
|
6367
6792
|
const [draft, setDraft] = useState({
|
|
6368
6793
|
label: "",
|
|
6369
6794
|
key: "",
|
|
@@ -6477,23 +6902,50 @@ const VariablePanel = ({ open, onClose }) => {
|
|
|
6477
6902
|
] }) }),
|
|
6478
6903
|
/* @__PURE__ */ jsxs("div", { className: "lex4-variable-list", children: [
|
|
6479
6904
|
Object.keys(grouped).length === 0 && /* @__PURE__ */ jsx("div", { className: "lex4-variable-list-empty", children: t.variables.noVariablesFound }),
|
|
6480
|
-
Object.entries(grouped).map(([group, defs]) =>
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
"
|
|
6905
|
+
Object.entries(grouped).map(([group, defs]) => {
|
|
6906
|
+
const isCollapsed = !filter && Boolean(collapsedGroups[group]);
|
|
6907
|
+
return /* @__PURE__ */ jsxs(
|
|
6908
|
+
"div",
|
|
6484
6909
|
{
|
|
6485
|
-
|
|
6486
|
-
className: "lex4-variable-list-item",
|
|
6487
|
-
"data-testid": `variable-panel-${def.key}`,
|
|
6910
|
+
className: `lex4-variable-group${isCollapsed ? " is-collapsed" : ""}`,
|
|
6488
6911
|
"data-variable-group": group,
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6912
|
+
children: [
|
|
6913
|
+
/* @__PURE__ */ jsxs(
|
|
6914
|
+
"button",
|
|
6915
|
+
{
|
|
6916
|
+
type: "button",
|
|
6917
|
+
className: "lex4-variable-group-header",
|
|
6918
|
+
"data-testid": `variable-panel-group-${group}`,
|
|
6919
|
+
"aria-expanded": !isCollapsed,
|
|
6920
|
+
onClick: () => toggleGroup(group),
|
|
6921
|
+
children: [
|
|
6922
|
+
/* @__PURE__ */ jsxs("span", { className: "lex4-variable-group-header-left", children: [
|
|
6923
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 12, className: "lex4-variable-group-chevron" }),
|
|
6924
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-variable-group-label", children: group })
|
|
6925
|
+
] }),
|
|
6926
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-variable-group-count", children: defs.length })
|
|
6927
|
+
]
|
|
6928
|
+
}
|
|
6929
|
+
),
|
|
6930
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-variable-group-items", children: defs.map((def) => /* @__PURE__ */ jsx(
|
|
6931
|
+
"button",
|
|
6932
|
+
{
|
|
6933
|
+
type: "button",
|
|
6934
|
+
className: "lex4-variable-list-item",
|
|
6935
|
+
"data-testid": `variable-panel-${def.key}`,
|
|
6936
|
+
"data-variable-group": group,
|
|
6937
|
+
onClick: () => handleInsert(def.key),
|
|
6938
|
+
disabled: !activeEditor,
|
|
6939
|
+
title: def.key,
|
|
6940
|
+
children: /* @__PURE__ */ jsx("span", { className: "lex4-variable-list-item-label", children: def.label })
|
|
6941
|
+
},
|
|
6942
|
+
def.key
|
|
6943
|
+
)) })
|
|
6944
|
+
]
|
|
6493
6945
|
},
|
|
6494
|
-
|
|
6495
|
-
)
|
|
6496
|
-
|
|
6946
|
+
group
|
|
6947
|
+
);
|
|
6948
|
+
})
|
|
6497
6949
|
] }),
|
|
6498
6950
|
/* @__PURE__ */ jsx("div", { className: "lex4-variable-create", children: creating ? /* @__PURE__ */ jsxs("form", { className: "lex4-variable-create-form", onSubmit: handleCreateVariable, children: [
|
|
6499
6951
|
/* @__PURE__ */ jsx("div", { className: "lex4-variable-create-title", children: t.variables.createVariableTitle }),
|
|
@@ -6619,6 +7071,48 @@ const VariableToolbarToggle = () => {
|
|
|
6619
7071
|
}
|
|
6620
7072
|
);
|
|
6621
7073
|
};
|
|
7074
|
+
const OptionalSegmentToolbarButton = () => {
|
|
7075
|
+
const { activeEditor, runHistoryAction } = useDocument();
|
|
7076
|
+
const toolbarConfig = useToolbarConfig();
|
|
7077
|
+
const t = useTranslations();
|
|
7078
|
+
const hasTextSelection = useToolbarStyleStore((state) => state.hasTextSelection);
|
|
7079
|
+
const insideOptionalSegment = useToolbarStyleStore((state) => state.insideOptionalSegment);
|
|
7080
|
+
if (!toolbarConfig.variables.visible) {
|
|
7081
|
+
return null;
|
|
7082
|
+
}
|
|
7083
|
+
if (!hasTextSelection && !insideOptionalSegment) {
|
|
7084
|
+
return null;
|
|
7085
|
+
}
|
|
7086
|
+
const handleClick = () => {
|
|
7087
|
+
if (!activeEditor) {
|
|
7088
|
+
return;
|
|
7089
|
+
}
|
|
7090
|
+
runHistoryAction(
|
|
7091
|
+
{
|
|
7092
|
+
label: t.history.actions.optionalSegmentToggled,
|
|
7093
|
+
source: "toolbar",
|
|
7094
|
+
region: "document"
|
|
7095
|
+
},
|
|
7096
|
+
() => {
|
|
7097
|
+
activeEditor.dispatchCommand(TOGGLE_OPTIONAL_SEGMENT_COMMAND, void 0);
|
|
7098
|
+
}
|
|
7099
|
+
);
|
|
7100
|
+
};
|
|
7101
|
+
return /* @__PURE__ */ jsx(
|
|
7102
|
+
"button",
|
|
7103
|
+
{
|
|
7104
|
+
type: "button",
|
|
7105
|
+
title: t.variables.optionalSegmentToggle,
|
|
7106
|
+
"aria-label": t.variables.optionalSegmentToggle,
|
|
7107
|
+
"aria-pressed": insideOptionalSegment,
|
|
7108
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
7109
|
+
onClick: handleClick,
|
|
7110
|
+
className: `lex4-toolbar-btn${insideOptionalSegment ? " active" : ""}`,
|
|
7111
|
+
"data-testid": "btn-optional-segment",
|
|
7112
|
+
children: /* @__PURE__ */ jsx(Brackets, { size: 15 })
|
|
7113
|
+
}
|
|
7114
|
+
);
|
|
7115
|
+
};
|
|
6622
7116
|
const VariablePanelWithState = () => {
|
|
6623
7117
|
const { panelOpen, setPanelOpen } = useVariablePanelState();
|
|
6624
7118
|
return /* @__PURE__ */ jsx(VariablePanel, { open: panelOpen, onClose: () => setPanelOpen(false) });
|
|
@@ -6646,8 +7140,9 @@ function variablesExtension(definitions = []) {
|
|
|
6646
7140
|
};
|
|
6647
7141
|
return {
|
|
6648
7142
|
name: "variables",
|
|
6649
|
-
nodes: [VariableNode],
|
|
6650
|
-
bodyPlugins: [VariablePlugin],
|
|
7143
|
+
nodes: [VariableNode, OptionalSegmentNode],
|
|
7144
|
+
bodyPlugins: [VariablePlugin, OptionalSegmentPlugin],
|
|
7145
|
+
toolbarItems: [OptionalSegmentToolbarButton],
|
|
6651
7146
|
toolbarEndItems: [VariableToolbarToggle],
|
|
6652
7147
|
sidePanel: VariablePanelWithState,
|
|
6653
7148
|
provider: ProviderWrapper,
|
|
@@ -6674,7 +7169,9 @@ function variablesExtension(definitions = []) {
|
|
|
6674
7169
|
};
|
|
6675
7170
|
}
|
|
6676
7171
|
export {
|
|
7172
|
+
$createOptionalSegmentNode,
|
|
6677
7173
|
$createVariableNode,
|
|
7174
|
+
$isOptionalSegmentNode,
|
|
6678
7175
|
$isVariableNode,
|
|
6679
7176
|
A4_HEIGHT_MM,
|
|
6680
7177
|
A4_HEIGHT_PX,
|
|
@@ -6686,7 +7183,9 @@ export {
|
|
|
6686
7183
|
Lex4Editor,
|
|
6687
7184
|
MAX_FOOTER_HEIGHT_PX,
|
|
6688
7185
|
MAX_HEADER_HEIGHT_PX,
|
|
7186
|
+
OptionalSegmentNode,
|
|
6689
7187
|
PT_BR_TRANSLATIONS,
|
|
7188
|
+
TOGGLE_OPTIONAL_SEGMENT_COMMAND,
|
|
6690
7189
|
VariableNode,
|
|
6691
7190
|
astExtension,
|
|
6692
7191
|
buildSavePayload,
|