Skip to content

Commit 666ee1e

Browse files
fix: text color was not applying to table block (#2663)
1 parent 64b47d0 commit 666ee1e

5 files changed

Lines changed: 50 additions & 0 deletions

File tree

packages/core/src/blocks/Table/block.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TableContent,
1111
} from "../../schema/index.js";
1212
import { mergeCSSClasses } from "../../util/browser.js";
13+
import { camelToDataKebab } from "../../util/string.js";
1314
import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
1415
import { defaultProps } from "../defaultProps.js";
1516
import { EMPTY_CELL_WIDTH, TableExtension } from "./TableExtension.js";
@@ -252,6 +253,31 @@ const TiptapTableNode = Node.create({
252253
super.ignoreMutation(record)
253254
);
254255
}
256+
257+
// `TableView` implements its own `update` method, as the view needs to
258+
// be persisted across updates for column resizing to work properly.
259+
// However, it doesn't do anything else, so we have to re-apply the
260+
// HTML attributes from props manually. This isn't an issue for node
261+
// views created e.g. by custom blocks, as those aren't persisted
262+
// across updates (they are reinstantiated each time), and so
263+
// `HTMLAttributes` is always up-to-date for those.
264+
update(updatedNode: PMNode): boolean {
265+
if (!super.update(updatedNode)) {
266+
return false;
267+
}
268+
269+
for (const [propName, propSpec] of Object.entries(tablePropSchema)) {
270+
const attrName = camelToDataKebab(propName);
271+
const value = updatedNode.attrs[propName];
272+
if (value !== propSpec.default) {
273+
this.dom.setAttribute(attrName, String(value));
274+
} else {
275+
this.dom.removeAttribute(attrName);
276+
}
277+
}
278+
279+
return true;
280+
}
255281
}
256282

257283
return new BlockNoteTableView(node, EMPTY_CELL_WIDTH, {

tests/src/end-to-end/colors/colors.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import {
77
DRAG_HANDLE_MENU_SELECTOR,
88
DRAG_HANDLE_SELECTOR,
99
H_TWO_BLOCK_SELECTOR,
10+
TABLE_SELECTOR,
1011
TEXT_COLOR_SELECTOR,
1112
} from "../../utils/const.js";
1213
import { insertHeading, insertParagraph } from "../../utils/copypaste.js";
1314
import { focusOnEditor } from "../../utils/editor.js";
15+
import { executeSlashCommand } from "../../utils/slashmenu.js";
1416

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

110112
expect(await page.screenshot()).toMatchSnapshot("blockBackgroundColor.png");
111113
});
114+
// Regression test: prosemirror-tables' TableView.update() preserves the
115+
// NodeView's DOM without re-applying node attrs, so prop changes (e.g.
116+
// textColor) wouldn't propagate to the blockContent wrapper. BlockNoteTableView
117+
// overrides update() to sync prop-derived data-* attributes.
118+
test("Should be able to set block text color on a table", async ({
119+
page,
120+
}) => {
121+
await focusOnEditor(page);
122+
await executeSlashCommand(page, "table");
123+
await page.keyboard.type("Table Cell");
124+
125+
await page.hover(TABLE_SELECTOR);
126+
await page.click(DRAG_HANDLE_SELECTOR);
127+
await page.waitForSelector(DRAG_HANDLE_MENU_SELECTOR);
128+
await page.hover("text=Colors");
129+
130+
const element = page.locator(TEXT_COLOR_SELECTOR("red"));
131+
const boundingBox = (await element.boundingBox())!;
132+
await page.mouse.click(boundingBox.x + 10, boundingBox.y + 10);
133+
134+
expect(await page.screenshot()).toMatchSnapshot("blockTextColorTable.png");
135+
});
112136
});
8.32 KB
Loading
24.8 KB
Loading
27.8 KB
Loading

0 commit comments

Comments
 (0)