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) => (
-
+ )
)
+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 (
{