Skip to content
Open
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
26 changes: 26 additions & 0 deletions packages/core/src/blocks/Table/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
TableContent,
} from "../../schema/index.js";
import { mergeCSSClasses } from "../../util/browser.js";
import { camelToDataKebab } from "../../util/string.js";
import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
import { defaultProps } from "../defaultProps.js";
import { EMPTY_CELL_WIDTH, TableExtension } from "./TableExtension.js";
Expand Down Expand Up @@ -252,6 +253,31 @@ const TiptapTableNode = Node.create({
super.ignoreMutation(record)
);
}

// `TableView` implements its own `update` method, as the view needs to
// be persisted across updates for column resizing to work properly.
// However, it doesn't do anything else, so we have to re-apply the
// HTML attributes from props manually. This isn't an issue for node
// views created e.g. by custom blocks, as those aren't persisted
// across updates (they are reinstantiated each time), and so
// `HTMLAttributes` is always up-to-date for those.
update(updatedNode: PMNode): boolean {
if (!super.update(updatedNode)) {
return false;
}

for (const [propName, propSpec] of Object.entries(tablePropSchema)) {
const attrName = camelToDataKebab(propName);
const value = updatedNode.attrs[propName];
if (value !== propSpec.default) {
this.dom.setAttribute(attrName, String(value));
} else {
this.dom.removeAttribute(attrName);
}
}

return true;
}
}

return new BlockNoteTableView(node, EMPTY_CELL_WIDTH, {
Expand Down
24 changes: 24 additions & 0 deletions tests/src/end-to-end/colors/colors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import {
DRAG_HANDLE_MENU_SELECTOR,
DRAG_HANDLE_SELECTOR,
H_TWO_BLOCK_SELECTOR,
TABLE_SELECTOR,
TEXT_COLOR_SELECTOR,
} from "../../utils/const.js";
import { insertHeading, insertParagraph } from "../../utils/copypaste.js";
import { focusOnEditor } from "../../utils/editor.js";
import { executeSlashCommand } from "../../utils/slashmenu.js";

test.beforeEach(async ({ page }) => {
await page.goto(BASE_URL, { waitUntil: "networkidle" });
Expand Down Expand Up @@ -109,4 +111,26 @@ test.describe("Check Background & Text Color Functionality", () => {

expect(await page.screenshot()).toMatchSnapshot("blockBackgroundColor.png");
});
// Regression test: prosemirror-tables' TableView.update() preserves the
// NodeView's DOM without re-applying node attrs, so prop changes (e.g.
// textColor) wouldn't propagate to the blockContent wrapper. BlockNoteTableView
// overrides update() to sync prop-derived data-* attributes.
test("Should be able to set block text color on a table", async ({
page,
}) => {
await focusOnEditor(page);
await executeSlashCommand(page, "table");
await page.keyboard.type("Table Cell");

await page.hover(TABLE_SELECTOR);
await page.click(DRAG_HANDLE_SELECTOR);
await page.waitForSelector(DRAG_HANDLE_MENU_SELECTOR);
await page.hover("text=Colors");

const element = page.locator(TEXT_COLOR_SELECTOR("red"));
const boundingBox = (await element.boundingBox())!;
await page.mouse.click(boundingBox.x + 10, boundingBox.y + 10);

expect(await page.screenshot()).toMatchSnapshot("blockTextColorTable.png");
});
Comment on lines +118 to +135
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a settle delay before the screenshot to avoid flakiness.

The other three block-color tests in this file wait 500ms after clicking the color swatch ("Waits for block side menu animation to finish") before taking the snapshot. This new test takes the screenshot immediately after page.mouse.click(...), so the drag-handle menu / Colors submenu may still be animating/closing when the snapshot is captured, leading to intermittent mismatches in CI.

🔧 Proposed fix
     const element = page.locator(TEXT_COLOR_SELECTOR("red"));
     const boundingBox = (await element.boundingBox())!;
     await page.mouse.click(boundingBox.x + 10, boundingBox.y + 10);

+    // Waits for block side menu animation to finish.
+    await page.waitForTimeout(500);
+
     expect(await page.screenshot()).toMatchSnapshot("blockTextColorTable.png");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test("Should be able to set block text color on a table", async ({
page,
}) => {
await focusOnEditor(page);
await executeSlashCommand(page, "table");
await page.keyboard.type("Table Cell");
await page.hover(TABLE_SELECTOR);
await page.click(DRAG_HANDLE_SELECTOR);
await page.waitForSelector(DRAG_HANDLE_MENU_SELECTOR);
await page.hover("text=Colors");
const element = page.locator(TEXT_COLOR_SELECTOR("red"));
const boundingBox = (await element.boundingBox())!;
await page.mouse.click(boundingBox.x + 10, boundingBox.y + 10);
expect(await page.screenshot()).toMatchSnapshot("blockTextColorTable.png");
});
test("Should be able to set block text color on a table", async ({
page,
}) => {
await focusOnEditor(page);
await executeSlashCommand(page, "table");
await page.keyboard.type("Table Cell");
await page.hover(TABLE_SELECTOR);
await page.click(DRAG_HANDLE_SELECTOR);
await page.waitForSelector(DRAG_HANDLE_MENU_SELECTOR);
await page.hover("text=Colors");
const element = page.locator(TEXT_COLOR_SELECTOR("red"));
const boundingBox = (await element.boundingBox())!;
await page.mouse.click(boundingBox.x + 10, boundingBox.y + 10);
// Waits for block side menu animation to finish.
await page.waitForTimeout(500);
expect(await page.screenshot()).toMatchSnapshot("blockTextColorTable.png");
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/src/end-to-end/colors/colors.test.ts` around lines 118 - 135, The test
"Should be able to set block text color on a table" is missing a short settle
delay after clicking the color swatch, causing flakiness; update the test (the
block using focusOnEditor, executeSlashCommand, TABLE_SELECTOR,
DRAG_HANDLE_SELECTOR, DRAG_HANDLE_MENU_SELECTOR, and TEXT_COLOR_SELECTOR) to
await a small pause (e.g., 500ms) after the page.mouse.click(...) that selects
the color before calling page.screenshot(), so the drag-handle / Colors submenu
animation has time to finish.

});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading