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