Merge pull request #1830 from MyPrototypeWhat/fix/UserArea-Dropdown

fix(UserArea): Enhance UserArea dropdown positioning with useRef
This commit is contained in:
Seefs
2025-09-22 12:59:54 +08:00
committed by GitHub
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com For commercial licensing, please contact support@quantumnous.com
*/ */
import React from 'react'; import React, { useRef } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Avatar, Button, Dropdown, Typography } from '@douyinfe/semi-ui'; import { Avatar, Button, Dropdown, Typography } from '@douyinfe/semi-ui';
import { ChevronDown } from 'lucide-react'; import { ChevronDown } from 'lucide-react';
@@ -39,6 +39,7 @@ const UserArea = ({
navigate, navigate,
t, t,
}) => { }) => {
const dropdownRef = useRef(null);
if (isLoading) { if (isLoading) {
return ( return (
<SkeletonWrapper <SkeletonWrapper
@@ -52,90 +53,93 @@ const UserArea = ({
if (userState.user) { if (userState.user) {
return ( return (
<Dropdown <div className='relative' ref={dropdownRef}>
position='bottomRight' <Dropdown
render={ position='bottomRight'
<Dropdown.Menu className='!bg-semi-color-bg-overlay !border-semi-color-border !shadow-lg !rounded-lg dark:!bg-gray-700 dark:!border-gray-600'> getPopupContainer={() => dropdownRef.current}
<Dropdown.Item render={
onClick={() => { <Dropdown.Menu className='!bg-semi-color-bg-overlay !border-semi-color-border !shadow-lg !rounded-lg dark:!bg-gray-700 dark:!border-gray-600'>
navigate('/console/personal'); <Dropdown.Item
}} onClick={() => {
className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-blue-500 dark:hover:!text-white' navigate('/console/personal');
> }}
<div className='flex items-center gap-2'> className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-blue-500 dark:hover:!text-white'
<IconUserSetting >
size='small' <div className='flex items-center gap-2'>
className='text-gray-500 dark:text-gray-400' <IconUserSetting
/> size='small'
<span>{t('个人设置')}</span> className='text-gray-500 dark:text-gray-400'
</div> />
</Dropdown.Item> <span>{t('个人设置')}</span>
<Dropdown.Item </div>
onClick={() => { </Dropdown.Item>
navigate('/console/token'); <Dropdown.Item
}} onClick={() => {
className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-blue-500 dark:hover:!text-white' navigate('/console/token');
> }}
<div className='flex items-center gap-2'> className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-blue-500 dark:hover:!text-white'
<IconKey >
size='small' <div className='flex items-center gap-2'>
className='text-gray-500 dark:text-gray-400' <IconKey
/> size='small'
<span>{t('令牌管理')}</span> className='text-gray-500 dark:text-gray-400'
</div> />
</Dropdown.Item> <span>{t('令牌管理')}</span>
<Dropdown.Item </div>
onClick={() => { </Dropdown.Item>
navigate('/console/topup'); <Dropdown.Item
}} onClick={() => {
className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-blue-500 dark:hover:!text-white' navigate('/console/topup');
> }}
<div className='flex items-center gap-2'> className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-blue-500 dark:hover:!text-white'
<IconCreditCard >
size='small' <div className='flex items-center gap-2'>
className='text-gray-500 dark:text-gray-400' <IconCreditCard
/> size='small'
<span>{t('钱包管理')}</span> className='text-gray-500 dark:text-gray-400'
</div> />
</Dropdown.Item> <span>{t('钱包管理')}</span>
<Dropdown.Item </div>
onClick={logout} </Dropdown.Item>
className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-red-500 dark:hover:!text-white' <Dropdown.Item
> onClick={logout}
<div className='flex items-center gap-2'> className='!px-3 !py-1.5 !text-sm !text-semi-color-text-0 hover:!bg-semi-color-fill-1 dark:!text-gray-200 dark:hover:!bg-red-500 dark:hover:!text-white'
<IconExit >
size='small' <div className='flex items-center gap-2'>
className='text-gray-500 dark:text-gray-400' <IconExit
/> size='small'
<span>{t('退出')}</span> className='text-gray-500 dark:text-gray-400'
</div> />
</Dropdown.Item> <span>{t('退出')}</span>
</Dropdown.Menu> </div>
} </Dropdown.Item>
> </Dropdown.Menu>
<Button }
theme='borderless'
type='tertiary'
className='flex items-center gap-1.5 !p-1 !rounded-full hover:!bg-semi-color-fill-1 dark:hover:!bg-gray-700 !bg-semi-color-fill-0 dark:!bg-semi-color-fill-1 dark:hover:!bg-semi-color-fill-2'
> >
<Avatar <Button
size='extra-small' theme='borderless'
color={stringToColor(userState.user.username)} type='tertiary'
className='mr-1' className='flex items-center gap-1.5 !p-1 !rounded-full hover:!bg-semi-color-fill-1 dark:hover:!bg-gray-700 !bg-semi-color-fill-0 dark:!bg-semi-color-fill-1 dark:hover:!bg-semi-color-fill-2'
> >
{userState.user.username[0].toUpperCase()} <Avatar
</Avatar> size='extra-small'
<span className='hidden md:inline'> color={stringToColor(userState.user.username)}
<Typography.Text className='!text-xs !font-medium !text-semi-color-text-1 dark:!text-gray-300 mr-1'> className='mr-1'
{userState.user.username} >
</Typography.Text> {userState.user.username[0].toUpperCase()}
</span> </Avatar>
<ChevronDown <span className='hidden md:inline'>
size={14} <Typography.Text className='!text-xs !font-medium !text-semi-color-text-1 dark:!text-gray-300 mr-1'>
className='text-xs text-semi-color-text-2 dark:text-gray-400' {userState.user.username}
/> </Typography.Text>
</Button> </span>
</Dropdown> <ChevronDown
size={14}
className='text-xs text-semi-color-text-2 dark:text-gray-400'
/>
</Button>
</Dropdown>
</div>
); );
} else { } else {
const showRegisterButton = !isSelfUseMode; const showRegisterButton = !isSelfUseMode;