Fix: avatar dropdown keyboard navigation (#12155)

This commit is contained in:
NFish 2024-12-27 18:10:36 +08:00 committed by GitHub
parent f4f2567105
commit 89ce9a5db2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 47 deletions

View File

@ -59,23 +59,21 @@ export default function AppSelector({ isMobile }: IAppSelector) {
{ {
({ open }) => ( ({ open }) => (
<> <>
<div> <Menu.Button
<Menu.Button className={`
className={`
inline-flex items-center inline-flex items-center
rounded-[20px] py-1 pr-2.5 pl-1 text-sm rounded-[20px] py-1 pr-2.5 pl-1 text-sm
text-gray-700 hover:bg-gray-200 text-gray-700 hover:bg-gray-200
mobile:px-1 mobile:px-1
${open && 'bg-gray-200'} ${open && 'bg-gray-200'}
`} `}
> >
<Avatar name={userProfile.name} className='sm:mr-2 mr-0' size={32} /> <Avatar name={userProfile.name} className='sm:mr-2 mr-0' size={32} />
{!isMobile && <> {!isMobile && <>
{userProfile.name} {userProfile.name}
<RiArrowDownSLine className="w-3 h-3 ml-1 text-gray-700" /> <RiArrowDownSLine className="w-3 h-3 ml-1 text-gray-700" />
</>} </>}
</Menu.Button> </Menu.Button>
</div>
<Transition <Transition
as={Fragment} as={Fragment}
enter="transition ease-out duration-100" enter="transition ease-out duration-100"
@ -89,10 +87,10 @@ export default function AppSelector({ isMobile }: IAppSelector) {
className=" className="
absolute right-0 mt-1.5 w-60 max-w-80 absolute right-0 mt-1.5 w-60 max-w-80
divide-y divide-divider-subtle origin-top-right rounded-lg bg-components-panel-bg-blur divide-y divide-divider-subtle origin-top-right rounded-lg bg-components-panel-bg-blur
shadow-lg shadow-lg focus:outline-none
" "
> >
<Menu.Item> <Menu.Item disabled>
<div className='flex flex-nowrap items-center px-4 py-[13px]'> <div className='flex flex-nowrap items-center px-4 py-[13px]'>
<Avatar name={userProfile.name} size={36} className='mr-3' /> <Avatar name={userProfile.name} size={36} className='mr-3' />
<div className='grow'> <div className='grow'>
@ -107,89 +105,107 @@ export default function AppSelector({ isMobile }: IAppSelector) {
</div> </div>
<div className="px-1 py-1"> <div className="px-1 py-1">
<Menu.Item> <Menu.Item>
<Link {({ active }) => <Link
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between',
active && 'bg-state-base-hover',
)}
href='/account' href='/account'
target='_self' rel='noopener noreferrer'> target='_self' rel='noopener noreferrer'>
<div>{t('common.account.account')}</div> <div>{t('common.account.account')}</div>
<ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' /> <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
</Link> </Link>}
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item>
<div className={itemClassName} onClick={() => setShowAccountSettingModal({ payload: 'members' })}> {({ active }) => <div className={classNames(itemClassName,
active && 'bg-state-base-hover',
)} onClick={() => setShowAccountSettingModal({ payload: 'members' })}>
<div>{t('common.userProfile.settings')}</div> <div>{t('common.userProfile.settings')}</div>
</div> </div>}
</Menu.Item> </Menu.Item>
{canEmailSupport && <Menu.Item> {canEmailSupport && <Menu.Item>
<a {({ active }) => <a
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between',
active && 'bg-state-base-hover',
)}
href={mailToSupport(userProfile.email, plan.type, langeniusVersionInfo.current_version)} href={mailToSupport(userProfile.email, plan.type, langeniusVersionInfo.current_version)}
target='_blank' rel='noopener noreferrer'> target='_blank' rel='noopener noreferrer'>
<div>{t('common.userProfile.emailSupport')}</div> <div>{t('common.userProfile.emailSupport')}</div>
<ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' /> <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
</a> </a>}
</Menu.Item>} </Menu.Item>}
<Menu.Item> <Menu.Item>
<Link {({ active }) => <Link
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between',
active && 'bg-state-base-hover',
)}
href='https://github.com/langgenius/dify/discussions/categories/feedbacks' href='https://github.com/langgenius/dify/discussions/categories/feedbacks'
target='_blank' rel='noopener noreferrer'> target='_blank' rel='noopener noreferrer'>
<div>{t('common.userProfile.communityFeedback')}</div> <div>{t('common.userProfile.communityFeedback')}</div>
<ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' /> <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
</Link> </Link>}
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item>
<Link {({ active }) => <Link
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between',
active && 'bg-state-base-hover',
)}
href='https://discord.gg/5AEfbxcd9k' href='https://discord.gg/5AEfbxcd9k'
target='_blank' rel='noopener noreferrer'> target='_blank' rel='noopener noreferrer'>
<div>{t('common.userProfile.community')}</div> <div>{t('common.userProfile.community')}</div>
<ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' /> <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
</Link> </Link>}
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item>
<Link {({ active }) => <Link
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between',
active && 'bg-state-base-hover',
)}
href={ href={
locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/' : `https://docs.dify.ai/v/${locale.toLowerCase()}/` locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/' : `https://docs.dify.ai/v/${locale.toLowerCase()}/`
} }
target='_blank' rel='noopener noreferrer'> target='_blank' rel='noopener noreferrer'>
<div>{t('common.userProfile.helpCenter')}</div> <div>{t('common.userProfile.helpCenter')}</div>
<ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' /> <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
</Link> </Link>}
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item>
<Link {({ active }) => <Link
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between',
active && 'bg-state-base-hover',
)}
href='https://roadmap.dify.ai' href='https://roadmap.dify.ai'
target='_blank' rel='noopener noreferrer'> target='_blank' rel='noopener noreferrer'>
<div>{t('common.userProfile.roadmap')}</div> <div>{t('common.userProfile.roadmap')}</div>
<ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' /> <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
</Link> </Link>}
</Menu.Item> </Menu.Item>
{ {
document?.body?.getAttribute('data-public-site-about') !== 'hide' && ( document?.body?.getAttribute('data-public-site-about') !== 'hide' && (
<Menu.Item> <Menu.Item>
<div className={classNames(itemClassName, 'justify-between')} onClick={() => setAboutVisible(true)}> {({ active }) => <div className={classNames(itemClassName, 'justify-between',
active && 'bg-state-base-hover',
)} onClick={() => setAboutVisible(true)}>
<div>{t('common.userProfile.about')}</div> <div>{t('common.userProfile.about')}</div>
<div className='flex items-center'> <div className='flex items-center'>
<div className='mr-2 system-xs-regular text-text-tertiary'>{langeniusVersionInfo.current_version}</div> <div className='mr-2 system-xs-regular text-text-tertiary'>{langeniusVersionInfo.current_version}</div>
<Indicator color={langeniusVersionInfo.current_version === langeniusVersionInfo.latest_version ? 'green' : 'orange'} /> <Indicator color={langeniusVersionInfo.current_version === langeniusVersionInfo.latest_version ? 'green' : 'orange'} />
</div> </div>
</div> </div>}
</Menu.Item> </Menu.Item>
) )
} }
</div> </div>
<Menu.Item> <Menu.Item>
<div className='p-1' onClick={() => handleLogout()}> {({ active }) => <div className='p-1' onClick={() => handleLogout()}>
<div <div
className='flex items-center justify-between h-9 px-3 rounded-lg cursor-pointer group hover:bg-state-base-hover' className={
classNames('flex items-center justify-between h-9 px-3 rounded-lg cursor-pointer group hover:bg-state-base-hover',
active && 'bg-state-base-hover')}
> >
<div className='system-md-regular text-text-secondary'>{t('common.userProfile.logout')}</div> <div className='system-md-regular text-text-secondary'>{t('common.userProfile.logout')}</div>
<RiLogoutBoxRLine className='hidden w-4 h-4 text-text-tertiary group-hover:flex' /> <RiLogoutBoxRLine className='hidden w-4 h-4 text-text-tertiary group-hover:flex' />
</div> </div>
</div> </div>}
</Menu.Item> </Menu.Item>
</Menu.Items> </Menu.Items>
</Transition> </Transition>

