@visactor/vtable-sheet 1.20.1-alpha.0 → 1.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/components/sheet-tab-event-handler.d.ts +18 -0
- package/cjs/components/sheet-tab-event-handler.js +142 -0
- package/cjs/components/sheet-tab-event-handler.js.map +1 -0
- package/cjs/components/vtable-sheet.d.ts +1 -8
- package/cjs/components/vtable-sheet.js +13 -121
- package/cjs/components/vtable-sheet.js.map +1 -1
- package/cjs/core/WorkSheet.js +2 -1
- package/cjs/core/WorkSheet.js.map +1 -1
- package/cjs/formula/formula-ui-manager.js +1 -2
- package/cjs/formula/index.js +2 -1
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +1 -1
- package/cjs/index.js.map +1 -1
- package/cjs/managers/menu-manager.js +1 -2
- package/cjs/managers/menu-manager.js.map +1 -1
- package/cjs/ts-types/event.d.ts +2 -0
- package/cjs/ts-types/event.js +1 -2
- package/cjs/ts-types/event.js.map +1 -1
- package/cjs/ts-types/events.js +0 -2
- package/dist/vtable-sheet.js +379 -272
- package/dist/vtable-sheet.min.js +1 -1
- package/es/components/sheet-tab-event-handler.d.ts +18 -0
- package/es/components/sheet-tab-event-handler.js +135 -0
- package/es/components/sheet-tab-event-handler.js.map +1 -0
- package/es/components/vtable-sheet.d.ts +1 -8
- package/es/components/vtable-sheet.js +14 -121
- package/es/components/vtable-sheet.js.map +1 -1
- package/es/core/WorkSheet.js +2 -1
- package/es/core/WorkSheet.js.map +1 -1
- package/es/formula/formula-ui-manager.js +1 -2
- package/es/formula/index.js +2 -1
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/index.js.map +1 -1
- package/es/managers/menu-manager.js +1 -2
- package/es/managers/menu-manager.js.map +1 -1
- package/es/ts-types/event.d.ts +2 -0
- package/es/ts-types/event.js +1 -2
- package/es/ts-types/event.js.map +1 -1
- package/es/ts-types/events.js +0 -2
- package/package.json +7 -7
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type VTableSheet from './vtable-sheet';
|
|
2
|
+
export declare class SheetTabEventHandler {
|
|
3
|
+
private vTableSheet;
|
|
4
|
+
constructor(vTableSheet: VTableSheet);
|
|
5
|
+
handleSheetTabDblClick(sheetKey: string, originalTitle: string): void;
|
|
6
|
+
private renameSheet;
|
|
7
|
+
private getSheetTabElementByKey;
|
|
8
|
+
activeSheetTab(): void;
|
|
9
|
+
updateFadeEffects(tabsContainer: HTMLElement, fadeLeft: HTMLElement, fadeRight: HTMLElement): void;
|
|
10
|
+
scrollSheetTabs(direction: 'left' | 'right', tabsContainer: HTMLElement): void;
|
|
11
|
+
scrollTabIntoView(tab: HTMLElement, container: HTMLElement): void;
|
|
12
|
+
toggleSheetMenu(event: MouseEvent): void;
|
|
13
|
+
private clickOutsideHandler;
|
|
14
|
+
addClickOutsideListener(): void;
|
|
15
|
+
removeClickOutsideListener(): void;
|
|
16
|
+
updateSheetMenu(): void;
|
|
17
|
+
activeSheetMenuItem(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { showSnackbar } from "../tools/ui/snackbar";
|
|
2
|
+
|
|
3
|
+
import { checkTabTitle } from "../tools";
|
|
4
|
+
|
|
5
|
+
export class SheetTabEventHandler {
|
|
6
|
+
constructor(vTableSheet) {
|
|
7
|
+
this.clickOutsideHandler = event => {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const menuContainer = null === (_a = this.vTableSheet.getSheetTabElement()) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-menu-list"), menuButton = null === (_b = this.vTableSheet.getSheetTabElement()) || void 0 === _b ? void 0 : _b.querySelector(".vtable-sheet-menu-button");
|
|
10
|
+
menuContainer && menuButton && !menuContainer.contains(event.target) && !menuButton.contains(event.target) && (menuContainer.classList.remove("active"),
|
|
11
|
+
this.removeClickOutsideListener());
|
|
12
|
+
}, this.vTableSheet = vTableSheet;
|
|
13
|
+
}
|
|
14
|
+
handleSheetTabDblClick(sheetKey, originalTitle) {
|
|
15
|
+
const targetTab = this.getSheetTabElementByKey(sheetKey);
|
|
16
|
+
if (!targetTab) return;
|
|
17
|
+
targetTab.setAttribute("contenteditable", "true"), targetTab.setAttribute("spellcheck", "false"),
|
|
18
|
+
targetTab.classList.add("editing");
|
|
19
|
+
const range = document.createRange();
|
|
20
|
+
range.selectNodeContents(targetTab);
|
|
21
|
+
const selection = window.getSelection();
|
|
22
|
+
selection.removeAllRanges(), selection.addRange(range);
|
|
23
|
+
const onBlur = () => {
|
|
24
|
+
finishInput(!0);
|
|
25
|
+
}, onKeyDown = e => {
|
|
26
|
+
e.stopPropagation(), "Enter" === e.key ? (e.preventDefault(), finishInput(!0)) : "Escape" === e.key && finishInput(!1);
|
|
27
|
+
}, finishInput = commit => {
|
|
28
|
+
var _a;
|
|
29
|
+
targetTab.removeEventListener("blur", onBlur), targetTab.removeEventListener("keydown", onKeyDown),
|
|
30
|
+
targetTab.classList.remove("editing"), targetTab.setAttribute("contenteditable", "false");
|
|
31
|
+
const newTitle = null === (_a = targetTab.textContent) || void 0 === _a ? void 0 : _a.trim();
|
|
32
|
+
commit && newTitle !== originalTitle && this.renameSheet(sheetKey, newTitle) || (targetTab.textContent = originalTitle);
|
|
33
|
+
};
|
|
34
|
+
targetTab.addEventListener("blur", onBlur), targetTab.addEventListener("keydown", onKeyDown);
|
|
35
|
+
}
|
|
36
|
+
renameSheet(sheetKey, newTitle) {
|
|
37
|
+
var _a;
|
|
38
|
+
if (!this.vTableSheet.getSheetManager().getSheet(sheetKey)) return !1;
|
|
39
|
+
const error = checkTabTitle(newTitle);
|
|
40
|
+
if (error) return showSnackbar(error, 1300), !1;
|
|
41
|
+
return this.vTableSheet.getSheetManager().getAllSheets().find((s => s.sheetKey !== sheetKey && s.sheetTitle === newTitle)) ? (showSnackbar("工作表名称已存在,请重新输入", 1300),
|
|
42
|
+
!1) : (this.vTableSheet.getSheetManager().renameSheet(sheetKey, newTitle), null === (_a = this.vTableSheet.workSheetInstances.get(sheetKey)) || void 0 === _a || _a.setTitle(newTitle),
|
|
43
|
+
this.vTableSheet.updateSheetTabs(), this.vTableSheet.updateSheetMenu(), !0);
|
|
44
|
+
}
|
|
45
|
+
getSheetTabElementByKey(sheetKey) {
|
|
46
|
+
var _a;
|
|
47
|
+
const tabsContainer = null === (_a = this.vTableSheet.getSheetTabElement()) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-tabs-container");
|
|
48
|
+
return null == tabsContainer ? void 0 : tabsContainer.querySelector(`.vtable-sheet-tab[data-key="${sheetKey}"]`);
|
|
49
|
+
}
|
|
50
|
+
activeSheetTab() {
|
|
51
|
+
var _a;
|
|
52
|
+
const tabs = null === (_a = this.vTableSheet.getSheetTabElement()) || void 0 === _a ? void 0 : _a.querySelectorAll(".vtable-sheet-tab");
|
|
53
|
+
let activeTab = null;
|
|
54
|
+
tabs.forEach((tab => {
|
|
55
|
+
var _a;
|
|
56
|
+
tab.classList.remove("active"), tab.dataset.key === (null === (_a = this.vTableSheet.getActiveSheet()) || void 0 === _a ? void 0 : _a.getKey()) && (tab.classList.add("active"),
|
|
57
|
+
activeTab = tab);
|
|
58
|
+
})), setTimeout((() => {
|
|
59
|
+
activeTab && activeTab.scrollIntoView({
|
|
60
|
+
behavior: "smooth",
|
|
61
|
+
block: "nearest"
|
|
62
|
+
});
|
|
63
|
+
}), 100);
|
|
64
|
+
}
|
|
65
|
+
updateFadeEffects(tabsContainer, fadeLeft, fadeRight) {
|
|
66
|
+
tabsContainer.scrollLeft > 10 ? fadeLeft.style.display = "block" : fadeLeft.style.display = "none";
|
|
67
|
+
const maxScroll = tabsContainer.scrollWidth - tabsContainer.clientWidth;
|
|
68
|
+
tabsContainer.scrollLeft < maxScroll - 10 ? fadeRight.style.display = "block" : fadeRight.style.display = "none";
|
|
69
|
+
}
|
|
70
|
+
scrollSheetTabs(direction, tabsContainer) {
|
|
71
|
+
const currentScroll = tabsContainer.scrollLeft;
|
|
72
|
+
"left" === direction ? tabsContainer.scrollTo({
|
|
73
|
+
left: Math.max(0, currentScroll - 200),
|
|
74
|
+
behavior: "smooth"
|
|
75
|
+
}) : tabsContainer.scrollTo({
|
|
76
|
+
left: currentScroll + 200,
|
|
77
|
+
behavior: "smooth"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
scrollTabIntoView(tab, container) {
|
|
81
|
+
const tabRect = tab.getBoundingClientRect(), containerRect = container.getBoundingClientRect();
|
|
82
|
+
tabRect.left < containerRect.left ? container.scrollLeft += tabRect.left - containerRect.left - 10 : tabRect.right > containerRect.right && (container.scrollLeft += tabRect.right - containerRect.right + 10);
|
|
83
|
+
}
|
|
84
|
+
toggleSheetMenu(event) {
|
|
85
|
+
var _a;
|
|
86
|
+
const menuContainer = null === (_a = this.vTableSheet.getSheetTabElement()) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-menu-list");
|
|
87
|
+
menuContainer.classList.toggle("active"), menuContainer.classList.contains("active") ? this.addClickOutsideListener() : this.removeClickOutsideListener();
|
|
88
|
+
}
|
|
89
|
+
addClickOutsideListener() {
|
|
90
|
+
document.addEventListener("click", this.clickOutsideHandler);
|
|
91
|
+
}
|
|
92
|
+
removeClickOutsideListener() {
|
|
93
|
+
document.removeEventListener("click", this.clickOutsideHandler);
|
|
94
|
+
}
|
|
95
|
+
updateSheetMenu() {
|
|
96
|
+
var _a;
|
|
97
|
+
const menuContainer = null === (_a = this.vTableSheet.getSheetTabElement()) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-menu-list");
|
|
98
|
+
menuContainer.innerHTML = "";
|
|
99
|
+
this.vTableSheet.getSheetManager().getAllSheets().forEach((sheet => {
|
|
100
|
+
const li = document.createElement("li");
|
|
101
|
+
li.className = "vtable-sheet-menu-item", li.dataset.key = sheet.sheetKey;
|
|
102
|
+
const title = document.createElement("span");
|
|
103
|
+
title.className = "vtable-sheet-menu-item-title", title.innerText = sheet.sheetTitle,
|
|
104
|
+
li.appendChild(title);
|
|
105
|
+
const div = document.createElement("div");
|
|
106
|
+
div.className = "vtable-sheet-menu-delete-button", div.innerHTML = '<svg class="x-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
107
|
+
div.addEventListener("click", (e => {
|
|
108
|
+
e.stopPropagation(), this.vTableSheet.removeSheet(sheet.sheetKey);
|
|
109
|
+
})), li.addEventListener("click", (() => this.vTableSheet.activateSheet(sheet.sheetKey))),
|
|
110
|
+
li.appendChild(div), menuContainer.appendChild(li);
|
|
111
|
+
})), this.activeSheetMenuItem(), setTimeout((() => {
|
|
112
|
+
const activeItem = menuContainer.querySelector(".vtable-sheet-main-menu-item.active");
|
|
113
|
+
activeItem && activeItem.scrollIntoView({
|
|
114
|
+
behavior: "smooth",
|
|
115
|
+
block: "nearest"
|
|
116
|
+
});
|
|
117
|
+
}), 100);
|
|
118
|
+
}
|
|
119
|
+
activeSheetMenuItem() {
|
|
120
|
+
var _a;
|
|
121
|
+
const menuItems = null === (_a = this.vTableSheet.getSheetTabElement()) || void 0 === _a ? void 0 : _a.querySelectorAll(".vtable-sheet-main-menu-item");
|
|
122
|
+
let activeItem = null;
|
|
123
|
+
menuItems.forEach((item => {
|
|
124
|
+
var _a;
|
|
125
|
+
item.classList.remove("active"), item.dataset.key === (null === (_a = this.vTableSheet.getActiveSheet()) || void 0 === _a ? void 0 : _a.getKey()) && (item.classList.add("active"),
|
|
126
|
+
activeItem = item);
|
|
127
|
+
})), setTimeout((() => {
|
|
128
|
+
activeItem && activeItem.scrollIntoView({
|
|
129
|
+
behavior: "smooth",
|
|
130
|
+
block: "nearest"
|
|
131
|
+
});
|
|
132
|
+
}), 100);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=sheet-tab-event-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/sheet-tab-event-handler.ts"],"names":[],"mappings":"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","file":"sheet-tab-event-handler.js","sourcesContent":["import type VTableSheet from './vtable-sheet';\nimport { showSnackbar } from '../tools/ui/snackbar';\nimport { checkTabTitle } from '../tools';\n\n/**\n * Sheet Tab Event Handler\n * 专门处理sheet标签页相关的事件逻辑\n */\nexport class SheetTabEventHandler {\n private vTableSheet: VTableSheet;\n\n constructor(vTableSheet: VTableSheet) {\n this.vTableSheet = vTableSheet;\n }\n\n /**\n * 处理sheet标签双击事件\n * 双击sheet标签后,将标签设为可编辑状态。输入完成后进行重命名。\n * @param sheetKey 工作表key\n * @param originalTitle 原始名称\n */\n handleSheetTabDblClick(sheetKey: string, originalTitle: string): void {\n const targetTab = this.getSheetTabElementByKey(sheetKey);\n if (!targetTab) {\n return;\n }\n // 将原文本节点设为可编辑\n targetTab.setAttribute('contenteditable', 'true');\n targetTab.setAttribute('spellcheck', 'false');\n targetTab.classList.add('editing'); // 添加编辑状态样式\n // 选中所有文本\n const range = document.createRange();\n range.selectNodeContents(targetTab);\n const selection = window.getSelection();\n selection.removeAllRanges();\n selection.addRange(range);\n\n const onBlur = () => {\n finishInput(true);\n };\n const onKeyDown = (e: KeyboardEvent) => {\n e.stopPropagation();\n if (e.key === 'Enter') {\n e.preventDefault();\n finishInput(true);\n } else if (e.key === 'Escape') {\n finishInput(false);\n }\n };\n const finishInput = (commit: boolean) => {\n targetTab.removeEventListener('blur', onBlur);\n targetTab.removeEventListener('keydown', onKeyDown);\n targetTab.classList.remove('editing');\n targetTab.setAttribute('contenteditable', 'false');\n const newTitle = targetTab.textContent?.trim();\n if (!commit || newTitle === originalTitle || !this.renameSheet(sheetKey, newTitle)) {\n targetTab.textContent = originalTitle;\n return;\n }\n };\n targetTab.addEventListener('blur', onBlur);\n targetTab.addEventListener('keydown', onKeyDown);\n }\n\n /**\n * 重命名sheet\n * @param sheetKey 工作表key\n * @param newTitle 新名称\n * @returns 是否成功\n */\n private renameSheet(sheetKey: string, newTitle: string): boolean {\n const sheet = this.vTableSheet.getSheetManager().getSheet(sheetKey);\n if (!sheet) {\n return false;\n }\n const error = checkTabTitle(newTitle);\n if (error) {\n showSnackbar(error, 1300);\n return false;\n }\n const isExist = this.vTableSheet\n .getSheetManager()\n .getAllSheets()\n .find(s => s.sheetKey !== sheetKey && s.sheetTitle === newTitle);\n if (isExist) {\n showSnackbar('工作表名称已存在,请重新输入', 1300);\n return false;\n }\n this.vTableSheet.getSheetManager().renameSheet(sheetKey, newTitle);\n this.vTableSheet.workSheetInstances.get(sheetKey)?.setTitle(newTitle);\n this.vTableSheet.updateSheetTabs();\n this.vTableSheet.updateSheetMenu();\n return true;\n }\n\n /**\n * 获取指定sheetKey的标签元素\n */\n private getSheetTabElementByKey(sheetKey: string): HTMLElement | null {\n const tabsContainer = this.vTableSheet\n .getSheetTabElement()\n ?.querySelector('.vtable-sheet-tabs-container') as HTMLElement;\n return tabsContainer?.querySelector(`.vtable-sheet-tab[data-key=\"${sheetKey}\"]`) as HTMLElement;\n }\n\n /**\n * 激活sheet标签并滚动到可见区域\n */\n activeSheetTab(): void {\n const tabs = this.vTableSheet\n .getSheetTabElement()\n ?.querySelectorAll('.vtable-sheet-tab') as NodeListOf<HTMLElement>;\n let activeTab: HTMLElement | null = null;\n tabs.forEach(tab => {\n tab.classList.remove('active');\n if (tab.dataset.key === this.vTableSheet.getActiveSheet()?.getKey()) {\n tab.classList.add('active');\n activeTab = tab;\n }\n });\n // 确保激活的标签可见\n setTimeout(() => {\n if (activeTab) {\n activeTab.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 100);\n }\n\n /**\n * 更新渐变效果\n * @param tabsContainer 标签容器\n * @param fadeLeft 左侧渐变效果\n * @param fadeRight 右侧渐变效果\n */\n updateFadeEffects(tabsContainer: HTMLElement, fadeLeft: HTMLElement, fadeRight: HTMLElement): void {\n // 显示/隐藏左侧渐变\n if (tabsContainer.scrollLeft > 10) {\n fadeLeft.style.display = 'block';\n } else {\n fadeLeft.style.display = 'none';\n }\n\n // 显示/隐藏右侧渐变\n const maxScroll = tabsContainer.scrollWidth - tabsContainer.clientWidth;\n if (tabsContainer.scrollLeft < maxScroll - 10) {\n fadeRight.style.display = 'block';\n } else {\n fadeRight.style.display = 'none';\n }\n }\n\n /**\n * 滚动sheet标签\n * @param direction 滚动方向\n * @param tabsContainer 标签容器\n */\n scrollSheetTabs(direction: 'left' | 'right', tabsContainer: HTMLElement): void {\n const scrollAmount = 200; // 每次滚动的像素数\n const currentScroll = tabsContainer.scrollLeft;\n\n if (direction === 'left') {\n tabsContainer.scrollTo({\n left: Math.max(0, currentScroll - scrollAmount),\n behavior: 'smooth'\n });\n } else {\n tabsContainer.scrollTo({\n left: currentScroll + scrollAmount,\n behavior: 'smooth'\n });\n }\n }\n\n /**\n * 滚动以确保标签可见\n * @param tab 标签\n * @param container 容器\n */\n scrollTabIntoView(tab: HTMLElement, container: HTMLElement): void {\n const tabRect = tab.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n\n if (tabRect.left < containerRect.left) {\n // 标签在可见区域左侧\n container.scrollLeft += tabRect.left - containerRect.left - 10;\n } else if (tabRect.right > containerRect.right) {\n // 标签在可见区域右侧\n container.scrollLeft += tabRect.right - containerRect.right + 10;\n }\n }\n\n /**\n * 显示工作表菜单\n */\n toggleSheetMenu(event: MouseEvent): void {\n const menuContainer = this.vTableSheet\n .getSheetTabElement()\n ?.querySelector('.vtable-sheet-menu-list') as HTMLElement;\n menuContainer.classList.toggle('active');\n\n // 如果菜单被打开,添加点击外部关闭的监听器\n if (menuContainer.classList.contains('active')) {\n this.addClickOutsideListener();\n } else {\n this.removeClickOutsideListener();\n }\n }\n\n /**\n * 添加点击外部关闭菜单的监听器\n */\n private clickOutsideHandler = (event: MouseEvent): void => {\n const menuContainer = this.vTableSheet\n .getSheetTabElement()\n ?.querySelector('.vtable-sheet-menu-list') as HTMLElement;\n const menuButton = this.vTableSheet.getSheetTabElement()?.querySelector('.vtable-sheet-menu-button') as HTMLElement;\n\n // 如果点击的不是菜单容器和菜单按钮,则关闭菜单\n if (\n menuContainer &&\n menuButton &&\n !menuContainer.contains(event.target as Node) &&\n !menuButton.contains(event.target as Node)\n ) {\n menuContainer.classList.remove('active');\n this.removeClickOutsideListener();\n }\n };\n\n /**\n * 添加点击外部监听器\n */\n addClickOutsideListener(): void {\n document.addEventListener('click', this.clickOutsideHandler);\n }\n\n /**\n * 移除点击外部监听器\n */\n removeClickOutsideListener(): void {\n document.removeEventListener('click', this.clickOutsideHandler);\n }\n\n /**\n * 更新sheet列表\n */\n updateSheetMenu(): void {\n const menuContainer = this.vTableSheet\n .getSheetTabElement()\n ?.querySelector('.vtable-sheet-menu-list') as HTMLElement;\n menuContainer.innerHTML = '';\n const sheets = this.vTableSheet.getSheetManager().getAllSheets();\n sheets.forEach(sheet => {\n // li\n const li = document.createElement('li');\n li.className = 'vtable-sheet-menu-item';\n li.dataset.key = sheet.sheetKey;\n // title\n const title = document.createElement('span');\n title.className = 'vtable-sheet-menu-item-title';\n title.innerText = sheet.sheetTitle;\n li.appendChild(title);\n // delete button\n const div = document.createElement('div');\n div.className = 'vtable-sheet-menu-delete-button';\n div.innerHTML =\n '<svg class=\"x-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">' +\n '<path d=\"M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>' +\n '<path d=\"M6 6L18 18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>' +\n '</svg>';\n div.addEventListener('click', e => {\n e.stopPropagation();\n this.vTableSheet.removeSheet(sheet.sheetKey);\n });\n li.addEventListener('click', () => this.vTableSheet.activateSheet(sheet.sheetKey));\n li.appendChild(div);\n menuContainer.appendChild(li);\n });\n this.activeSheetMenuItem();\n // 确保激活的标签可见\n setTimeout(() => {\n const activeItem = menuContainer.querySelector('.vtable-sheet-main-menu-item.active');\n if (activeItem) {\n activeItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 100);\n }\n\n /**\n * 激活sheet菜单项并滚动到可见区域\n */\n activeSheetMenuItem(): void {\n const menuItems = this.vTableSheet\n .getSheetTabElement()\n ?.querySelectorAll('.vtable-sheet-main-menu-item') as NodeListOf<HTMLElement>;\n let activeItem: HTMLElement | null = null;\n menuItems.forEach(item => {\n item.classList.remove('active');\n if (item.dataset.key === this.vTableSheet.getActiveSheet()?.getKey()) {\n item.classList.add('active');\n activeItem = item;\n }\n });\n setTimeout(() => {\n if (activeItem) {\n activeItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 100);\n }\n}\n"]}
|
|
@@ -20,23 +20,16 @@ export default class VTableSheet {
|
|
|
20
20
|
private mainMenuElement;
|
|
21
21
|
private contentElement;
|
|
22
22
|
private dragManager;
|
|
23
|
+
private sheetTabEventHandler;
|
|
23
24
|
constructor(container: HTMLElement, options: IVTableSheetOptions);
|
|
24
25
|
private mergeDefaultOptions;
|
|
25
26
|
private initFormulaAutocomplete;
|
|
26
27
|
private initUI;
|
|
27
28
|
private createSheetTab;
|
|
28
|
-
private toggleSheetMenu;
|
|
29
|
-
private updateFadeEffects;
|
|
30
|
-
private scrollSheetTabs;
|
|
31
29
|
private _activeSheetTab;
|
|
32
30
|
updateSheetTabs(tabsContainer?: HTMLElement): void;
|
|
33
31
|
private createSheetTabItem;
|
|
34
|
-
private handleSheetTabDblClick;
|
|
35
|
-
private renameSheet;
|
|
36
|
-
private getSheetTabElementByKey;
|
|
37
32
|
updateSheetMenu(): void;
|
|
38
|
-
private activeSheetMenuItem;
|
|
39
|
-
private scrollTabIntoView;
|
|
40
33
|
private initSheets;
|
|
41
34
|
activateSheet(sheetKey: string): void;
|
|
42
35
|
addSheet(sheet: ISheetDefine): void;
|
|
@@ -26,8 +26,6 @@ import { WorkSheetEventType } from "../ts-types";
|
|
|
26
26
|
|
|
27
27
|
import SheetTabDragManager from "../managers/tab-drag-manager";
|
|
28
28
|
|
|
29
|
-
import { checkTabTitle } from "../tools";
|
|
30
|
-
|
|
31
29
|
import { FormulaAutocomplete } from "../formula/formula-autocomplete";
|
|
32
30
|
|
|
33
31
|
import { formulaEditor } from "../formula/formula-editor";
|
|
@@ -36,6 +34,8 @@ import { MenuManager } from "../managers/menu-manager";
|
|
|
36
34
|
|
|
37
35
|
import { FormulaUIManager } from "../formula/formula-ui-manager";
|
|
38
36
|
|
|
37
|
+
import { SheetTabEventHandler } from "./sheet-tab-event-handler";
|
|
38
|
+
|
|
39
39
|
VTable.register.editor("formula", formulaEditor);
|
|
40
40
|
|
|
41
41
|
export default class VTableSheet {
|
|
@@ -45,8 +45,8 @@ export default class VTableSheet {
|
|
|
45
45
|
this.container = container, this.options = this.mergeDefaultOptions(options), this.sheetManager = new SheetManager,
|
|
46
46
|
this.formulaManager = new FormulaManager(this), this.eventManager = new EventManager(this),
|
|
47
47
|
this.dragManager = new SheetTabDragManager(this), this.menuManager = new MenuManager(this),
|
|
48
|
-
this.formulaUIManager = new FormulaUIManager(this), this.
|
|
49
|
-
this.resize();
|
|
48
|
+
this.formulaUIManager = new FormulaUIManager(this), this.sheetTabEventHandler = new SheetTabEventHandler(this),
|
|
49
|
+
this.initUI(), this.initSheets(), this.resize();
|
|
50
50
|
}
|
|
51
51
|
mergeDefaultOptions(options) {
|
|
52
52
|
return Object.assign({
|
|
@@ -82,7 +82,7 @@ export default class VTableSheet {
|
|
|
82
82
|
fadeLeft.className = "vtable-sheet-fade-left", fadeLeft.style.display = "none",
|
|
83
83
|
sheetTab.appendChild(fadeLeft);
|
|
84
84
|
const tabsContainer = document.createElement("div");
|
|
85
|
-
tabsContainer.className = "vtable-sheet-tabs-container", tabsContainer.addEventListener("scroll", (() => this.updateFadeEffects(tabsContainer, fadeLeft, fadeRight))),
|
|
85
|
+
tabsContainer.className = "vtable-sheet-tabs-container", tabsContainer.addEventListener("scroll", (() => this.sheetTabEventHandler.updateFadeEffects(tabsContainer, fadeLeft, fadeRight))),
|
|
86
86
|
sheetTab.appendChild(tabsContainer);
|
|
87
87
|
const insertIndicator = document.createElement("div");
|
|
88
88
|
insertIndicator.className = "vtable-sheet-insert-indicator", insertIndicator.style.display = "none",
|
|
@@ -97,55 +97,24 @@ export default class VTableSheet {
|
|
|
97
97
|
navButtons.className = "vtable-sheet-nav-buttons";
|
|
98
98
|
const leftScrollBtn = document.createElement("button");
|
|
99
99
|
leftScrollBtn.className = "vtable-sheet-scroll-button", leftScrollBtn.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>',
|
|
100
|
-
leftScrollBtn.title = "向左滚动", leftScrollBtn.addEventListener("click", (() => this.scrollSheetTabs("left", tabsContainer))),
|
|
100
|
+
leftScrollBtn.title = "向左滚动", leftScrollBtn.addEventListener("click", (() => this.sheetTabEventHandler.scrollSheetTabs("left", tabsContainer))),
|
|
101
101
|
navButtons.appendChild(leftScrollBtn);
|
|
102
102
|
const rightScrollBtn = document.createElement("button");
|
|
103
103
|
rightScrollBtn.className = "vtable-sheet-scroll-button", rightScrollBtn.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>',
|
|
104
|
-
rightScrollBtn.title = "向右滚动", rightScrollBtn.addEventListener("click", (() => this.scrollSheetTabs("right", tabsContainer))),
|
|
104
|
+
rightScrollBtn.title = "向右滚动", rightScrollBtn.addEventListener("click", (() => this.sheetTabEventHandler.scrollSheetTabs("right", tabsContainer))),
|
|
105
105
|
navButtons.appendChild(rightScrollBtn);
|
|
106
106
|
const menuButton = document.createElement("button");
|
|
107
107
|
menuButton.className = "vtable-sheet-menu-button", menuButton.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>',
|
|
108
|
-
menuButton.title = "工作表选项", menuButton.addEventListener("click", (e => this.toggleSheetMenu(e))),
|
|
108
|
+
menuButton.title = "工作表选项", menuButton.addEventListener("click", (e => this.sheetTabEventHandler.toggleSheetMenu(e))),
|
|
109
109
|
navButtons.appendChild(menuButton);
|
|
110
110
|
const menuContainer = document.createElement("ul");
|
|
111
111
|
return menuContainer.className = "vtable-sheet-menu-list", sheetTab.appendChild(menuContainer),
|
|
112
112
|
sheetTab.appendChild(navButtons), setTimeout((() => {
|
|
113
|
-
this.updateFadeEffects(tabsContainer, fadeLeft, fadeRight);
|
|
113
|
+
this.sheetTabEventHandler.updateFadeEffects(tabsContainer, fadeLeft, fadeRight);
|
|
114
114
|
}), 100), sheetTab;
|
|
115
115
|
}
|
|
116
|
-
toggleSheetMenu(event) {
|
|
117
|
-
var _a;
|
|
118
|
-
(null === (_a = this.sheetTabElement) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-menu-list")).classList.toggle("active");
|
|
119
|
-
}
|
|
120
|
-
updateFadeEffects(tabsContainer, fadeLeft, fadeRight) {
|
|
121
|
-
tabsContainer.scrollLeft > 10 ? fadeLeft.style.display = "block" : fadeLeft.style.display = "none";
|
|
122
|
-
const maxScroll = tabsContainer.scrollWidth - tabsContainer.clientWidth;
|
|
123
|
-
tabsContainer.scrollLeft < maxScroll - 10 ? fadeRight.style.display = "block" : fadeRight.style.display = "none";
|
|
124
|
-
}
|
|
125
|
-
scrollSheetTabs(direction, tabsContainer) {
|
|
126
|
-
const currentScroll = tabsContainer.scrollLeft;
|
|
127
|
-
"left" === direction ? tabsContainer.scrollTo({
|
|
128
|
-
left: Math.max(0, currentScroll - 200),
|
|
129
|
-
behavior: "smooth"
|
|
130
|
-
}) : tabsContainer.scrollTo({
|
|
131
|
-
left: currentScroll + 200,
|
|
132
|
-
behavior: "smooth"
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
116
|
_activeSheetTab() {
|
|
136
|
-
|
|
137
|
-
const tabs = null === (_a = this.sheetTabElement) || void 0 === _a ? void 0 : _a.querySelectorAll(".vtable-sheet-tab");
|
|
138
|
-
let activeTab = null;
|
|
139
|
-
tabs.forEach((tab => {
|
|
140
|
-
var _a;
|
|
141
|
-
tab.classList.remove("active"), tab.dataset.key === (null === (_a = this.activeWorkSheet) || void 0 === _a ? void 0 : _a.getKey()) && (tab.classList.add("active"),
|
|
142
|
-
activeTab = tab);
|
|
143
|
-
})), setTimeout((() => {
|
|
144
|
-
activeTab && activeTab.scrollIntoView({
|
|
145
|
-
behavior: "smooth",
|
|
146
|
-
block: "nearest"
|
|
147
|
-
});
|
|
148
|
-
}), 100);
|
|
117
|
+
this.sheetTabEventHandler.activeSheetTab();
|
|
149
118
|
}
|
|
150
119
|
updateSheetTabs(tabsContainer) {
|
|
151
120
|
var _a;
|
|
@@ -162,88 +131,12 @@ export default class VTableSheet {
|
|
|
162
131
|
const tab = document.createElement("div");
|
|
163
132
|
return tab.className = "vtable-sheet-tab", tab.dataset.key = sheet.sheetKey, tab.textContent = sheet.sheetTitle,
|
|
164
133
|
tab.title = sheet.sheetTitle, tab.addEventListener("click", (() => this.activateSheet(sheet.sheetKey))),
|
|
165
|
-
tab.addEventListener("dblclick", (() => this.handleSheetTabDblClick(sheet.sheetKey, sheet.sheetTitle))),
|
|
134
|
+
tab.addEventListener("dblclick", (() => this.sheetTabEventHandler.handleSheetTabDblClick(sheet.sheetKey, sheet.sheetTitle))),
|
|
166
135
|
tab.addEventListener("mousedown", (e => this.dragManager.handleTabMouseDown(e, sheet.sheetKey))),
|
|
167
136
|
tab;
|
|
168
137
|
}
|
|
169
|
-
handleSheetTabDblClick(sheetKey, originalTitle) {
|
|
170
|
-
const targetTab = this.getSheetTabElementByKey(sheetKey);
|
|
171
|
-
if (!targetTab) return;
|
|
172
|
-
targetTab.setAttribute("contenteditable", "true"), targetTab.setAttribute("spellcheck", "false"),
|
|
173
|
-
targetTab.classList.add("editing");
|
|
174
|
-
const range = document.createRange();
|
|
175
|
-
range.selectNodeContents(targetTab);
|
|
176
|
-
const selection = window.getSelection();
|
|
177
|
-
selection.removeAllRanges(), selection.addRange(range);
|
|
178
|
-
const onBlur = () => {
|
|
179
|
-
finishInput(!0);
|
|
180
|
-
}, onKeyDown = e => {
|
|
181
|
-
e.stopPropagation(), "Enter" === e.key ? (e.preventDefault(), finishInput(!0)) : "Escape" === e.key && finishInput(!1);
|
|
182
|
-
}, finishInput = commit => {
|
|
183
|
-
var _a;
|
|
184
|
-
targetTab.removeEventListener("blur", onBlur), targetTab.removeEventListener("keydown", onKeyDown),
|
|
185
|
-
targetTab.classList.remove("editing"), targetTab.setAttribute("contenteditable", "false");
|
|
186
|
-
const newTitle = null === (_a = targetTab.textContent) || void 0 === _a ? void 0 : _a.trim();
|
|
187
|
-
commit && newTitle !== originalTitle && this.renameSheet(sheetKey, newTitle) || (targetTab.textContent = originalTitle);
|
|
188
|
-
};
|
|
189
|
-
targetTab.addEventListener("blur", onBlur), targetTab.addEventListener("keydown", onKeyDown);
|
|
190
|
-
}
|
|
191
|
-
renameSheet(sheetKey, newTitle) {
|
|
192
|
-
var _a;
|
|
193
|
-
if (!this.sheetManager.getSheet(sheetKey)) return !1;
|
|
194
|
-
const error = checkTabTitle(newTitle);
|
|
195
|
-
if (error) return showSnackbar(error, 1300), !1;
|
|
196
|
-
return this.sheetManager.getAllSheets().find((s => s.sheetKey !== sheetKey && s.sheetTitle === newTitle)) ? (showSnackbar("工作表名称已存在,请重新输入", 1300),
|
|
197
|
-
!1) : (this.sheetManager.renameSheet(sheetKey, newTitle), null === (_a = this.workSheetInstances.get(sheetKey)) || void 0 === _a || _a.setTitle(newTitle),
|
|
198
|
-
this.updateSheetTabs(), this.updateSheetMenu(), !0);
|
|
199
|
-
}
|
|
200
|
-
getSheetTabElementByKey(sheetKey) {
|
|
201
|
-
var _a;
|
|
202
|
-
const tabsContainer = null === (_a = this.sheetTabElement) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-tabs-container");
|
|
203
|
-
return null == tabsContainer ? void 0 : tabsContainer.querySelector(`.vtable-sheet-tab[data-key="${sheetKey}"]`);
|
|
204
|
-
}
|
|
205
138
|
updateSheetMenu() {
|
|
206
|
-
|
|
207
|
-
const menuContainer = null === (_a = this.sheetTabElement) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-menu-list");
|
|
208
|
-
menuContainer.innerHTML = "";
|
|
209
|
-
this.sheetManager.getAllSheets().forEach((sheet => {
|
|
210
|
-
const li = document.createElement("li");
|
|
211
|
-
li.className = "vtable-sheet-menu-item", li.dataset.key = sheet.sheetKey;
|
|
212
|
-
const title = document.createElement("span");
|
|
213
|
-
title.className = "vtable-sheet-menu-item-title", title.innerText = sheet.sheetTitle,
|
|
214
|
-
li.appendChild(title);
|
|
215
|
-
const div = document.createElement("div");
|
|
216
|
-
div.className = "vtable-sheet-menu-delete-button", div.innerHTML = '<svg class="x-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
217
|
-
div.addEventListener("click", (e => {
|
|
218
|
-
e.stopPropagation(), this.removeSheet(sheet.sheetKey);
|
|
219
|
-
})), li.addEventListener("click", (() => this.activateSheet(sheet.sheetKey))), li.appendChild(div),
|
|
220
|
-
menuContainer.appendChild(li);
|
|
221
|
-
})), this.activeSheetMenuItem(), setTimeout((() => {
|
|
222
|
-
const activeItem = menuContainer.querySelector(".vtable-sheet-main-menu-item.active");
|
|
223
|
-
activeItem && activeItem.scrollIntoView({
|
|
224
|
-
behavior: "smooth",
|
|
225
|
-
block: "nearest"
|
|
226
|
-
});
|
|
227
|
-
}), 100);
|
|
228
|
-
}
|
|
229
|
-
activeSheetMenuItem() {
|
|
230
|
-
var _a;
|
|
231
|
-
const menuItems = null === (_a = this.sheetTabElement) || void 0 === _a ? void 0 : _a.querySelectorAll(".vtable-sheet-main-menu-item");
|
|
232
|
-
let activeItem = null;
|
|
233
|
-
menuItems.forEach((item => {
|
|
234
|
-
var _a;
|
|
235
|
-
item.classList.remove("active"), item.dataset.key === (null === (_a = this.activeWorkSheet) || void 0 === _a ? void 0 : _a.getKey()) && (item.classList.add("active"),
|
|
236
|
-
activeItem = item);
|
|
237
|
-
})), setTimeout((() => {
|
|
238
|
-
activeItem && activeItem.scrollIntoView({
|
|
239
|
-
behavior: "smooth",
|
|
240
|
-
block: "nearest"
|
|
241
|
-
});
|
|
242
|
-
}), 100);
|
|
243
|
-
}
|
|
244
|
-
scrollTabIntoView(tab, container) {
|
|
245
|
-
const tabRect = tab.getBoundingClientRect(), containerRect = container.getBoundingClientRect();
|
|
246
|
-
tabRect.left < containerRect.left ? container.scrollLeft += tabRect.left - containerRect.left - 10 : tabRect.right > containerRect.right && (container.scrollLeft += tabRect.right - containerRect.right + 10);
|
|
139
|
+
this.sheetTabEventHandler.updateSheetMenu();
|
|
247
140
|
}
|
|
248
141
|
initSheets() {
|
|
249
142
|
if (this.options.sheets && this.options.sheets.length > 0) {
|
|
@@ -265,7 +158,7 @@ export default class VTableSheet {
|
|
|
265
158
|
})), this.workSheetInstances.has(sheetKey)) {
|
|
266
159
|
const instance = this.workSheetInstances.get(sheetKey);
|
|
267
160
|
instance.getElement().style.display = "block", this.activeWorkSheet = instance,
|
|
268
|
-
this.formulaManager.setActiveSheet(sheetKey), this._activeSheetTab(), this.activeSheetMenuItem(),
|
|
161
|
+
this.formulaManager.setActiveSheet(sheetKey), this._activeSheetTab(), this.sheetTabEventHandler.activeSheetMenuItem(),
|
|
269
162
|
this.restoreFilterState(instance, sheetDefine);
|
|
270
163
|
} else {
|
|
271
164
|
const instance = this.createWorkSheetInstance(sheetDefine);
|
|
@@ -464,7 +357,7 @@ export default class VTableSheet {
|
|
|
464
357
|
}
|
|
465
358
|
release() {
|
|
466
359
|
this.eventManager.release(), this.formulaManager.release(), this.formulaUIManager.release(),
|
|
467
|
-
this.workSheetInstances.forEach((instance => {
|
|
360
|
+
this.sheetTabEventHandler.removeClickOutsideListener(), this.workSheetInstances.forEach((instance => {
|
|
468
361
|
instance.release();
|
|
469
362
|
})), this.rootElement && this.rootElement.parentNode && this.rootElement.parentNode.removeChild(this.rootElement),
|
|
470
363
|
this.formulaAutocomplete && this.formulaAutocomplete.release(), this.formulaManager.cellHighlightManager && this.formulaManager.cellHighlightManager.release();
|