Skip to content

Commit 2ec7c34

Browse files
committed
[FIX] borders: preserve side borders when combining External and All
When applying an External border on a range and then applying All borders on an inner/overlapping range, the side borders (left/right) of the inner cells were lost after re-opening the spreadsheet. The exported border data was correct, but the BordersPlugin recomputation logic in addBorder incorrectly cleared adjacent borders on import/update. The adjacency check (adjacent(existingBorder.zone, zone)) reported the side of the existing zone, but we were deciding whether to clear it based on the same side key in the new border, instead of the opposite side (shared edge) on the new zone. As a result, importing the combination of: C2:C4 with All borders B2:B4 with left/top/bottom D2:D4 with right/top/bottom ended up clearing the left and right borders of C2:C4. This commit adjusts the adjacent clearing logic to: Map the adjacent side of the existing zone to the opposite side on the new zone. Only clear the existing side if the corresponding opposite side is actually being written on the new border. Task: 5270171
1 parent eccc2e0 commit 2ec7c34

File tree

2 files changed

+80
-18
lines changed

2 files changed

+80
-18
lines changed

src/plugins/core/borders.ts

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -354,25 +354,39 @@ export class BordersPlugin extends CorePlugin<BordersPluginState> implements Bor
354354
if (!inter) {
355355
// Clear adjacent borders on which you write
356356
const adjacentEdge = adjacent(existingBorder.zone, zone);
357-
if (adjacentEdge && sideToClear[adjacentEdge.position]) {
358-
for (const newZone of splitIfAdjacent(existingBorder.zone, zone)) {
359-
const border = this.computeBorderFromZone(newZone, existingBorder);
360-
const adjacentEdge = adjacent(newZone, zone);
361-
switch (adjacentEdge?.position) {
362-
case "left":
363-
border.style.left = undefined;
364-
break;
365-
case "right":
366-
border.style.right = undefined;
367-
break;
368-
case "top":
369-
border.style.top = undefined;
370-
break;
371-
case "bottom":
372-
border.style.bottom = undefined;
373-
break;
357+
if (adjacentEdge) {
358+
// Side on the *new* zone that lies on the same line as `adjacentEdge.position`
359+
const sideOnNewBorder: "left" | "right" | "top" | "bottom" =
360+
adjacentEdge.position === "left"
361+
? "right"
362+
: adjacentEdge.position === "right"
363+
? "left"
364+
: adjacentEdge.position === "top"
365+
? "bottom"
366+
: "top";
367+
368+
if (sideToClear[sideOnNewBorder]) {
369+
for (const newZone of splitIfAdjacent(existingBorder.zone, zone)) {
370+
const border = this.computeBorderFromZone(newZone, existingBorder);
371+
const edge = adjacent(newZone, zone);
372+
switch (edge?.position) {
373+
case "left":
374+
border.style.left = undefined;
375+
break;
376+
case "right":
377+
border.style.right = undefined;
378+
break;
379+
case "top":
380+
border.style.top = undefined;
381+
break;
382+
case "bottom":
383+
border.style.bottom = undefined;
384+
break;
385+
}
386+
borders.push(border);
374387
}
375-
borders.push(border);
388+
} else {
389+
borders.push(existingBorder);
376390
}
377391
} else {
378392
borders.push(existingBorder);

tests/borders/border_plugin.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,54 @@ test("Cells that have undefined borders don't override borders of neighboring ce
12551255
});
12561256
});
12571257

1258+
test("Import preserves side borders when combining External and All borders", () => {
1259+
const defaultBorder = DEFAULT_BORDER_DESC;
1260+
const data = {
1261+
sheets: [
1262+
{
1263+
id: "Sheet1",
1264+
name: "Sheet1",
1265+
colNumber: 26,
1266+
rowNumber: 100,
1267+
cells: {},
1268+
borders: {
1269+
"C2:C4": 1,
1270+
"B2:B4": 2,
1271+
"D2:D4": 3,
1272+
},
1273+
},
1274+
],
1275+
borders: {
1276+
1: {
1277+
top: defaultBorder,
1278+
bottom: defaultBorder,
1279+
left: defaultBorder,
1280+
right: defaultBorder,
1281+
vertical: defaultBorder,
1282+
horizontal: defaultBorder,
1283+
},
1284+
2: {
1285+
top: defaultBorder,
1286+
bottom: defaultBorder,
1287+
left: defaultBorder,
1288+
},
1289+
3: {
1290+
top: defaultBorder,
1291+
bottom: defaultBorder,
1292+
right: defaultBorder,
1293+
},
1294+
},
1295+
};
1296+
1297+
const model = new Model(data);
1298+
expect(getBorder(model, "C2")).toEqual({
1299+
top: defaultBorder,
1300+
bottom: defaultBorder,
1301+
left: defaultBorder,
1302+
right: defaultBorder,
1303+
});
1304+
});
1305+
12581306
describe("Borders formatting", () => {
12591307
let model: Model;
12601308

0 commit comments

Comments
 (0)