View File

@ -9,6 +9,7 @@ import { useWorkspacesContext } from '@/context/workspace-context'
import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows'
import { Check } from '@/app/components/base/icons/src/vender/line/general' import { Check } from '@/app/components/base/icons/src/vender/line/general'
import { ToastContext } from '@/app/components/base/toast' import { ToastContext } from '@/app/components/base/toast'
import classNames from '@/utils/classnames'
const itemClassName = ` const itemClassName = `
flex items-center px-3 py-2 h-10 cursor-pointer flex items-center px-3 py-2 h-10 cursor-pointer
@ -50,7 +51,7 @@ const WorkplaceSelector = () => {
<Menu.Button className={cn( <Menu.Button className={cn(
` `
${itemClassName} w-full ${itemClassName} w-full
group hover:bg-gray-50 cursor-pointer ${open && 'bg-gray-50'} rounded-lg group hover:bg-state-base-hover cursor-pointer ${open && 'bg-state-base-hover'} rounded-lg
`, `,
)}> )}>
<div className={itemIconClassName}>{currentWorkspace?.name[0].toLocaleUpperCase()}</div> <div className={itemIconClassName}>{currentWorkspace?.name[0].toLocaleUpperCase()}</div>
@ -70,7 +71,7 @@ const WorkplaceSelector = () => {
className={cn( className={cn(
` `
absolute top-[1px] min-w-[200px] max-h-[70vh] overflow-y-scroll z-10 bg-white border-[0.5px] border-gray-200 absolute top-[1px] min-w-[200px] max-h-[70vh] overflow-y-scroll z-10 bg-white border-[0.5px] border-gray-200
divide-y divide-gray-100 origin-top-right rounded-xl divide-y divide-gray-100 origin-top-right rounded-xl focus:outline-none
`, `,
s.popup, s.popup,
)} )}
@ -78,11 +79,16 @@ const WorkplaceSelector = () => {
<div className="px-1 py-1"> <div className="px-1 py-1">
{ {
workspaces.map(workspace => ( workspaces.map(workspace => (
<div className={itemClassName} key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}> <Menu.Item key={workspace.id}>
<div className={itemIconClassName}>{workspace.name[0].toLocaleUpperCase()}</div> {({ active }) => <div className={classNames(itemClassName,
<div className={itemNameClassName}>{workspace.name}</div> active && 'bg-state-base-hover',
{workspace.current && <Check className={itemCheckClassName} />} )} key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
</div> <div className={itemIconClassName}>{workspace.name[0].toLocaleUpperCase()}</div>
<div className={itemNameClassName}>{workspace.name}</div>
{workspace.current && <Check className={itemCheckClassName} />}
</div>}
</Menu.Item>
)) ))
} }
</div> </div>

View File

@ -17,9 +17,9 @@ const Operator = ({ handleUndo, handleRedo }: OperatorProps) => {
width: 102, width: 102,
height: 72, height: 72,
}} }}
maskColor='var(--color-shadow-shadow-5)' maskColor='var(--color-workflow-minimap-bg)'
className='!absolute !left-4 !bottom-14 z-[9] !m-0 !w-[102px] !h-[72px] !border-[0.5px] !border-divider-subtle className='!absolute !left-4 !bottom-14 z-[9] !m-0 !w-[102px] !h-[72px] !border-[0.5px] !border-divider-subtle
!rounded-lg !shadow-md !shadow-shadow-shadow-5 !bg-workflow-minimap-bg' !rounded-lg !shadow-md !shadow-shadow-shadow-5 !bg-background-default-subtle'
/> />
<div className='flex items-center mt-1 gap-2 absolute left-4 bottom-4 z-[9]'> <div className='flex items-center mt-1 gap-2 absolute left-4 bottom-4 z-[9]'>
<ZoomInOut /> <ZoomInOut />