fix: harden app sidebar popover
This commit is contained in:
@@ -73,12 +73,12 @@ export function AppSidebar({
|
||||
onOpenRedeem,
|
||||
onOpenLogout,
|
||||
}: AppSidebarProps) {
|
||||
const { isMobile, setOpen, setOpenMobile, state } = useSidebar();
|
||||
const { isMobile, setOpen, setOpenMobile, state, viewport } = useSidebar();
|
||||
const firstSessionRef = useRef<HTMLButtonElement>(null);
|
||||
const historyHeadingRef = useRef<HTMLHeadingElement>(null);
|
||||
const isCollapsedDesktop = state === "collapsed" && !isMobile;
|
||||
const showExpandedContent = !isCollapsedDesktop;
|
||||
const popoverPlacement = `${isMobile}:${state}`;
|
||||
const popoverPlacement = `${viewport}:${state}`;
|
||||
const previousPopoverPlacement = useRef(popoverPlacement);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -192,7 +192,7 @@ export function AppSidebar({
|
||||
sideOffset={8}
|
||||
collisionPadding={12}
|
||||
>
|
||||
<Popover.Popup className="account-menu" role="menu" aria-label="账户菜单">
|
||||
<Popover.Popup className="account-menu-popup" role="menu" aria-label="账户菜单">
|
||||
<div className="account-menu-identity">
|
||||
<span className="account-menu-avatar" aria-hidden="true">{account.initial}</span>
|
||||
<span><b>{account.name}</b><small>{account.email}</small></span>
|
||||
|
||||
@@ -114,10 +114,14 @@ test("uses a portaled Base UI account popover with safe collision padding", () =
|
||||
assert.match(appSidebar, /import \{ Popover \} from "@base-ui\/react\/popover"/);
|
||||
assert.match(appSidebar, /<Popover\.Portal>/);
|
||||
assert.match(appSidebar, /collisionPadding=\{12\}/);
|
||||
assert.match(appSidebar, /<Popover\.Popup className="account-menu-popup"/);
|
||||
assert.doesNotMatch(appSidebar, /<Popover\.Popup className="account-menu"/);
|
||||
});
|
||||
|
||||
test("closes an open account menu only when its sidebar placement changes", () => {
|
||||
test("closes an open account menu when the sidebar viewport or state changes", () => {
|
||||
const appSidebar = readProjectFile("src/components/app-sidebar.tsx");
|
||||
assert.match(appSidebar, /const \{[^}]*\bviewport\b[^}]*\} = useSidebar\(\)/);
|
||||
assert.match(appSidebar, /const popoverPlacement = `\$\{viewport\}:\$\{state\}`/);
|
||||
assert.match(appSidebar, /previousPopoverPlacement/);
|
||||
assert.match(appSidebar, /previousPopoverPlacement\.current !== popoverPlacement && accountMenuOpen/);
|
||||
});
|
||||
|
||||
@@ -83,7 +83,8 @@ test("routes account actions through a popover and focused dialogs", () => {
|
||||
assert.match(pageSource, /openAccountDialog\("profile"/);
|
||||
assert.match(pageSource, /openAccountDialog\("redeem"/);
|
||||
assert.match(pageSource, /openAccountDialog\("logout"/);
|
||||
assert.match(appSidebarSource, /className="account-menu"/);
|
||||
assert.match(appSidebarSource, /<Popover\.Popup className="account-menu-popup"/);
|
||||
assert.doesNotMatch(appSidebarSource, /<Popover\.Popup className="account-menu"/);
|
||||
assert.match(appSidebarSource, /<Popover\.Root open=\{accountMenuOpen\} onOpenChange=\{onAccountMenuOpenChange\}>/);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user