♻️(frontend) refactor options menu

@manuhabitela introduced Menu and MenuTrigger components. Refactor the
options menu to benefits from his components.

Few details are not perfect yet. wip
This commit is contained in:
lebaudantoine
2024-08-13 15:17:03 +02:00
committed by aleb_the_flash
parent 5b8c8d493a
commit 03b3630611
4 changed files with 114 additions and 134 deletions

View File

@@ -1,22 +1,38 @@
import { useTranslation } from 'react-i18next'
import { RiMore2Line } from '@remixicon/react'
import { Button } from '@/primitives'
import { OptionsMenu } from '@/features/rooms/livekit/components/controls/Options/OptionsMenu.tsx'
import { MenuTrigger } from 'react-aria-components'
import { Button, Menu } from '@/primitives'
import { useState } from 'react'
import { UsernameDialog } from '@/features/rooms/livekit/components/dialogs/UsernameDialog'
import { SettingsDialog } from '@/features/settings'
import { OptionsMenuItems } from '@/features/rooms/livekit/components/controls/Options/OptionsMenuItems'
export type DialogState = 'username' | 'settings' | null
export const OptionsButton = () => {
const { t } = useTranslation('rooms')
const [dialogOpen, setDialogOpen] = useState<DialogState>(null)
return (
<MenuTrigger>
<Button
square
legacyStyle
aria-label={t('options.buttonLabel')}
tooltip={t('options.buttonLabel')}
>
<RiMore2Line />
</Button>
<OptionsMenu />
</MenuTrigger>
<>
<Menu>
<Button
square
legacyStyle
aria-label={t('options.buttonLabel')}
tooltip={t('options.buttonLabel')}
>
<RiMore2Line />
</Button>
<OptionsMenuItems onOpenDialog={setDialogOpen} />
</Menu>
<UsernameDialog
isOpen={dialogOpen === 'username'}
onOpenChange={(v) => !v && setDialogOpen(null)}
/>
<SettingsDialog
isOpen={dialogOpen === 'settings'}
onOpenChange={(v) => !v && setDialogOpen(null)}
/>
</>
)
}

View File

@@ -1,118 +0,0 @@
import { useTranslation } from 'react-i18next'
import {
RiFeedbackLine,
RiQuestionLine,
RiSettings3Line,
RiUser5Line,
} from '@remixicon/react'
import { useState } from 'react'
import { styled } from '@/styled-system/jsx'
import {
Menu as RACMenu,
MenuItem as RACMenuItem,
Popover as RACPopover,
Separator as RACSeparator,
} from 'react-aria-components'
import { SettingsDialog } from '@/features/settings'
import { UsernameDialog } from '../../dialogs/UsernameDialog'
// Styled components to be refactored
const StyledMenu = styled(RACMenu, {
base: {
maxHeight: 'inherit',
boxSizing: 'border-box',
overflow: 'auto',
padding: '2px',
minWidth: '150px',
outline: 'none',
},
})
const StyledMenuItem = styled(RACMenuItem, {
base: {
margin: '2px',
padding: '0.286rem 0.571rem',
borderRadius: '6px',
outline: 'none',
cursor: 'default',
color: 'black',
fontSize: '1.072rem',
position: 'relative',
display: 'flex',
alignItems: 'center',
gap: '20px',
forcedColorAdjust: 'none',
'&[data-focused]': {
color: 'primary.text',
backgroundColor: 'primary',
outline: 'none!',
},
},
})
const StyledPopover = styled(RACPopover, {
base: {
border: '1px solid #9ca3af',
boxShadow: '0 8px 20px rgba(0, 0, 0, 0.1)',
borderRadius: '4px',
background: 'white',
color: 'var(--text-color)',
outline: 'none',
minWidth: '112px',
width: '300px',
},
})
const StyledSeparator = styled(RACSeparator, {
base: {
height: '1px',
background: '#9ca3af',
margin: '2px 4px',
},
})
type DialogState = 'username' | 'settings' | null
export const OptionsMenu = () => {
const { t } = useTranslation('rooms')
const [dialogOpen, setDialogOpen] = useState<DialogState>(null)
return (
<>
<StyledPopover>
<StyledMenu>
<StyledMenuItem onAction={() => setDialogOpen('username')}>
<RiUser5Line size={18} />
{t('options.items.username')}
</StyledMenuItem>
<StyledSeparator />
<StyledMenuItem
href="https://tchap.gouv.fr/#/room/!aGImQayAgBLjSBycpm:agent.dinum.tchap.gouv.fr?via=agent.dinum.tchap.gouv.fr"
target="_blank"
>
<RiQuestionLine size={18} />
{t('options.items.support')}
</StyledMenuItem>
<StyledMenuItem
href="https://grist.incubateur.net/o/docs/forms/1YrfNP1QSSy8p2gCxMFnSf/4"
target="_blank"
>
<RiFeedbackLine size={18} />
{t('options.items.feedbacks')}
</StyledMenuItem>
<StyledMenuItem onAction={() => setDialogOpen('settings')}>
<RiSettings3Line size={18} />
{t('options.items.settings')}
</StyledMenuItem>
</StyledMenu>
</StyledPopover>
<UsernameDialog
isOpen={dialogOpen === 'username'}
onOpenChange={(v) => !v && setDialogOpen(null)}
/>
<SettingsDialog
isOpen={dialogOpen === 'settings'}
onOpenChange={(v) => !v && setDialogOpen(null)}
/>
</>
)
}

