markdown: Render checkboxes in markdown table cells (#50595)
iam-liam
created
Render `[x]` and `[ ]` as checkbox widgets when they appear as the sole
content of a markdown table cell. Previously these were displayed as raw
text. List-item checkboxes were already rendered correctly; this extends
the same treatment to table cells.
Fixes #50045.
## What this does
- Table cells containing only `[x]`, `[X]`, or `[ ]` now render as
visual checkboxes instead of plain text
- Both markdown rendering paths are covered: the `markdown` crate (agent
panel, chat) and the `markdown_preview` crate (file preview)
- Checkboxes are display-only, matching the existing list-item checkbox
behavior
## How it works
pulldown-cmark splits `[x]` in table cells into three separate `Text`
events (`[`, `x`, `]`) rather than emitting a `TaskListMarker` event
(which only fires for list items per the GFM spec). The fix operates at
each crate's natural interception point:
- **`markdown` crate**: After all text events for a table cell have been
buffered, `replace_pending_checkbox()` checks the accumulated text
before the cell div is finalized. If it matches the checkbox pattern,
the pending text is replaced with a `Checkbox` widget.
- **`markdown_preview` crate**: In `render_markdown_text()`, text chunks
whose trimmed content matches the checkbox pattern are rendered as
`MarkdownCheckbox` widgets instead of `InteractiveText`.
## Scope
Three files, purely additive:
- `crates/markdown/src/markdown.rs` — `replace_pending_checkbox()` on
builder, called at `TableCell` end
- `crates/markdown_preview/src/markdown_renderer.rs` — checkbox
detection in `render_markdown_text()`
- `crates/markdown_preview/src/markdown_parser.rs` — test only
No changes to parser data models, GPUI, or any shared infrastructure.
## What's not in scope
- **HTML `<input type="checkbox">`** — pulldown-cmark strips these as
raw HTML. Supporting them requires HTML tag parsing, which is a separate
concern.
- **Interactive (click-to-toggle) checkboxes in tables** — table
checkboxes are display-only. List-item checkboxes in Zed support
Cmd+click toggling, but extending that to table cells would require
tracking source ranges across the split parser events, which is a
separate enhancement.
## Follow-up
Table checkbox interactivity (Cmd+click toggle) is straightforward to
add as a follow-up — the source ranges are already available in
`markdown_preview`, and the `markdown` crate would need minor callback
plumbing.
## Screenshots
**Markdown checkbox before**
<img width="1603" height="863" alt="md-checkbox-before-1"
src="https://github.com/user-attachments/assets/8539d79d-c74f-4d14-a3e5-525e4d0083aa"
/>
<img width="1599" height="892" alt="md-checkbox-before-2"
src="https://github.com/user-attachments/assets/7badfab1-651f-4fab-8879-deb109c56670"
/>
**Markdown checkbox after**
<img width="1832" height="889" alt="md-checkbox-after-1"
src="https://github.com/user-attachments/assets/463b6334-9f50-41c0-ab7e-24d238244873"
/>
<img width="1795" height="886" alt="md-checkbox-after-2"
src="https://github.com/user-attachments/assets/57d3d9de-1d23-42ba-bc0a-5aa0c699b13d"
/>
## Test plan
**Unit tests** (2 new):
- `test_table_with_checkboxes` (markdown_preview) — parser delivers
`[x]`/`[ ]` text into table cell structures
- `test_table_checkbox_detection` (markdown) — parser events accumulate
checkbox text in table cells, confirming `replace_pending_checkbox`
detection logic
**Automated**:
- [x] `cargo test -p markdown` — 27 tests pass (26 existing + 1 new)
- [x] `cargo test -p markdown_preview` — 61 tests pass (60 existing + 1
new)
**Manual** (verified against `test-checkbox-table.md`):
- [x] Basic `[x]`/`[ ]` in a status column
- [x] Checkbox-only column alongside text
- [x] Multiple checkbox columns in one table
- [x] Left, center, and right column alignments
- [x] Uppercase `[X]` variant
- [x] Leading/trailing whitespace in cell
- [x] Checkboxes alongside other inline elements (links, bold text)
- [x] Single-column and minimal two-column tables
- [x] Normal table text unaffected by detection
- [x] List checkboxes still render correctly (regression)
- [x] Agent panel: asked agent to output table with checkbox columns
Release Notes:
- Fixed `[x]` and `[ ]` checkboxes not rendering in markdown table cells
(#50045)