Skip to content

Commit 39e9d09

Browse files
committed
fix: preserve start value and handle multi-level selections in changeListNumberingType
- Read existing start value from list definition instead of hardcoding '1' - Apply format to each distinct ilvl in a group so multi-level range selections reformat all levels correctly - Extract SVG icon factory to reduce ~100 lines of duplicated boilerplate
1 parent cd3b902 commit 39e9d09

2 files changed

Lines changed: 38 additions & 112 deletions

File tree

Lines changed: 15 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,29 @@
11
// SVG icons for list numbering types
22
// Each icon shows a list with 2 items at 200% zoom
33

4-
export const numberingIcons = {
5-
decimalPlain: `
6-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
7-
<style>
8-
.list-text { font: bold 40px sans-serif; fill: #222; }
9-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
10-
</style>
11-
<text x="15" y="50" class="list-text">1</text>
12-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
13-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
14-
<text x="15" y="120" class="list-text">2</text>
15-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
16-
</svg>
17-
`,
18-
19-
decimal: `
20-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
21-
<style>
22-
.list-text { font: bold 40px sans-serif; fill: #222; }
23-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
24-
</style>
25-
<text x="15" y="50" class="list-text">1.</text>
26-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
27-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
28-
<text x="15" y="120" class="list-text">2.</text>
29-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
30-
</svg>
31-
`,
32-
33-
decimalParen: `
34-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
35-
<style>
36-
.list-text { font: bold 40px sans-serif; fill: #222; }
37-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
38-
</style>
39-
<text x="15" y="50" class="list-text">1)</text>
40-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
41-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
42-
<text x="15" y="120" class="list-text">2)</text>
43-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
44-
</svg>
45-
`,
46-
47-
upperLetter: `
4+
function makeListIcon(text1, text2, text2X = 15) {
5+
return `
486
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
497
<style>
508
.list-text { font: bold 40px sans-serif; fill: #222; }
519
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
5210
</style>
53-
<text x="15" y="50" class="list-text">A.</text>
11+
<text x="15" y="50" class="list-text">${text1}</text>
5412
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
5513
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
56-
<text x="15" y="120" class="list-text">B.</text>
14+
<text x="${text2X}" y="120" class="list-text">${text2}</text>
5715
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
5816
</svg>
59-
`,
17+
`;
18+
}
6019

61-
lowerLetter: `
62-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
63-
<style>
64-
.list-text { font: bold 40px sans-serif; fill: #222; }
65-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
66-
</style>
67-
<text x="15" y="50" class="list-text">a.</text>
68-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
69-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
70-
<text x="15" y="120" class="list-text">b.</text>
71-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
72-
</svg>
73-
`,
74-
75-
letterParen: `
76-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
77-
<style>
78-
.list-text { font: bold 40px sans-serif; fill: #222; }
79-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
80-
</style>
81-
<text x="15" y="50" class="list-text">a)</text>
82-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
83-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
84-
<text x="15" y="120" class="list-text">b)</text>
85-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
86-
</svg>
87-
`,
88-
89-
upperRoman: `
90-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
91-
<style>
92-
.list-text { font: bold 40px sans-serif; fill: #222; }
93-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
94-
</style>
95-
<text x="15" y="50" class="list-text">I.</text>
96-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
97-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
98-
<text x="10" y="120" class="list-text">II.</text>
99-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
100-
</svg>
101-
`,
102-
103-
lowerRoman: `
104-
<svg width="200" height="150" viewBox="0 0 200 150" xmlns="http://www.w3.org/2000/svg">
105-
<style>
106-
.list-text { font: bold 40px sans-serif; fill: #222; }
107-
.list-line { stroke: #222; stroke-width: 3; stroke-linecap: round; }
108-
</style>
109-
<text x="15" y="50" class="list-text">i.</text>
110-
<line x1="75" y1="40" x2="185" y2="40" class="list-line" />
111-
<line x1="75" y1="80" x2="185" y2="80" class="list-line" />
112-
<text x="15" y="120" class="list-text">ii.</text>
113-
<line x1="75" y1="115" x2="185" y2="115" class="list-line" />
114-
</svg>
115-
`,
20+
export const numberingIcons = {
21+
decimalPlain: makeListIcon('1', '2'),
22+
decimal: makeListIcon('1.', '2.'),
23+
decimalParen: makeListIcon('1)', '2)'),
24+
upperLetter: makeListIcon('A.', 'B.'),
25+
lowerLetter: makeListIcon('a.', 'b.'),
26+
letterParen: makeListIcon('a)', 'b)'),
27+
upperRoman: makeListIcon('I.', 'II.', 10),
28+
lowerRoman: makeListIcon('i.', 'ii.'),
11629
};

packages/super-editor/src/core/commands/changeListNumberingType.js

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,31 @@ function findAdjacentListItems(doc, startPos, targetNumId, targetIlvl) {
8787
*/
8888
function applyFormatToGroup(paragraphs, formatConfig, editor, tr) {
8989
const firstItem = paragraphs[0];
90-
const existingIlvl = firstItem.paraProps.numberingProperties?.ilvl ?? 0;
90+
const existingNumId = firstItem.paraProps.numberingProperties?.numId;
9191

9292
const newNumId = ListHelpers.getNewListId(editor);
93-
ListHelpers.generateNewListDefinition({
94-
numId: Number(newNumId),
95-
listType: 'orderedList',
96-
level: String(existingIlvl),
97-
start: '1',
98-
text: formatConfig.lvlText,
99-
fmt: formatConfig.fmt,
100-
editor,
101-
});
93+
94+
// Collect distinct ilvls and apply the format to each level
95+
const seenIlvls = new Set();
96+
for (const { paraProps } of paragraphs) {
97+
seenIlvls.add(paraProps.numberingProperties?.ilvl ?? 0);
98+
}
99+
100+
for (const ilvl of seenIlvls) {
101+
// Preserve existing start value from the original definition
102+
const details = ListHelpers.getListDefinitionDetails({ numId: existingNumId, level: ilvl, editor });
103+
const existingStart = details?.start ?? '1';
104+
105+
ListHelpers.generateNewListDefinition({
106+
numId: Number(newNumId),
107+
listType: 'orderedList',
108+
level: String(ilvl),
109+
start: existingStart,
110+
text: formatConfig.lvlText,
111+
fmt: formatConfig.fmt,
112+
editor,
113+
});
114+
}
102115

103116
for (const { node, pos, paraProps } of paragraphs) {
104117
const currentIlvl = paraProps.numberingProperties?.ilvl ?? 0;

0 commit comments

Comments
 (0)