View File

@@ -0,0 +1,74 @@
import { menuItemRecipe } from '@/primitives/menuItemRecipe'
import {
RiFeedbackLine,
RiQuestionLine,
RiSettings3Line,
RiUser5Line,
} from '@remixicon/react'
import { styled } from '@/styled-system/jsx'
import {
MenuItem,
Menu as RACMenu,
Separator as RACSeparator,
} from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { Dispatch, SetStateAction } from 'react'
import { DialogState } from '@/features/rooms/livekit/components/controls/Options/OptionsButton'
const StyledSeparator = styled(RACSeparator, {
base: {
height: '1px',
background: 'gray.300',
margin: '4px 0',
},
})
// @todo try refactoring it to use MenuList component
export const OptionsMenuItems = ({
onOpenDialog,
}: {
onOpenDialog: Dispatch<SetStateAction<DialogState>>
}) => {
const { t } = useTranslation('rooms')
return (
<RACMenu
style={{
minWidth: '150px',
width: '300px',
}}
>
<MenuItem
className={menuItemRecipe({ icon: true })}
onAction={() => onOpenDialog('username')}
>
<RiUser5Line size={18} />
{t('options.items.username')}
</MenuItem>
<StyledSeparator />
<MenuItem
href="https://tchap.gouv.fr/#/room/!aGImQayAgBLjSBycpm:agent.dinum.tchap.gouv.fr?via=agent.dinum.tchap.gouv.fr"
target="_blank"
className={menuItemRecipe({ icon: true })}
>
<RiQuestionLine size={18} />
{t('options.items.support')}
</MenuItem>
<MenuItem
href="https://grist.incubateur.net/o/docs/forms/1YrfNP1QSSy8p2gCxMFnSf/4"
target="_blank"
className={menuItemRecipe({ icon: true })}
>
<RiFeedbackLine size={18} />
{t('options.items.feedbacks')}
</MenuItem>
<MenuItem
className={menuItemRecipe({ icon: true })}
onAction={() => onOpenDialog('settings')}
>
<RiSettings3Line size={18} />
{t('options.items.settings')}
</MenuItem>
</RACMenu>
)
}

View File

@@ -8,9 +8,8 @@ import { cva } from '@/styled-system/css'
*/
export const menuItemRecipe = cva({
base: {
paddingY: 0.125,
paddingY: '0.4rem',
paddingX: 0.5,
paddingLeft: 1.5,
textAlign: 'left',
width: 'full',
borderRadius: 4,
@@ -37,4 +36,13 @@ export const menuItemRecipe = cva({
outline: 'none!',
},
},
variants: {
icon: {
true: {
display: 'flex',
alignItems: 'center',
gap: '1rem',
},
},
},
})