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
This commit is contained in:
parent
270a26d89a
commit
1a0e5c1805
17 changed files with 210 additions and 194 deletions
|
@ -22,6 +22,11 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SelectableDeviceTile_checkbox {
|
.mx_SelectableDeviceTile_checkbox {
|
||||||
flex: 0 0;
|
flex: 1 0;
|
||||||
margin-right: $spacing-16;
|
|
||||||
|
.mx_Checkbox_background + div {
|
||||||
|
flex: 1 0;
|
||||||
|
/* override more specific selector */
|
||||||
|
margin-left: $spacing-16 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ const EffectsOverlay: FunctionComponent<IProps> = ({ roomWidth }) => {
|
||||||
top: 0,
|
top: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
}}
|
}}
|
||||||
|
aria-hidden={true}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -540,8 +540,9 @@ export default class ImageView extends React.Component<IProps, IState> {
|
||||||
<FocusLock
|
<FocusLock
|
||||||
returnFocus={true}
|
returnFocus={true}
|
||||||
lockProps={{
|
lockProps={{
|
||||||
onKeyDown: this.onKeyDown,
|
"onKeyDown": this.onKeyDown,
|
||||||
role: "dialog",
|
"role": "dialog",
|
||||||
|
"aria-label": _t("Image view"),
|
||||||
}}
|
}}
|
||||||
className="mx_ImageView"
|
className="mx_ImageView"
|
||||||
ref={this.focusLock}
|
ref={this.focusLock}
|
||||||
|
|
|
@ -62,7 +62,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSettingValue(): boolean {
|
private getSettingValue(): boolean {
|
||||||
return SettingsStore.getValueAt(
|
return !!SettingsStore.getValueAt(
|
||||||
this.props.level,
|
this.props.level,
|
||||||
this.props.name,
|
this.props.name,
|
||||||
this.props.roomId ?? null,
|
this.props.roomId ?? null,
|
||||||
|
|
|
@ -35,6 +35,8 @@ interface IProps {
|
||||||
|
|
||||||
// Whether the slider is disabled
|
// Whether the slider is disabled
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
|
||||||
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const THUMB_SIZE = 2.4; // em
|
const THUMB_SIZE = 2.4; // em
|
||||||
|
@ -77,6 +79,7 @@ export default class Slider extends React.Component<IProps> {
|
||||||
disabled={this.props.disabled}
|
disabled={this.props.disabled}
|
||||||
step={this.props.step}
|
step={this.props.step}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
aria-label={this.props.label}
|
||||||
/>
|
/>
|
||||||
{selection}
|
{selection}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -322,7 +322,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const label = this.getLabel();
|
const label = this.getLabel();
|
||||||
|
|
||||||
let dateHeaderContent;
|
let dateHeaderContent: JSX.Element;
|
||||||
if (this.state.jumpToDateEnabled) {
|
if (this.state.jumpToDateEnabled) {
|
||||||
dateHeaderContent = this.renderJumpToDateMenu();
|
dateHeaderContent = this.renderJumpToDateMenu();
|
||||||
} else {
|
} 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
|
// 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 (
|
return (
|
||||||
<div className="mx_DateSeparator" role="separator" tabIndex={-1} aria-label={label}>
|
<div className="mx_DateSeparator" role="separator" aria-label={label}>
|
||||||
<hr role="none" />
|
<hr role="none" />
|
||||||
{dateHeaderContent}
|
{dateHeaderContent}
|
||||||
<hr role="none" />
|
<hr role="none" />
|
||||||
|
|
|
@ -128,6 +128,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
|
||||||
onChange={this.onFontSizeChanged}
|
onChange={this.onFontSizeChanged}
|
||||||
displayFunc={(_) => ""}
|
displayFunc={(_) => ""}
|
||||||
disabled={this.state.useCustomFontSize}
|
disabled={this.state.useCustomFontSize}
|
||||||
|
label={_t("Font size")}
|
||||||
/>
|
/>
|
||||||
<div className="mx_FontScalingPanel_fontSlider_largeText">Aa</div>
|
<div className="mx_FontScalingPanel_fontSlider_largeText">Aa</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,10 +35,11 @@ const SelectableDeviceTile: React.FC<Props> = ({ children, device, isSelected, o
|
||||||
className="mx_SelectableDeviceTile_checkbox"
|
className="mx_SelectableDeviceTile_checkbox"
|
||||||
id={`device-tile-checkbox-${device.device_id}`}
|
id={`device-tile-checkbox-${device.device_id}`}
|
||||||
data-testid={`device-tile-checkbox-${device.device_id}`}
|
data-testid={`device-tile-checkbox-${device.device_id}`}
|
||||||
/>
|
>
|
||||||
<DeviceTile device={device} onClick={onClick} isSelected={isSelected}>
|
<DeviceTile device={device} onClick={onClick} isSelected={isSelected}>
|
||||||
{children}
|
{children}
|
||||||
</DeviceTile>
|
</DeviceTile>
|
||||||
|
</StyledCheckbox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -284,6 +284,7 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
|
||||||
onClick={chromeFileInputFix}
|
onClick={chromeFileInputFix}
|
||||||
onChange={this.onSoundUploadChanged}
|
onChange={this.onSoundUploadChanged}
|
||||||
accept="audio/*"
|
accept="audio/*"
|
||||||
|
aria-label={_t("Upload custom sound")}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -1701,6 +1701,7 @@
|
||||||
"Sounds": "Sounds",
|
"Sounds": "Sounds",
|
||||||
"Notification sound": "Notification sound",
|
"Notification sound": "Notification sound",
|
||||||
"Set a new custom sound": "Set a new custom sound",
|
"Set a new custom sound": "Set a new custom sound",
|
||||||
|
"Upload custom sound": "Upload custom sound",
|
||||||
"Browse": "Browse",
|
"Browse": "Browse",
|
||||||
"Failed to unban": "Failed to unban",
|
"Failed to unban": "Failed to unban",
|
||||||
"Unban": "Unban",
|
"Unban": "Unban",
|
||||||
|
@ -2600,6 +2601,7 @@
|
||||||
"%(oneUser)ssent %(count)s hidden messages|one": "%(oneUser)ssent a hidden message",
|
"%(oneUser)ssent %(count)s hidden messages|one": "%(oneUser)ssent a hidden message",
|
||||||
"collapse": "collapse",
|
"collapse": "collapse",
|
||||||
"expand": "expand",
|
"expand": "expand",
|
||||||
|
"Image view": "Image view",
|
||||||
"Rotate Left": "Rotate Left",
|
"Rotate Left": "Rotate Left",
|
||||||
"Rotate Right": "Rotate Right",
|
"Rotate Right": "Rotate Right",
|
||||||
"Information": "Information",
|
"Information": "Information",
|
||||||
|
|
|
@ -42,7 +42,6 @@ exports[`MessagePanel should handle lots of membership events quickly 1`] = `
|
||||||
aria-label="Thu, Jan 1 1970"
|
aria-label="Thu, Jan 1 1970"
|
||||||
class="mx_DateSeparator"
|
class="mx_DateSeparator"
|
||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
|
||||||
>
|
>
|
||||||
<hr
|
<hr
|
||||||
role="none"
|
role="none"
|
||||||
|
|
|
@ -48,7 +48,6 @@ exports[`<MessageEditHistory /> should match the snapshot 1`] = `
|
||||||
aria-label="Thu, Jan 1 1970"
|
aria-label="Thu, Jan 1 1970"
|
||||||
class="mx_DateSeparator"
|
class="mx_DateSeparator"
|
||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
|
||||||
>
|
>
|
||||||
<hr
|
<hr
|
||||||
role="none"
|
role="none"
|
||||||
|
@ -165,7 +164,6 @@ exports[`<MessageEditHistory /> should support events with 1`] = `
|
||||||
aria-label=", NaN NaN"
|
aria-label=", NaN NaN"
|
||||||
class="mx_DateSeparator"
|
class="mx_DateSeparator"
|
||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
|
||||||
>
|
>
|
||||||
<hr
|
<hr
|
||||||
role="none"
|
role="none"
|
||||||
|
|
|
@ -6,7 +6,6 @@ exports[`DateSeparator renders the date separator correctly 1`] = `
|
||||||
aria-label="Today"
|
aria-label="Today"
|
||||||
class="mx_DateSeparator"
|
class="mx_DateSeparator"
|
||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
|
||||||
>
|
>
|
||||||
<hr
|
<hr
|
||||||
role="none"
|
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"
|
aria-label="Fri, Dec 17 2021"
|
||||||
class="mx_DateSeparator"
|
class="mx_DateSeparator"
|
||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
|
||||||
>
|
>
|
||||||
<hr
|
<hr
|
||||||
role="none"
|
role="none"
|
||||||
|
|
|
@ -232,8 +232,7 @@ exports[`<DevicesPanel /> renders device panel with devices 1`] = `
|
||||||
class="mx_Checkbox_checkmark"
|
class="mx_Checkbox_checkmark"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
<div>
|
||||||
</span>
|
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile"
|
class="mx_DeviceTile"
|
||||||
data-testid="device-tile-device_2"
|
data-testid="device-tile-device_2"
|
||||||
|
@ -293,6 +292,9 @@ exports[`<DevicesPanel /> renders device panel with devices 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_DevicesPanel_device"
|
class="mx_DevicesPanel_device"
|
||||||
|
@ -318,8 +320,7 @@ exports[`<DevicesPanel /> renders device panel with devices 1`] = `
|
||||||
class="mx_Checkbox_checkmark"
|
class="mx_Checkbox_checkmark"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
<div>
|
||||||
</span>
|
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile"
|
class="mx_DeviceTile"
|
||||||
data-testid="device-tile-device_3"
|
data-testid="device-tile-device_3"
|
||||||
|
@ -379,6 +380,9 @@ exports[`<DevicesPanel /> renders device panel with devices 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
|
|
|
@ -37,6 +37,7 @@ exports[`FontScalingPanel renders the font scaling UI 1`] = `
|
||||||
class="mx_Slider"
|
class="mx_Slider"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
aria-label="Font size"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
max="18"
|
max="18"
|
||||||
min="13"
|
min="13"
|
||||||
|
|
|
@ -32,8 +32,7 @@ exports[`<SelectableDeviceTile /> renders unselected device tile with checkbox 1
|
||||||
class="mx_Checkbox_checkmark"
|
class="mx_Checkbox_checkmark"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
<div>
|
||||||
</span>
|
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile mx_DeviceTile_interactive"
|
class="mx_DeviceTile mx_DeviceTile_interactive"
|
||||||
data-testid="device-tile-my-device"
|
data-testid="device-tile-my-device"
|
||||||
|
@ -95,5 +94,8 @@ exports[`<SelectableDeviceTile /> renders unselected device tile with checkbox 1
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue