@veltra/sheet 2.0.1 → 2.1.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.
Files changed (211) hide show
  1. package/dist/index.d.ts +4 -26
  2. package/dist/index.js +3 -23
  3. package/dist/tools/builtin.js +279 -8
  4. package/dist/tools/context.d.ts +54 -11
  5. package/dist/tools/context.js +28 -5
  6. package/dist/tools/download.js +68 -0
  7. package/dist/tools/export.worker.d.ts +16 -0
  8. package/dist/tools/export.worker.js +29 -0
  9. package/dist/tools/registry.d.ts +7 -4
  10. package/dist/tools/registry.js +1 -3
  11. package/dist/types/index.d.ts +1 -0
  12. package/dist/types/sheet.d.ts +6 -5
  13. package/dist/vue/formula-bar.js +393 -0
  14. package/dist/vue/formula-suggest-list.js +66 -0
  15. package/dist/vue/import-file.js +140 -0
  16. package/dist/vue/insert-count-menu-item.js +68 -0
  17. package/dist/vue/insert-image.js +79 -0
  18. package/dist/vue/popup-helpers.js +73 -0
  19. package/dist/vue/popups/border-popup.js +75 -0
  20. package/dist/vue/popups/border-preset-glyph.js +106 -0
  21. package/dist/vue/popups/export-popup.js +51 -0
  22. package/dist/vue/popups/fill-color-popup.js +37 -0
  23. package/dist/vue/popups/find-popup.js +113 -0
  24. package/dist/vue/popups/font-color-popup.js +37 -0
  25. package/dist/vue/popups/font-size-popup.js +63 -0
  26. package/dist/vue/popups/import.worker.d.ts +21 -0
  27. package/dist/vue/popups/import.worker.js +41 -0
  28. package/dist/vue/popups/insert-image-popup.js +38 -0
  29. package/dist/vue/sheet-context-menu.js +200 -0
  30. package/dist/vue/sheet-tabs.js +162 -0
  31. package/dist/vue/sheet-toolbar.js +106 -0
  32. package/dist/vue/sheet.js +144 -164
  33. package/dist/vue/style.d.ts +11 -1
  34. package/dist/vue/style.js +10 -0
  35. package/dist/vue/style2.css +564 -3
  36. package/dist/vue/use-find-replace.js +161 -0
  37. package/dist/vue/use-formula-ref-select.js +37 -0
  38. package/dist/vue/use-formula-suggest.js +126 -0
  39. package/dist/vue/use-sheet-grid.js +180 -0
  40. package/dist/vue/use-sheet-state.js +122 -0
  41. package/dist/vue/use-sheet-tabs-bar.js +90 -0
  42. package/dist/vue/use-tool-groups.js +42 -0
  43. package/dist/vue/use-tool-popup.js +123 -0
  44. package/dist/vue/use-toolbar-scroll.js +72 -0
  45. package/package.json +12 -7
  46. package/src/env.d.ts +11 -0
  47. package/src/index.ts +203 -14
  48. package/src/tools/__test__/builtin.test.ts +208 -66
  49. package/src/tools/__test__/context.test.ts +62 -2
  50. package/src/tools/builtin.ts +350 -6
  51. package/src/tools/context.ts +89 -11
  52. package/src/tools/download.ts +82 -0
  53. package/src/tools/export.worker.ts +61 -0
  54. package/src/tools/registry.ts +16 -1
  55. package/src/types/index.ts +6 -0
  56. package/src/types/sheet.ts +5 -3
  57. package/src/vue/__test__/formula-bar.test.ts +455 -0
  58. package/src/vue/__test__/import-file.test.ts +183 -0
  59. package/src/vue/__test__/insert-count-menu-item.test.ts +123 -0
  60. package/src/vue/__test__/insert-image-popup.test.ts +89 -0
  61. package/src/vue/__test__/insert-image.test.ts +100 -0
  62. package/src/vue/__test__/sheet-component.test.ts +716 -27
  63. package/src/vue/__test__/sheet-context-menu.test.ts +206 -0
  64. package/src/vue/__test__/use-formula-ref-select.test.ts +35 -0
  65. package/src/vue/__test__/use-formula-suggest.test.ts +83 -0
  66. package/src/vue/formula-bar.vue +473 -0
  67. package/src/vue/formula-suggest-list.vue +64 -0
  68. package/src/vue/import-file.ts +173 -0
  69. package/src/vue/insert-count-menu-item.vue +69 -0
  70. package/src/vue/insert-image.ts +90 -0
  71. package/src/vue/parsing.ts +11 -0
  72. package/src/vue/popup-helpers.ts +50 -0
  73. package/src/vue/popups/border-popup.vue +93 -0
  74. package/src/vue/popups/border-preset-glyph.vue +111 -0
  75. package/src/vue/popups/export-popup.vue +52 -0
  76. package/src/vue/popups/fill-color-popup.vue +39 -0
  77. package/src/vue/popups/find-popup.vue +111 -0
  78. package/src/vue/popups/font-color-popup.vue +39 -0
  79. package/src/vue/popups/font-size-popup.vue +52 -0
  80. package/src/vue/popups/import.worker.ts +66 -0
  81. package/src/vue/popups/insert-image-popup.vue +39 -0
  82. package/src/vue/sheet-context-menu.ts +229 -0
  83. package/src/vue/sheet-tabs.vue +162 -0
  84. package/src/vue/sheet-toolbar.vue +91 -0
  85. package/src/vue/sheet.vue +161 -186
  86. package/src/vue/style.scss +646 -3
  87. package/src/vue/style.ts +11 -0
  88. package/src/vue/use-find-replace.ts +200 -0
  89. package/src/vue/use-formula-ref-select.ts +34 -0
  90. package/src/vue/use-formula-suggest.ts +150 -0
  91. package/src/vue/use-sheet-grid.ts +243 -0
  92. package/src/vue/use-sheet-state.ts +161 -0
  93. package/src/vue/use-sheet-tabs-bar.ts +115 -0
  94. package/src/vue/use-tool-groups.ts +61 -0
  95. package/src/vue/use-tool-popup.ts +150 -0
  96. package/src/vue/use-toolbar-scroll.ts +95 -0
  97. package/dist/core/address.d.ts +0 -60
  98. package/dist/core/address.js +0 -142
  99. package/dist/core/address.js.map +0 -1
  100. package/dist/core/cell-store.d.ts +0 -61
  101. package/dist/core/cell-store.js +0 -135
  102. package/dist/core/cell-store.js.map +0 -1
  103. package/dist/core/command/default-registry.d.ts +0 -10
  104. package/dist/core/command/default-registry.js +0 -18
  105. package/dist/core/command/default-registry.js.map +0 -1
  106. package/dist/core/command/history.d.ts +0 -64
  107. package/dist/core/command/history.js +0 -127
  108. package/dist/core/command/history.js.map +0 -1
  109. package/dist/core/command/merge-cells.d.ts +0 -21
  110. package/dist/core/command/merge-cells.js +0 -74
  111. package/dist/core/command/merge-cells.js.map +0 -1
  112. package/dist/core/command/registry.d.ts +0 -17
  113. package/dist/core/command/registry.js +0 -26
  114. package/dist/core/command/registry.js.map +0 -1
  115. package/dist/core/command/set-cell-formula.d.ts +0 -17
  116. package/dist/core/command/set-cell-formula.js +0 -29
  117. package/dist/core/command/set-cell-formula.js.map +0 -1
  118. package/dist/core/command/set-cell-value.d.ts +0 -22
  119. package/dist/core/command/set-cell-value.js +0 -35
  120. package/dist/core/command/set-cell-value.js.map +0 -1
  121. package/dist/core/command/types.d.ts +0 -68
  122. package/dist/core/events.js +0 -29
  123. package/dist/core/events.js.map +0 -1
  124. package/dist/core/fill.d.ts +0 -34
  125. package/dist/core/fill.js +0 -320
  126. package/dist/core/fill.js.map +0 -1
  127. package/dist/core/formula/ast.d.ts +0 -58
  128. package/dist/core/formula/ast.js +0 -38
  129. package/dist/core/formula/ast.js.map +0 -1
  130. package/dist/core/formula/dependency-graph.d.ts +0 -70
  131. package/dist/core/formula/dependency-graph.js +0 -269
  132. package/dist/core/formula/dependency-graph.js.map +0 -1
  133. package/dist/core/formula/errors.d.ts +0 -25
  134. package/dist/core/formula/errors.js +0 -36
  135. package/dist/core/formula/errors.js.map +0 -1
  136. package/dist/core/formula/evaluator.d.ts +0 -41
  137. package/dist/core/formula/evaluator.js +0 -154
  138. package/dist/core/formula/evaluator.js.map +0 -1
  139. package/dist/core/formula/functions.d.ts +0 -30
  140. package/dist/core/formula/functions.js +0 -209
  141. package/dist/core/formula/functions.js.map +0 -1
  142. package/dist/core/formula/parser.d.ts +0 -7
  143. package/dist/core/formula/parser.js +0 -208
  144. package/dist/core/formula/parser.js.map +0 -1
  145. package/dist/core/formula/tokenizer.d.ts +0 -37
  146. package/dist/core/formula/tokenizer.js +0 -146
  147. package/dist/core/formula/tokenizer.js.map +0 -1
  148. package/dist/core/merge-manager.d.ts +0 -64
  149. package/dist/core/merge-manager.js +0 -111
  150. package/dist/core/merge-manager.js.map +0 -1
  151. package/dist/core/selection.d.ts +0 -31
  152. package/dist/core/selection.js +0 -62
  153. package/dist/core/selection.js.map +0 -1
  154. package/dist/core/sheet.d.ts +0 -116
  155. package/dist/core/sheet.js +0 -224
  156. package/dist/core/sheet.js.map +0 -1
  157. package/dist/core/workbook.d.ts +0 -43
  158. package/dist/core/workbook.js +0 -77
  159. package/dist/core/workbook.js.map +0 -1
  160. package/dist/grid/sheet-grid.d.ts +0 -81
  161. package/dist/grid/sheet-grid.js +0 -331
  162. package/dist/grid/sheet-grid.js.map +0 -1
  163. package/dist/grid/vtable-theme.js +0 -80
  164. package/dist/grid/vtable-theme.js.map +0 -1
  165. package/dist/tools/builtin.js.map +0 -1
  166. package/dist/tools/context.js.map +0 -1
  167. package/dist/tools/registry.js.map +0 -1
  168. package/dist/vue/index.d.ts +0 -2
  169. package/dist/vue/sheet.js.map +0 -1
  170. package/dist/vue/sheet.vue.d.ts +0 -24
  171. package/src/core/__test__/address.test.ts +0 -113
  172. package/src/core/__test__/cell-store.test.ts +0 -97
  173. package/src/core/__test__/command.test.ts +0 -377
  174. package/src/core/__test__/fill.test.ts +0 -140
  175. package/src/core/__test__/formula-adversarial.test.ts +0 -265
  176. package/src/core/__test__/formula-engine.test.ts +0 -470
  177. package/src/core/__test__/formula-functions.test.ts +0 -178
  178. package/src/core/__test__/formula-parser.test.ts +0 -160
  179. package/src/core/__test__/history.test.ts +0 -225
  180. package/src/core/__test__/merge-manager.test.ts +0 -106
  181. package/src/core/__test__/sheet.test.ts +0 -142
  182. package/src/core/address.ts +0 -166
  183. package/src/core/cell-store.ts +0 -173
  184. package/src/core/command/default-registry.ts +0 -15
  185. package/src/core/command/history.ts +0 -167
  186. package/src/core/command/index.ts +0 -7
  187. package/src/core/command/merge-cells.ts +0 -74
  188. package/src/core/command/registry.ts +0 -30
  189. package/src/core/command/set-cell-formula.ts +0 -29
  190. package/src/core/command/set-cell-value.ts +0 -38
  191. package/src/core/command/types.ts +0 -73
  192. package/src/core/events.ts +0 -37
  193. package/src/core/fill.ts +0 -314
  194. package/src/core/formula/ast.ts +0 -66
  195. package/src/core/formula/dependency-graph.ts +0 -329
  196. package/src/core/formula/errors.ts +0 -41
  197. package/src/core/formula/evaluator.ts +0 -219
  198. package/src/core/formula/functions.ts +0 -266
  199. package/src/core/formula/index.ts +0 -7
  200. package/src/core/formula/parser.ts +0 -198
  201. package/src/core/formula/tokenizer.ts +0 -160
  202. package/src/core/merge-manager.ts +0 -158
  203. package/src/core/selection.ts +0 -66
  204. package/src/core/sheet.ts +0 -282
  205. package/src/core/workbook.ts +0 -99
  206. package/src/grid/__test__/canvas-mock.ts +0 -49
  207. package/src/grid/__test__/setup.ts +0 -3
  208. package/src/grid/__test__/sheet-grid-formula.test.ts +0 -140
  209. package/src/grid/__test__/sheet-grid.test.ts +0 -275
  210. package/src/grid/sheet-grid.ts +0 -407
  211. package/src/grid/vtable-theme.ts +0 -61
@@ -0,0 +1,106 @@
1
+ import { useToolbarScroll } from "./use-toolbar-scroll.js";
2
+ import { ArrowLeft, ArrowRight } from "@veltra/icons/normal";
3
+ import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, resolveComponent, resolveDynamicComponent, toDisplayString, toRef, unref, useTemplateRef, withCtx } from "vue";
4
+ import { UIcon } from "@veltra/desktop";
5
+ import { bem } from "@veltra/utils";
6
+ //#region src/vue/sheet-toolbar.vue
7
+ const _hoisted_1 = ["disabled"];
8
+ const _hoisted_2 = [
9
+ "data-tool-id",
10
+ "disabled",
11
+ "title",
12
+ "onClick"
13
+ ];
14
+ const _hoisted_3 = { key: 1 };
15
+ const _hoisted_4 = ["disabled"];
16
+ const _sfc_main = /*@__PURE__*/ defineComponent({
17
+ name: "USheetToolbar",
18
+ __name: "sheet-toolbar",
19
+ props: { groups: {} },
20
+ emits: ["toolClick"],
21
+ setup(__props, { emit: __emit }) {
22
+ /**
23
+ * 工具栏(渲染 defaultToolRegistry 分组工具 + 分隔符,单行溢出滚动)。
24
+ * 纯展示:有 icon 时只渲染图标(title/tooltip 经 UTip + 原生 title 兜底);
25
+ * 无 icon 时回落文字按钮(自定义工具兼容)。
26
+ * 内容超出视口时显示左右箭头(点击步进滚动、滚轮横滚),不换行挤压 grid。
27
+ */
28
+ const props = __props;
29
+ const emit = __emit;
30
+ const cls = bem("sheet");
31
+ const scrollRef = useTemplateRef("scrollRef");
32
+ const listRef = useTemplateRef("listRef");
33
+ const { showNav, canPrev, canNext, scrollByStep } = useToolbarScroll({
34
+ viewportRef: scrollRef,
35
+ listRef,
36
+ content: toRef(props, "groups")
37
+ });
38
+ return (_ctx, _cache) => {
39
+ const _component_u_tip = resolveComponent("u-tip");
40
+ return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).e("toolbar")) }, [
41
+ unref(showNav) ? (openBlock(), createElementBlock("button", {
42
+ key: 0,
43
+ type: "button",
44
+ class: normalizeClass(unref(cls).e("toolbar-nav")),
45
+ disabled: !unref(canPrev),
46
+ "aria-label": "向左滚动工具栏",
47
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(scrollByStep)(-1))
48
+ }, [createVNode(unref(UIcon), null, {
49
+ default: withCtx(() => [createVNode(unref(ArrowLeft))]),
50
+ _: 1
51
+ })], 10, _hoisted_1)) : createCommentVNode("v-if", true),
52
+ createCommentVNode(" 单行滚动视口:内容超出时由左右箭头导航(use-toolbar-scroll),不再换行 "),
53
+ createElementVNode("div", {
54
+ ref_key: "scrollRef",
55
+ ref: scrollRef,
56
+ class: normalizeClass(unref(cls).e("toolbar-scroll"))
57
+ }, [createElementVNode("div", {
58
+ ref_key: "listRef",
59
+ ref: listRef,
60
+ class: normalizeClass(unref(cls).e("toolbar-list"))
61
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.groups, (group, groupIndex) => {
62
+ return openBlock(), createElementBlock(Fragment, { key: group.name }, [groupIndex > 0 ? (openBlock(), createElementBlock("span", {
63
+ key: 0,
64
+ class: normalizeClass(unref(cls).e("toolbar-divider"))
65
+ }, null, 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(group.tools, (item) => {
66
+ return openBlock(), createBlock(_component_u_tip, {
67
+ key: item.tool.id,
68
+ content: item.tool.tooltip ?? item.tool.title,
69
+ trigger: "hover",
70
+ direction: "top",
71
+ alignment: "center",
72
+ "show-delay": 400,
73
+ disabled: item.disabled
74
+ }, {
75
+ default: withCtx(() => [createElementVNode("button", {
76
+ type: "button",
77
+ class: normalizeClass([unref(cls).e("tool"), unref(bem).is("active", item.active)]),
78
+ "data-tool-id": item.tool.id,
79
+ disabled: item.disabled,
80
+ title: item.tool.tooltip ?? item.tool.title,
81
+ onClick: ($event) => emit("toolClick", item.tool, $event)
82
+ }, [item.tool.icon ? (openBlock(), createBlock(resolveDynamicComponent(item.tool.icon), {
83
+ key: 0,
84
+ class: normalizeClass(unref(cls).e("tool-icon"))
85
+ }, null, 8, ["class"])) : (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(item.tool.title), 1))], 10, _hoisted_2)]),
86
+ _: 2
87
+ }, 1032, ["content", "disabled"]);
88
+ }), 128))], 64);
89
+ }), 128))], 2)], 2),
90
+ unref(showNav) ? (openBlock(), createElementBlock("button", {
91
+ key: 1,
92
+ type: "button",
93
+ class: normalizeClass(unref(cls).e("toolbar-nav")),
94
+ disabled: !unref(canNext),
95
+ "aria-label": "向右滚动工具栏",
96
+ onClick: _cache[1] || (_cache[1] = ($event) => unref(scrollByStep)(1))
97
+ }, [createVNode(unref(UIcon), null, {
98
+ default: withCtx(() => [createVNode(unref(ArrowRight))]),
99
+ _: 1
100
+ })], 10, _hoisted_4)) : createCommentVNode("v-if", true)
101
+ ], 2);
102
+ };
103
+ }
104
+ });
105
+ //#endregion
106
+ export { _sfc_main as default };
package/dist/vue/sheet.js CHANGED
@@ -1,18 +1,22 @@
1
- import { rangeContainsAddress } from "../core/address.js";
2
- import { defaultToolRegistry } from "../tools/registry.js";
3
- import { Workbook } from "../core/workbook.js";
4
- import { SheetGrid } from "../grid/sheet-grid.js";
5
- import { createSheetContext } from "../tools/context.js";
6
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, onBeforeUnmount, onMounted, openBlock, ref, renderList, resolveDynamicComponent, shallowRef, toDisplayString, unref, useTemplateRef, watch } from "vue";
7
- import { contextmenu } from "@veltra/desktop";
1
+ import _sfc_main$1 from "./formula-bar.js";
2
+ import { pickAndImportFile } from "./import-file.js";
3
+ import _sfc_main$2 from "./popups/border-popup.js";
4
+ import _sfc_main$3 from "./popups/export-popup.js";
5
+ import _sfc_main$4 from "./popups/fill-color-popup.js";
6
+ import _sfc_main$5 from "./popups/find-popup.js";
7
+ import _sfc_main$6 from "./popups/font-color-popup.js";
8
+ import _sfc_main$7 from "./popups/font-size-popup.js";
9
+ import _sfc_main$8 from "./popups/insert-image-popup.js";
10
+ import _sfc_main$9 from "./sheet-tabs.js";
11
+ import _sfc_main$10 from "./sheet-toolbar.js";
12
+ import { useSheetGrid } from "./use-sheet-grid.js";
13
+ import { useSheetState } from "./use-sheet-state.js";
14
+ import { useToolGroups } from "./use-tool-groups.js";
15
+ import { useToolPopup } from "./use-tool-popup.js";
16
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, ref, toDisplayString, unref, useTemplateRef, watch, withCtx, withModifiers } from "vue";
17
+ import { UDropdown } from "@veltra/desktop";
8
18
  import { bem } from "@veltra/utils";
