Skip to content

Commit a9ecd48

Browse files
committed
🎨 The menu no longer extends beyond the window
fix #15400
1 parent 4a167ee commit a9ecd48

File tree

5 files changed

+38
-12
lines changed

5 files changed

+38
-12
lines changed

app/src/assets/scss/component/_menu.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
}
170170

171171
&__items {
172-
max-height: min(80vh, calc(100vh - 20px - var(--b3-menu-position-top, 0px))); // 20px 是 .b3-menu 的上下 padding
172+
max-height: 80vh;
173173
overflow: auto;
174174
padding: 0 8px;
175175
}

app/src/boot/onGetConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export const onGetConfig = (isStart: boolean, app: App) => {
8484
adjustLayout();
8585
resizeTabs();
8686
resizeTopBar();
87+
window.siyuan.menus.menu.resetPosition();
8788
firstResize = true;
8889
}, 200);
8990
});

app/src/menus/Menu.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,25 @@ export class Menu {
146146
this.element.style.zIndex = (++window.siyuan.zIndex).toString();
147147
this.element.classList.remove("fn__none");
148148
setPosition(this.element, options.x - (options.isLeft ? this.element.clientWidth : 0), options.y, options.h, options.w);
149-
this.element.style.setProperty("--b3-menu-position-top", this.element.style.top);
149+
const menuTop = parseInt(this.element.style.top) || options.y;
150+
const availableHeight = window.innerHeight - menuTop - Constants.SIZE_TOOLBAR_HEIGHT;
151+
(this.element.lastElementChild as HTMLElement).style.maxHeight = Math.max(availableHeight, 0) + "px";
152+
}
153+
154+
public resetPosition() {
155+
if (this.element.classList.contains("fn__none")) {
156+
return;
157+
}
158+
159+
setPosition(this.element, parseInt(this.element.style.left) || 0, parseInt(this.element.style.top) || 0, 0, 0);
160+
const menuTop = parseInt(this.element.style.top) || 0;
161+
const availableHeight = window.innerHeight - menuTop - Constants.SIZE_TOOLBAR_HEIGHT;
162+
(this.element.lastElementChild as HTMLElement).style.maxHeight = Math.max(availableHeight, 0) + "px";
163+
164+
const showSubMenus = this.element.querySelectorAll(".b3-menu__item--show .b3-menu__submenu");
165+
showSubMenus.forEach((subMenuElement) => {
166+
this.showSubMenu(subMenuElement as HTMLElement);
167+
});
150168
}
151169

152170
public fullscreen(position: "bottom" | "all" = "all") {

app/src/util/setPosition.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@ export const setPosition = (element: HTMLElement, x: number, y: number, targetHe
44
element.style.top = y + "px";
55
element.style.left = x + "px";
66
const rect = element.getBoundingClientRect();
7-
// 上下超出屏幕
7+
8+
// 垂直方向调整
89
if (rect.bottom > window.innerHeight || rect.top < Constants.SIZE_TOOLBAR_HEIGHT) {
9-
const top = y - rect.height - targetHeight;
10-
if (top > Constants.SIZE_TOOLBAR_HEIGHT && (top + rect.height) < window.innerHeight) {
11-
// 上部
12-
element.style.top = top + "px";
13-
} else if (top <= Constants.SIZE_TOOLBAR_HEIGHT) {
14-
// 位置超越到屏幕上方外时,需移动到屏幕顶部。eg:光标在第一个块,然后滚动到上方看不见的位置,按 ctrl+a
15-
element.style.top = Constants.SIZE_TOOLBAR_HEIGHT + "px";
10+
const bottomSpace = window.innerHeight - y;
11+
const topSpace = y - Constants.SIZE_TOOLBAR_HEIGHT;
12+
13+
if (bottomSpace >= rect.height) {
14+
// 如果下方空间足够,直接使用原位置
15+
element.style.top = y + "px";
16+
} else if (topSpace >= rect.height) {
17+
// 如果上方空间足够,向上调整
18+
element.style.top = (y - rect.height - targetHeight) + "px";
1619
} else {
17-
// 依旧展现在下部,只是位置上移
18-
element.style.top = Math.max(Constants.SIZE_TOOLBAR_HEIGHT, window.innerHeight - rect.height) + "px";
20+
// 如果上下空间都不够,优先展现在下部
21+
const maxTop = Math.max(Constants.SIZE_TOOLBAR_HEIGHT, window.innerHeight - rect.height);
22+
element.style.top = maxTop + "px";
1923
}
2024
}
25+
26+
// 水平方向调整
2127
if (rect.right > window.innerWidth) {
2228
// 展现在左侧
2329
element.style.left = `${window.innerWidth - rect.width - targetLeft}px`;

app/src/window/init.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export const init = (app: App) => {
6161
resizeTimeout = window.setTimeout(() => {
6262
adjustLayout(window.siyuan.layout.centerLayout);
6363
resizeTabs();
64+
window.siyuan.menus.menu.resetPosition();
6465
}, 200);
6566
});
6667
};

0 commit comments

Comments
 (0)