@veltra/sheet 2.0.1 → 2.2.0

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 (339) hide show
  1. package/dist/components/report/binding-badge.js +76 -0
  2. package/dist/components/report/designer/cell-coords.js +46 -0
  3. package/dist/components/report/designer/col-widths.js +15 -0
  4. package/dist/components/report/designer/conditional-rules/helpers.js +139 -0
  5. package/dist/components/report/designer/drop-highlight-overlay.js +76 -0
  6. package/dist/components/report/designer/float-panel.js +385 -0
  7. package/dist/components/report/designer/role.js +17 -0
  8. package/dist/components/report/designer/rule-preview.js +33 -0
  9. package/dist/components/report/designer/rule-row.js +269 -0
  10. package/dist/components/report/designer/rules-dialog.js +135 -0
  11. package/dist/components/report/designer/topology-overlay.js +122 -0
  12. package/dist/components/report/designer/topology.js +64 -0
  13. package/dist/components/report/designer/use-grid-overlay.js +75 -0
  14. package/dist/components/report/designer-hub.js +177 -0
  15. package/dist/components/report/field-panel-helpers.js +33 -0
  16. package/dist/components/report/field-panel.js +132 -0
  17. package/dist/components/report/filter-bar.js +74 -0
  18. package/dist/components/report/hub-connection-form.js +145 -0
  19. package/dist/components/report/hub-dataset-editor.js +394 -0
  20. package/dist/components/report/report-designer.js +343 -0
  21. package/dist/components/report/report-viewer.js +111 -0
  22. package/dist/components/report/style.d.ts +17 -0
  23. package/dist/components/report/style.js +18 -0
  24. package/dist/components/report/style2.css +869 -0
  25. package/dist/components/report/use-report-designer.js +360 -0
  26. package/dist/components/report/use-report-viewer.js +50 -0
  27. package/dist/components/sheet/formula-bar.js +393 -0
  28. package/dist/components/sheet/formula-suggest-list.js +66 -0
  29. package/dist/components/sheet/import-file.js +140 -0
  30. package/dist/components/sheet/insert-count-menu-item.js +68 -0
  31. package/dist/components/sheet/insert-image.js +79 -0
  32. package/dist/components/sheet/popup-helpers.js +73 -0
  33. package/dist/components/sheet/popups/border-popup.js +75 -0
  34. package/dist/components/sheet/popups/border-preset-glyph.js +106 -0
  35. package/dist/components/sheet/popups/export-popup.js +51 -0
  36. package/dist/components/sheet/popups/fill-color-popup.js +37 -0
  37. package/dist/components/sheet/popups/find-popup.js +113 -0
  38. package/dist/components/sheet/popups/font-color-popup.js +37 -0
  39. package/dist/components/sheet/popups/font-size-popup.js +63 -0
  40. package/dist/components/sheet/popups/import.worker.d.ts +21 -0
  41. package/dist/components/sheet/popups/import.worker.js +41 -0
  42. package/dist/components/sheet/popups/insert-image-popup.js +38 -0
  43. package/dist/components/sheet/sheet-context-menu.js +200 -0
  44. package/dist/components/sheet/sheet-tabs.js +162 -0
  45. package/dist/components/sheet/sheet-toolbar.js +106 -0
  46. package/dist/components/sheet/sheet.js +198 -0
  47. package/dist/components/sheet/style.d.ts +11 -0
  48. package/dist/components/sheet/style.js +12 -0
  49. package/dist/components/sheet/style2.css +654 -0
  50. package/dist/components/sheet/use-find-replace.js +161 -0
  51. package/dist/components/sheet/use-formula-ref-select.js +37 -0
  52. package/dist/components/sheet/use-formula-suggest.js +126 -0
  53. package/dist/components/sheet/use-sheet-grid.js +188 -0
  54. package/dist/components/sheet/use-sheet-state.js +122 -0
  55. package/dist/components/sheet/use-sheet-tabs-bar.js +90 -0
  56. package/dist/components/sheet/use-tool-groups.js +42 -0
  57. package/dist/components/sheet/use-tool-popup.js +123 -0
  58. package/dist/components/sheet/use-toolbar-scroll.js +72 -0
  59. package/dist/index.d.ts +18 -26
  60. package/dist/index.js +14 -24
  61. package/dist/report/binding.d.ts +45 -0
  62. package/dist/report/binding.js +175 -0
  63. package/dist/report/connector.d.ts +66 -0
  64. package/dist/report/connector.js +159 -0
  65. package/dist/report/export-xlsx.d.ts +19 -0
  66. package/dist/report/export-xlsx.js +95 -0
  67. package/dist/report/filter-bar.d.ts +10 -0
  68. package/dist/report/filter-bar.js +31 -0
  69. package/dist/report/index.d.ts +12 -0
  70. package/dist/report/params.d.ts +13 -0
  71. package/dist/report/params.js +61 -0
  72. package/dist/report/render/aggregate.js +157 -0
  73. package/dist/report/render/builder.d.ts +12 -0
  74. package/dist/report/render/builder.js +139 -0
  75. package/dist/report/render/coordinate.d.ts +25 -0
  76. package/dist/report/render/coordinate.js +733 -0
  77. package/dist/report/render/index.d.ts +14 -0
  78. package/dist/report/render/index.js +21 -0
  79. package/dist/report/render/style-resolver.js +50 -0
  80. package/dist/report/render/template-index.d.ts +24 -0
  81. package/dist/report/render/template-index.js +137 -0
  82. package/dist/report/rules/evaluate.d.ts +25 -0
  83. package/dist/report/rules/evaluate.js +82 -0
  84. package/dist/report/rules/index.d.ts +2 -0
  85. package/dist/report/template.d.ts +59 -0
  86. package/dist/report/template.js +80 -0
  87. package/dist/report/types.d.ts +85 -0
  88. package/dist/tools/builtin.js +279 -8
  89. package/dist/tools/context.d.ts +54 -11
  90. package/dist/tools/context.js +28 -5
  91. package/dist/tools/download.js +68 -0
  92. package/dist/tools/export.worker.d.ts +16 -0
  93. package/dist/tools/export.worker.js +29 -0
  94. package/dist/tools/registry.d.ts +7 -4
  95. package/dist/tools/registry.js +1 -3
  96. package/dist/types/index.d.ts +3 -1
  97. package/dist/types/report-designer.d.ts +36 -0
  98. package/dist/types/report-viewer.d.ts +38 -0
  99. package/dist/types/sheet.d.ts +22 -5
  100. package/package.json +10 -7
  101. package/src/components/report/__test__/conditional-rules-helpers.test.ts +87 -0
  102. package/src/components/report/__test__/field-panel-helpers.test.ts +65 -0
  103. package/src/components/report/__test__/float-panel-position.test.ts +45 -0
  104. package/src/components/report/__test__/report-designer.test.ts +388 -0
  105. package/src/components/report/__test__/report-viewer.test.ts +334 -0
  106. package/src/components/report/__test__/topology.test.ts +143 -0
  107. package/src/components/report/__test__/use-report-designer.test.ts +565 -0
  108. package/src/components/report/binding-badge.ts +73 -0
  109. package/src/components/report/designer/cell-coords.ts +94 -0
  110. package/src/components/report/designer/col-widths.ts +33 -0
  111. package/src/components/report/designer/conditional-rules/helpers.ts +186 -0
  112. package/src/components/report/designer/drop-highlight-overlay.vue +74 -0
  113. package/src/components/report/designer/float-panel.vue +387 -0
  114. package/src/components/report/designer/role.ts +32 -0
  115. package/src/components/report/designer/rule-preview.vue +40 -0
  116. package/src/components/report/designer/rule-row.vue +252 -0
  117. package/src/components/report/designer/rules-dialog.vue +126 -0
  118. package/src/components/report/designer/topology-overlay.vue +127 -0
  119. package/src/components/report/designer/topology.ts +124 -0
  120. package/src/components/report/designer/use-grid-overlay.ts +113 -0
  121. package/src/components/report/designer-hub.vue +198 -0
  122. package/src/components/report/field-panel-helpers.ts +44 -0
  123. package/src/components/report/field-panel.vue +136 -0
  124. package/src/components/report/filter-bar.vue +77 -0
  125. package/src/components/report/hub-connection-form.vue +124 -0
  126. package/src/components/report/hub-dataset-editor.vue +369 -0
  127. package/src/components/report/index.ts +2 -0
  128. package/src/components/report/report-designer.vue +356 -0
  129. package/src/components/report/report-viewer.vue +128 -0
  130. package/src/components/report/style-designer.scss +583 -0
  131. package/src/components/report/style-hub.scss +292 -0
  132. package/src/components/report/style-viewer.scss +104 -0
  133. package/src/components/report/style.scss +3 -0
  134. package/src/components/report/style.ts +20 -0
  135. package/src/components/report/use-report-designer.ts +547 -0
  136. package/src/components/report/use-report-viewer.ts +79 -0
  137. package/src/components/sheet/__test__/formula-bar.test.ts +474 -0
  138. package/src/components/sheet/__test__/import-file.test.ts +183 -0
  139. package/src/components/sheet/__test__/insert-count-menu-item.test.ts +123 -0
  140. package/src/components/sheet/__test__/insert-image-popup.test.ts +89 -0
  141. package/src/components/sheet/__test__/insert-image.test.ts +100 -0
  142. package/src/components/sheet/__test__/sheet-component.test.ts +993 -0
  143. package/src/components/sheet/__test__/sheet-context-menu.test.ts +206 -0
  144. package/src/components/sheet/__test__/use-formula-ref-select.test.ts +35 -0
  145. package/src/components/sheet/__test__/use-formula-suggest.test.ts +83 -0
  146. package/src/components/sheet/formula-bar.vue +473 -0
  147. package/src/components/sheet/formula-suggest-list.vue +64 -0
  148. package/src/components/sheet/import-file.ts +173 -0
  149. package/src/components/sheet/insert-count-menu-item.vue +69 -0
  150. package/src/components/sheet/insert-image.ts +90 -0
  151. package/src/components/sheet/parsing.ts +11 -0
  152. package/src/components/sheet/popup-helpers.ts +50 -0
  153. package/src/components/sheet/popups/border-popup.vue +93 -0
  154. package/src/components/sheet/popups/border-preset-glyph.vue +111 -0
  155. package/src/components/sheet/popups/export-popup.vue +52 -0
  156. package/src/components/sheet/popups/fill-color-popup.vue +39 -0
  157. package/src/components/sheet/popups/find-popup.vue +111 -0
  158. package/src/components/sheet/popups/font-color-popup.vue +39 -0
  159. package/src/components/sheet/popups/font-size-popup.vue +52 -0
  160. package/src/components/sheet/popups/import.worker.ts +66 -0
  161. package/src/components/sheet/popups/insert-image-popup.vue +39 -0
  162. package/src/components/sheet/sheet-context-menu.ts +229 -0
  163. package/src/components/sheet/sheet-tabs.vue +162 -0
  164. package/src/components/sheet/sheet-toolbar.vue +91 -0
  165. package/src/components/sheet/sheet.vue +211 -0
  166. package/src/components/sheet/style.scss +737 -0
  167. package/src/components/sheet/style.ts +13 -0
  168. package/src/components/sheet/use-find-replace.ts +200 -0
  169. package/src/components/sheet/use-formula-ref-select.ts +34 -0
  170. package/src/components/sheet/use-formula-suggest.ts +150 -0
  171. package/src/components/sheet/use-sheet-grid.ts +247 -0
  172. package/src/components/sheet/use-sheet-state.ts +161 -0
  173. package/src/components/sheet/use-sheet-tabs-bar.ts +115 -0
  174. package/src/components/sheet/use-tool-groups.ts +61 -0
  175. package/src/components/sheet/use-tool-popup.ts +150 -0
  176. package/src/components/sheet/use-toolbar-scroll.ts +95 -0
  177. package/src/env.d.ts +11 -0
  178. package/src/index.ts +39 -14
  179. package/src/report/__test__/binding.test.ts +218 -0
  180. package/src/report/__test__/connector.test.ts +218 -0
  181. package/src/report/__test__/export-xlsx.test.ts +118 -0
  182. package/src/report/__test__/filter-bar.test.ts +58 -0
  183. package/src/report/__test__/params.test.ts +156 -0
  184. package/src/report/__test__/render.test.ts +728 -0
  185. package/src/report/__test__/rules.test.ts +131 -0
  186. package/src/report/__test__/template.test.ts +355 -0
  187. package/src/report/binding.ts +243 -0
  188. package/src/report/connector.ts +205 -0
  189. package/src/report/export-xlsx.ts +118 -0
  190. package/src/report/filter-bar.ts +36 -0
  191. package/src/report/index.ts +13 -0
  192. package/src/report/params.ts +96 -0
  193. package/src/report/render/__test__/aggregate.test.ts +16 -0
  194. package/src/report/render/__test__/coordinate.test.ts +405 -0
  195. package/src/report/render/aggregate.ts +240 -0
  196. package/src/report/render/builder.ts +211 -0
  197. package/src/report/render/coordinate.ts +1239 -0
  198. package/src/report/render/index.ts +30 -0
  199. package/src/report/render/style-resolver.ts +68 -0
  200. package/src/report/render/template-index.ts +200 -0
  201. package/src/report/rules/evaluate.ts +113 -0
  202. package/src/report/rules/index.ts +7 -0
  203. package/src/report/template.ts +141 -0
  204. package/src/report/types.ts +96 -0
  205. package/src/tools/__test__/builtin.test.ts +208 -66
  206. package/src/tools/__test__/context.test.ts +62 -2
  207. package/src/tools/builtin.ts +350 -6
  208. package/src/tools/context.ts +89 -11
  209. package/src/tools/download.ts +82 -0
  210. package/src/tools/export.worker.ts +61 -0
  211. package/src/tools/registry.ts +16 -1
  212. package/src/types/index.ts +2 -0
  213. package/src/types/report-designer.ts +36 -0
  214. package/src/types/report-viewer.ts +37 -0
  215. package/src/types/sheet.ts +26 -3
  216. package/dist/core/address.d.ts +0 -60
  217. package/dist/core/address.js +0 -142
  218. package/dist/core/address.js.map +0 -1
  219. package/dist/core/cell-store.d.ts +0 -61
  220. package/dist/core/cell-store.js +0 -135
  221. package/dist/core/cell-store.js.map +0 -1
  222. package/dist/core/command/default-registry.d.ts +0 -10
  223. package/dist/core/command/default-registry.js +0 -18
  224. package/dist/core/command/default-registry.js.map +0 -1
  225. package/dist/core/command/history.d.ts +0 -64
  226. package/dist/core/command/history.js +0 -127
  227. package/dist/core/command/history.js.map +0 -1
  228. package/dist/core/command/merge-cells.d.ts +0 -21
  229. package/dist/core/command/merge-cells.js +0 -74
  230. package/dist/core/command/merge-cells.js.map +0 -1
  231. package/dist/core/command/registry.d.ts +0 -17
  232. package/dist/core/command/registry.js +0 -26
  233. package/dist/core/command/registry.js.map +0 -1
  234. package/dist/core/command/set-cell-formula.d.ts +0 -17
  235. package/dist/core/command/set-cell-formula.js +0 -29
  236. package/dist/core/command/set-cell-formula.js.map +0 -1
  237. package/dist/core/command/set-cell-value.d.ts +0 -22
  238. package/dist/core/command/set-cell-value.js +0 -35
  239. package/dist/core/command/set-cell-value.js.map +0 -1
  240. package/dist/core/command/types.d.ts +0 -68
  241. package/dist/core/events.js +0 -29
  242. package/dist/core/events.js.map +0 -1
  243. package/dist/core/fill.d.ts +0 -34
  244. package/dist/core/fill.js +0 -320
  245. package/dist/core/fill.js.map +0 -1
  246. package/dist/core/formula/ast.d.ts +0 -58
  247. package/dist/core/formula/ast.js +0 -38
  248. package/dist/core/formula/ast.js.map +0 -1
  249. package/dist/core/formula/dependency-graph.d.ts +0 -70
  250. package/dist/core/formula/dependency-graph.js +0 -269
  251. package/dist/core/formula/dependency-graph.js.map +0 -1
  252. package/dist/core/formula/errors.d.ts +0 -25
  253. package/dist/core/formula/errors.js +0 -36
  254. package/dist/core/formula/errors.js.map +0 -1
  255. package/dist/core/formula/evaluator.d.ts +0 -41
  256. package/dist/core/formula/evaluator.js +0 -154
  257. package/dist/core/formula/evaluator.js.map +0 -1
  258. package/dist/core/formula/functions.d.ts +0 -30
  259. package/dist/core/formula/functions.js +0 -209
  260. package/dist/core/formula/functions.js.map +0 -1
  261. package/dist/core/formula/parser.d.ts +0 -7
  262. package/dist/core/formula/parser.js +0 -208
  263. package/dist/core/formula/parser.js.map +0 -1
  264. package/dist/core/formula/tokenizer.d.ts +0 -37
  265. package/dist/core/formula/tokenizer.js +0 -146
  266. package/dist/core/formula/tokenizer.js.map +0 -1
  267. package/dist/core/merge-manager.d.ts +0 -64
  268. package/dist/core/merge-manager.js +0 -111
  269. package/dist/core/merge-manager.js.map +0 -1
  270. package/dist/core/selection.d.ts +0 -31
  271. package/dist/core/selection.js +0 -62
  272. package/dist/core/selection.js.map +0 -1
  273. package/dist/core/sheet.d.ts +0 -116
  274. package/dist/core/sheet.js +0 -224
  275. package/dist/core/sheet.js.map +0 -1
  276. package/dist/core/workbook.d.ts +0 -43
  277. package/dist/core/workbook.js +0 -77
  278. package/dist/core/workbook.js.map +0 -1
  279. package/dist/grid/sheet-grid.d.ts +0 -81
  280. package/dist/grid/sheet-grid.js +0 -331
  281. package/dist/grid/sheet-grid.js.map +0 -1
  282. package/dist/grid/vtable-theme.js +0 -80
  283. package/dist/grid/vtable-theme.js.map +0 -1
  284. package/dist/tools/builtin.js.map +0 -1
  285. package/dist/tools/context.js.map +0 -1
  286. package/dist/tools/registry.js.map +0 -1
  287. package/dist/vue/index.d.ts +0 -2
  288. package/dist/vue/sheet.js +0 -211
  289. package/dist/vue/sheet.js.map +0 -1
  290. package/dist/vue/sheet.vue.d.ts +0 -24
  291. package/dist/vue/style.d.ts +0 -1
  292. package/dist/vue/style.js +0 -2
  293. package/dist/vue/style2.css +0 -93
  294. package/src/core/__test__/address.test.ts +0 -113
  295. package/src/core/__test__/cell-store.test.ts +0 -97
  296. package/src/core/__test__/command.test.ts +0 -377
  297. package/src/core/__test__/fill.test.ts +0 -140
  298. package/src/core/__test__/formula-adversarial.test.ts +0 -265
  299. package/src/core/__test__/formula-engine.test.ts +0 -470
  300. package/src/core/__test__/formula-functions.test.ts +0 -178
  301. package/src/core/__test__/formula-parser.test.ts +0 -160
  302. package/src/core/__test__/history.test.ts +0 -225
  303. package/src/core/__test__/merge-manager.test.ts +0 -106
  304. package/src/core/__test__/sheet.test.ts +0 -142
  305. package/src/core/address.ts +0 -166
  306. package/src/core/cell-store.ts +0 -173
  307. package/src/core/command/default-registry.ts +0 -15
  308. package/src/core/command/history.ts +0 -167
  309. package/src/core/command/index.ts +0 -7
  310. package/src/core/command/merge-cells.ts +0 -74
  311. package/src/core/command/registry.ts +0 -30
  312. package/src/core/command/set-cell-formula.ts +0 -29
  313. package/src/core/command/set-cell-value.ts +0 -38
  314. package/src/core/command/types.ts +0 -73
  315. package/src/core/events.ts +0 -37
  316. package/src/core/fill.ts +0 -314
  317. package/src/core/formula/ast.ts +0 -66
  318. package/src/core/formula/dependency-graph.ts +0 -329
  319. package/src/core/formula/errors.ts +0 -41
  320. package/src/core/formula/evaluator.ts +0 -219
  321. package/src/core/formula/functions.ts +0 -266
  322. package/src/core/formula/index.ts +0 -7
  323. package/src/core/formula/parser.ts +0 -198
  324. package/src/core/formula/tokenizer.ts +0 -160
  325. package/src/core/merge-manager.ts +0 -158
  326. package/src/core/selection.ts +0 -66
  327. package/src/core/sheet.ts +0 -282
  328. package/src/core/workbook.ts +0 -99
  329. package/src/grid/__test__/canvas-mock.ts +0 -49
  330. package/src/grid/__test__/setup.ts +0 -3
  331. package/src/grid/__test__/sheet-grid-formula.test.ts +0 -140
  332. package/src/grid/__test__/sheet-grid.test.ts +0 -275
  333. package/src/grid/sheet-grid.ts +0 -407
  334. package/src/grid/vtable-theme.ts +0 -61
  335. package/src/vue/__test__/sheet-component.test.ts +0 -267
  336. package/src/vue/sheet.vue +0 -235
  337. package/src/vue/style.scss +0 -94
  338. package/src/vue/style.ts +0 -2
  339. /package/src/{vue → components/sheet}/index.ts +0 -0
