feat(a11y) add headings across the app for easier screen reader nav (#12427)
feat(a11y): added headings across the app for easier screen reader nav
This commit is contained in:
parent
fed74afffe
commit
72dd609247
|
@ -452,6 +452,11 @@
|
|||
"veryBad": "Very Bad",
|
||||
"veryGood": "Very Good"
|
||||
},
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Video thumbnails"
|
||||
}
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "No results found :(",
|
||||
"search": "Search GIPHY"
|
||||
|
@ -1097,6 +1102,7 @@
|
|||
"giphy": "Toggle GIPHY menu",
|
||||
"grantModerator": "Grant Moderator Rights",
|
||||
"hangup": "Leave the meeting",
|
||||
"heading": "Toolbar",
|
||||
"help": "Help",
|
||||
"invite": "Invite people",
|
||||
"kick": "Kick participant",
|
||||
|
@ -1393,5 +1399,10 @@
|
|||
"terms": "Terms",
|
||||
"title": "Secure, fully featured, and completely free video conferencing",
|
||||
"upcomingMeetings": "Your upcoming meetings"
|
||||
},
|
||||
"whiteboard": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Whiteboard"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,12 @@ function Header({ onCancel, className, isPollsEnabled, t }: Props) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className = { className || 'chat-dialog-header' }
|
||||
role = 'heading'>
|
||||
{ t(isPollsEnabled ? 'chat.titleWithPolls' : 'chat.title') }
|
||||
className = { className || 'chat-dialog-header' }>
|
||||
<span
|
||||
aria-level = { 1 }
|
||||
role = 'heading'>
|
||||
{ t(isPollsEnabled ? 'chat.titleWithPolls' : 'chat.title') }
|
||||
</span>
|
||||
<Icon
|
||||
ariaLabel = { t('toolbar.closeChat') }
|
||||
onClick = { onCancel }
|
||||
|
|
|
@ -210,7 +210,8 @@ class Conference extends AbstractConference<Props, *> {
|
|||
_notificationsVisible,
|
||||
_overflowDrawer,
|
||||
_showLobby,
|
||||
_showPrejoin
|
||||
_showPrejoin,
|
||||
t
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
@ -240,7 +241,17 @@ class Conference extends AbstractConference<Props, *> {
|
|||
}
|
||||
</div>
|
||||
|
||||
{ _showPrejoin || _showLobby || <Toolbox /> }
|
||||
{ _showPrejoin || _showLobby || (
|
||||
<>
|
||||
<span
|
||||
aria-level = { 1 }
|
||||
className = 'sr-only'
|
||||
role = 'heading'>
|
||||
{ t('toolbar.accessibilityLabel.heading') }
|
||||
</span>
|
||||
<Toolbox />
|
||||
</>
|
||||
)}
|
||||
|
||||
{_notificationsVisible && !_isAnyOverlayVisible && (_overflowDrawer
|
||||
? <JitsiPortal className = 'notification-portal'>
|
||||
|
|
|
@ -343,7 +343,8 @@ class Filmstrip extends PureComponent <IProps, IState> {
|
|||
_verticalViewGrid,
|
||||
_verticalViewMaxWidth,
|
||||
classes,
|
||||
filmstripType
|
||||
filmstripType,
|
||||
t
|
||||
} = this.props;
|
||||
const { isMouseDown } = this.state;
|
||||
const tileViewActive = _currentLayout === LAYOUTS.TILE_VIEW;
|
||||
|
@ -434,6 +435,12 @@ class Filmstrip extends PureComponent <IProps, IState> {
|
|||
_verticalViewGrid && 'no-vertical-padding',
|
||||
_verticalViewBackground && classes.filmstripBackground) }
|
||||
style = { filmstripStyle }>
|
||||
<span
|
||||
aria-level = { 1 }
|
||||
className = 'sr-only'
|
||||
role = 'heading'>
|
||||
{ t('filmstrip.accessibilityLabel.heading') }
|
||||
</span>
|
||||
{ toolbar }
|
||||
{_resizableFilmstrip
|
||||
? <div
|
||||
|
|
|
@ -112,6 +112,12 @@ function MeetingParticipants({
|
|||
|
||||
return (
|
||||
<>
|
||||
<span
|
||||
aria-level = { 1 }
|
||||
className = 'sr-only'
|
||||
role = 'heading'>
|
||||
{ t('participantsPane.title') }
|
||||
</span>
|
||||
<div className = { cx(styles.heading, styles.headingW) }>
|
||||
{visitorsCount && visitorsCount > 0
|
||||
&& t('participantsPane.headings.visitors', { count: visitorsCount })}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { useSelector } from 'react-redux';
|
|||
// @ts-expect-error
|
||||
import Filmstrip from '../../../../../modules/UI/videolayout/Filmstrip';
|
||||
import { IReduxState } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { getLocalParticipant } from '../../../base/participants/functions';
|
||||
import { getVerticalViewMaxWidth } from '../../../filmstrip/functions.web';
|
||||
import { getToolboxHeight } from '../../../toolbox/functions.web';
|
||||
|
@ -32,12 +33,24 @@ interface IDimensions {
|
|||
width: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link Whiteboard}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function;
|
||||
};
|
||||
|
||||
/**
|
||||
* The Whiteboard component.
|
||||
*
|
||||
* @param {Props} props - The React props passed to this component.
|
||||
* @returns {JSX.Element} - The React component.
|
||||
*/
|
||||
const Whiteboard: () => JSX.Element = () => {
|
||||
const Whiteboard = (props: Props): JSX.Element => {
|
||||
const excalidrawRef = useRef<any>(null);
|
||||
const collabAPIRef = useRef<any>(null);
|
||||
|
||||
|
@ -113,6 +126,20 @@ const Whiteboard: () => JSX.Element = () => {
|
|||
{
|
||||
isOpen && (
|
||||
<div className = 'excalidraw-wrapper'>
|
||||
{/*
|
||||
* Excalidraw renders a few lvl 2 headings. This is
|
||||
* quite fortunate, because we actually use lvl 1
|
||||
* headings to mark the big sections of our app. So make
|
||||
* sure to mark the Excalidraw context with a lvl 1
|
||||
* heading before showing the whiteboard.
|
||||
*/
|
||||
<span
|
||||
aria-level = { 1 }
|
||||
className = 'sr-only'
|
||||
role = 'heading'>
|
||||
{ props.t('whiteboard.accessibilityLabel.heading') }
|
||||
</span>
|
||||
}
|
||||
<ExcalidrawApp
|
||||
collabDetails = { collabDetails }
|
||||
collabServerUrl = { collabServerUrl }
|
||||
|
@ -132,4 +159,4 @@ const Whiteboard: () => JSX.Element = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Whiteboard;
|
||||
export default translate(Whiteboard);
|
||||
|
|
Loading…
Reference in New Issue