Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/paste-hidden-columns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sheetwrite/core": patch
---

Fix pasting across hidden columns. Paste into the visible columns, leave hidden cells unchanged, and undo the paste in one step.
1 change: 1 addition & 0 deletions packages/core/src/clipboard-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ export class ClipboardController {
availableRows > 0 &&
width > 0 &&
targetCols.length === width &&
targetCols.every((col, index) => col === focus.col + index) &&
Array.from({ length: availableRows }, (_, row) => row).every(
(row) =>
widthAt(row) === width && this.deps.toDataRow(focus.row + row) === firstDataRow + row,
Expand Down
40 changes: 40 additions & 0 deletions packages/core/test/grid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { XlsxTableExportBackend } from "../src/export.js";
import { setXlsxTableExportBackend } from "../src/export.js";
import {
AUTO_FIT_CHUNK_CELLS,
createGrid,
DEFAULT_THEME,
GridImpl,
initSheetwrite,
Expand Down Expand Up @@ -141,6 +142,45 @@ describe("Grid editing (Layer 3)", () => {
await initSheetwrite();
});

it("pastes across hidden columns without changing them and undoes in one step", async () => {
const workbook = makeWorkbook(2);
const sheet = workbook.sheets[0];
const hiddenColumn = sheet?.columns[1];
if (!hiddenColumn) throw new Error("expected the amount column in the fixture");
hiddenColumn.visible = false;
const clipboardDescriptor = Object.getOwnPropertyDescriptor(navigator, "clipboard");
Object.defineProperty(navigator, "clipboard", {
configurable: true,
value: { readText: async () => "Alice\tParis\nBob\tTokyo" },
});
const grid = createGrid(mountHost(), { workbook, data: makeColumnarData(2) });
const changes: ChangeEvent[] = [];
grid.on("change", (event) => changes.push(event));
const readCells = () =>
[0, 1].map((row) =>
[0, 1, 2].map((col) => grid.store.getCell({ sheet: "s1", row, col }).resolved),
);
try {
expect(grid.store).toBeInstanceOf(SheetwriteStore);
grid.setSelection({ kind: "cell", addr: { sheet: "s1", row: 0, col: 0 } });
expect(await grid.actions.paste()).toBe("done");
expect(readCells()).toEqual([
["Alice", 0.5, "Paris"],
["Bob", 10.5, "Tokyo"],
]);
grid.undo();
expect(readCells()).toEqual([
["Customer 0", 0.5, "Phnom Penh"],
["Customer 1", 10.5, "Tokyo"],
]);
expect(changes.map((event) => event.commitReason)).toEqual(["paste", "undo"]);
} finally {
grid.destroy();
if (clipboardDescriptor) Object.defineProperty(navigator, "clipboard", clipboardDescriptor);
else Reflect.deleteProperty(navigator, "clipboard");
}
});

it("commits a typed edit through the editor into the store", () => {
const workbook = makeWorkbook(20);
const store = new SheetwriteStore(workbook, makeColumnarData(20));
Expand Down
Loading