Doc tree supports Shift+Click to select multiple documents (#15965)

*  feat(文件管理): 支持 Shift+点击多选文档
- 添加 lastClickedFileItem 属性以跟踪最后点击的文档项
- 实现 Shift+点击选择范围功能
- 更新文档项选择状态

* 🎨 文档树「在页签下侧打开」快捷键改为ctrl+shift+click

* 🎨 文档树「在页签下侧打开」快捷键改为ctrl+shift+click
This commit is contained in:
Achuan-2 2025-09-29 12:03:16 +08:00 committed by GitHub
parent ba42d4f34b
commit 89fe4fc560
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 2 deletions

View file

@ -34,6 +34,7 @@ export class Files extends Model {
public parent: Tab;
private actionsElement: HTMLElement;
public closeElement: HTMLElement;
private lastClickedFileItem: HTMLElement = null;
constructor(options: { tab: Tab, app: App }) {
super({
@ -333,9 +334,47 @@ export class Files extends Model {
} else if (target.tagName === "LI") {
if (isOnlyMeta(event) && !event.altKey && !event.shiftKey) {
target.classList.toggle("b3-list-item--focus");
} else if (event.shiftKey && !event.altKey && !isOnlyMeta(event) && target.getAttribute("data-type") === "navigation-file") {
// Shift+click 多选文档
event.preventDefault();
event.stopPropagation();
if (!this.lastClickedFileItem) {
this.lastClickedFileItem = target;
this.setCurrent(target, false);
return;
}
// 获取所有文档项
const allFiles = Array.from(this.element.querySelectorAll('li[data-type="navigation-file"]'));
// 获取起始和结束索引
const startIndex = allFiles.indexOf(this.lastClickedFileItem);
const endIndex = allFiles.indexOf(target);
if (startIndex === -1 || endIndex === -1) return;
// 确定选择范围
const start = Math.min(startIndex, endIndex);
const end = Math.max(startIndex, endIndex);
// 清除现有选择
allFiles.forEach(file => {
(file as HTMLElement).classList.remove("b3-list-item--focus");
});
// 添加新选择
for (let i = start; i <= end; i++) {
(allFiles[i] as HTMLElement).classList.add("b3-list-item--focus");
}
needFocus = false;
return;
} else {
this.setCurrent(target, false);
if (target.getAttribute("data-type") === "navigation-file") {
// 更新最后点击的文档项
this.lastClickedFileItem = target;
needFocus = false;
if (target.getAttribute("data-opening")) {
return;
@ -351,7 +390,7 @@ export class Files extends Model {
target.removeAttribute("data-opening");
}
});
} else if (!event.altKey && isNotCtrl(event) && event.shiftKey) {
} else if (!event.altKey && !isNotCtrl(event) && event.shiftKey) {
openFileById({
app: options.app,
id: target.getAttribute("data-node-id"),

View file

@ -67,7 +67,7 @@ export const openEditorTab = (app: App, ids: string[], notebookId?: string, path
id: "insertBottom",
icon: "iconLayoutBottom",
label: window.siyuan.languages.insertBottom,
accelerator: ids.length === 1 ? "⇧" + window.siyuan.languages.click : "",
accelerator: ids.length === 1 ? "⇧" + window.siyuan.languages.click : "",
click: () => {
if (notebookId) {
openFileById({