@veltra/sheet 2.5.8 → 2.6.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 (37) hide show
  1. package/dist/components/sheet/formula-bar.js +6 -1
  2. package/dist/components/sheet/sheet-context-menu.js +41 -5
  3. package/dist/components/sheet/sheet.js +12 -4
  4. package/dist/components/sheet/style2.css +1 -1
  5. package/dist/components/sheet/use-sheet-grid.js +17 -7
  6. package/dist/components/sheet/use-sheet-state.js +4 -1
  7. package/dist/components/sheet/use-tool-popup.js +1 -2
  8. package/dist/index.d.ts +2 -2
  9. package/dist/tools/context.d.ts +15 -0
  10. package/dist/tools/context.js +22 -1
  11. package/dist/types/sheet.d.ts +15 -5
  12. package/package.json +5 -2
  13. package/src/components/sheet/__test__/formula-bar.test.ts +52 -42
  14. package/src/components/sheet/__test__/functions-popup.test.ts +1 -1
  15. package/src/components/sheet/__test__/import-file.test.ts +1 -1
  16. package/src/components/sheet/__test__/insert-count-menu-item.test.ts +1 -1
  17. package/src/components/sheet/__test__/insert-image-popup.test.ts +1 -1
  18. package/src/components/sheet/__test__/insert-image.test.ts +1 -1
  19. package/src/components/sheet/__test__/sheet-component.test.ts +311 -24
  20. package/src/components/sheet/__test__/sheet-context-menu.test.ts +32 -3
  21. package/src/components/sheet/__test__/use-formula-ref-select.test.ts +1 -1
  22. package/src/components/sheet/__test__/use-formula-suggest.test.ts +1 -1
  23. package/src/components/sheet/formula-bar.vue +14 -1
  24. package/src/components/sheet/sheet-context-menu.ts +61 -4
  25. package/src/components/sheet/sheet.vue +5 -2
  26. package/src/components/sheet/style.scss +2 -2
  27. package/src/components/sheet/use-sheet-grid.ts +31 -9
  28. package/src/components/sheet/use-sheet-state.ts +5 -1
  29. package/src/components/sheet/use-tool-popup.ts +5 -4
  30. package/src/index.ts +1 -1
  31. package/src/tools/__test__/apply-style.test.ts +1 -1
  32. package/src/tools/__test__/builtin.test.ts +1 -1
  33. package/src/tools/__test__/context.test.ts +66 -2
  34. package/src/tools/__test__/registry.test.ts +1 -1
  35. package/src/tools/context.ts +47 -0
  36. package/src/types/sheet.ts +17 -5
  37. package/src/components/sheet/parsing.ts +0 -11
@@ -1,7 +1,7 @@
1
1
  import { parseRange } from '@veltra/sheet-core/core/address.js'
2
2
  import { Workbook } from '@veltra/sheet-core/core/workbook.js'
3
3
  import type { SheetGrid } from '@veltra/sheet-core/grid'
4
- import { afterEach, describe, expect, it } from 'vitest'
4
+ import { afterEach, describe, expect, it } from 'vite-plus/test'
5
5
  import { createApp, h, nextTick, type App } from 'vue'
6
6
 
7
7
  import { USheet } from '../../../index'
@@ -226,8 +226,8 @@ describe('USheet 公式栏(名称框 + fx 输入栏)', () => {
226
226
  await nextTick()
227
227
  expect(sheet.getCellData({ row: 2, col: 0 })).toMatchObject({ f: 'SUM(A1:A2)', v: 3 })
228
228
 
229
- // 提交后网格渲染计算值(模型 A3 → 表格坐标 (1,3))
230
- expect(exposed.value?.getGrid()?.getTable().getCellValue(1, 3)).toBe(3)
229
+ // 提交后网格渲染计算值(模型 A3 = 引擎数据坐标 (0,2),无行列头偏移)
230
+ expect(exposed.value?.getGrid()?.getTable().getCellText(0, 2)).toBe('3')
231
231
  })
