Archived
fix: show pwa refresh menu options
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@jmfederico/pi-web": patch
|
||||
---
|
||||
|
||||
Fix the PWA refresh control menu so its reload options are visible when opened from the compact header button.
|
||||
@@ -0,0 +1,27 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { actionMenuPanelStyle } from "./actionMenu";
|
||||
|
||||
describe("actionMenuPanelStyle", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it("can constrain menus to the viewport for compact shadow-root controls", () => {
|
||||
vi.stubGlobal("window", { innerWidth: 400, innerHeight: 800 });
|
||||
vi.stubGlobal("HTMLElement", FakeHTMLElement);
|
||||
|
||||
const target = new FakeHTMLElement({ top: 10, right: 390, bottom: 46, left: 354 });
|
||||
|
||||
expect(actionMenuPanelStyle(target, { constrainTo: "viewport" })).toBe("top: 46px; max-height: 754px; right: 10px; max-width: 390px;");
|
||||
});
|
||||
});
|
||||
|
||||
class FakeHTMLElement extends EventTarget {
|
||||
constructor(private readonly rect: { top: number; right: number; bottom: number; left: number }) {
|
||||
super();
|
||||
}
|
||||
|
||||
getBoundingClientRect(): { top: number; right: number; bottom: number; left: number } {
|
||||
return this.rect;
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,14 @@ interface ActionMenuRect {
|
||||
left: number;
|
||||
}
|
||||
|
||||
export function actionMenuPanelStyle(target: EventTarget | null): string {
|
||||
interface ActionMenuPanelStyleOptions {
|
||||
constrainTo?: "host" | "viewport";
|
||||
}
|
||||
|
||||
export function actionMenuPanelStyle(target: EventTarget | null, options: ActionMenuPanelStyleOptions = {}): string {
|
||||
if (typeof HTMLElement === "undefined" || typeof window === "undefined" || !(target instanceof HTMLElement)) return "";
|
||||
const trigger = target.getBoundingClientRect();
|
||||
const bounds = actionMenuBounds(target);
|
||||
const bounds = options.constrainTo === "viewport" ? viewportBounds() : actionMenuBounds(target);
|
||||
const viewportWidth = window.innerWidth;
|
||||
const viewportHeight = window.innerHeight;
|
||||
const leftBound = Math.max(0, bounds.left);
|
||||
@@ -35,6 +39,10 @@ export function actionMenuPanelStyle(target: EventTarget | null): string {
|
||||
function actionMenuBounds(target: HTMLElement): ActionMenuRect {
|
||||
const root = target.getRootNode();
|
||||
if (typeof ShadowRoot !== "undefined" && root instanceof ShadowRoot && root.host instanceof HTMLElement) return root.host.getBoundingClientRect();
|
||||
return viewportBounds();
|
||||
}
|
||||
|
||||
function viewportBounds(): ActionMenuRect {
|
||||
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0 };
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ export class AppRefreshControl extends LitElement {
|
||||
};
|
||||
|
||||
private openMenu(target: EventTarget | null): void {
|
||||
this.menuStyle = actionMenuPanelStyle(target);
|
||||
this.menuStyle = actionMenuPanelStyle(target, { constrainTo: "viewport" });
|
||||
this.menuOpen = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user