diff --git a/CHANGELOG.md b/CHANGELOG.md index 09787572..34bcdf60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to - 🩹(backend) identify externally provisioned users to PostHog - 🐛(backend) fix info panel crash for unregistered rooms +- ♿️(frontend) focus side panel container on open #1452 ## [1.23.0] - 2026-07-08 diff --git a/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx b/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx index 900ca9f2..dedb495f 100644 --- a/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx +++ b/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx @@ -6,8 +6,8 @@ import { Button, Div } from '@/primitives' import { RiArrowLeftLine, RiCloseLine } from '@remixicon/react' import { useTranslation } from 'react-i18next' import { ParticipantsList } from './controls/Participants/ParticipantsList' -import { useSidePanel } from '../hooks/useSidePanel' -import { ReactNode } from 'react' +import { PanelId, useSidePanel } from '../hooks/useSidePanel' +import React, { ReactNode, useCallback, useRef } from 'react' import { Chat } from '../prefabs/Chat' import { Effects } from './effects/Effects' import { Admin } from './Admin' @@ -15,6 +15,7 @@ import { Tools } from './Tools' import { Info } from './Info' import { HStack } from '@/styled-system/jsx' import { useReactionsToolbar } from '@/features/reactions/hooks/useReactionsToolbar' +import { useRestoreFocus } from '@/hooks/useRestoreFocus' type StyledSidePanelProps = { title: string @@ -29,103 +30,115 @@ type StyledSidePanelProps = { isReactionToolbarOpen?: boolean } -const StyledSidePanel = ({ - title, - ariaLabel, - children, - onClose, - isClosed, - isReactionToolbarOpen, - closeButtonTooltip, - isSubmenu = false, - onBack, - backButtonLabel, -}: StyledSidePanelProps) => ( - + + + {children} + + ) ) +StyledSidePanel.displayName = 'StyledSidePanel' + type PanelProps = { isOpen: boolean children: React.ReactNode @@ -162,8 +175,24 @@ export const SidePanel = () => { const { isOpen: isReactionToolbarOpen } = useReactionsToolbar() + const asideRef = useRef(null) + + const panelManagesFocus = activePanelId === PanelId.CHAT + + const focusAside = useCallback(() => { + requestAnimationFrame(() => { + asideRef.current?.focus({ preventScroll: true }) + }) + }, []) + + useRestoreFocus(isSidePanelOpen && !panelManagesFocus, { + onOpened: focusAside, + preventScroll: true, + }) + return ( {