Skip to content

fix(docs): announce the hero copy, and stop remounting the icons - #452

Merged
allxsmith merged 1 commit into
mainfrom
fix/hero-a11y-and-static-icons
Aug 2, 2026
Merged

allxsmith merged 1 commit into
mainfrom
fix/hero-a11y-and-static-icons

Conversation

@allxsmith

Copy link
Copy Markdown
Owner

Pull Request

Description

CodeRabbit's review on #434 arrived six minutes after the last push and the PR merged before
these landed, so this is the follow-up. Three findings, all in the homepage hero.

1. The copy box had no accessible name of its own. It derived one from its content — the
install command — so a screen reader announced "pnpm add @allxsmith/bestax-bulma, button"
rather than what activating it does. Now aria-label="Copy install command for {manager}",
naming the manager it would actually copy. The command stays readable as content.

2. Nothing announced the copy. The icon swap and the title flip to "Copied!" are both
silent to assistive tech, so the confirmation existed only for sighted users. Added a
visually-hidden role="status" aria-live="polite" region.

Two details that make it actually work:

  • It renders empty rather than conditionally, so the region is in the accessibility tree
    before the text arrives — announcing depends on the region's content changing, not on the
    node appearing.
  • .srOnly uses the clip/absolute pattern, not display: none or visibility: hidden —
    either of those removes the node from the accessibility tree, and a live region using them
    never announces at all.

3. The three icons were declared inside HomepageHeader. A component defined during render
is a new component type every render, so React remounts instead of updating —
react-hooks/static-components. Mostly theoretical for static SVGs, except the copy box swaps
CheckIcon/CopyIcon on every copy, which is where it actually happened. Moved to module
scope.

Also drops the unused siteConfig destructure in HomepageHeader; the import stays because
Home still uses it.

  • bulma-ui (@allxsmith/bestax-bulma)
  • create-bestax (create-bestax)
  • docs (@allxsmith/bestax-docs)

Related Issue(s)

Refs #434

Type of Change

  • Bug fix
  • Other: accessibility

Note on CI

Nothing in CI catches any of this. docs has no lint script, so turbo run lint skips
the package entirely — which is why a react-hooks/static-components violation has been
sitting in index.js unflagged. Worth a separate issue; adding a lint script to docs would
surface a backlog of pre-existing violations, so it isn't a drive-by fix.

Checklist

  • My code follows the project style guidelines
  • I have performed a self-review of my code
  • I have added/updated documentation as needed
  • All new and existing tests passed

Verification

From the prerendered build:

21 tests pass; lint and format clean.

Not verified in a browser: that a screen reader actually announces "Copied to clipboard" on
copy. The markup is the standard live-region pattern and the empty-render detail is the usual
reason these silently fail, but a real AT check would be worth doing if you have VoiceOver
handy.

CodeRabbit's review on #434, which merged before these landed.

**The copy box had no accessible name of its own.** It derived one from its
content — the install command — so a screen reader announced
"pnpm add @allxsmith/bestax-bulma, button" instead of what activating it does.
Now labelled with the action, naming the manager it would copy. The command
stays readable as content.

**Nothing announced the copy.** The icon swap and the `title` flip to "Copied!"
are both silent to assistive tech, so the confirmation existed only for sighted
users. Added a visually-hidden `role="status"` live region. It renders empty
rather than conditionally, so the region is already in the accessibility tree
when the text arrives — announcing depends on the region's *content* changing,
not on the node appearing. The `.srOnly` class deliberately avoids
`display: none` and `visibility: hidden`, either of which would remove it from
the accessibility tree and stop it announcing at all.

**The three icons were declared inside HomepageHeader.** A component defined
during render is a new component type each render, so React remounts rather
than updates — `react-hooks/static-components`. Mostly theoretical for static
SVGs, except the copy box swaps CheckIcon and CopyIcon on every copy, which is
where it actually happened. Moved to module scope.

Also drops the unused `siteConfig` destructure in HomepageHeader. The import
stays — `Home` still uses it.

Nothing in CI catches any of this: `docs` has no lint script, so
`turbo run lint` skips the package entirely.

Claude-Session: https://claude.ai/code/session_01TGA6sFTUGsJ6oXhfpjKEnh
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

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

Next review available in: 28 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bafd2c57-a35f-4356-8ab9-680b0585d3df

📥 Commits

Reviewing files that changed from the base of the PR and between a1fcf51 and 98e2cb0.

📒 Files selected for processing (2)
  • docs/src/pages/index.js
  • docs/src/pages/index.module.css

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 Aug 1, 2026

Copy link
Copy Markdown
Contributor

AI triage — issues this PR may resolve

If this PR resolves one of these, add the line below to the PR description
so the issue closes on merge:

Fixes #N

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://32a7f30d.bestax.pages.dev

@allxsmith
allxsmith merged commit 71bd493 into main Aug 2, 2026
16 checks passed
@allxsmith
allxsmith deleted the fix/hero-a11y-and-static-icons branch August 2, 2026 00:07
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 4.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.8.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant