Anchor file row menu to button edge

File row overflow menus in the dashboard now open anchored to the ⋯ button (below it with right-edge alignment) instead of pointer position, improving placement consistency. UIContextMenu now supports `position.right` for right-edge pinning, and the ⋯ trigger keeps an active visual state while its menu is open so hover styling doesn’t drop when the cursor moves onto the menu.
This commit is contained in:
Nariman Jelveh
2026-07-29 15:25:51 -07:00
parent dbb52171c8
commit a87a517b82
3 changed files with 30 additions and 5 deletions
+13 -2
View File
@@ -3421,8 +3421,19 @@ const TabFiles = {
// row would lose all visual state the moment the pointer moves
// onto the menu (same treatment as the right-click handler).
const releaseCtxState = this.markRowContextMenuOpen(rowElement);
const menu = UIContextMenu({ items: items });
menu.onClose = releaseCtxState;
// Anchor the menu to the button — below it, right edges aligned —
// rather than at the pointer, and keep the button in its active
// state until the menu closes.
const btnRect = targetElement.getBoundingClientRect();
targetElement.classList.add('has-open-contextmenu');
const menu = UIContextMenu({
items: items,
position: { top: btnRect.bottom, right: btnRect.right },
});
menu.onClose = () => {
targetElement.classList.remove('has-open-contextmenu');
releaseCtxState();
};
}
},
+9 -2
View File
@@ -378,7 +378,9 @@
* @param {string} [options.id] - Unique identifier for the menu
* @param {Object} [options.position] - Custom positioning for the menu
* @param {number} options.position.top - Top position in pixels
* @param {number} options.position.left - Left position in pixels
* @param {number} [options.position.left] - Left position in pixels (pins the menu's left edge)
* @param {number} [options.position.right] - Right position in pixels (pins the menu's right
* edge instead for anchoring to right-edge buttons)
* @param {boolean|number} [options.delay] - Animation delay for menu appearance
* true/1/undefined = 50ms fade
* false = no animation
@@ -541,7 +543,12 @@ function UIContextMenu (options) {
// custom position
//--------------------------------
else {
start_x = options.position.left;
// position.right pins the menu's right edge (anchors that sit at
// the right edge of their container would otherwise trigger the
// overflow flip only sometimes, making placement inconsistent)
start_x = options.position.right !== undefined
? options.position.right - $(contextMenu).outerWidth()
: options.position.left;
start_y = options.position.top;
}
+8 -1
View File
@@ -1821,6 +1821,12 @@ body.myapps-reordering .myapps-tile {
}
}
/* The '⋯' button stays in its active look while the menu it opened is up
(the pointer is on the menu by then, so :hover alone can't hold it). */
.dashboard-section-files .row .item-more.has-open-contextmenu {
color: var(--dashboard-text);
}
.dashboard-section-files .row.selected .item-more {
color: var(--dashboard-text-secondary);
}
@@ -2388,7 +2394,8 @@ body.myapps-reordering .myapps-tile {
transition: background-color 0.15s ease, color 0.15s ease;
}
.dashboard-section-files .files-tab .files.files-grid-view .row .item-more:hover {
.dashboard-section-files .files-tab .files.files-grid-view .row .item-more:hover,
.dashboard-section-files .files-tab .files.files-grid-view .row .item-more.has-open-contextmenu {
color: var(--dashboard-text-primary);
background: var(--dashboard-hover);
}