Who is affected
Anyone using a screen reader who turns on a Switch that does asynchronous
work, and anyone using Astryx in a language other than English.
What happens
While a Switch is busy it renders
{isBusy && <VisuallyHidden role="status">Loading</VisuallyHidden>}
Two things go wrong with that one line.
- The status is born with its content. The live region is mounted at the
same moment its text appears. Assistive technology announces changes to a
live region, so a region that already contains its text when it is inserted
is usually silent. The person hears nothing at all: they press the switch,
the switch does not visibly change yet, and nothing tells them the change is
in flight.
- The word is hardcoded English. Every other assistive-technology-facing
string in core goes through the translator — Button announces
t('@astryx.button.loading') — but Switch says the literal Loading. A
French or Japanese user hears an English word in the middle of their own
interface.
Button already does this correctly: it renders the live region
unconditionally and swaps the translated text in and out.
Expected
A busy Switch announces its busy state, in the user's language, through the
persistent live region the repository already provides (useAnnounce, or the
always-mounted-region shape Button uses), with the string routed through the
i18n key system.
Where
packages/core/src/Switch/Switch.tsx — the isBusy branch of switchElement.
Compare with packages/core/src/Button/Button.tsx.
Notes
Found while inventorying Switch's states for the shared accessibility
spec-test contract. The contract does not encode announcements: what an
assistive technology actually says is a real-AT observation and is out of scope
for a runtime contract, so this is filed as its own defect rather than recorded
as a contract failure.
The repository accessibility checklist covers both halves — the "Announcements"
item ("Never render a live region that is born with content") and the "i18n"
item ("Every AT-facing string … goes through useTranslator()").
Who is affected
Anyone using a screen reader who turns on a
Switchthat does asynchronouswork, and anyone using Astryx in a language other than English.
What happens
While a
Switchis busy it rendersTwo things go wrong with that one line.
same moment its text appears. Assistive technology announces changes to a
live region, so a region that already contains its text when it is inserted
is usually silent. The person hears nothing at all: they press the switch,
the switch does not visibly change yet, and nothing tells them the change is
in flight.
string in core goes through the translator —
Buttonannouncest('@astryx.button.loading')— butSwitchsays the literalLoading. AFrench or Japanese user hears an English word in the middle of their own
interface.
Buttonalready does this correctly: it renders the live regionunconditionally and swaps the translated text in and out.
Expected
A busy
Switchannounces its busy state, in the user's language, through thepersistent live region the repository already provides (
useAnnounce, or thealways-mounted-region shape
Buttonuses), with the string routed through thei18n key system.
Where
packages/core/src/Switch/Switch.tsx— theisBusybranch ofswitchElement.Compare with
packages/core/src/Button/Button.tsx.Notes
Found while inventorying Switch's states for the shared accessibility
spec-test contract. The contract does not encode announcements: what an
assistive technology actually says is a real-AT observation and is out of scope
for a runtime contract, so this is filed as its own defect rather than recorded
as a contract failure.
The repository accessibility checklist covers both halves — the "Announcements"
item ("Never render a live region that is born with content") and the "i18n"
item ("Every AT-facing string … goes through
useTranslator()").