Merge pull request #19094 from Scroody/user-list-keyboard
fix(accessibility): restore roving functionality in user list
This commit is contained in:
commit
c689b650c1
@ -3,6 +3,7 @@ import { useSubscription } from '@apollo/client';
|
|||||||
import { AutoSizer } from 'react-virtualized';
|
import { AutoSizer } from 'react-virtualized';
|
||||||
import { debounce } from 'radash';
|
import { debounce } from 'radash';
|
||||||
import { ListProps } from 'react-virtualized/dist/es/List';
|
import { ListProps } from 'react-virtualized/dist/es/List';
|
||||||
|
import { findDOMNode } from 'react-dom';
|
||||||
import Styled from './styles';
|
import Styled from './styles';
|
||||||
import ListItem from './list-item/component';
|
import ListItem from './list-item/component';
|
||||||
import Skeleton from './list-item/skeleton/component';
|
import Skeleton from './list-item/skeleton/component';
|
||||||
@ -19,6 +20,7 @@ import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
|
|||||||
import { layoutSelect } from '/imports/ui/components/layout/context';
|
import { layoutSelect } from '/imports/ui/components/layout/context';
|
||||||
import { Layout } from '/imports/ui/components/layout/layoutTypes';
|
import { Layout } from '/imports/ui/components/layout/layoutTypes';
|
||||||
import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context';
|
import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context';
|
||||||
|
import Service from '/imports/ui/components/user-list/service';
|
||||||
|
|
||||||
interface UserListParticipantsProps {
|
interface UserListParticipantsProps {
|
||||||
users: Array<User>;
|
users: Array<User>;
|
||||||
@ -75,6 +77,11 @@ const UserListParticipants: React.FC<UserListParticipantsProps> = ({
|
|||||||
? currentUser
|
? currentUser
|
||||||
: { userId: '', isModerator: false, presenter: false };
|
: { userId: '', isModerator: false, presenter: false };
|
||||||
|
|
||||||
|
const userListRef = React.useRef<HTMLDivElement | null>(null);
|
||||||
|
const userItemsRef = React.useRef<HTMLDivElement | null>(null);
|
||||||
|
const [selectedUser, setSelectedUser] = React.useState<HTMLElement>();
|
||||||
|
const { roving } = Service;
|
||||||
|
|
||||||
const isRTL = layoutSelect((i: Layout) => i.isRTL);
|
const isRTL = layoutSelect((i: Layout) => i.isRTL);
|
||||||
const [previousUsersData, setPreviousUsersData] = React.useState(users);
|
const [previousUsersData, setPreviousUsersData] = React.useState(users);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -82,8 +89,26 @@ const UserListParticipants: React.FC<UserListParticipantsProps> = ({
|
|||||||
setPreviousUsersData(users);
|
setPreviousUsersData(users);
|
||||||
}
|
}
|
||||||
}, [users]);
|
}, [users]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const firstChild = (selectedUser as HTMLElement)?.firstChild;
|
||||||
|
|
||||||
|
const fourthChild = firstChild?.firstChild?.firstChild?.firstChild;
|
||||||
|
if (fourthChild && fourthChild instanceof HTMLElement) fourthChild.focus();
|
||||||
|
}, [selectedUser]);
|
||||||
|
|
||||||
|
const rove = (event: React.KeyboardEvent) => {
|
||||||
|
// eslint-disable-next-line react/no-find-dom-node
|
||||||
|
const usrItemsRef = findDOMNode(userItemsRef.current);
|
||||||
|
const usrItemsRefChild = usrItemsRef?.firstChild;
|
||||||
|
|
||||||
|
roving(event, setSelectedUser, usrItemsRefChild, selectedUser);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.UserListColumn>
|
<Styled.UserListColumn onKeyDown={rove} tabIndex={0} ref={userListRef}>
|
||||||
<AutoSizer>
|
<AutoSizer>
|
||||||
{({ width, height }) => (
|
{({ width, height }) => (
|
||||||
<Styled.VirtualizedList
|
<Styled.VirtualizedList
|
||||||
@ -94,6 +119,7 @@ const UserListParticipants: React.FC<UserListParticipantsProps> = ({
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
ref={userItemsRef}
|
||||||
noRowRenderer={() => <div>no users</div>}
|
noRowRenderer={() => <div>no users</div>}
|
||||||
rowCount={count}
|
rowCount={count}
|
||||||
height={height - 1}
|
height={height - 1}
|
||||||
@ -105,7 +131,6 @@ const UserListParticipants: React.FC<UserListParticipantsProps> = ({
|
|||||||
})}
|
})}
|
||||||
overscanRowCount={10}
|
overscanRowCount={10}
|
||||||
rowHeight={50}
|
rowHeight={50}
|
||||||
tabIndex={0}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</AutoSizer>
|
</AutoSizer>
|
||||||
|
@ -162,7 +162,7 @@ const UserListItem: React.FC<UserListItemProps> = ({ user, lockSettings }) => {
|
|||||||
const hasWhiteboardAccess = user?.presPagesWritable?.some((page) => page.isCurrentPage);
|
const hasWhiteboardAccess = user?.presPagesWritable?.some((page) => page.isCurrentPage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.UserItemContents data-test={(user.userId === Auth.userID) ? 'userListItemCurrent' : 'userListItem'}>
|
<Styled.UserItemContents tabIndex={-1} data-test={(user.userId === Auth.userID) ? 'userListItemCurrent' : 'userListItem'}>
|
||||||
<Styled.Avatar
|
<Styled.Avatar
|
||||||
data-test={user.role === ROLE_MODERATOR ? 'moderatorAvatar' : 'viewerAvatar'}
|
data-test={user.role === ROLE_MODERATOR ? 'moderatorAvatar' : 'viewerAvatar'}
|
||||||
data-test-presenter={user.presenter ? '' : undefined}
|
data-test-presenter={user.presenter ? '' : undefined}
|
||||||
|
Loading…
Reference in New Issue
Block a user