ProfileMenuButton: use self-built Menu
All checks were successful
/ depoly (push) Successful in 1m20s

This commit is contained in:
thislight 2024-11-19 17:03:56 +08:00
parent 0a9d833f09
commit 4190b8847d
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E
2 changed files with 11 additions and 33 deletions

View file

@ -14,6 +14,7 @@ import {
animateGrowFromTopRight, animateGrowFromTopRight,
animateShrinkToTopRight, animateShrinkToTopRight,
} from "../platform/anim"; } from "../platform/anim";
import type { MenuListProps } from "@suid/material/MenuList";
export type Anchor = Pick<DOMRect, "top" | "left" | "right"> & { e?: number }; export type Anchor = Pick<DOMRect, "top" | "left" | "right"> & { e?: number };
@ -22,6 +23,7 @@ export type MenuProps = ParentProps<
open?: boolean; open?: boolean;
onClose?: JSX.EventHandlerUnion<HTMLDialogElement, Event>; onClose?: JSX.EventHandlerUnion<HTMLDialogElement, Event>;
anchor: () => Anchor; anchor: () => Anchor;
MenuListProps?: MenuListProps;
id?: string; id?: string;
} & JSX.AriaAttributes } & JSX.AriaAttributes
@ -213,11 +215,8 @@ const Menu: Component<MenuProps> = (props) => {
tabIndex={-1} tabIndex={-1}
{...rest} {...rest}
> >
<div <div class="container" role="presentation">
class="container" <MenuList {...props.MenuListProps}>{props.children}</MenuList>
role="presentation"
>
<MenuList>{props.children}</MenuList>
</div> </div>
</dialog> </dialog>
); );

View file

@ -5,13 +5,10 @@ import {
ListItemAvatar, ListItemAvatar,
ListItemIcon, ListItemIcon,
ListItemText, ListItemText,
Menu,
MenuItem, MenuItem,
} from "@suid/material"; } from "@suid/material";
import { import {
ErrorBoundary,
Show, Show,
createSignal,
createUniqueId, createUniqueId,
type ParentComponent, type ParentComponent,
} from "solid-js"; } from "solid-js";
@ -22,6 +19,7 @@ import {
FeaturedPlayList as ListIcon, FeaturedPlayList as ListIcon,
} from "@suid/icons-material"; } from "@suid/icons-material";
import A from "../platform/A"; import A from "../platform/A";
import Menu, { createManagedMenuState } from "../material/Menu";
const ProfileMenuButton: ParentComponent<{ const ProfileMenuButton: ParentComponent<{
profile?: { profile?: {
@ -35,29 +33,20 @@ const ProfileMenuButton: ParentComponent<{
}; };
}; };
}; };
onClick?: () => void;
onClose?: () => void;
}> = (props) => { }> = (props) => {
const menuId = createUniqueId(); const menuId = createUniqueId();
const buttonId = createUniqueId(); const buttonId = createUniqueId();
let [anchor, setAnchor] = createSignal<HTMLButtonElement | null>(null); const [open, state] = createManagedMenuState();
const open = () => !!anchor();
const onClick = ( const onClick = (
event: MouseEvent & { currentTarget: HTMLButtonElement }, event: MouseEvent & { currentTarget: HTMLButtonElement },
) => { ) => {
setAnchor(event.currentTarget); open(event.currentTarget.getBoundingClientRect());
props.onClick?.();
}; };
const inf = () => props.profile?.account.inf; const inf = () => props.profile?.account.inf;
const onClose = () => {
props.onClick?.();
setAnchor(null);
};
return ( return (
<> <>
<ButtonBase <ButtonBase
@ -75,23 +64,13 @@ const ProfileMenuButton: ParentComponent<{
</ButtonBase> </ButtonBase>
<Menu <Menu
id={menuId} id={menuId}
anchorEl={anchor()}
open={open()}
onClose={onClose}
MenuListProps={{ MenuListProps={{
"aria-labelledby": buttonId, "aria-labelledby": menuId,
sx: { style: {
minWidth: "220px", "min-width": "220px",
}, },
}} }}
anchorOrigin={{ {...state}
vertical: "top",
horizontal: "right",
}}
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
> >
<MenuItem <MenuItem
component={A} component={A}