Skip to content

feat: Tables a11y (BLO-1230) (BLO-1231) - #3215

Open
matthewlipski wants to merge 6 commits into
a11y-testingfrom
tables-a11y
Open

matthewlipski wants to merge 6 commits into
a11y-testingfrom
tables-a11y

Conversation

@matthewlipski

Copy link
Copy Markdown
Collaborator

Summary

This PR adds some additional HTML attributes to tables:

  • Header id
  • Header scope (determines whether header is for a row or column)
  • Cell headers (determines which headers the cell is under)

They are not required by WCAG guidelines and so are not caught in axe scans, but make the relationships between cells and headers more explicit, especially when they span multiple rows/columns.

This is implemented using decorations. Serializing to HTML has additional logic to apply the attributes as decorations can't be applied.

Closes #2825
Closes #2826

Rationale

This is an a11y improvement.

Changes

  • Added TableAccessibilityPlugin to apply cell & header decorations
  • Updated table serialization code

Impact

N/A

Testing

Updates table format conversion snapshots. No changes to a11y tests as axe scans do not check this.

Screenshots/Video

N/A

Checklist

  • Code follows the project's coding standards.
  • Unit tests covering the new feature have been added.
  • All existing tests pass.
  • The documentation has been updated to reflect the new feature

Additional Notes

N/A

@vercel

vercel Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
blocknote Ready Ready Preview Oct 28, 2026 7:08pm UTC
blocknote-website Error Error Oct 28, 2026 7:08pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 75372884-90f5-4e91-a365-31e47df91781

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://TypeCellOS.github.io/BlockNote/pr-preview/pr-3215/

Built to branch gh-pages at 2026-10-28 19:14 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@matthewlipski matthewlipski changed the title feat: Tables a11y feat: Tables a11y (BLO-1230 BLO 1231) Oct 22, 2026
@matthewlipski matthewlipski changed the title feat: Tables a11y (BLO-1230 BLO 1231) feat: Tables a11y (BLO-1230) (BLO 1231) Oct 22, 2026
@matthewlipski matthewlipski changed the title feat: Tables a11y (BLO-1230) (BLO 1231) feat: Tables a11y (BLO-1230) (BLO-1231) Oct 22, 2026

@nperez0111 nperez0111 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused on the approach for this. Is is that we need to do a bunch of calculations to get the right attribute values? Why are we not just adding new attributes to the nodes that we need. Tables are especially easy to do this from since they are transformed anyway for the blocknote representation

{ type: "table", content: tableContent } as any,
);

const isHeaderCol = headerCols[absoluteCellIndex.col];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

purposeful?

}
// Mark the cell as a header if it is a tableHeader node.
headerMatrix[rowIndex][cellIndex] = cellNode.type.name === "tableHeader";
row.cells = rowNode.content.content.map((cellNode) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused why this changed

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This and the above change you commented on fix a bug with converting to/from TipTap nodes. Check commit c141d42 which adds a test case for it. When either of the changes is reverted, the test fails on round trip.

applyHeaderScope,
} from "./cellAttributes.js";

export function TableAccessibilityPlugin() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused on why we are doing this via decorations and serializers, why are we not just adding the attributes to the table cells/headers

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

To get the value for headers we need the position of the cell, so we need to use a node view. I tried doing that instead of using decorations but settled on decorations because it was more readable basically.

@pkg-pr-new

pkg-pr-new Bot commented Oct 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/@blocknote/ariakit@3215

@blocknote/code-block

npm i https://pkg.pr.new/@blocknote/code-block@3215

@blocknote/core

npm i https://pkg.pr.new/@blocknote/core@3215

@blocknote/diagram-block

npm i https://pkg.pr.new/@blocknote/diagram-block@3215

@blocknote/mantine

npm i https://pkg.pr.new/@blocknote/mantine@3215

@blocknote/math-block

npm i https://pkg.pr.new/@blocknote/math-block@3215

@blocknote/react

npm i https://pkg.pr.new/@blocknote/react@3215

@blocknote/server-util

npm i https://pkg.pr.new/@blocknote/server-util@3215

@blocknote/shadcn

npm i https://pkg.pr.new/@blocknote/shadcn@3215

@blocknote/xl-ai

npm i https://pkg.pr.new/@blocknote/xl-ai@3215

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/@blocknote/xl-docx-exporter@3215

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/@blocknote/xl-email-exporter@3215

@blocknote/xl-multi-column

npm i https://pkg.pr.new/@blocknote/xl-multi-column@3215

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/@blocknote/xl-odt-exporter@3215

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/@blocknote/xl-pdf-exporter@3215

@blocknote/xl-typst-exporter

npm i https://pkg.pr.new/@blocknote/xl-typst-exporter@3215

commit: 776aefd

This branch had an error being deployed

1 failed and 1 active deployments
Preview – blocknote-website — 776aefde Deployed Oct 28, 2026 by vercel[bot]
Preview – blocknote — 776aefde Deployed Oct 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants