Skip to content

Make docs code-copy controls accessible - #403

Open
Alek99 wants to merge 4 commits into
mainfrom
agent/fix-395-accessible-code-copy
Open

Make docs code-copy controls accessible#403
Alek99 wants to merge 4 commits into
mainfrom
agent/fix-395-accessible-code-copy

Conversation

@Alek99

@Alek99 Alek99 commented Jul 31, 2026

Copy link
Copy Markdown
Member

What changed

  • Added an XY-local Shiki code-block wrapper with a native, named copy button.
  • Routed Markdown fences and Preview/Code/Data examples through the wrapper.
  • Added focus-visible styling, per-button local state, aria-live feedback, and distinct copied/failed labels.
  • Added a focused accessibility contract test.

Why

The locked upstream code component rendered icon-only buttons whose icon was hidden from assistive technology. Across the docs, those controls therefore had no accessible name or perceivable success state.

Impact

Code-copy controls now expose Copy code, remain keyboard-focusable as native buttons, announce Copied or Copy failed, swap to a check icon on success, and reset after 1.5 seconds.

Validation

  • docs/app/.venv/bin/pytest -q docs/app/tests — 105 passed
  • Ruff lint and format checks on the changed docs files
  • Production docs build completed successfully
  • Live browser verification on the Annotations component page: named control, visible keyboard focus, click-to-copy state, copied icon/label, and timed reset all passed

Fixes #395

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added accessible, syntax-highlighted code blocks throughout the documentation.
    • Added copy buttons with clear success and failure feedback, keyboard focus styling, and screen-reader announcements.
    • Added support for language aliases, formatted Python examples, optional line ranges, and expandable long code blocks.
    • Updated documentation rendering to provide consistent code block behavior across source examples and Markdown content.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Alek99, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 027d212f-d3d6-4cc8-9a80-cd4a90e65438

📥 Commits

Reviewing files that changed from the base of the PR and between 1dd838f and 7066851.

⛔ Files ignored due to path filters (1)
  • docs/app/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/docs.yml
  • docs/app/pyproject.toml
  • docs/app/tests/test_code_copy.py
📝 Walkthrough

Walkthrough

Documentation code blocks now use accessible copy controls with clipboard status feedback, syntax highlighting, expandable long blocks, and dedicated markdown rendering for non-demo fences.

Changes

Documentation code-copy flow

Layer / File(s) Summary
Code block controls and helpers
docs/app/xy_docs/code.py, docs/app/tests/test_code_copy.py
The new module renders syntax-highlighted code blocks with accessible copy buttons, clipboard success or failure states, optional line ranges, and expandable long blocks. Tests validate accessibility, state transitions, and mount-handler installation.
Markdown and example integration
docs/app/xy_docs/markdown.py, docs/app/xy_docs/examples.py
The markdown transformer keeps executable Python demo fences on the base renderer and routes other fences to code_block. Examples import doccode from xy_docs.code.
Documentation layout wiring
docs/app/xy_docs/xy_docs.py
The documentation layout installs the delegated code-copy feedback handler alongside the existing sidebar highlighting handler.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Markdown
  participant XyDocsMarkdownTransformer
  participant code_block
  participant CopyButton
  participant Clipboard
  Markdown->>XyDocsMarkdownTransformer: provide code fence
  XyDocsMarkdownTransformer->>code_block: render non-demo fence
  code_block->>CopyButton: render accessible copy control
  CopyButton->>Clipboard: copy code
  Clipboard-->>CopyButton: report success or failure
  CopyButton-->>Markdown: show copy status
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change to make documentation code-copy controls accessible.
Linked Issues check ✅ Passed The changes address issue [#395] by adding accessible names, preserving copy behavior, providing perceivable state feedback, and adding automated contract tests.
Out of Scope Changes check ✅ Passed All changes support the linked issue [#395] by implementing and testing accessible documentation code-copy controls.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-395-accessible-code-copy

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

@Alek99
Alek99 marked this pull request as ready for review July 31, 2026 03:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/app/xy_docs/code.py (1)

65-97: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Align the group-data variants with the button attribute.

Change both variants to group-data-[xy-code-copy-state=copied]. The inline selectors currently keep the icon swap working; remove them after the corrected variants are in place.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/app/xy_docs/code.py` around lines 65 - 97, Update both icon class_name
values in the code-copy button to use the group-data-[xy-code-copy-state=copied]
variant, matching the data-xy-code-copy-state attribute. After correcting the
variants, remove the redundant inline icon-swap selectors from the button’s
style configuration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/app/xy_docs/code.py`:
- Around line 60-89: Update the button created in the component’s super().create
call to include a persistent visually hidden span containing the reactive label,
such as the existing label expression, alongside the icons. Keep aria_live and
aria_atomic unchanged so status updates modify live-region text as well as the
button attributes.

---

Nitpick comments:
In `@docs/app/xy_docs/code.py`:
- Around line 65-97: Update both icon class_name values in the code-copy button
to use the group-data-[xy-code-copy-state=copied] variant, matching the
data-xy-code-copy-state attribute. After correcting the variants, remove the
redundant inline icon-swap selectors from the button’s style configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4800fb1b-56c4-46d6-b5d9-79f0da7bd745

📥 Commits

Reviewing files that changed from the base of the PR and between d505ef5 and cacc622.

📒 Files selected for processing (4)
  • docs/app/tests/test_code_copy.py
  • docs/app/xy_docs/code.py
  • docs/app/xy_docs/examples.py
  • docs/app/xy_docs/markdown.py

Comment thread docs/app/xy_docs/code.py Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 4 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread docs/app/xy_docs/examples.py
Comment thread docs/app/xy_docs/code.py Outdated
Comment thread docs/app/xy_docs/code.py Outdated
Comment thread docs/app/xy_docs/code.py Outdated
Comment thread docs/app/xy_docs/code.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/app/tests/test_code_copy.py`:
- Around line 15-45: Extend the tests around the existing serialized code-block
assertions with a browser test that loads the built documentation and enumerates
every visible production copy button. Compute each button’s accessible name and
fail when any visible button has an empty name, preserving the existing
single-code-block assertions while validating the contract across the full built
documentation DOM.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f18df519-00a9-468d-be81-31ce5a551243

📥 Commits

Reviewing files that changed from the base of the PR and between cacc622 and 1dd838f.

📒 Files selected for processing (3)
  • docs/app/tests/test_code_copy.py
  • docs/app/xy_docs/code.py
  • docs/app/xy_docs/xy_docs.py

Comment thread docs/app/tests/test_code_copy.py
@codspeed-hq

codspeed-hq Bot commented Jul 31, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 109 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing agent/fix-395-accessible-code-copy (7066851) with main (d505ef5)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

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.

Docs code-copy buttons have no accessible name

1 participant