diff --git a/css/_polls.scss b/css/_polls.scss index 1ee433269..966f7452e 100644 --- a/css/_polls.scss +++ b/css/_polls.scss @@ -1,3 +1,3 @@ -#polls-panel { +.polls-panel { height: calc(100% - 119px); } diff --git a/react/features/base/ui/components/web/Tabs.tsx b/react/features/base/ui/components/web/Tabs.tsx index e198d5cda..323168c22 100644 --- a/react/features/base/ui/components/web/Tabs.tsx +++ b/react/features/base/ui/components/web/Tabs.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { makeStyles } from 'tss-react/mui'; import { isMobileBrowser } from '../../../environment/utils'; @@ -11,6 +11,7 @@ interface ITabProps { selected: string; tabs: Array<{ accessibilityLabel: string; + controlsId: string; countBadge?: number; disabled?: boolean; id: string; @@ -87,26 +88,52 @@ const Tabs = ({ }: ITabProps) => { const { classes, cx } = useStyles(); const isMobile = isMobileBrowser(); - - const handleChange = useCallback((e: React.MouseEvent) => { - onChange(e.currentTarget.id); + const onClick = useCallback(id => () => { + onChange(id); }, []); + const onKeyDown = useCallback((index: number) => (event: React.KeyboardEvent) => { + let newIndex: number | null = null; + + if (event.key === 'ArrowLeft') { + event.preventDefault(); + newIndex = index === 0 ? tabs.length - 1 : index - 1; + } + + if (event.key === 'ArrowRight') { + event.preventDefault(); + newIndex = index === tabs.length - 1 ? 0 : index + 1; + } + + if (newIndex !== null) { + onChange(tabs[newIndex].id); + } + }, [ tabs ]); + + useEffect(() => { + // this test is needed to make sure the effect is triggered because of user actually changing tab + if (document.activeElement?.getAttribute('role') === 'tab') { + document.querySelector(`#${selected}`)?.focus(); + } + }, [ selected ]); return (
- {tabs.map(tab => ( + {tabs.map((tab, index) => ( diff --git a/react/features/chat/components/web/Chat.js b/react/features/chat/components/web/Chat.js index aab8f3365..486e8e227 100644 --- a/react/features/chat/components/web/Chat.js +++ b/react/features/chat/components/web/Chat.js @@ -134,35 +134,38 @@ class Chat extends AbstractChat { _renderChat() { const { _isPollsEnabled, _isPollsTabFocused } = this.props; - if (_isPollsTabFocused) { - return ( - <> - { _isPollsEnabled && this._renderTabs() } -
- -
- - - ); - } - return ( <> { _isPollsEnabled && this._renderTabs() }
+ className = { clsx( + 'chat-panel', + !_isPollsEnabled && 'chat-panel-no-tabs', + _isPollsTabFocused && 'hide' + ) } + id = { `${CHAT_TABS.CHAT}-panel` } + role = 'tabpanel' + tabIndex = { 0 }>
+ { _isPollsEnabled && ( + <> +
+ +
+ + + )} ); } @@ -185,11 +188,13 @@ class Chat extends AbstractChat { accessibilityLabel: t('chat.tabs.chat'), countBadge: _isPollsTabFocused && _nbUnreadMessages > 0 ? _nbUnreadMessages : undefined, id: CHAT_TABS.CHAT, + controlsId: `${CHAT_TABS.CHAT}-panel`, label: t('chat.tabs.chat') }, { accessibilityLabel: t('chat.tabs.polls'), countBadge: !_isPollsTabFocused && _nbUnreadPolls > 0 ? _nbUnreadPolls : undefined, id: CHAT_TABS.POLLS, + controlsId: `${CHAT_TABS.POLLS}-panel`, label: t('chat.tabs.polls') } ] } />