Repository navigation
fix(ui): expose DataTable loading semantics and hide the decorative spinner - #11869
Merged
diegosouzapw merged 2 commits intoAug 28, 2026
Conversation
…pinner The DataTable loading early-return rendered a bare <div> with an animated 'hourglass' emoji followed by the localized loading label. The emoji carries no aria-hidden, so assistive technology reads it as content ahead of the label, and the container advertised neither a status role nor aria-busy. Mirror PageLoading in src/shared/components/Loading.tsx: role="status", aria-live="polite", aria-busy="true" on the container and aria-hidden on the decorative glyph. Layout, animation, keyboard behaviour, the empty state and the consumer contracts are untouched.
diegosouzapw
merged commit Aug 28, 2026
5c0b68e
into
cheaper-inference:release/v3.8.51
7 of 16 checks passed
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…pinner (cheaper-inference#11869) DataTable's loading state now mirrors PageLoading's a11y convention (role=status, aria-live=polite, aria-busy=true on the container, aria-hidden on the decorative glyph) instead of announcing a bare emoji as content to assistive tech. Honest scope note in the PR body about when aria-live actually fires today. Thanks!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DataTable's loading early-return renders a bare<div>containing an animated ⏳ emojifollowed by the localized loading label. The emoji carries no
aria-hidden, so assistivetechnology reads the decorative glyph as content immediately ahead of the label, and the
container advertises neither a status role nor
aria-busy.This PR mirrors
PageLoadinginsrc/shared/components/Loading.tsx— the repo's ownconvention for a loading surface:
role="status",aria-live="polite"andaria-busy="true"on the container,aria-hidden="true"on the decorative glyph.Scope, stated honestly. The guaranteed, user-visible win here is (a): the decorative
glyph stops being announced as noise before the label. (b) is correct, future-proof
semantic labelling — it is not an announcement fix in the tree as it stands today.
All three call sites that pass
loading(ComplianceTab, and the twoConductorPageClienttables) enter the loading state only on mount and never re-enter it —
setLoading(false)is never followed by
setLoading(true), andsnapshotis never reset tonull— soaria-livehas no transition to announce right now. It starts announcing the moment anyconsumer re-enters the loading state (a refresh button, a poll that clears its snapshot),
and until then it costs nothing and keeps the primitive consistent with
PageLoading.No i18n keys were added:
common.loadingandcommon.noDataalready exist. Layout,animation, keyboard behaviour, the empty state and the public prop contract are untouched.
Changelog fragment:
changelog.d/fixes/11869-data-table-loading-a11y.md.Related Issues
Validation
npm run lintrelease/v3.8.51@dd8575e); focused checks rerun afterwardchangelog.d/fixes/(npm run check:changelog-integrity→ exit 0)Test output
Red — new test run against the unpatched component (
git checkout HEAD~1 -- src/shared/components/DataTable.tsx):Green — new test plus the existing keyboard test, with the fix applied:
Lint (repo-wide) and format:
Tests Added Or Updated
tests/unit/ui/data-table-loading-a11y.test.tsx(8 cases).tests/unit/ui/data-table-keyboard-activation.test.tsxwas re-run unchanged, as a regression guard for fix(dashboard): enable keyboard activation for data-table rows #11610.
Coverage Notes
src/shared/components/DataTable.tsxis the only production file touched, and only itsloadingearly-return. The new test file covers that branch directly — status role,aria-live,aria-busy, the hidden glyph, the readable text left in the region, and thepreserved inline flex styling /
@keyframes spinblock — and also asserts the other twobranches (empty state, populated table) do not gain a status region or
aria-busy.The keyboard branch remains covered by the existing test. Coverage on the touched file
moves up, not down.
Reviewer Notes
live-region wiring is deliberately framed as correct labelling rather than as an
announcement, because nothing in the current tree re-enters the loading state. Please
hold the description to that standard.
<style>{@Keyframes spin ...}</style>now lives inside therole="status"element.A
<style>element contributes no text to the accessibility tree, so it does not affectthe region's accessible content; the readable-text assertion in the test excludes it
explicitly so the behaviour is pinned rather than assumed.
emptyIconglyph is likewise decorative and unlabelled, but changing itis outside this PR's scope and would touch a different branch and different consumer
expectations. Happy to follow up separately if you want it.