(feat) add pip lateral menu component

add pip chevron menu
This commit is contained in:
Cyril
2026-01-22 08:52:52 +01:00
parent 09bb4daebc
commit 57a27de8e7
2 changed files with 107 additions and 11 deletions
@@ -8,6 +8,7 @@ import { SubtitlesToggle } from './controls/SubtitlesToggle'
import { HandToggle } from './controls/HandToggle'
import { OptionsButton } from './controls/Options/OptionsButton'
import { StartMediaButton } from './controls/StartMediaButton'
import { PipLateralMenu } from './controls/PipLateralMenu'
/**
* Compact control bar for the Picture-in-Picture window.
@@ -19,15 +20,20 @@ export const PipControlBar = ({
showScreenShare: boolean
}) => (
<PipControls>
<AudioDevicesControl hideMenu />
<VideoDeviceControl hideMenu />
<ReactionsToggle />
{showScreenShare && <ScreenShareToggle />}
<SubtitlesToggle />
<HandToggle />
<OptionsButton />
<LeaveButton />
<StartMediaButton />
<PipControlsCenter>
<AudioDevicesControl hideMenu />
<VideoDeviceControl hideMenu />
<ReactionsToggle />
{showScreenShare && <ScreenShareToggle />}
<SubtitlesToggle />
<HandToggle />
<OptionsButton />
<LeaveButton />
<StartMediaButton />
</PipControlsCenter>
<PipControlsRight>
<PipLateralMenu />
</PipControlsRight>
</PipControls>
)
@@ -35,13 +41,36 @@ const PipControls = styled('div', {
base: {
flex: '0 0 auto',
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'center',
gap: '0.4rem',
alignItems: 'center',
gap: '0.5rem',
padding: '0.5rem 0.75rem',
backgroundColor: 'var(--lk-controlbar-bg)',
borderTop: '1px solid',
borderColor: 'var(--lk-control-border-color)',
width: '100%',
position: 'relative',
},
})
const PipControlsCenter = styled('div', {
base: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'center',
alignItems: 'center',
gap: '0.4rem',
flex: '1 1 auto',
},
})
const PipControlsRight = styled('div', {
base: {
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
position: 'absolute',
right: '1.35rem',
},
})
@@ -0,0 +1,67 @@
import { css } from '@/styled-system/css'
import { useState } from 'react'
import { Dialog, DialogTrigger } from 'react-aria-components'
import { Button } from '@/primitives'
import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { StyledPopover } from '@/primitives/Popover'
import { useOverlayBoundaryElement } from '@/primitives/useOverlayPortalContainer'
import { ChatToggle } from './ChatToggle'
import { ParticipantsToggle } from './Participants/ParticipantsToggle'
import { ToolsToggle } from './ToolsToggle'
import { InfoToggle } from './InfoToggle'
import { AdminToggle } from '../AdminToggle'
const NavigationControls = ({ onPress }: { onPress?: () => void }) => (
<>
<InfoToggle onPress={onPress} tooltipType="delayed" />
<ChatToggle onPress={onPress} tooltipType="delayed" />
<ParticipantsToggle onPress={onPress} tooltipType="delayed" />
<ToolsToggle onPress={onPress} tooltipType="delayed" />
<AdminToggle onPress={onPress} tooltipType="delayed" />
</>
)
/**
* PiP chevron menu that exposes Info/Chat/Participants/Tools/Admin.
*/
export const PipLateralMenu = () => {
const { t } = useTranslation('rooms')
const [isOpen, setIsOpen] = useState(false)
const boundaryElement = useOverlayBoundaryElement()
const handlePress = () => setIsOpen(!isOpen)
const handleClose = () => setIsOpen(false)
return (
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
<Button
id="pip-controlbar-more-options-trigger"
square
variant="secondaryDark"
aria-label={t('controls.moreOptions')}
tooltip={t('controls.moreOptions')}
onPress={handlePress}
>
{isOpen ? <RiArrowDownSLine /> : <RiArrowUpSLine />}
</Button>
<StyledPopover placement="top" boundaryElement={boundaryElement}>
<Dialog
className={css({
width: '65px',
backgroundColor: 'primaryDark.50',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
borderRadius: '4px',
paddingTop: '10px',
gap: '0.5rem',
})}
>
<NavigationControls onPress={handleClose} />
</Dialog>
</StyledPopover>
</DialogTrigger>
)
}