9
19
  //#region src/vue/sheet.vue
10
- const _hoisted_1 = [
11
- "disabled",
12
- "title",
13
- "onClick"
14
- ];
15
- const _hoisted_2 = ["onClick"];
16
20
  const _sfc_main = /*@__PURE__*/ defineComponent({
17
21
  name: "USheet",
18
22
  __name: "sheet",
@@ -24,6 +28,10 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
24
28
  type: Boolean,
25
29
  default: true
26
30
  },
31
+ showFormulaBar: {
32
+ type: Boolean,
33
+ default: true
34
+ },
27
35
  showTabs: {
28
36
  type: Boolean,
29
37
  default: true
@@ -34,178 +42,150 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
34
42
  const props = __props;
35
43
  const emit = __emit;
36
44
  const cls = bem("sheet");
37
- /** 工作簿:外部传入或内部自建(单 sheet) */
38
- const internalWorkbook = new Workbook();
39
- const workbook = computed(() => props.workbook ?? internalWorkbook);
40
- /** 激活 sheet 索引(镜像 workbook.activeSheetIndex,经事件同步) */
41
- const activeIndex = ref(workbook.value.activeSheetIndex);
42
- /** sheet 列表(tabs 渲染;由 sheets-change 同步) */
43
- const sheetList = shallowRef(workbook.value.getSheets());
44
- const activeSheet = computed(() => sheetList.value[activeIndex.value] ?? workbook.value.activeSheet);
45
- /** 工具上下文:动态解析活动 sheet,tab 切换后自动指向当前 sheet */
46
- const context = createSheetContext(() => activeSheet.value);
47
- const gridRef = useTemplateRef("gridRef");
48
- let grid;
49
- const stateTick = ref(0);
50
- const bump = () => {
51
- stateTick.value++;
52
- };
53
- let disposeSheetEvents = [];
54
- /** 订阅活动 sheet 的状态源(tab 切换 / 工作簿变更时重绑) */
55
- function bindSheetEvents(sheet) {
56
- for (const dispose of disposeSheetEvents) dispose();
57
- disposeSheetEvents = [
58
- sheet.on("selection-change", bump),
59
- sheet.on("history-change", bump),
60
- sheet.on("cell-change", bump),
61
- sheet.on("merge-change", bump)
62
- ];
63
- }
64
- let disposeWorkbookEvents = [];
65
- function bindWorkbookEvents(wb) {
66
- for (const dispose of disposeWorkbookEvents) dispose();
67
- disposeWorkbookEvents = [wb.on("sheets-change", ({ sheets }) => {
68
- sheetList.value = sheets;
69
- bump();
70
- }), wb.on("active-sheet-change", ({ sheet, index }) => {
71
- activeIndex.value = index;
72
- bindSheetEvents(sheet);
73
- rebuildGrid();
74
- bump();
75
- emit("active-sheet-change", {
76
- sheet,
77
- index
78
- });
79
- })];
80
- }
81
- const offRegistryChange = defaultToolRegistry.onChange(bump);
82
- const toolGroups = computed(() => {
83
- stateTick.value;
84
- return defaultToolRegistry.getGroups().map((group) => ({
85
- name: group.name,
86
- tools: group.tools.map((tool) => ({
87
- tool,
88
- visible: tool.visible?.(context) ?? true,
89
- disabled: tool.disabled?.(context) ?? false
90
- })).filter((item) => item.visible)
91
- })).filter((group) => group.tools.length > 0);
45
+ /** 根容器 ref:Ctrl/Cmd+F 判定焦点是否在本实例内(#6,避免劫持浏览器查找) */
46
+ const rootRef = useTemplateRef("rootRef");
47
+ const { workbook, activeIndex, sheetList, activeSheet, context, stateTick, syncFromWorkbook } = useSheetState(props, emit, {
48
+ onBeforeSheetChange: () => closePopup(),
49
+ rebuildGrid: () => rebuildGrid(),
50
+ activateGrid: () => activateGrid(),
51
+ pruneCache: (sheets) => pruneCache(sheets)
92
52
  });
93
- function handleToolClick(tool) {
94
- if (tool.disabled?.(context)) return;
95
- tool.onClick(context);
96
- }
97
- function handleTabClick(index) {
98
- if (index === activeIndex.value) return;
99
- const sheet = sheetList.value[index];
100
- if (sheet) workbook.value.activateSheet(sheet.name);
101
- }
102
- function handleContextMenu(info) {
103
- if (info.addr) {
104
- if (!context.getSelection().ranges.some((range) => rangeContainsAddress(range, info.addr))) context.selectCell(info.addr);
53
+ const { popupTool, popupAnchor, closePopup, handleToolClick: openOrRunTool } = useToolPopup(context, rootRef);
54
+ const parsing = ref(false);
55
+ const parseProgress = ref({
56
+ done: 0,
57
+ total: 0
58
+ });
59
+ const parseText = computed(() => parseProgress.value.total > 0 ? `正在解析… ${parseProgress.value.done}/${parseProgress.value.total}` : "正在读取文件结构…");
60
+ /** 导入无弹层:直接系统文件选择;其余工具走 useToolPopup */
61
+ function handleToolClick(tool, event) {
62
+ if (tool.id === "import") {
63
+ if (tool.disabled?.(context)) return;
64
+ pickAndImportFile({
65
+ workbook: workbook.value,
66
+ activeSheet: activeSheet.value,
67
+ parsing,
68
+ parseProgress,
69
+ onCsvImported: () => rebuildGrid(),
70
+ onWorkbookReplaced: () => syncFromWorkbook()
71
+ });
72
+ return;
105
73
  }
106
- const mergeTool = defaultToolRegistry.get("merge");
107
- const unmergeTool = defaultToolRegistry.get("unmerge");
108
- contextmenu.pop({
109
- mousePosition: {
110
- x: info.x,
111
- y: info.y
112
- },
113
- width: 180,
114
- menus: [{
115
- label: "合并单元格",
116
- disabled: mergeTool?.disabled?.(context) ?? true,
117
- callback: () => mergeTool?.onClick(context)
118
- }, {
119
- label: "取消合并单元格",
120
- disabled: unmergeTool?.disabled?.(context) ?? true,
121
- callback: () => unmergeTool?.onClick(context)
122
- }]
123
- });
124
- }
125
- function rebuildGrid() {
126
- const container = gridRef.value;
127
- if (!container) return;
128
- grid?.release();
129
- grid = new SheetGrid({
130
- container,
131
- sheet: activeSheet.value,
132
- rows: props.rows,
133
- cols: props.cols,
134
- onContextMenu: handleContextMenu
135
- });
74
+ openOrRunTool(tool, event);
136
75
  }
137
- onMounted(() => {
138
- bindWorkbookEvents(workbook.value);
139
- bindSheetEvents(activeSheet.value);
140
- rebuildGrid();
141
- });
142
- watch(() => [props.rows, props.cols], rebuildGrid);
143
- watch(() => props.workbook, (wb, prev) => {
144
- if (wb === prev) return;
145
- activeIndex.value = workbook.value.activeSheetIndex;
146
- sheetList.value = workbook.value.getSheets();
147
- bindWorkbookEvents(workbook.value);
148
- bindSheetEvents(activeSheet.value);
149
- rebuildGrid();
150
- bump();
76
+ const popupDropdownRef = useTemplateRef("popupDropdownRef");
77
+ watch(popupTool, () => {
78
+ const dropdown = popupDropdownRef.value;
79
+ if (!dropdown) return;
80
+ if (popupTool.value) dropdown.open({ trigger: popupAnchor.value ?? void 0 });
81
+ else dropdown.close();
151
82
  });
152
- onBeforeUnmount(() => {
153
- offRegistryChange();
154
- for (const dispose of disposeWorkbookEvents) dispose();
155
- for (const dispose of disposeSheetEvents) dispose();
156
- grid?.release();
157
- grid = void 0;
83
+ /** UDropdown 内部关闭(滚动 / resize / transition 结束)→ 同步状态并提交面板事务 */
84
+ function handlePopupVisible(visible) {
85
+ if (!visible) closePopup();
86
+ }
87
+ const toolGroups = useToolGroups(context, stateTick);
88
+ const gridRef = useTemplateRef("gridRef");
89
+ const formulaBarRef = useTemplateRef("formulaBarRef");
90
+ const { rebuildGrid, activateGrid, pruneCache, getGrid } = useSheetGrid({
91
+ props,
92
+ gridRef,
93
+ getActiveSheet: () => activeSheet.value,
94
+ context,
95
+ formulaBarRef
158
96
  });
159
97
  __expose({
160
98
  workbook,
161
99
  getActiveSheet: () => activeSheet.value,
162
100
  getContext: () => context,
163
- getGrid: () => grid
101
+ getGrid
164
102
  });
165
103
  return (_ctx, _cache) => {
166
- return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).b) }, [
167
- __props.showToolbar ? (openBlock(), createElementBlock("div", {
168
- key: 0,
169
- class: normalizeClass(unref(cls).e("toolbar"))
170
- }, [(openBlock(true), createElementBlock(Fragment, null, renderList(toolGroups.value, (group, groupIndex) => {
171
- return openBlock(), createElementBlock(Fragment, { key: group.name }, [groupIndex > 0 ? (openBlock(), createElementBlock("span", {
104
+ return openBlock(), createElementBlock("div", {
105
+ ref_key: "rootRef",
106
+ ref: rootRef,
107
+ class: normalizeClass(unref(cls).b)
108
+ }, [
109
+ createElementVNode("div", { class: normalizeClass(unref(cls).e("toolbar-wrap")) }, [
110
+ __props.showToolbar ? (openBlock(), createBlock(_sfc_main$10, {
172
111
  key: 0,
173
- class: normalizeClass(unref(cls).e("toolbar-divider"))
174
- }, null, 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(group.tools, (item) => {
175
- return openBlock(), createElementBlock("button", {
176
- key: item.tool.id,
177
- type: "button",
178
- class: normalizeClass(unref(cls).e("tool")),
179
- disabled: item.disabled,
180
- title: item.tool.tooltip ?? item.tool.title,
181
- onClick: ($event) => handleToolClick(item.tool)
182
- }, [item.tool.icon ? (openBlock(), createBlock(resolveDynamicComponent(item.tool.icon), {
112
+ groups: unref(toolGroups),
113
+ onToolClick: handleToolClick
114
+ }, null, 8, ["groups"])) : createCommentVNode("v-if", true),
115
+ createCommentVNode(" 弹层型工具面板(填充/边框/字体色/字号/查找/插入图片/导出):UDropdown(Teleport 到\n #pop-container + floating-ui 定位:锚点跟随触发按钮、自动翻转/边界位移;\n 触发元素滚动/窗口缩放时自动关闭)。面板交互走 SheetContext 命令入口。\n 导入无弹层:点击直接系统文件选择(见 handleToolClick → pickAndImportFile) "),
116
+ createVNode(unref(UDropdown), {
117
+ ref_key: "popupDropdownRef",
118
+ ref: popupDropdownRef,
119
+ trigger: "custom",
120
+ visible: unref(popupTool) !== null,
121
+ width: "auto",
122
+ "onUpdate:visible": handlePopupVisible
123
+ }, {
124
+ content: withCtx(() => [unref(popupTool) ? (openBlock(), createElementBlock("div", {
125
+ key: 0,
126
+ class: normalizeClass(unref(cls).e("popup")),
127
+ onClick: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"]))
128
+ }, [unref(popupTool).popup === "fill-color" ? (openBlock(), createBlock(_sfc_main$4, {
183
129
  key: 0,
184
- class: normalizeClass(unref(cls).e("tool-icon"))
185
- }, null, 8, ["class"])) : createCommentVNode("v-if", true), createElementVNode("span", null, toDisplayString(item.tool.title), 1)], 10, _hoisted_1);
186
- }), 128))], 64);
187
- }), 128))], 2)) : createCommentVNode("v-if", true),
130
+ context: unref(context)
131
+ }, null, 8, ["context"])) : unref(popupTool).popup === "border" ? (openBlock(), createBlock(_sfc_main$2, {
132
+ key: 1,
133
+ context: unref(context)
134
+ }, null, 8, ["context"])) : unref(popupTool).popup === "font-color" ? (openBlock(), createBlock(_sfc_main$6, {
135
+ key: 2,
136
+ context: unref(context)
137
+ }, null, 8, ["context"])) : unref(popupTool).popup === "font-size" ? (openBlock(), createBlock(_sfc_main$7, {
138
+ key: 3,
139
+ context: unref(context)
140
+ }, null, 8, ["context"])) : unref(popupTool).popup === "find" ? (openBlock(), createBlock(_sfc_main$5, {
141
+ key: 4,
142
+ sheet: unref(activeSheet),
143
+ context: unref(context),
144
+ onClose: unref(closePopup)
145
+ }, null, 8, [
146
+ "sheet",
147
+ "context",
148
+ "onClose"
149
+ ])) : unref(popupTool).popup === "insert-image" ? (openBlock(), createBlock(_sfc_main$8, {
150
+ key: 5,
151
+ context: unref(context),
152
+ onClose: unref(closePopup)
153
+ }, null, 8, ["context", "onClose"])) : unref(popupTool).popup === "export" ? (openBlock(), createBlock(_sfc_main$3, {
154
+ key: 6,
155
+ context: unref(context),
156
+ onClose: unref(closePopup)
157
+ }, null, 8, ["context", "onClose"])) : createCommentVNode("v-if", true)], 2)) : createCommentVNode("v-if", true)]),
158
+ _: 1
159
+ }, 8, ["visible"])
160
+ ], 2),
161
+ __props.showFormulaBar ? (openBlock(), createBlock(_sfc_main$1, {
162
+ key: 0,
163
+ ref_key: "formulaBarRef",
164
+ ref: formulaBarRef,
165
+ sheet: unref(activeSheet),
166
+ context: unref(context)
167
+ }, null, 8, ["sheet", "context"])) : createCommentVNode("v-if", true),
188
168
  createElementVNode("div", {
189
169
  ref_key: "gridRef",
190
170
  ref: gridRef,
191
171
  class: normalizeClass(unref(cls).e("grid"))
192
- }, null, 2),
193
- __props.showTabs ? (openBlock(), createElementBlock("div", {
172
+ }, [createCommentVNode(" 导入解析覆盖层(自绘,不动 desktop Loading 组件):遮罩 + 动画 + 文字\n 同一层,动画在上、文字在下,不存在被遮罩掩盖的问题 "), parsing.value ? (openBlock(), createElementBlock("div", {
173
+ key: 0,
174
+ class: normalizeClass(unref(cls).e("loading-mask"))
175
+ }, [createElementVNode("div", { class: normalizeClass(unref(cls).e("loading-spinner")) }, null, 2), createElementVNode("div", { class: normalizeClass(unref(cls).e("loading-text")) }, toDisplayString(parseText.value), 3)], 2)) : createCommentVNode("v-if", true)], 2),
176
+ __props.showTabs ? (openBlock(), createBlock(_sfc_main$9, {
194
177
  key: 1,
195
- class: normalizeClass(unref(cls).e("tabs"))
196
- }, [(openBlock(true), createElementBlock(Fragment, null, renderList(sheetList.value, (sheet, index) => {
197
- return openBlock(), createElementBlock("button", {
198
- key: sheet.name,
199
- type: "button",
200
- class: normalizeClass([unref(cls).e("tab"), unref(bem).is("active", index === activeIndex.value)]),
201
- onClick: ($event) => handleTabClick(index)
202
- }, toDisplayString(sheet.name), 11, _hoisted_2);
203
- }), 128))], 2)) : createCommentVNode("v-if", true)
178
+ workbook: unref(workbook),
179
+ "sheet-list": unref(sheetList),
180
+ "active-index": unref(activeIndex)
181
+ }, null, 8, [
182
+ "workbook",
183
+ "sheet-list",
184
+ "active-index"
185
+ ])) : createCommentVNode("v-if", true)
204
186
  ], 2);
205
187
  };
206
188
  }
207
189
  });
208
190
  //#endregion
209
191
  export { _sfc_main as default };
210
-
211
- //# sourceMappingURL=sheet.js.map
@@ -1 +1,11 @@
1
- import "@veltra/desktop/components/contextmenu/style";
1
+ import "@veltra/desktop/components/contextmenu/style";
2
+ import "@veltra/desktop/components/dropdown/style";
3
+ import "@veltra/desktop/components/number-input/style";
4
+ import "@veltra/desktop/components/palette/style";
5
+ import "@veltra/desktop/components/scroll/style";
6
+ import "@veltra/desktop/components/tip/style";
7
+ import "@veltra/desktop/components/loading/style";
8
+ import "@veltra/desktop/components/message/style";
9
+ import "@veltra/desktop/components/input/style";
10
+ import "@veltra/desktop/components/file-picker/style";
11
+ import "@veltra/desktop/components/icon/style";
package/dist/vue/style.js CHANGED
@@ -1,2 +1,12 @@
1
1
  import "./style2.css";
2
2
  import "@veltra/desktop/components/contextmenu/style";
3
+ import "@veltra/desktop/components/dropdown/style";
4
+ import "@veltra/desktop/components/number-input/style";
5
+ import "@veltra/desktop/components/palette/style";
6
+ import "@veltra/desktop/components/scroll/style";
7
+ import "@veltra/desktop/components/tip/style";
8
+ import "@veltra/desktop/components/loading/style";
9
+ import "@veltra/desktop/components/message/style";
10
+ import "@veltra/desktop/components/input/style";
11
+ import "@veltra/desktop/components/file-picker/style";
12
+ import "@veltra/desktop/components/icon/style";