ui: update menu bar

This commit is contained in:
wj-xiao
2026-01-05 17:37:44 +08:00
parent 1b7021d64b
commit a3440cf867
4 changed files with 53 additions and 8 deletions

View File

@@ -26,9 +26,12 @@ export const Menu = () => {
const [menuDisabledItems, setMenuDisabledItems] = useAtom(menuDisabledItemsAtom);
const [isMenuOpen, setIsMenuOpen] = useState(true);
const [isMenuMoved, setIsMenuMoved] = useState(false);
const [isMenuHovered, setIsMenuHovered] = useState(true);
const [bounds, setBounds] = useState({ left: 0, right: 0, top: 0, bottom: 0 });
const nodeRef = useRef<any>(null);
const nodeRef = useRef<HTMLDivElement | null>(null);
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
// disabled menu items
@@ -51,26 +54,63 @@ export const Menu = () => {
};
handleResize();
handleMouseLeave();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
if (timerRef.current) {
clearTimeout(timerRef.current);
}
};
}, []);
function handleMouseEnter() {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
setIsMenuHovered(true);
}
function handleMouseLeave() {
timerRef.current = setTimeout(() => {
setIsMenuHovered(false);
}, 5000);
}
return (
<Draggable
nodeRef={nodeRef}
bounds={bounds}
handle="strong"
positionOffset={{ x: '-50%', y: '0%' }}
onStop={(_e, data) => {
if (data.x !== 0 || data.y !== 0) {
setIsMenuMoved(true);
}
}}
>
<div ref={nodeRef} className="fixed left-1/2 top-[10px] z-[1000] -translate-x-1/2">
<div
ref={nodeRef}
className="fixed left-1/2 top-[10px] z-[1000] -translate-x-1/2"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{/* Trigger area for auto-show when hidden */}
{isMenuOpen && (
<div className="absolute -top-[10px] left-0 right-0 h-[60px] w-full bg-transparent" />
)}
<div className="sticky top-[10px] flex w-full justify-center">
<div
className={clsx(
'h-[36px] items-center rounded bg-neutral-800/80',
isMenuOpen ? 'flex' : 'hidden'
'h-[36px] items-center rounded bg-neutral-800/80 transition-all duration-300',
isMenuOpen ? 'flex' : 'hidden',
isMenuOpen && !isMenuMoved && !isMenuHovered
? '-translate-y-[110%] opacity-80'
: 'translate-y-0 opacity-100'
)}
>
<strong>

View File

@@ -48,7 +48,12 @@ export const Power = () => {
}
const icon = (
<div className={clsx('h-[18px] w-[18px]', isPowerOn ? 'text-green-600' : 'text-neutral-300')}>
<div
className={clsx(
'h-[18px] w-[18px]',
isPowerOn ? 'text-green-600' : 'text-neutral-300 hover:text-white'
)}
>
{isLoading ? (
<LoaderCircleIcon className="animate-spin" size={18} />
) : (

View File

@@ -107,11 +107,11 @@ export const Settings = () => {
<>
<Tooltip title={t('settings.title')} placement="bottom" mouseEnterDelay={0.6}>
<div
className="flex h-[30px] w-[30px] cursor-pointer items-center justify-center rounded text-white hover:bg-neutral-700/80"
className="flex h-[30px] w-[30px] cursor-pointer items-center justify-center rounded hover:bg-neutral-700/80"
onClick={openModal}
>
<Badge dot={isUpdateAvailable} color="blue" offset={[0, 2]}>
<div className="pt-[3px]">
<div className="pt-[3px] text-neutral-300 hover:text-white">
<SettingsIcon size={18} />
</div>
</Badge>

View File

@@ -213,7 +213,7 @@ export const Wol = () => {
return (
<MenuItem
title={t('wol.title')}
icon={<NetworkIcon size={16} />}
icon={<NetworkIcon size={18} />}
content={content}
onOpenChange={handleOpenChange}
/>