mirror of
https://github.com/suitenumerique/meet.git
synced 2026-09-04 14:45:40 +00:00
♿️(frontend) focus side panel container on open
Focus aside on side panel open so screen readers announce the aria-label
This commit is contained in:
@@ -29,6 +29,7 @@ and this project adheres to
|
|||||||
|
|
||||||
- 🩹(backend) identify externally provisioned users to PostHog
|
- 🩹(backend) identify externally provisioned users to PostHog
|
||||||
- 🐛(backend) fix info panel crash for unregistered rooms
|
- 🐛(backend) fix info panel crash for unregistered rooms
|
||||||
|
- ♿️(frontend) focus side panel container on open #1452
|
||||||
|
|
||||||
## [1.23.0] - 2026-07-08
|
## [1.23.0] - 2026-07-08
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { Button, Div } from '@/primitives'
|
|||||||
import { RiArrowLeftLine, RiCloseLine } from '@remixicon/react'
|
import { RiArrowLeftLine, RiCloseLine } from '@remixicon/react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { ParticipantsList } from './controls/Participants/ParticipantsList'
|
import { ParticipantsList } from './controls/Participants/ParticipantsList'
|
||||||
import { useSidePanel } from '../hooks/useSidePanel'
|
import { PanelId, useSidePanel } from '../hooks/useSidePanel'
|
||||||
import { ReactNode } from 'react'
|
import React, { ReactNode, useCallback, useRef } from 'react'
|
||||||
import { Chat } from '../prefabs/Chat'
|
import { Chat } from '../prefabs/Chat'
|
||||||
import { Effects } from './effects/Effects'
|
import { Effects } from './effects/Effects'
|
||||||
import { Admin } from './Admin'
|
import { Admin } from './Admin'
|
||||||
@@ -15,6 +15,7 @@ import { Tools } from './Tools'
|
|||||||
import { Info } from './Info'
|
import { Info } from './Info'
|
||||||
import { HStack } from '@/styled-system/jsx'
|
import { HStack } from '@/styled-system/jsx'
|
||||||
import { useReactionsToolbar } from '@/features/reactions/hooks/useReactionsToolbar'
|
import { useReactionsToolbar } from '@/features/reactions/hooks/useReactionsToolbar'
|
||||||
|
import { useRestoreFocus } from '@/hooks/useRestoreFocus'
|
||||||
|
|
||||||
type StyledSidePanelProps = {
|
type StyledSidePanelProps = {
|
||||||
title: string
|
title: string
|
||||||
@@ -29,7 +30,9 @@ type StyledSidePanelProps = {
|
|||||||
isReactionToolbarOpen?: boolean
|
isReactionToolbarOpen?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledSidePanel = ({
|
const StyledSidePanel = React.forwardRef<HTMLElement, StyledSidePanelProps>(
|
||||||
|
(
|
||||||
|
{
|
||||||
title,
|
title,
|
||||||
ariaLabel,
|
ariaLabel,
|
||||||
children,
|
children,
|
||||||
@@ -40,8 +43,12 @@ const StyledSidePanel = ({
|
|||||||
isSubmenu = false,
|
isSubmenu = false,
|
||||||
onBack,
|
onBack,
|
||||||
backButtonLabel,
|
backButtonLabel,
|
||||||
}: StyledSidePanelProps) => (
|
},
|
||||||
|
ref
|
||||||
|
) => (
|
||||||
<aside
|
<aside
|
||||||
|
ref={ref}
|
||||||
|
tabIndex={-1}
|
||||||
className={css({
|
className={css({
|
||||||
borderWidth: '1px',
|
borderWidth: '1px',
|
||||||
borderStyle: 'solid',
|
borderStyle: 'solid',
|
||||||
@@ -63,6 +70,9 @@ const StyledSidePanel = ({
|
|||||||
top: 0,
|
top: 0,
|
||||||
width: 'var(--sizes-room-side-panel)',
|
width: 'var(--sizes-room-side-panel)',
|
||||||
transition: '.5s cubic-bezier(.4,0,.2,1) 5ms',
|
transition: '.5s cubic-bezier(.4,0,.2,1) 5ms',
|
||||||
|
'&:focus': {
|
||||||
|
outline: 'none',
|
||||||
|
},
|
||||||
})}
|
})}
|
||||||
style={{
|
style={{
|
||||||
transform: isClosed
|
transform: isClosed
|
||||||
@@ -124,8 +134,11 @@ const StyledSidePanel = ({
|
|||||||
</Div>
|
</Div>
|
||||||
{children}
|
{children}
|
||||||
</aside>
|
</aside>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
StyledSidePanel.displayName = 'StyledSidePanel'
|
||||||
|
|
||||||
type PanelProps = {
|
type PanelProps = {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
@@ -162,8 +175,24 @@ export const SidePanel = () => {
|
|||||||
|
|
||||||
const { isOpen: isReactionToolbarOpen } = useReactionsToolbar()
|
const { isOpen: isReactionToolbarOpen } = useReactionsToolbar()
|
||||||
|
|
||||||
|
const asideRef = useRef<HTMLElement>(null)
|
||||||
|
|
||||||
|
const panelManagesFocus = activePanelId === PanelId.CHAT
|
||||||
|
|
||||||
|
const focusAside = useCallback(() => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
asideRef.current?.focus({ preventScroll: true })
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useRestoreFocus(isSidePanelOpen && !panelManagesFocus, {
|
||||||
|
onOpened: focusAside,
|
||||||
|
preventScroll: true,
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledSidePanel
|
<StyledSidePanel
|
||||||
|
ref={asideRef}
|
||||||
title={title}
|
title={title}
|
||||||
ariaLabel={t('ariaLabel', { title })}
|
ariaLabel={t('ariaLabel', { title })}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user