mirror of
https://github.com/HeyPuter/puter.git
synced 2026-10-12 23:00:06 +00:00
Keep toolbar buttons in place when a menu opens near the viewport edge
On phones the expanded frame was clamped to an 8px viewport margin, which moved the whole toolbar row (by the header padding minus 8px) under the user's finger. The frame now shrinks to fit beside and below the collapsed toolbar, and only falls back to shifting when there isn't enough room.
This commit is contained in:
1 parent
a338c8db46
commit
ed32c212d3
2 files changed
+42
-7
No files matched your search
@@ -22,12 +22,32 @@ export function shouldShowUpgrade (user) {
|
||||
return !user.subscription?.active && !user.team?.uid;
|
||||
}
|
||||
|
||||
const MIN_PANEL_WIDTH = 280;
|
||||
const MIN_PANEL_HEIGHT = 240;
|
||||
|
||||
/**
|
||||
* Places the expanded toolbar frame inside the viewport. It grows left and down
|
||||
* from the collapsed frame and shrinks rather than shifts when there is room, so
|
||||
* the toolbar buttons stay under the pointer.
|
||||
*/
|
||||
export function toolbarBounds (anchor, viewport, panel, requestedHeight) {
|
||||
const width = Math.min(panel === 'apps' ? 440 : 360, viewport.width - 16);
|
||||
const height = Math.min(panel === 'apps' ? 620 : (Number.isFinite(requestedHeight) ? Math.max(180, Math.min(requestedHeight, 800)) : 560), viewport.height - 16);
|
||||
return {
|
||||
width: Math.max(0, width), height: Math.max(0, height),
|
||||
left: Math.max(8, Math.min(anchor.right - width, viewport.width - width - 8)),
|
||||
top: Math.max(8, Math.min(anchor.top, viewport.height - height - 8)),
|
||||
};
|
||||
let width = Math.max(0, Math.min(panel === 'apps' ? 440 : 360, viewport.width - 16));
|
||||
let height = Math.max(0, Math.min(panel === 'apps' ? 620 : (Number.isFinite(requestedHeight) ? Math.max(180, Math.min(requestedHeight, 800)) : 560), viewport.height - 16));
|
||||
let left;
|
||||
let top;
|
||||
const roomLeft = anchor.right - 8;
|
||||
if ( anchor.right <= viewport.width - 8 && roomLeft >= Math.min(width, MIN_PANEL_WIDTH) ) {
|
||||
width = Math.min(width, roomLeft);
|
||||
left = anchor.right - width;
|
||||
} else {
|
||||
left = Math.max(8, Math.min(anchor.right - width, viewport.width - width - 8));
|
||||
}
|
||||
const roomBelow = viewport.height - anchor.top - 8;
|
||||
if ( anchor.top >= 8 && roomBelow >= Math.min(height, MIN_PANEL_HEIGHT) ) {
|
||||
height = Math.min(height, roomBelow);
|
||||
top = anchor.top;
|
||||
} else {
|
||||
top = Math.max(8, Math.min(anchor.top, viewport.height - height - 8));
|
||||
}
|
||||
return { width, height, left, top };
|
||||
}
|
||||
@@ -34,6 +34,21 @@ describe('toolbar integration', () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
it('keeps the toolbar buttons in place when the menu fits beside them', () => {
|
||||
for ( const [viewport, anchor] of [
|
||||
[{ width: 390, height: 700 }, { right: 374, top: 8 }],
|
||||
[{ width: 320, height: 560 }, { right: 304, top: 12 }],
|
||||
[{ width: 1100, height: 600 }, { right: 1084, top: 12 }],
|
||||
] ) {
|
||||
for ( const panel of ['apps', 'account'] ) {
|
||||
const box = toolbarBounds(anchor, viewport, panel);
|
||||
expect(box.left + box.width).toBe(anchor.right);
|
||||
expect(box.top).toBe(anchor.top);
|
||||
expect(box.left).toBeGreaterThanOrEqual(8);
|
||||
expect(box.top + box.height).toBeLessThanOrEqual(viewport.height - 8);
|
||||
}
|
||||
}
|
||||
});
|
||||
it('opens an upgrade deep link once the billing UI is ready', () => {
|
||||
let opens = 0;
|
||||
const target = { location: { href: 'https://puter.com/dashboard?upgrade=1#usage' } };
|
||||
|
||||
Reference in new issue
Block a user