feat(a11y): label form controls + overlays (P3-4)

Accessible names for ~15 controls that lacked them: invite/join/create-room/
account-data/image-pack/private-note/power-level inputs (visible <label htmlFor>
where a label exists, else aria-label); the two range sliders (night-light
intensity, noise-gate threshold); the soundboard file input; media <video>
elements; and the Media Gallery (region) + Search (dialog) overlays. Hidden
notification/preview <audio> marked aria-hidden.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 11:45:21 -04:00
parent 8729ccfcf5
commit 4380041014
14 changed files with 58 additions and 15 deletions
+1
View File
@@ -213,6 +213,7 @@ function AccountDataView({ type, defaultContent, onEdit }: AccountDataViewProps)
<Text size="L400">Account Data</Text>
<Input
variant="SurfaceVariant"
aria-label="Account data type"
size="400"
radii="300"
readOnly
+6 -1
View File
@@ -282,7 +282,12 @@ export function VoiceMessageRecorder({ onSend, onError }: VoiceRecorderProps) {
>
{previewUrl && (
<>
<audio ref={previewAudioRef} src={previewUrl} onEnded={() => setPreviewPlaying(false)} />
<audio
ref={previewAudioRef}
src={previewUrl}
onEnded={() => setPreviewPlaying(false)}
aria-hidden="true"
/>
<IconButton
onClick={() => {
const audio = previewAudioRef.current;
@@ -78,11 +78,14 @@ export function CreateRoomAliasInput({ disabled }: { disabled?: boolean }) {
return (
<Box shrink="No" direction="Column" gap="100">
<Text size="L400">Address (Optional)</Text>
<Text as="label" htmlFor="create-room-alias" size="L400">
Address (Optional)
</Text>
<Text size="T200" priority="300">
Pick an unique address to make it discoverable.
</Text>
<Input
id="create-room-alias"
ref={aliasInputRef}
onChange={handleAliasChange}
before={
@@ -200,12 +200,24 @@ export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfil
</Box>
</Box>
<Box direction="Inherit" gap="100">
<Text size="L400">Name</Text>
<Input name="nameInput" defaultValue={meta.name} variant="Secondary" radii="300" required />
<Text as="label" htmlFor="image-pack-name" size="L400">
Name
</Text>
<Input
id="image-pack-name"
name="nameInput"
defaultValue={meta.name}
variant="Secondary"
radii="300"
required
/>
</Box>
<Box direction="Inherit" gap="100">
<Text size="L400">Attribution</Text>
<Text as="label" htmlFor="image-pack-attribution" size="L400">
Attribution
</Text>
<TextArea
id="image-pack-attribution"
name="attributionTextArea"
defaultValue={meta.attribution}
variant="Secondary"
@@ -261,9 +261,12 @@ export function InviteUserPrompt({ room, requestClose }: InviteUserProps) {
gap="400"
>
<Box direction="Column" gap="100">
<Text size="L400">User ID</Text>
<Text as="label" htmlFor="invite-user-id" size="L400">
User ID
</Text>
<div>
<Input
id="invite-user-id"
size="500"
ref={inputRef}
onChange={handleSearchChange}
@@ -334,8 +337,11 @@ export function InviteUserPrompt({ room, requestClose }: InviteUserProps) {
</div>
</Box>
<Box direction="Column" gap="100">
<Text size="L400">Reason (Optional)</Text>
<Text as="label" htmlFor="invite-reason" size="L400">
Reason (Optional)
</Text>
<TextArea
id="invite-reason"
size="500"
name="reasonInput"
variant="Background"
@@ -108,8 +108,11 @@ export function JoinAddressPrompt({ onOpen, onCancel }: JoinAddressProps) {
</Text>
</Box>
<Box direction="Column" gap="100">
<Text size="L400">Address</Text>
<Text as="label" htmlFor="join-address" size="L400">
Address
</Text>
<Input
id="join-address"
size="500"
autoFocus
name="addressInput"
@@ -278,6 +278,7 @@ export function SoundboardPackEditor({ pack, canEdit, onUpdate }: SoundboardPack
<Box direction="Column" gap="300">
<input
ref={fileInputRef}
aria-label="Upload soundboard clip"
type="file"
accept={SOUNDBOARD_ACCEPT}
multiple
@@ -56,6 +56,7 @@ function PreviewVideo({ fileItem }: PreviewVideoProps) {
return (
<video
aria-label="Video attachment preview"
style={{
objectFit: 'contain',
width: '100%',
@@ -253,6 +253,7 @@ function UserPrivateNotes({ userId }: { userId: string }) {
)}
</Box>
<textarea
aria-label="Private note about this user"
value={draft}
onChange={handleChange}
maxLength={USER_NOTE_MAX_LENGTH}