232
232
 
233
233
  it('网格侧编辑提交(change_cell_value)后公式栏同步显示', async () => {
@@ -239,8 +239,8 @@ describe('USheet 公式栏(名称框 + fx 输入栏)', () => {
239
239
  sheet.selectCell({ row: 0, col: 0 })
240
240
  await nextTick()
241
241
 
242
- // 模拟网格双击编辑提交(与 grid 测试同一路径:change_cell_value → 模型回写)
243
- exposed.value?.getGrid()?.getTable().changeCellValue(1, 1, 'grid-edited', false, true)
242
+ // 模拟网格编辑提交(引擎公开回写 API:updateCell → TableModel → 模型命令系统)
243
+ exposed.value?.getGrid()?.getTable().updateCell(0, 0, 'grid-edited')
244
244
  await nextTick()
245
245
  expect(fxInput(el).value).toBe('grid-edited')
246
246
  })
@@ -255,14 +255,14 @@ describe('USheet 公式栏(名称框 + fx 输入栏)', () => {
255
255
  sheet.selectCell({ row: 0, col: 0 })
256
256
  await nextTick()
257
257
 
258
- // 程序化进入网格编辑(表格坐标 (1,1) = 模型 A1)
259
- exposed.value?.getGrid()?.getTable().startEditCell(1, 1)
258
+ // 程序化进入网格编辑(引擎数据坐标 (0,0) = 模型 A1)
259
+ expect(exposed.value?.getGrid()?.getTable().startEdit(0, 0)).toBe(true)
260
260
  await nextTick()
261
261
  expect(fxInput(el).readOnly).toBe(true)
262
262
  expect(fxInput(el).value).toBe('=SUM(1,2)')
263
263
 
264
264
  // 提交 → 编辑器 onEnd → 公式栏退出镜像(显示模型内容)
265
- exposed.value?.getGrid()?.getTable().completeEditCell()
265
+ exposed.value?.getGrid()?.getTable().commitEdit()
266
266
  await nextTick()
267
267
  expect(sheet.getCellData({ row: 0, col: 0 })).toMatchObject({ f: 'SUM(1,2)' })
268
268
  expect(fxInput(el).readOnly).toBe(false)
@@ -271,7 +271,6 @@ describe('USheet 公式栏(名称框 + fx 输入栏)', () => {
271
271
 
272
272
  it('tab 切换:重绑订阅并刷新(新 sheet 的选区 / 单元格内容回显)', async () => {
273
273
  const workbook = createWorkbook()
274
- const sheet1 = workbook.activeSheet
275
274
  const sheet2 = workbook.getSheet('Sheet2')!
276
275
  const { el } = mount(() => ({ workbook, rows: 20, cols: 8 }))
277
276
  await nextTick()
@@ -551,15 +550,33 @@ describe('USheet 公式栏:函数补全与引用选择', () => {
551
550
  const input = setFxText(el, '=SUM(')
552
551
  await nextTick()
553
552
 
554
- // pointerdown on grid → blur 不提交(引用选择);监听绑定在实例容器(LRU 缓存)
553
+ // 画布数据格点选(引擎选区事件管线)→ 引用插入 + blur 挂起(引用选择);
554
+ // 引用拾取为手势收敛语义(按下起手记录、抬手一次回交,见 sheet-core
555
+ // grid-selection),故插入断言在 pointerup 之后。pointerdown 监听绑定在
556
+ // 实例容器(LRU 缓存)。画布几何口径与 sheet-core grid-theme 一致
557
+ // (行号列 46、列头 28、列宽 80、行高 28)→ (51, 117) 命中 A4
555
558
  const gridEl = el.querySelector('.u-sheet__grid-instance')!
556
- gridEl.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true }))
557
- input.dispatchEvent(new FocusEvent('blur'))
559
+ gridEl.dispatchEvent(
560
+ new PointerEvent('pointerdown', { clientX: 51, clientY: 117, bubbles: true })
561
+ )
558
562
  await nextTick()
563
+ // 手势未结束(未抬手):不插入、模型选区不变
559
564
  expect(sheet.getCellData({ row: 2, col: 0 })).toBeUndefined()
560
565
  expect(input.value).toBe('=SUM(')
566
+ gridEl.dispatchEvent(
567
+ new PointerEvent('pointerup', { clientX: 51, clientY: 117, bubbles: true })
568
+ )
569
+ await nextTick()
570
+ expect(sheet.getCellData({ row: 2, col: 0 })).toBeUndefined()
571
+ expect(input.value).toBe('=SUM(A4')
572
+
573
+ // 插入后失焦仍被挂起(beginBlurSuppress 置位):草稿不提交
574
+ input.dispatchEvent(new FocusEvent('blur'))
575
+ await nextTick()
576
+ expect(sheet.getCellData({ row: 2, col: 0 })).toBeUndefined()
577
+ expect(input.value).toBe('=SUM(A4')
561
578
 
562
- // 网格选区拦截 → handleRefSelect 路径(VTable 时序见 sheet-core selection-debug)
579
+ // 网格选区拦截 → handleRefSelect 路径(引擎选区事件管线,见 sheet-core grid-selection)
563
580
  const { el: barEl, exposed: barExposed } = mountFormulaBar(sheet)
564
581
  await nextTick()
565
582
  setFxText(barEl, '=SUM(')
@@ -588,13 +605,13 @@ describe('USheet 公式栏:函数补全与引用选择', () => {
588
605
  sheet.selectCell({ row: 0, col: 0 })
589
606
  await nextTick()
590
607
 
591
- exposed.value?.getGrid()?.getTable().startEditCell(1, 1)
608
+ expect(exposed.value?.getGrid()?.getTable().startEdit(0, 0)).toBe(true)
592
609
  await nextTick()
593
610
  expect(fxInput(el).readOnly).toBe(true)
594
611
  expect(fxInput(el).value).toBe('=SUM(1,2)')
595
612
  expect(suggestList(el)).toBeNull()
596
613
 
597
- exposed.value?.getGrid()?.getTable().completeEditCell()
614
+ exposed.value?.getGrid()?.getTable().commitEdit()
598
615
  await nextTick()
599
616
  })
600
617
 
@@ -644,19 +661,14 @@ describe('USheet 公式栏:函数补全与引用选择', () => {
644
661
 
645
662
  // ─── 目标格选区高亮保持(弹框打开与参数点选期间)──────────────
646
663
 
647
- /** VTable 事件名(ListTable.EVENT_TYPE 常量值;@veltra/sheet 不直接依赖 @visactor/vtable,不做运行时引入) */
648
- const EVT_SELECTED_CELL = 'selected_cell'
649
- const EVT_DRAG_SELECT_END = 'drag_select_end'
650
-
651
664
  type GridTable = ReturnType<SheetGrid['getTable']>
652
665
 
653
- /** 模拟画布点选格(VTable 时序:selectCells → SELECTED_CELL) */
666
+ /** 模拟画布点选格(引擎选区事件管线:selectCells 即驱动拦截 / 回写路径) */
654
667
  function canvasClickCell(table: GridTable, col: number, row: number): void {
655
668
  table.selectCells([{ start: { col, row }, end: { col, row } }])
656
- table.fireListeners(EVT_SELECTED_CELL, { col, row })
657
669
  }
658
670
 
659
- /** 画布当前选区末尾项(表格坐标;VTable 范围对象含额外内部字段,按坐标匹配) */
671
+ /** 画布当前选区末尾项(引擎数据坐标,无行列头偏移) */
660
672
  function lastCanvasRange(table: GridTable) {
661
673
  return table.getSelectedCellRanges().at(-1)
662
674
  }
@@ -675,19 +687,19 @@ describe('USheet 公式栏:目标格选区高亮保持', () => {
675
687
  await flushPopup()
676
688
  expect(functionsPanel()).not.toBeNull()
677
689
 
678
- // 弹框打开期间点选画布 B2(表格坐标 (2,2))
690
+ // 弹框打开期间点选画布 B2(引擎数据坐标 (1,1))
679
691
  const table = exposed.value!.getGrid()!.getTable()
680
- canvasClickCell(table, 2, 2)
692
+ canvasClickCell(table, 1, 1)
681
693
 
682
694
  expect(sheet.getSelection().activeCell).toEqual({ row: 2, col: 0 })
683
695
  expect(sheet.getSelection().ranges[0]).toEqual({
684
696
  start: { row: 2, col: 0 },
685
697
  end: { row: 2, col: 0 }
686
698
  })
687
- // 画布选区回推为目标格 A3(表格坐标 (1,3)),名称框仍显示 A3
699
+ // 画布选区回推为目标格 A3(引擎数据坐标 (0,2)),名称框仍显示 A3
688
700
  expect(lastCanvasRange(table)).toMatchObject({
689
- start: { col: 1, row: 3 },
690
- end: { col: 1, row: 3 }
701
+ start: { col: 0, row: 2 },
702
+ end: { col: 0, row: 2 }
691
703
  })
692
704
  expect(nameBox(el).value).toBe('A3')
693
705
  // 未处于引用选择上下文:不插入引用文本
@@ -713,15 +725,15 @@ describe('USheet 公式栏:目标格选区高亮保持', () => {
713
725
  const input = fxInput(el)
714
726
  expect(input.value).toBe('=SUM()')
715
727
 
716
- // 点选参数格 A1(表格坐标 (1,1))→ 只插入引用文本(括号随 =SUM() 模板闭合),目标格选区不变
728
+ // 点选参数格 A1(引擎数据坐标 (0,0))→ 只插入引用文本(括号随 =SUM() 模板闭合),目标格选区不变
717
729
  const table = exposed.value!.getGrid()!.getTable()
718
- canvasClickCell(table, 1, 1)
730
+ canvasClickCell(table, 0, 0)
719
731
  await nextTick()
720
732
  expect(input.value).toBe('=SUM(A1)')
721
733
  expect(sheet.getSelection().activeCell).toEqual({ row: 2, col: 0 })
722
734
  expect(lastCanvasRange(table)).toMatchObject({
723
- start: { col: 1, row: 3 },
724
- end: { col: 1, row: 3 }
735
+ start: { col: 0, row: 2 },
736
+ end: { col: 0, row: 2 }
725
737
  })
726
738
  expect(nameBox(el).value).toBe('A3')
727
739
 
@@ -732,8 +744,8 @@ describe('USheet 公式栏:目标格选区高亮保持', () => {
732
744
  expect(sheet.getSelection().activeCell).toEqual({ row: 2, col: 0 })
733
745
  expect(nameBox(el).value).toBe('A3')
734
746
  expect(lastCanvasRange(table)).toMatchObject({
735
- start: { col: 1, row: 3 },
736
- end: { col: 1, row: 3 }
747
+ start: { col: 0, row: 2 },
748
+ end: { col: 0, row: 2 }
737
749
  })
738
750
  })
739
751
 
@@ -755,23 +767,21 @@ describe('USheet 公式栏:目标格选区高亮保持', () => {
755
767
 
756
768
  // 弹框打开期间点选画布 B2:目标格 A3 高亮保持、模型选区不变、不插入文本
757
769
  const table = exposed.value!.getGrid()!.getTable()
758
- canvasClickCell(table, 2, 2)
770
+ canvasClickCell(table, 1, 1)
759
771
  expect(sheet.getSelection().activeCell).toEqual({ row: 2, col: 0 })
760
772
  expect(lastCanvasRange(table)).toMatchObject({
761
- start: { col: 1, row: 3 },
762
- end: { col: 1, row: 3 }
773
+ start: { col: 0, row: 2 },
774
+ end: { col: 0, row: 2 }
763
775
  })
764
776
  expect(fxInput(el).value).toBe('')
765
777
 
766
- // 选中 SUM → 拖选参数区域 A1:A2(SELECTED_CELL → DRAG_SELECT_END 完整时序)
778
+ // 选中 SUM → 拖选参数区域 A1:A2(引擎选区事件:selectCells 即完整时序)
767
779
  document.querySelector<HTMLElement>('#pop-container .u-sheet__functions-item')!.click()
768
780
  await nextTick()
769
781
  await nextTick()
770
782
  const input = fxInput(el)
771
783
  expect(input.value).toBe('=SUM()')
772
- table.selectCells([{ start: { col: 1, row: 1 }, end: { col: 1, row: 2 } }])
773
- table.fireListeners(EVT_SELECTED_CELL, { col: 1, row: 2 })
774
- table.fireListeners(EVT_DRAG_SELECT_END, {})
784
+ table.selectCells([{ start: { col: 0, row: 0 }, end: { col: 0, row: 1 } }])
775
785
  await nextTick()
776
786
  expect(input.value).toBe('=SUM(A1:A2)')
777
787
  expect(sheet.getSelection().activeCell).toEqual({ row: 2, col: 0 })
@@ -808,8 +818,8 @@ describe('USheet 公式栏:目标格选区高亮保持', () => {
808
818
  expect(sheet.getSelection().activeCell).toEqual({ row: 2, col: 0 })
809
819
  expect(nameBox(el).value).toBe('A3')
810
820
  expect(lastCanvasRange(exposed.value!.getGrid()!.getTable())).toMatchObject({
811
- start: { col: 1, row: 3 },
812
- end: { col: 1, row: 3 }
821
+ start: { col: 0, row: 2 },
822
+ end: { col: 0, row: 2 }
813
823
  })
814
824
  })
815
825
  })
@@ -2,7 +2,7 @@ import {
2
2
  listFormulaFunctions,
3
3
  registerFormulaFunction
4
4
  } from '@veltra/sheet-core/core/formula/functions.js'
5
- import { afterEach, describe, expect, it, vi } from 'vitest'
5
+ import { afterEach, describe, expect, it, vi } from 'vite-plus/test'
6
6
  import { createApp, h, nextTick, type App } from 'vue'
7
7
 
8
8
  import USheetFunctionsPopup from '../popups/functions-popup.vue'
@@ -1,6 +1,6 @@
1
1
  import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
2
2
  import { Workbook } from '@veltra/sheet-core/core/workbook.js'
3
- import { afterEach, describe, expect, it, vi } from 'vitest'
3
+ import { afterEach, describe, expect, it, vi } from 'vite-plus/test'
4
4
  import { ref } from 'vue'
5
5
 
6
6
  import { IMPORT_FILE_ACCEPT, importFromFile, pickAndImportFile } from '../import-file'
@@ -1,5 +1,5 @@
1
1
  import { ContextmenuRootDIKey } from '@veltra/desktop'
2
- import { describe, expect, it, vi } from 'vitest'
2
+ import { describe, expect, it, vi } from 'vite-plus/test'
3
3
  import { createApp, h, nextTick } from 'vue'
4
4
 
5
5
  import InsertCountMenuItem from '../insert-count-menu-item.vue'
@@ -1,5 +1,5 @@
1
1
  import { Sheet } from '@veltra/sheet-core/core/sheet.js'
2
- import { afterEach, describe, expect, it, vi } from 'vitest'
2
+ import { afterEach, describe, expect, it, vi } from 'vite-plus/test'
3
3
  import { createApp, h, type App } from 'vue'
4
4
 
5
5
  import { createSheetContext } from '../../../tools/context'
@@ -1,5 +1,5 @@
1
1
  import { Sheet } from '@veltra/sheet-core/core/sheet.js'
2
- import { afterEach, describe, expect, it, vi } from 'vitest'
2
+ import { afterEach, describe, expect, it, vi } from 'vite-plus/test'
3
3
 
4
4
  import { createSheetContext } from '../../../tools/context'
5
5
  import {