@@ -0,0 +1,41 @@
1
+ //#region src/components/sheet/popups/import.worker.ts
2
+ self.onmessage = (e) => {
3
+ const { buffer } = e.data;
4
+ (async () => {
5
+ try {
6
+ const [{ readXlsx }, { buildWorkbookFromHucre }] = await Promise.all([import("hucre/xlsx"), import("@veltra/sheet-core/core/io/import")]);
7
+ const hucreWb = await readXlsx(new Uint8Array(buffer), { readStyles: true });
8
+ let lastPercent = -1;
9
+ const wb = buildWorkbookFromHucre(hucreWb, (done, total) => {
10
+ const percent = total > 0 ? Math.floor(done / total * 10) : 10;
11
+ if (percent !== lastPercent || done === total) {
12
+ lastPercent = percent;
13
+ const progress = {
14
+ type: "progress",
15
+ done,
16
+ total
17
+ };
18
+ self.postMessage(progress);
19
+ }
20
+ });
21
+ const response = {
22
+ type: "done",
23
+ ok: true,
24
+ sheets: wb.getSheets().map((s) => ({
25
+ name: s.name,
26
+ snapshot: s.snapshot()
27
+ })),
28
+ activeIndex: wb.activeSheetIndex
29
+ };
30
+ self.postMessage(response);
31
+ } catch (err) {
32
+ const response = {
33
+ type: "done",
34
+ ok: false,
35
+ error: err instanceof Error ? err.message : String(err)
36
+ };
37
+ self.postMessage(response);
38
+ }
39
+ })();
40
+ };
41
+ //#endregion
@@ -0,0 +1,38 @@
1
+ import { INSERT_IMAGE_ACCEPT, insertImageFromFile } from "../insert-image.js";
2
+ import { createBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, openBlock, unref, withCtx } from "vue";
3
+ import { UFilePicker } from "@veltra/desktop";
4
+ import { bem } from "@veltra/utils";
5
+ //#region src/components/sheet/popups/insert-image-popup.vue
6
+ const _sfc_main = /*@__PURE__*/ defineComponent({
7
+ name: "USheetInsertImagePopup",
8
+ __name: "insert-image-popup",
9
+ props: { context: {} },
10
+ emits: ["close"],
11
+ setup(__props, { emit: __emit }) {
12
+ /**
13
+ * 插入图片面板(UFilePicker):选文件后走共享 insertImageFromFile,锚定当前选区活动格。
14
+ * 不参与面板事务(单次插入 = 一个 undo 单元)。
15
+ */
16
+ const props = __props;
17
+ const emit = __emit;
18
+ const cls = bem("sheet");
19
+ function handlePick(files) {
20
+ const file = files[0];
21
+ if (!file) return;
22
+ emit("close");
23
+ insertImageFromFile(props.context, file);
24
+ }
25
+ return (_ctx, _cache) => {
26
+ return openBlock(), createBlock(unref(UFilePicker), {
27
+ accept: unref(INSERT_IMAGE_ACCEPT),
28
+ class: normalizeClass(unref(cls).e("insert-image-picker")),
29
+ onPick: handlePick
30
+ }, {
31
+ default: withCtx(() => [createElementVNode("div", { class: normalizeClass(unref(cls).e("insert-image-hint")) }, [_cache[0] || (_cache[0] = createTextVNode(" 选择图片文件 ", -1)), createElementVNode("div", { class: normalizeClass(unref(cls).e("insert-image-sub")) }, "支持 png / jpeg / gif / svg / webp", 2)], 2)]),
32
+ _: 1
33
+ }, 8, ["accept", "class"]);
34
+ };
35
+ }
36
+ });
37
+ //#endregion
38
+ export { _sfc_main as default };
@@ -0,0 +1,200 @@
1
+ import { defaultToolRegistry } from "../../tools/registry.js";
2
+ import { pickAndInsertImage } from "./insert-image.js";
3
+ import _sfc_main from "./insert-count-menu-item.js";
4
+ import { createRange } from "@veltra/sheet-core/core/address";
5
+ import { defineComponent, h } from "vue";
6
+ const INSERT_COUNT_MAX = 1e3;
7
+ /** 选区覆盖行/列数 → 插入默认 N(min 1 / max 1000) */
8
+ function defaultInsertCount(range, axis) {
9
+ if (!range) return 1;
10
+ const n = axis === "row" ? range.end.row - range.start.row + 1 : range.end.col - range.start.col + 1;
11
+ return Math.min(INSERT_COUNT_MAX, Math.max(1, n));
12
+ }
13
+ /** 点击行是否落在任一选区内(按行号覆盖) */
14
+ function isRowInSelection(ranges, row) {
15
+ return ranges.some((r) => r.start.row <= row && row <= r.end.row);
16
+ }
17
+ /** 点击列是否落在任一选区内(按列号覆盖) */
18
+ function isColInSelection(ranges, col) {
19
+ return ranges.some((r) => r.start.col <= col && col <= r.end.col);
20
+ }
21
+ /** 整行选区(列跨渲染宽度) */
22
+ function wholeRowRange(row, colCount) {
23
+ return createRange({
24
+ row,
25
+ col: 0
26
+ }, {
27
+ row,
28
+ col: Math.max(colCount - 1, 0)
29
+ });
30
+ }
31
+ /** 整列选区(行跨渲染高度) */
32
+ function wholeColRange(col, rowCount) {
33
+ return createRange({
34
+ row: 0,
35
+ col
36
+ }, {
37
+ row: Math.max(rowCount - 1, 0),
38
+ col
39
+ });
40
+ }
41
+ /** 渲染尺寸 = max(props, sheet.rows/cols),与 SheetGrid 一致 */
42
+ function resolveRenderSize(propsRows, propsCols, sheetRows, sheetCols) {
43
+ return {
44
+ rows: Math.max(propsRows ?? 100, sheetRows),
45
+ cols: Math.max(propsCols ?? 26, sheetCols)
46
+ };
47
+ }
48
+ function insertCountRender(options) {
49
+ return defineComponent({
50
+ name: "SheetInsertCountMenuRender",
51
+ setup() {
52
+ return () => h(_sfc_main, {
53
+ prefix: options.prefix,
54
+ suffix: options.suffix,
55
+ defaultValue: options.defaultValue,
56
+ min: 1,
57
+ max: INSERT_COUNT_MAX,
58
+ onConfirm: options.onConfirm
59
+ });
60
+ }
61
+ });
62
+ }
63
+ function primaryRange(ctx) {
64
+ return ctx.getSelection().ranges[0] ?? null;
65
+ }
66
+ /** 行号右键菜单:插入×2 / 删除 / divider / 冻结 / 取消冻结 */
67
+ function buildRowHeaderMenus(ctx) {
68
+ const range = primaryRange(ctx);
69
+ const startRow = range?.start.row ?? 0;
70
+ const endRow = range?.end.row ?? startRow;
71
+ const rowCount = defaultInsertCount(range, "row");
72
+ const deleteCount = range ? endRow - startRow + 1 : 1;
73
+ const frozen = ctx.frozen;
74
+ const freezeActive = frozen.rows === endRow + 1;
75
+ return [
76
+ {
77
+ label: "在上方插入行",
78
+ keepOpen: true,
79
+ render: insertCountRender({
80
+ prefix: "在上方插入",
81
+ suffix: "行",
82
+ defaultValue: rowCount,
83
+ onConfirm: (n) => ctx.insertRows(startRow, n)
84
+ })
85
+ },
86
+ {
87
+ label: "在下方插入行",
88
+ keepOpen: true,
89
+ render: insertCountRender({
90
+ prefix: "在下方插入",
91
+ suffix: "行",
92
+ defaultValue: rowCount,
93
+ onConfirm: (n) => ctx.insertRows(endRow + 1, n)
94
+ })
95
+ },
96
+ {
97
+ label: "删除行",
98
+ callback: () => ctx.deleteRows(startRow, deleteCount)
99
+ },
100
+ { divider: true },
101
+ {
102
+ label: freezeActive ? "✓ 冻结到当前行" : "冻结到当前行",
103
+ callback: () => ctx.setFrozen(endRow + 1, frozen.cols)
104
+ },
105
+ {
106
+ label: "取消冻结",
107
+ disabled: frozen.rows === 0 && frozen.cols === 0,
108
+ callback: () => ctx.setFrozen(0, 0)
109
+ }
110
+ ];
111
+ }
112
+ /** 列头右键菜单:插入×2 / 删除 / divider / 冻结 / 取消冻结 */
113
+ function buildColHeaderMenus(ctx) {
114
+ const range = primaryRange(ctx);
115
+ const startCol = range?.start.col ?? 0;
116
+ const endCol = range?.end.col ?? startCol;
117
+ const colCount = defaultInsertCount(range, "col");
118
+ const deleteCount = range ? endCol - startCol + 1 : 1;
119
+ const frozen = ctx.frozen;
120
+ const freezeActive = frozen.cols === endCol + 1;
121
+ return [
122
+ {
123
+ label: "在左侧插入列",
124
+ keepOpen: true,
125
+ render: insertCountRender({
126
+ prefix: "在左侧插入",
127
+ suffix: "列",
128
+ defaultValue: colCount,
129
+ onConfirm: (n) => ctx.insertCols(startCol, n)
130
+ })
131
+ },
132
+ {
133
+ label: "在右侧插入列",
134
+ keepOpen: true,
135
+ render: insertCountRender({
136
+ prefix: "在右侧插入",
137
+ suffix: "列",
138
+ defaultValue: colCount,
139
+ onConfirm: (n) => ctx.insertCols(endCol + 1, n)
140
+ })
141
+ },
142
+ {
143
+ label: "删除列",
144
+ callback: () => ctx.deleteCols(startCol, deleteCount)
145
+ },
146
+ { divider: true },
147
+ {
148
+ label: freezeActive ? "✓ 冻结到当前列" : "冻结到当前列",
149
+ callback: () => ctx.setFrozen(frozen.rows, endCol + 1)
150
+ },
151
+ {
152
+ label: "取消冻结",
153
+ disabled: frozen.rows === 0 && frozen.cols === 0,
154
+ callback: () => ctx.setFrozen(0, 0)
155
+ }
156
+ ];
157
+ }
158
+ /** body 格右键菜单:合并/取消合并 + 插入图片(行列插入/删除仅行号/列头菜单) */
159
+ function buildBodyMenus(ctx) {
160
+ const mergeTool = defaultToolRegistry.get("merge");
161
+ const unmergeTool = defaultToolRegistry.get("unmerge");
162
+ const active = ctx.getSelection().activeCell;
163
+ return [
164
+ {
165
+ label: "合并单元格",
166
+ disabled: mergeTool?.disabled?.(ctx) ?? true,
167
+ callback: () => mergeTool?.onClick(ctx)
168
+ },
169
+ {
170
+ label: "取消合并单元格",
171
+ disabled: unmergeTool?.disabled?.(ctx) ?? true,
172
+ callback: () => unmergeTool?.onClick(ctx)
173
+ },
174
+ {
175
+ label: "插入图片",
176
+ disabled: !active,
177
+ callback: () => pickAndInsertImage(ctx)
178
+ }
179
+ ];
180
+ }
181
+ /**
182
+ * 右键落点预处理:body 格落在选区外 → 选中该格;
183
+ * 行号/列头落在选区外 → 选中整行/整列(渲染尺寸)。
184
+ */
185
+ function ensureContextMenuSelection(ctx, info, renderSize) {
186
+ const ranges = ctx.getSelection().ranges;
187
+ if (info.kind === "body" && info.addr) {
188
+ if (!ranges.some((range) => range.start.row <= info.addr.row && info.addr.row <= range.end.row && range.start.col <= info.addr.col && info.addr.col <= range.end.col)) ctx.selectCell(info.addr);
189
+ return;
190
+ }
191
+ if (info.kind === "row-header" && info.row != null) {
192
+ if (!isRowInSelection(ranges, info.row)) ctx.selectRange(wholeRowRange(info.row, renderSize.cols));
193
+ return;
194
+ }
195
+ if (info.kind === "col-header" && info.col != null) {
196
+ if (!isColInSelection(ranges, info.col)) ctx.selectRange(wholeColRange(info.col, renderSize.rows));
197
+ }
198
+ }
199
+ //#endregion
200
+ export { INSERT_COUNT_MAX, buildBodyMenus, buildColHeaderMenus, buildRowHeaderMenus, defaultInsertCount, ensureContextMenuSelection, isColInSelection, isRowInSelection, resolveRenderSize, wholeColRange, wholeRowRange };
@@ -0,0 +1,162 @@
1
+ import { useSheetTabsBar } from "./use-sheet-tabs-bar.js";
2
+ import { ArrowLeft, ArrowRight } from "@veltra/icons/normal";
3
+ import { Fragment, createElementBlock, createElementVNode, createVNode, defineComponent, nextTick, normalizeClass, openBlock, ref, renderList, toDisplayString, toRef, unref, useTemplateRef, vModelText, vShow, withCtx, withDirectives, withKeys, withModifiers } from "vue";
4
+ import { UIcon, contextmenu, message, messageConfirm } from "@veltra/desktop";
5
+ import { bem } from "@veltra/utils";
6
+ //#region src/components/sheet/sheet-tabs.vue
7
+ const _hoisted_1 = ["disabled"];
8
+ const _hoisted_2 = ["onClick", "onContextmenu"];
9
+ const _hoisted_3 = ["onKeydown"];
10
+ const _hoisted_4 = { key: 1 };
11
+ const _hoisted_5 = ["disabled"];
12
+ const _sfc_main = /*@__PURE__*/ defineComponent({
13
+ name: "USheetTabs",
14
+ __name: "sheet-tabs",
15
+ props: {
16
+ workbook: {},
17
+ sheetList: {},
18
+ activeIndex: {}
19
+ },
20
+ setup(__props) {
21
+ /**
22
+ * 底部 sheet tabs(可滚动视口 + 左右导航;「+」钉在视口外):
23
+ * - tab 点击切换;末尾「+」addSheet + 自动激活新表(激活事件驱动 grid 重建)
24
+ * - tab 右键菜单「重命名 / 删除」:重命名进入行内输入(Enter 提交、Esc 取消、失焦提交;
25
+ * 冲突提示且不写入),删除二次确认(最后一个 sheet 的删除项禁用)
26
+ * - sheet 增删改名是工作簿级结构操作(不走 undo),直接调用 Workbook——
27
+ * 不经 SheetContext(见 AGENTS.md 门面边界);UI 刷新由 workbook 事件驱动
28
+ */
29
+ const props = __props;
30
+ const cls = bem("sheet");
31
+ const tabsViewportRef = useTemplateRef("tabsViewportRef");
32
+ const tabsListRef = useTemplateRef("tabsListRef");
33
+ const { showNav, canPrev, canNext, scrollByStep } = useSheetTabsBar({
34
+ viewportRef: tabsViewportRef,
35
+ listRef: tabsListRef,
36
+ sheetList: toRef(props, "sheetList"),
37
+ activeIndex: toRef(props, "activeIndex")
38
+ });
39
+ function handleTabClick(index) {
40
+ if (index === props.activeIndex) return;
41
+ const sheet = props.sheetList[index];
42
+ if (sheet) props.workbook.activateSheet(sheet.name);
43
+ }
44
+ /** 「+」添加 sheet:自动激活新表(激活事件驱动 grid 重建) */
45
+ function handleAddSheet() {
46
+ const sheet = props.workbook.addSheet();
47
+ props.workbook.activateSheet(sheet.name);
48
+ }
49
+ /** 正在行内重命名的 tab 下标(-1 = 无) */
50
+ const renamingIndex = ref(-1);
51
+ const renameDraft = ref("");
52
+ const renameInputRef = useTemplateRef("renameInputRef");
53
+ function handleTabContextMenu(event, sheet, index) {
54
+ contextmenu.pop({
55
+ mousePosition: {
56
+ x: event.clientX,
57
+ y: event.clientY
58
+ },
59
+ width: 160,
60
+ menus: [{
61
+ label: "重命名",
62
+ callback: () => startRename(index)
63
+ }, {
64
+ label: "删除",
65
+ disabled: props.sheetList.length <= 1,
66
+ callback: () => confirmRemoveSheet(sheet)
67
+ }]
68
+ });
69
+ }
70
+ /** 进入行内重命名(预填当前名并全选) */
71
+ function startRename(index) {
72
+ renamingIndex.value = index;
73
+ renameDraft.value = props.sheetList[index]?.name ?? "";
74
+ nextTick(() => renameInputRef.value?.[0]?.select());
75
+ }
76
+ /** 提交重命名:空名 / 重名(含大小写变体)由 Workbook 拒绝,提示且不写入 */
77
+ function commitRename() {
78
+ const index = renamingIndex.value;
79
+ if (index < 0) return;
80
+ renamingIndex.value = -1;
81
+ const sheet = props.sheetList[index];
82
+ if (!sheet) return;
83
+ const next = renameDraft.value.trim();
84
+ if (next === "" || next === sheet.name) return;
85
+ if (!props.workbook.renameSheet(sheet.name, next)) message.warn(`无法重命名:名称“${next}”无效或已被占用`);
86
+ }
87
+ function cancelRename() {
88
+ renamingIndex.value = -1;
89
+ }
90
+ /** 删除确认(message-confirm);最后一个 sheet 在菜单层已禁用,这里再兜底 */
91
+ function confirmRemoveSheet(sheet) {
92
+ if (props.workbook.sheetCount <= 1) return;
93
+ messageConfirm.danger(`确定删除工作表“${sheet.name}”吗?删除后不可恢复。`, {
94
+ confirmButtonText: "删除",
95
+ onClosed: (action) => {
96
+ if (action !== "confirm") return;
97
+ props.workbook.removeSheet(sheet.name);
98
+ }
99
+ });
100
+ }
101
+ return (_ctx, _cache) => {
102
+ return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).e("tabs")) }, [
103
+ withDirectives(createElementVNode("button", {
104
+ type: "button",
105
+ class: normalizeClass(unref(cls).e("tabs-nav")),
106
+ disabled: !unref(canPrev),
107
+ title: "向左滚动",
108
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(scrollByStep)(-1))
109
+ }, [createVNode(unref(UIcon), null, {
110
+ default: withCtx(() => [createVNode(unref(ArrowLeft))]),
111
+ _: 1
112
+ })], 10, _hoisted_1), [[vShow, unref(showNav)]]),
113
+ createElementVNode("div", {
114
+ ref_key: "tabsViewportRef",
115
+ ref: tabsViewportRef,
116
+ class: normalizeClass(unref(cls).e("tabs-viewport"))
117
+ }, [createElementVNode("div", {
118
+ ref_key: "tabsListRef",
119
+ ref: tabsListRef,
120
+ class: normalizeClass(unref(cls).e("tabs-list"))
121
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.sheetList, (sheet, index) => {
122
+ return openBlock(), createElementBlock("div", {
123
+ key: sheet,
124
+ class: normalizeClass([unref(cls).e("tab"), unref(bem).is("active", index === __props.activeIndex)]),
125
+ title: "右键重命名 / 删除",
126
+ onClick: ($event) => handleTabClick(index),
127
+ onContextmenu: withModifiers(($event) => handleTabContextMenu($event, sheet, index), ["prevent"])
128
+ }, [renamingIndex.value === index ? withDirectives((openBlock(), createElementBlock("input", {
129
+ key: 0,
130
+ ref_for: true,
131
+ ref_key: "renameInputRef",
132
+ ref: renameInputRef,
133
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => renameDraft.value = $event),
134
+ class: normalizeClass(unref(cls).e("tab-rename-input")),
135
+ maxlength: 31,
136
+ onClick: _cache[2] || (_cache[2] = withModifiers(() => {}, ["stop"])),
137
+ onKeydown: [withKeys(withModifiers(commitRename, ["prevent"]), ["enter"]), withKeys(withModifiers(cancelRename, ["prevent"]), ["esc"])],
138
+ onBlur: commitRename
139
+ }, null, 42, _hoisted_3)), [[vModelText, renameDraft.value]]) : (openBlock(), createElementBlock("span", _hoisted_4, toDisplayString(sheet.name), 1))], 42, _hoisted_2);
140
+ }), 128))], 2)], 2),
141
+ withDirectives(createElementVNode("button", {
142
+ type: "button",
143
+ class: normalizeClass(unref(cls).e("tabs-nav")),
144
+ disabled: !unref(canNext),
145
+ title: "向右滚动",
146
+ onClick: _cache[3] || (_cache[3] = ($event) => unref(scrollByStep)(1))
147
+ }, [createVNode(unref(UIcon), null, {
148
+ default: withCtx(() => [createVNode(unref(ArrowRight))]),
149
+ _: 1
150
+ })], 10, _hoisted_5), [[vShow, unref(showNav)]]),
151
+ createElementVNode("button", {
152
+ type: "button",
153
+ class: normalizeClass(unref(cls).e("tab-add")),
154
+ title: "添加工作表",
155
+ onClick: handleAddSheet
156
+ }, " + ", 2)
157
+ ], 2);
158
+ };
159
+ }
160
+ });
161
+ //#endregion
162
+ export { _sfc_main as default };
@@ -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/components/sheet/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 };