Fix multiple accessibility defects identified by AXE (#10606)

* Mark effects overlay canvas as aria hidden

* Ensure date separators aren't seen as focusable aria separators

* Fix

* Fix font slider not having aria label

* Add missing aria labels

* Fix settings flags setting aria-checked={null}

* Update snapshots
t3chguy/dedup-icons-17oct
Michael Telatynski 2023-04-17 17:09:45 +01:00 committed by GitHub
parent 270a26d89a
commit 1a0e5c1805
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 210 additions and 194 deletions

View File

@ -22,6 +22,11 @@ limitations under the License.
}
.mx_SelectableDeviceTile_checkbox {
flex: 0 0;
margin-right: $spacing-16;
flex: 1 0;
.mx_Checkbox_background + div {
flex: 1 0;
/* override more specific selector */
margin-left: $spacing-16 !important;
}
}

View File

@ -90,6 +90,7 @@ const EffectsOverlay: FunctionComponent<IProps> = ({ roomWidth }) => {
top: 0,
right: 0,
}}
aria-hidden={true}
/>
);
};

View File

@ -540,8 +540,9 @@ export default class ImageView extends React.Component<IProps, IState> {
<FocusLock
returnFocus={true}
lockProps={{
onKeyDown: this.onKeyDown,
role: "dialog",
"onKeyDown": this.onKeyDown,
"role": "dialog",
"aria-label": _t("Image view"),
}}
className="mx_ImageView"
ref={this.focusLock}

View File

@ -62,7 +62,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
}
private getSettingValue(): boolean {
return SettingsStore.getValueAt(
return !!SettingsStore.getValueAt(
this.props.level,
this.props.name,
this.props.roomId ?? null,

View File

@ -35,6 +35,8 @@ interface IProps {
// Whether the slider is disabled
disabled: boolean;
label: string;
}
const THUMB_SIZE = 2.4; // em
@ -77,6 +79,7 @@ export default class Slider extends React.Component<IProps> {
disabled={this.props.disabled}
step={this.props.step}
autoComplete="off"
aria-label={this.props.label}
/>
{selection}
</div>

View File

@ -322,7 +322,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
public render(): React.ReactNode {
const label = this.getLabel();
let dateHeaderContent;
let dateHeaderContent: JSX.Element;
if (this.state.jumpToDateEnabled) {
dateHeaderContent = this.renderJumpToDateMenu();
} else {
@ -336,9 +336,8 @@ export default class DateSeparator extends React.Component<IProps, IState> {
}
// ARIA treats <hr/>s as separators, here we abuse them slightly so manually treat this entire thing as one
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
return (
<div className="mx_DateSeparator" role="separator" tabIndex={-1} aria-label={label}>
<div className="mx_DateSeparator" role="separator" aria-label={label}>
<hr role="none" />
{dateHeaderContent}
<hr role="none" />

View File

@ -128,6 +128,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
onChange={this.onFontSizeChanged}
displayFunc={(_) => ""}
disabled={this.state.useCustomFontSize}
label={_t("Font size")}
/>
<div className="mx_FontScalingPanel_fontSlider_largeText">Aa</div>
</div>

View File

@ -35,10 +35,11 @@ const SelectableDeviceTile: React.FC<Props> = ({ children, device, isSelected, o
className="mx_SelectableDeviceTile_checkbox"
id={`device-tile-checkbox-${device.device_id}`}
data-testid={`device-tile-checkbox-${device.device_id}`}
/>
<DeviceTile device={device} onClick={onClick} isSelected={isSelected}>
{children}
</DeviceTile>
>
<DeviceTile device={device} onClick={onClick} isSelected={isSelected}>
{children}
</DeviceTile>
</StyledCheckbox>
</div>
);
};

View File

@ -284,6 +284,7 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
onClick={chromeFileInputFix}
onChange={this.onSoundUploadChanged}
accept="audio/*"
aria-label={_t("Upload custom sound")}
/>
</form>

View File

@ -1701,6 +1701,7 @@
"Sounds": "Sounds",
"Notification sound": "Notification sound",
"Set a new custom sound": "Set a new custom sound",
"Upload custom sound": "Upload custom sound",
"Browse": "Browse",
"Failed to unban": "Failed to unban",
"Unban": "Unban",
@ -2600,6 +2601,7 @@
"%(oneUser)ssent %(count)s hidden messages|one": "%(oneUser)ssent a hidden message",
"collapse": "collapse",
"expand": "expand",
"Image view": "Image view",
"Rotate Left": "Rotate Left",
"Rotate Right": "Rotate Right",
"Information": "Information",

View File

@ -42,7 +42,6 @@ exports[`MessagePanel should handle lots of membership events quickly 1`] = `
aria-label="Thu, Jan 1 1970"
class="mx_DateSeparator"
role="separator"
tabindex="-1"
>
<hr
role="none"

View File

@ -48,7 +48,6 @@ exports[`<MessageEditHistory /> should match the snapshot 1`] = `
aria-label="Thu, Jan 1 1970"
class="mx_DateSeparator"
role="separator"
tabindex="-1"
>
<hr
role="none"
@ -165,7 +164,6 @@ exports[`<MessageEditHistory /> should support events with 1`] = `
aria-label=", NaN NaN"
class="mx_DateSeparator"
role="separator"
tabindex="-1"
>
<hr
role="none"

View File

@ -6,7 +6,6 @@ exports[`DateSeparator renders the date separator correctly 1`] = `
aria-label="Today"
class="mx_DateSeparator"
role="separator"
tabindex="-1"
>
<hr
role="none"
@ -34,7 +33,6 @@ exports[`DateSeparator when feature_jump_to_date is enabled renders the date sep
aria-label="Fri, Dec 17 2021"
class="mx_DateSeparator"
role="separator"
tabindex="-1"
>
<hr
role="none"

View File

@ -232,66 +232,68 @@ exports[`<DevicesPanel /> renders device panel with devices 1`] = `
class="mx_Checkbox_checkmark"
/>
</div>
<div>
<div
class="mx_DeviceTile"
data-testid="device-tile-device_2"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Unverified"
class="mx_DeviceTypeIcon_verificationIcon unverified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
device_2
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Unverified
</span>
·
<span
data-testid="device-metadata-deviceId"
>
device_2
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
role="button"
tabindex="0"
>
Rename
</div>
</div>
</div>
</div>
</label>
</span>
<div
class="mx_DeviceTile"
data-testid="device-tile-device_2"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Unverified"
class="mx_DeviceTypeIcon_verificationIcon unverified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
device_2
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Unverified
</span>
·
<span
data-testid="device-metadata-deviceId"
>
device_2
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
role="button"
tabindex="0"
>
Rename
</div>
</div>
</div>
</div>
</div>
<div
@ -318,66 +320,68 @@ exports[`<DevicesPanel /> renders device panel with devices 1`] = `
class="mx_Checkbox_checkmark"
/>
</div>
<div>
<div
class="mx_DeviceTile"
data-testid="device-tile-device_3"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Unverified"
class="mx_DeviceTypeIcon_verificationIcon unverified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
device_3
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Unverified
</span>
·
<span
data-testid="device-metadata-deviceId"
>
device_3
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
role="button"
tabindex="0"
>
Rename
</div>
</div>
</div>
</div>
</label>
</span>
<div
class="mx_DeviceTile"
data-testid="device-tile-device_3"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Unverified"
class="mx_DeviceTypeIcon_verificationIcon unverified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
device_3
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Unverified
</span>
·
<span
data-testid="device-metadata-deviceId"
>
device_3
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
role="button"
tabindex="0"
>
Rename
</div>
</div>
</div>
</div>
</div>
<div

View File

@ -37,6 +37,7 @@ exports[`FontScalingPanel renders the font scaling UI 1`] = `
class="mx_Slider"
>
<input
aria-label="Font size"
autocomplete="off"
max="18"
min="13"

View File

@ -32,68 +32,70 @@ exports[`<SelectableDeviceTile /> renders unselected device tile with checkbox 1
class="mx_Checkbox_checkmark"
/>
</div>
<div>
<div
class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-my-device"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Unverified"
class="mx_DeviceTypeIcon_verificationIcon unverified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
My Device
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Unverified
</span>
·
<span
data-testid="device-metadata-lastSeenIp"
>
123.456.789
</span>
·
<span
data-testid="device-metadata-deviceId"
>
my-device
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div>
test
</div>
</div>
</div>
</div>
</label>
</span>
<div
class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-my-device"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Unverified"
class="mx_DeviceTypeIcon_verificationIcon unverified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
My Device
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Unverified
</span>
·
<span
data-testid="device-metadata-lastSeenIp"
>
123.456.789
</span>
·
<span
data-testid="device-metadata-deviceId"
>
my-device
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div>
test
</div>
</div>
</div>
</div>
</div>
`;

File diff suppressed because one or more lines are too long