♻️(frontend) extract menu items into individual components

Each menu item is now a standalone component, improving:
- Code organization & reusability
- Maintainability by reducing OptionsMenuItems complexity

This breaks down large components.
This commit is contained in:
lebaudantoine
2025-01-22 14:30:22 +01:00
committed by aleb_the_flash
parent a44b6e8e34
commit 1b52d76168
5 changed files with 103 additions and 61 deletions

View File

@@ -0,0 +1,20 @@
import { RiAccountBoxLine } from '@remixicon/react'
import { MenuItem } from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { menuRecipe } from '@/primitives/menuRecipe'
import { useSidePanel } from '../../../hooks/useSidePanel'
export const EffectsMenuItem = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'options.items' })
const { toggleEffects } = useSidePanel()
return (
<MenuItem
onAction={() => toggleEffects()}
className={menuRecipe({ icon: true, variant: 'dark' }).item}
>
<RiAccountBoxLine size={20} />
{t('effects')}
</MenuItem>
)
}

View File

@@ -0,0 +1,20 @@
import { RiMegaphoneLine } from '@remixicon/react'
import { MenuItem } from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { menuRecipe } from '@/primitives/menuRecipe'
import { GRIST_FORM } from '@/utils/constants'
export const FeedbackMenuItem = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'options.items' })
return (
<MenuItem
href={GRIST_FORM}
target="_blank"
className={menuRecipe({ icon: true, variant: 'dark' }).item}
>
<RiMegaphoneLine size={20} />
{t('feedback')}
</MenuItem>
)
}

View File

@@ -0,0 +1,34 @@
import { RiFullscreenExitLine, RiFullscreenLine } from '@remixicon/react'
import { MenuItem } from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { menuRecipe } from '@/primitives/menuRecipe'
import { useFullScreen } from '../../../hooks/useFullScreen'
export const FullScreenMenuItem = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'options.items' })
const { toggleFullScreen, isCurrentlyFullscreen, isFullscreenAvailable } =
useFullScreen()
if (!isFullscreenAvailable) {
return null
}
return (
<MenuItem
onAction={() => toggleFullScreen()}
className={menuRecipe({ icon: true, variant: 'dark' }).item}
>
{isCurrentlyFullscreen ? (
<>
<RiFullscreenExitLine size={20} />
{t('fullscreen.exit')}
</>
) : (
<>
<RiFullscreenLine size={20} />
{t('fullscreen.enter')}
</>
)}
</MenuItem>
)
}

View File

@@ -1,28 +1,12 @@
import { import { Menu as RACMenu, MenuSection } from 'react-aria-components'
RiAccountBoxLine,
RiFullscreenExitLine,
RiFullscreenLine,
RiMegaphoneLine,
RiSettings3Line,
} from '@remixicon/react'
import { MenuItem, Menu as RACMenu, MenuSection } from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { Separator } from '@/primitives/Separator' import { Separator } from '@/primitives/Separator'
import { useSidePanel } from '../../../hooks/useSidePanel' import { FullScreenMenuItem } from './FullScreenMenuItem'
import { menuRecipe } from '@/primitives/menuRecipe.ts' import { SettingsMenuItem } from './SettingsMenuItem'
import { useSettingsDialog } from '../SettingsDialogContext' import { FeedbackMenuItem } from './FeedbackMenuItem'
import { GRIST_FORM } from '@/utils/constants' import { EffectsMenuItem } from './EffectsMenuItem'
import { useFullScreen } from '../../../hooks/useFullScreen'
// @todo try refactoring it to use MenuList component // @todo try refactoring it to use MenuList component
export const OptionsMenuItems = () => { export const OptionsMenuItems = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'options.items' })
const { toggleEffects } = useSidePanel()
const { setDialogOpen } = useSettingsDialog()
const { toggleFullScreen, isCurrentlyFullscreen, isFullscreenAvailable } =
useFullScreen()
return ( return (
<RACMenu <RACMenu
style={{ style={{
@@ -31,49 +15,13 @@ export const OptionsMenuItems = () => {
}} }}
> >
<MenuSection> <MenuSection>
{isFullscreenAvailable && ( <FullScreenMenuItem />
<MenuItem <EffectsMenuItem />
onAction={() => toggleFullScreen()}
className={menuRecipe({ icon: true, variant: 'dark' }).item}
>
{isCurrentlyFullscreen ? (
<>
<RiFullscreenExitLine size={20} />
{t('fullscreen.exit')}
</>
) : (
<>
<RiFullscreenLine size={20} />
{t('fullscreen.enter')}
</>
)}
</MenuItem>
)}
<MenuItem
onAction={() => toggleEffects()}
className={menuRecipe({ icon: true, variant: 'dark' }).item}
>
<RiAccountBoxLine size={20} />
{t('effects')}
</MenuItem>
</MenuSection> </MenuSection>
<Separator /> <Separator />
<MenuSection> <MenuSection>
<MenuItem <FeedbackMenuItem />
href={GRIST_FORM} <SettingsMenuItem />
target="_blank"
className={menuRecipe({ icon: true, variant: 'dark' }).item}
>
<RiMegaphoneLine size={20} />
{t('feedback')}
</MenuItem>
<MenuItem
className={menuRecipe({ icon: true, variant: 'dark' }).item}
onAction={() => setDialogOpen(true)}
>
<RiSettings3Line size={20} />
{t('settings')}
</MenuItem>
</MenuSection> </MenuSection>
</RACMenu> </RACMenu>
) )

View File

@@ -0,0 +1,20 @@
import { RiSettings3Line } from '@remixicon/react'
import { MenuItem } from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { menuRecipe } from '@/primitives/menuRecipe'
import { useSettingsDialog } from '../SettingsDialogContext'
export const SettingsMenuItem = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'options.items' })
const { setDialogOpen } = useSettingsDialog()
return (
<MenuItem
className={menuRecipe({ icon: true, variant: 'dark' }).item}
onAction={() => setDialogOpen(true)}
>
<RiSettings3Line size={20} />
{t('settings')}
</MenuItem>
)
}