@veltra/sheet 2.1.1 → 2.3.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.
- package/dist/components/report/binding-badge.js +100 -0
- package/dist/components/report/designer/cell-coords.js +46 -0
- package/dist/components/report/designer/col-widths.js +29 -0
- package/dist/components/report/designer/conditional-rules/helpers.js +139 -0
- package/dist/components/report/designer/drop-highlight-overlay.js +76 -0
- package/dist/components/report/designer/float-panel.js +422 -0
- package/dist/components/report/designer/role.js +17 -0
- package/dist/components/report/designer/rule-preview.js +33 -0
- package/dist/components/report/designer/rule-row.js +253 -0
- package/dist/components/report/designer/rules-dialog.js +118 -0
- package/dist/components/report/designer/topology-overlay.js +122 -0
- package/dist/components/report/designer/topology.js +64 -0
- package/dist/components/report/designer/use-grid-overlay.js +75 -0
- package/dist/components/report/designer-hub.js +177 -0
- package/dist/components/report/field-panel-helpers.js +33 -0
- package/dist/components/report/field-panel.js +132 -0
- package/dist/components/report/filter-bar.js +74 -0
- package/dist/components/report/hub-connection-form.js +145 -0
- package/dist/components/report/hub-dataset-editor.js +394 -0
- package/dist/components/report/preview-grid-size.js +32 -0
- package/dist/components/report/report-designer.js +393 -0
- package/dist/components/report/report-viewer.js +124 -0
- package/dist/components/report/style.d.ts +17 -0
- package/dist/components/report/style.js +18 -0
- package/dist/components/report/style2.css +874 -0
- package/dist/components/report/use-report-designer.js +382 -0
- package/dist/components/report/use-report-viewer.js +55 -0
- package/dist/{vue → components/sheet}/formula-bar.js +1 -1
- package/dist/{vue → components/sheet}/formula-suggest-list.js +1 -1
- package/dist/{vue → components/sheet}/import-file.js +1 -1
- package/dist/{vue → components/sheet}/insert-count-menu-item.js +1 -1
- package/dist/{vue → components/sheet}/insert-image.js +1 -1
- package/dist/{vue → components/sheet}/popup-helpers.js +1 -1
- package/dist/{vue → components/sheet}/popups/border-popup.js +31 -3
- package/dist/{vue → components/sheet}/popups/border-preset-glyph.js +1 -1
- package/dist/{vue → components/sheet}/popups/export-popup.js +2 -2
- package/dist/{vue → components/sheet}/popups/fill-color-popup.js +3 -3
- package/dist/{vue → components/sheet}/popups/find-popup.js +1 -1
- package/dist/{vue → components/sheet}/popups/font-color-popup.js +3 -3
- package/dist/{vue → components/sheet}/popups/font-size-popup.js +3 -3
- package/dist/{vue → components/sheet}/popups/import.worker.d.ts +1 -1
- package/dist/{vue → components/sheet}/popups/import.worker.js +1 -1
- package/dist/{vue → components/sheet}/popups/insert-image-popup.js +1 -1
- package/dist/{vue → components/sheet}/sheet-context-menu.js +7 -4
- package/dist/{vue → components/sheet}/sheet-tabs.js +1 -1
- package/dist/{vue → components/sheet}/sheet-toolbar.js +1 -1
- package/dist/{vue → components/sheet}/sheet.js +16 -1
- package/dist/{vue → components/sheet}/use-find-replace.js +1 -1
- package/dist/{vue → components/sheet}/use-formula-ref-select.js +1 -1
- package/dist/{vue → components/sheet}/use-sheet-grid.js +22 -4
- package/dist/{vue → components/sheet}/use-sheet-state.js +6 -5
- package/dist/{vue → components/sheet}/use-sheet-tabs-bar.js +1 -1
- package/dist/{vue → components/sheet}/use-tool-groups.js +2 -2
- package/dist/{vue → components/sheet}/use-tool-popup.js +2 -2
- package/dist/{vue → components/sheet}/use-toolbar-scroll.js +1 -1
- package/dist/index.d.ts +17 -3
- package/dist/index.js +13 -3
- package/dist/report/binding.d.ts +83 -0
- package/dist/report/binding.js +332 -0
- package/dist/report/connector.d.ts +66 -0
- package/dist/report/connector.js +159 -0
- package/dist/report/export-xlsx.d.ts +17 -0
- package/dist/report/export-xlsx.js +92 -0
- package/dist/report/filter-bar.d.ts +10 -0
- package/dist/report/filter-bar.js +31 -0
- package/dist/report/index.d.ts +12 -0
- package/dist/report/params.d.ts +13 -0
- package/dist/report/params.js +61 -0
- package/dist/report/render/aggregate.js +169 -0
- package/dist/report/render/builder.d.ts +12 -0
- package/dist/report/render/builder.js +139 -0
- package/dist/report/render/coordinate.d.ts +25 -0
- package/dist/report/render/coordinate.js +733 -0
- package/dist/report/render/index.d.ts +14 -0
- package/dist/report/render/index.js +21 -0
- package/dist/report/render/style-resolver.js +50 -0
- package/dist/report/render/template-index.d.ts +24 -0
- package/dist/report/render/template-index.js +137 -0
- package/dist/report/rules/evaluate.d.ts +25 -0
- package/dist/report/rules/evaluate.js +82 -0
- package/dist/report/rules/index.d.ts +2 -0
- package/dist/report/template.d.ts +63 -0
- package/dist/report/template.js +83 -0
- package/dist/report/types.d.ts +85 -0
- package/dist/tools/apply-style.js +29 -0
- package/dist/tools/builtin.js +17 -17
- package/dist/tools/context.d.ts +39 -6
- package/dist/tools/context.js +38 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/report-designer.d.ts +38 -0
- package/dist/types/report-viewer.d.ts +38 -0
- package/dist/types/sheet.d.ts +21 -1
- package/package.json +6 -8
- package/src/components/report/__test__/conditional-rules-helpers.test.ts +88 -0
- package/src/components/report/__test__/field-panel-helpers.test.ts +65 -0
- package/src/components/report/__test__/float-panel-position.test.ts +45 -0
- package/src/components/report/__test__/preview-grid-size.test.ts +63 -0
- package/src/components/report/__test__/report-designer.test.ts +464 -0
- package/src/components/report/__test__/report-viewer.test.ts +357 -0
- package/src/components/report/__test__/topology.test.ts +143 -0
- package/src/components/report/__test__/use-report-designer.test.ts +697 -0
- package/src/components/report/binding-badge.ts +92 -0
- package/src/components/report/designer/cell-coords.ts +94 -0
- package/src/components/report/designer/col-widths.ts +56 -0
- package/src/components/report/designer/conditional-rules/helpers.ts +189 -0
- package/src/components/report/designer/drop-highlight-overlay.vue +74 -0
- package/src/components/report/designer/float-panel.vue +431 -0
- package/src/components/report/designer/role.ts +32 -0
- package/src/components/report/designer/rule-preview.vue +40 -0
- package/src/components/report/designer/rule-row.vue +252 -0
- package/src/components/report/designer/rules-dialog.vue +110 -0
- package/src/components/report/designer/topology-overlay.vue +127 -0
- package/src/components/report/designer/topology.ts +124 -0
- package/src/components/report/designer/use-grid-overlay.ts +113 -0
- package/src/components/report/designer-hub.vue +198 -0
- package/src/components/report/field-panel-helpers.ts +44 -0
- package/src/components/report/field-panel.vue +136 -0
- package/src/components/report/filter-bar.vue +77 -0
- package/src/components/report/hub-connection-form.vue +124 -0
- package/src/components/report/hub-dataset-editor.vue +369 -0
- package/src/components/report/index.ts +2 -0
- package/src/components/report/preview-grid-size.ts +33 -0
- package/src/components/report/report-designer.vue +420 -0
- package/src/components/report/report-viewer.vue +136 -0
- package/src/components/report/style-designer.scss +587 -0
- package/src/components/report/style-hub.scss +292 -0
- package/src/components/report/style-viewer.scss +104 -0
- package/src/components/report/style.scss +3 -0
- package/src/components/report/style.ts +20 -0
- package/src/components/report/use-report-designer.ts +596 -0
- package/src/components/report/use-report-viewer.ts +88 -0
- package/src/{vue → components/sheet}/__test__/formula-bar.test.ts +37 -18
- package/src/{vue → components/sheet}/__test__/insert-image-popup.test.ts +1 -1
- package/src/{vue → components/sheet}/__test__/insert-image.test.ts +1 -1
- package/src/{vue → components/sheet}/__test__/sheet-component.test.ts +77 -3
- package/src/{vue → components/sheet}/__test__/sheet-context-menu.test.ts +4 -3
- package/src/{vue → components/sheet}/formula-bar.vue +1 -1
- package/src/{vue → components/sheet}/insert-image.ts +1 -1
- package/src/{vue → components/sheet}/popup-helpers.ts +1 -1
- package/src/{vue → components/sheet}/popups/border-popup.vue +32 -4
- package/src/{vue → components/sheet}/popups/export-popup.vue +2 -2
- package/src/{vue → components/sheet}/popups/fill-color-popup.vue +3 -3
- package/src/{vue → components/sheet}/popups/find-popup.vue +1 -1
- package/src/{vue → components/sheet}/popups/font-color-popup.vue +3 -3
- package/src/{vue → components/sheet}/popups/font-size-popup.vue +3 -3
- package/src/{vue → components/sheet}/popups/insert-image-popup.vue +1 -1
- package/src/{vue → components/sheet}/sheet-context-menu.ts +10 -4
- package/src/{vue → components/sheet}/sheet-toolbar.vue +2 -2
- package/src/{vue → components/sheet}/sheet.vue +6 -3
- package/src/{vue → components/sheet}/use-find-replace.ts +1 -1
- package/src/{vue → components/sheet}/use-sheet-grid.ts +23 -5
- package/src/{vue → components/sheet}/use-sheet-state.ts +11 -6
- package/src/{vue → components/sheet}/use-tool-groups.ts +2 -2
- package/src/{vue → components/sheet}/use-tool-popup.ts +2 -2
- package/src/index.ts +24 -188
- package/src/report/__test__/binding.test.ts +320 -0
- package/src/report/__test__/connector.test.ts +239 -0
- package/src/report/__test__/export-xlsx.test.ts +118 -0
- package/src/report/__test__/filter-bar.test.ts +58 -0
- package/src/report/__test__/params.test.ts +156 -0
- package/src/report/__test__/render.test.ts +830 -0
- package/src/report/__test__/rules.test.ts +131 -0
- package/src/report/__test__/template.test.ts +366 -0
- package/src/report/binding.ts +474 -0
- package/src/report/connector.ts +206 -0
- package/src/report/export-xlsx.ts +113 -0
- package/src/report/filter-bar.ts +36 -0
- package/src/report/index.ts +13 -0
- package/src/report/params.ts +96 -0
- package/src/report/render/__test__/aggregate.test.ts +16 -0
- package/src/report/render/__test__/coordinate.test.ts +405 -0
- package/src/report/render/aggregate.ts +261 -0
- package/src/report/render/builder.ts +211 -0
- package/src/report/render/coordinate.ts +1239 -0
- package/src/report/render/index.ts +30 -0
- package/src/report/render/style-resolver.ts +68 -0
- package/src/report/render/template-index.ts +200 -0
- package/src/report/rules/evaluate.ts +113 -0
- package/src/report/rules/index.ts +7 -0
- package/src/report/template.ts +145 -0
- package/src/report/types.ts +96 -0
- package/src/tools/__test__/apply-style.test.ts +129 -0
- package/src/tools/apply-style.ts +41 -0
- package/src/tools/builtin.ts +20 -20
- package/src/tools/context.ts +67 -4
- package/src/tools/index.ts +1 -0
- package/src/types/index.ts +2 -6
- package/src/types/report-designer.ts +38 -0
- package/src/types/report-viewer.ts +37 -0
- package/src/types/sheet.ts +26 -1
- /package/dist/{vue → components/sheet}/style.d.ts +0 -0
- /package/dist/{vue → components/sheet}/style.js +0 -0
- /package/dist/{vue → components/sheet}/style2.css +0 -0
- /package/dist/{vue → components/sheet}/use-formula-suggest.js +0 -0
- /package/src/{vue → components/sheet}/__test__/import-file.test.ts +0 -0
- /package/src/{vue → components/sheet}/__test__/insert-count-menu-item.test.ts +0 -0
- /package/src/{vue → components/sheet}/__test__/use-formula-ref-select.test.ts +0 -0
- /package/src/{vue → components/sheet}/__test__/use-formula-suggest.test.ts +0 -0
- /package/src/{vue → components/sheet}/formula-suggest-list.vue +0 -0
- /package/src/{vue → components/sheet}/import-file.ts +0 -0
- /package/src/{vue → components/sheet}/index.ts +0 -0
- /package/src/{vue → components/sheet}/insert-count-menu-item.vue +0 -0
- /package/src/{vue → components/sheet}/parsing.ts +0 -0
- /package/src/{vue → components/sheet}/popups/border-preset-glyph.vue +0 -0
- /package/src/{vue → components/sheet}/popups/import.worker.ts +0 -0
- /package/src/{vue → components/sheet}/sheet-tabs.vue +0 -0
- /package/src/{vue → components/sheet}/style.scss +0 -0
- /package/src/{vue → components/sheet}/style.ts +0 -0
- /package/src/{vue → components/sheet}/use-formula-ref-select.ts +0 -0
- /package/src/{vue → components/sheet}/use-formula-suggest.ts +0 -0
- /package/src/{vue → components/sheet}/use-sheet-tabs-bar.ts +0 -0
- /package/src/{vue → components/sheet}/use-toolbar-scroll.ts +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { parseRange } from '@veltra/sheet-core/core/address'
|
|
1
2
|
import { Workbook } from '@veltra/sheet-core/core/workbook'
|
|
2
|
-
import { ListTable } from '@visactor/vtable'
|
|
3
3
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
4
4
|
import { createApp, h, nextTick, type App } from 'vue'
|
|
5
5
|
|
|
6
|
-
import { USheet } from '
|
|
7
|
-
import
|
|
6
|
+
import { USheet } from '../../../index'
|
|
7
|
+
import { createSheetContext } from '../../../tools/context'
|
|
8
|
+
import type { SheetExposed } from '../../../types'
|
|
9
|
+
import UFormulaBar from '../formula-bar.vue'
|
|
8
10
|
|
|
9
11
|
const apps: App[] = []
|
|
10
12
|
const containers: HTMLElement[] = []
|
|
@@ -32,6 +34,26 @@ function mount(
|
|
|
32
34
|
return { app, el }
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
function mountFormulaBar(sheet: Workbook['activeSheet']) {
|
|
38
|
+
const el = document.createElement('div')
|
|
39
|
+
document.body.appendChild(el)
|
|
40
|
+
containers.push(el)
|
|
41
|
+
const exposed: { value: InstanceType<typeof UFormulaBar> | undefined } = { value: undefined }
|
|
42
|
+
const app = createApp({
|
|
43
|
+
render: () =>
|
|
44
|
+
h(UFormulaBar, {
|
|
45
|
+
sheet,
|
|
46
|
+
context: createSheetContext(sheet),
|
|
47
|
+
ref: (value: unknown) => {
|
|
48
|
+
exposed.value = value as InstanceType<typeof UFormulaBar> | undefined
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
app.mount(el)
|
|
53
|
+
apps.push(app)
|
|
54
|
+
return { el, exposed }
|
|
55
|
+
}
|
|
56
|
+
|
|
35
57
|
function createWorkbook() {
|
|
36
58
|
const workbook = new Workbook()
|
|
37
59
|
workbook.addSheet('Sheet2')
|
|
@@ -397,15 +419,16 @@ describe('USheet 公式栏:函数补全与引用选择', () => {
|
|
|
397
419
|
expect(sheet.getCellData({ row: 2, col: 0 })).toBeUndefined()
|
|
398
420
|
expect(input.value).toBe('=SUM(')
|
|
399
421
|
|
|
400
|
-
//
|
|
401
|
-
const
|
|
402
|
-
table.selectCells([{ start: { col: 1, row: 1 }, end: { col: 2, row: 2 } }])
|
|
403
|
-
table.fireListeners(ListTable.EVENT_TYPE.SELECTED_CELL, { col: 2, row: 2 })
|
|
422
|
+
// 网格选区拦截 → handleRefSelect 路径(VTable 时序见 sheet-core selection-debug)
|
|
423
|
+
const { el: barEl, exposed: barExposed } = mountFormulaBar(sheet)
|
|
404
424
|
await nextTick()
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
425
|
+
setFxText(barEl, '=SUM(')
|
|
426
|
+
await nextTick()
|
|
427
|
+
barExposed.value!.handleRefSelect(parseRange('A1:B2'))
|
|
428
|
+
await nextTick()
|
|
429
|
+
const barInput = fxInput(barEl)
|
|
430
|
+
expect(barInput.value).toBe('=SUM(A1:B2')
|
|
431
|
+
expect(barInput.selectionStart).toBe('=SUM(A1:B2'.length)
|
|
409
432
|
|
|
410
433
|
// 非引用选择场景失焦提交
|
|
411
434
|
setFxText(el, 'plain')
|
|
@@ -436,19 +459,15 @@ describe('USheet 公式栏:函数补全与引用选择', () => {
|
|
|
436
459
|
})
|
|
437
460
|
|
|
438
461
|
it('连续引用选择:=A1+ 后再插入 B1', async () => {
|
|
439
|
-
const
|
|
440
|
-
const
|
|
441
|
-
const exposed: { value: SheetExposed | undefined } = { value: undefined }
|
|
442
|
-
const { el } = mount(() => ({ workbook, rows: 20, cols: 8 }), exposed)
|
|
462
|
+
const sheet = new Workbook().activeSheet
|
|
463
|
+
const { el, exposed } = mountFormulaBar(sheet)
|
|
443
464
|
await nextTick()
|
|
444
465
|
sheet.selectCell({ row: 2, col: 0 })
|
|
445
466
|
await nextTick()
|
|
446
467
|
|
|
447
468
|
setFxText(el, '=A1+')
|
|
448
469
|
await nextTick()
|
|
449
|
-
|
|
450
|
-
table.selectCells([{ start: { col: 2, row: 1 }, end: { col: 2, row: 1 } }])
|
|
451
|
-
table.fireListeners(ListTable.EVENT_TYPE.SELECTED_CELL, { col: 2, row: 1 })
|
|
470
|
+
exposed.value!.handleRefSelect(parseRange('B1'))
|
|
452
471
|
await nextTick()
|
|
453
472
|
expect(fxInput(el).value).toBe('=A1+B1')
|
|
454
473
|
})
|
|
@@ -2,7 +2,7 @@ import { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
|
2
2
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
import { createApp, h, type App } from 'vue'
|
|
4
4
|
|
|
5
|
-
import { createSheetContext } from '
|
|
5
|
+
import { createSheetContext } from '../../../tools/context'
|
|
6
6
|
import USheetInsertImagePopup from '../popups/insert-image-popup.vue'
|
|
7
7
|
|
|
8
8
|
const mocks = vi.hoisted(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
2
2
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
|
-
import { createSheetContext } from '
|
|
4
|
+
import { createSheetContext } from '../../../tools/context'
|
|
5
5
|
import {
|
|
6
6
|
INSERT_IMAGE_ACCEPT,
|
|
7
7
|
insertImageFromFile,
|
|
@@ -2,9 +2,9 @@ import { Workbook } from '@veltra/sheet-core/core/workbook'
|
|
|
2
2
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
import { createApp, h, nextTick, ref, type App } from 'vue'
|
|
4
4
|
|
|
5
|
-
import { USheet } from '
|
|
6
|
-
import { registerTool, unregisterTool } from '
|
|
7
|
-
import type { SheetExposed } from '
|
|
5
|
+
import { USheet } from '../../../index'
|
|
6
|
+
import { registerTool, unregisterTool } from '../../../tools/registry'
|
|
7
|
+
import type { SheetExposed } from '../../../types'
|
|
8
8
|
|
|
9
9
|
const apps: App[] = []
|
|
10
10
|
const containers: HTMLElement[] = []
|
|
@@ -258,6 +258,80 @@ describe('USheet 组件', () => {
|
|
|
258
258
|
expect(gridAfter).not.toBe(gridBefore)
|
|
259
259
|
})
|
|
260
260
|
|
|
261
|
+
it('showRowHeader/showColHeader 为 false 时隐藏行号与列头', async () => {
|
|
262
|
+
const workbook = createWorkbook()
|
|
263
|
+
const exposed: { value: SheetExposed | undefined } = { value: undefined }
|
|
264
|
+
mount(
|
|
265
|
+
() => ({ workbook, rows: 8, cols: 4, showRowHeader: false, showColHeader: false }),
|
|
266
|
+
exposed
|
|
267
|
+
)
|
|
268
|
+
await nextTick()
|
|
269
|
+
|
|
270
|
+
workbook.activeSheet.setCellValue({ row: 0, col: 0 }, 'A1')
|
|
271
|
+
await nextTick()
|
|
272
|
+
const table = exposed.value!.getGrid()!.getTable()
|
|
273
|
+
expect(table.options.showHeader).toBe(false)
|
|
274
|
+
expect(table.options.rowSeriesNumber).toBeUndefined()
|
|
275
|
+
expect(table.columnHeaderLevelCount).toBe(0)
|
|
276
|
+
expect(table.rowCount).toBe(8)
|
|
277
|
+
expect(table.getCellValue(0, 0)).toBe('A1')
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
it('删除行后渲染行数跟随模型收缩(不被 props.rows 撑回)', async () => {
|
|
281
|
+
const workbook = createWorkbook()
|
|
282
|
+
const exposed: { value: SheetExposed | undefined } = { value: undefined }
|
|
283
|
+
mount(() => ({ workbook, rows: 10, cols: 6 }), exposed)
|
|
284
|
+
await nextTick()
|
|
285
|
+
|
|
286
|
+
const sheet = exposed.value!.getActiveSheet()
|
|
287
|
+
expect(sheet.rows).toBe(10)
|
|
288
|
+
expect(exposed.value!.getGrid()!.getTable().rowCount).toBe(11) // 列头 + 10
|
|
289
|
+
|
|
290
|
+
sheet.deleteRows(0, 2)
|
|
291
|
+
await nextTick()
|
|
292
|
+
await nextTick()
|
|
293
|
+
|
|
294
|
+
expect(sheet.rows).toBe(8)
|
|
295
|
+
expect(exposed.value!.getGrid()!.getTable().rowCount).toBe(9) // 列头 + 8
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
it('resolveCellStyle prop 传入 SheetGrid 视口渲染', async () => {
|
|
299
|
+
const workbook = createWorkbook()
|
|
300
|
+
const sheet = workbook.activeSheet
|
|
301
|
+
const exposed: { value: SheetExposed | undefined } = { value: undefined }
|
|
302
|
+
mount(
|
|
303
|
+
() => ({
|
|
304
|
+
workbook,
|
|
305
|
+
rows: 10,
|
|
306
|
+
cols: 6,
|
|
307
|
+
resolveCellStyle: (
|
|
308
|
+
addr: { row: number; col: number },
|
|
309
|
+
baseStyle?: { fill?: { color: string } }
|
|
310
|
+
) => {
|
|
311
|
+
if (addr.row === 1 && addr.col === 1) {
|
|
312
|
+
return { ...baseStyle, fill: { color: '#FFE0E0' } }
|
|
313
|
+
}
|
|
314
|
+
return baseStyle
|
|
315
|
+
}
|
|
316
|
+
}),
|
|
317
|
+
exposed
|
|
318
|
+
)
|
|
319
|
+
await nextTick()
|
|
320
|
+
|
|
321
|
+
const addr = { row: 1, col: 1 }
|
|
322
|
+
sheet.setCellStyle({ start: addr, end: addr }, { fill: { color: '#CCCCCC' } })
|
|
323
|
+
await nextTick()
|
|
324
|
+
|
|
325
|
+
const table = exposed.value?.getGrid()?.getTable()
|
|
326
|
+
expect(table).toBeDefined()
|
|
327
|
+
const column = table!.getBodyColumnDefine(2, 2) as {
|
|
328
|
+
style?: (arg: { row: number; col: number; table: unknown }) => Record<string, unknown>
|
|
329
|
+
}
|
|
330
|
+
const rendered = column.style!({ row: 2, col: 2, table })
|
|
331
|
+
expect(rendered.bgColor).toBe('#FFE0E0')
|
|
332
|
+
expect(sheet.getCellStyle(addr)?.fill?.color).toBe('#CCCCCC')
|
|
333
|
+
})
|
|
334
|
+
|
|
261
335
|
it('workbook prop 变更:tabs 与 grid 切到新工作簿', async () => {
|
|
262
336
|
const workbook1 = createWorkbook()
|
|
263
337
|
const workbook2 = new Workbook()
|
|
@@ -2,7 +2,7 @@ import { createRange } from '@veltra/sheet-core/core/address'
|
|
|
2
2
|
import { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
3
3
|
import { describe, expect, it } from 'vitest'
|
|
4
4
|
|
|
5
|
-
import { createSheetContext } from '
|
|
5
|
+
import { createSheetContext } from '../../../tools/context'
|
|
6
6
|
import {
|
|
7
7
|
buildBodyMenus,
|
|
8
8
|
buildColHeaderMenus,
|
|
@@ -36,8 +36,9 @@ describe('sheet-context-menu helpers', () => {
|
|
|
36
36
|
expect(isColInSelection(ranges, 6)).toBe(false)
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
it('resolveRenderSize
|
|
40
|
-
expect(resolveRenderSize(100, 26, 120, 10)).toEqual({ rows: 120, cols:
|
|
39
|
+
it('resolveRenderSize:模型已声明时以模型为准(可低于 props)', () => {
|
|
40
|
+
expect(resolveRenderSize(100, 26, 120, 10)).toEqual({ rows: 120, cols: 10 })
|
|
41
|
+
expect(resolveRenderSize(100, 26, 29, 26)).toEqual({ rows: 29, cols: 26 })
|
|
41
42
|
expect(resolveRenderSize(undefined, undefined, 0, 0)).toEqual({ rows: 100, cols: 26 })
|
|
42
43
|
})
|
|
43
44
|
})
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
watch
|
|
87
87
|
} from 'vue'
|
|
88
88
|
|
|
89
|
-
import type { SheetContext } from '
|
|
89
|
+
import type { SheetContext } from '../../tools/context'
|
|
90
90
|
import UFormulaSuggestList from './formula-suggest-list.vue'
|
|
91
91
|
import { insertRefText, isRefSelectContext } from './use-formula-ref-select'
|
|
92
92
|
import {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { message } from '@veltra/desktop'
|
|
2
2
|
import type { SheetImageType } from '@veltra/sheet-core/core/image'
|
|
3
3
|
|
|
4
|
-
import type { SheetContext } from '
|
|
4
|
+
import type { SheetContext } from '../../tools/context'
|
|
5
5
|
|
|
6
6
|
/** 文件选择 accept(工具栏弹层与右键菜单共用;不用裸 image/*) */
|
|
7
7
|
export const INSERT_IMAGE_ACCEPT = '.png,.jpg,.jpeg,.gif,.svg,.webp'
|
|
@@ -2,7 +2,7 @@ import type { CellRange } from '@veltra/sheet-core/core/address'
|
|
|
2
2
|
import type { BorderPreset } from '@veltra/sheet-core/core/style/border-presets'
|
|
3
3
|
import { BORDER_STYLE_WIDTH, type BorderLineStyle } from '@veltra/sheet-core/core/style/types'
|
|
4
4
|
|
|
5
|
-
import type { SheetContext } from '
|
|
5
|
+
import type { SheetContext } from '../../tools/context'
|
|
6
6
|
|
|
7
7
|
/** 当前选区(ranges[0] 优先;无区域选区时用活动格单格) */
|
|
8
8
|
export function currentRange(context: SheetContext): CellRange | null {
|
|
@@ -40,12 +40,13 @@ import { buildBorderPresetItems } from '@veltra/sheet-core/core/style/border-pre
|
|
|
40
40
|
import {
|
|
41
41
|
BORDER_STYLE_WIDTH,
|
|
42
42
|
type BorderEdge,
|
|
43
|
-
type BorderLineStyle
|
|
43
|
+
type BorderLineStyle,
|
|
44
|
+
type CellStylePatch
|
|
44
45
|
} from '@veltra/sheet-core/core/style/types'
|
|
45
46
|
import { bem } from '@veltra/utils'
|
|
46
47
|
import { ref } from 'vue'
|
|
47
48
|
|
|
48
|
-
import type { SheetContext } from '
|
|
49
|
+
import type { SheetContext } from '../../../tools/context'
|
|
49
50
|
import {
|
|
50
51
|
BORDER_LINE_STYLES,
|
|
51
52
|
BORDER_LINE_TITLES,
|
|
@@ -63,6 +64,7 @@ defineOptions({ name: 'USheetBorderPopup' })
|
|
|
63
64
|
* 预设补丁由 core/style/border-presets 生成(含邻居格共享边同步,对齐
|
|
64
65
|
* Excel「写入时同步、最近设置生效」);面板打开期间的写入由
|
|
65
66
|
* use-tool-popup 事务包裹为一个 undo 单元。
|
|
67
|
+
* 整行/整列选区下,均匀预设(all/none/单侧)走 applyStyle → 行列默认样式。
|
|
66
68
|
*/
|
|
67
69
|
const props = defineProps<{
|
|
68
70
|
/** 工具上下文(写入走命令系统,天然可撤销) */
|
|
@@ -75,7 +77,27 @@ const cls = bem('sheet')
|
|
|
75
77
|
const borderLineStyle = ref<BorderLineStyle>('thin')
|
|
76
78
|
const borderColor = ref('#000000')
|
|
77
79
|
|
|
78
|
-
/**
|
|
80
|
+
/** 均匀边框补丁(可写进行/列默认样式);outer/inner 几何相关 → null */
|
|
81
|
+
function uniformBorderPatch(preset: BorderPresetId, edge: BorderEdge): CellStylePatch | null {
|
|
82
|
+
switch (preset) {
|
|
83
|
+
case 'all':
|
|
84
|
+
return { border: { top: edge, right: edge, bottom: edge, left: edge } }
|
|
85
|
+
case 'none':
|
|
86
|
+
return { border: { top: null, right: null, bottom: null, left: null } }
|
|
87
|
+
case 'top':
|
|
88
|
+
return { border: { top: edge } }
|
|
89
|
+
case 'bottom':
|
|
90
|
+
return { border: { bottom: edge } }
|
|
91
|
+
case 'left':
|
|
92
|
+
return { border: { left: edge } }
|
|
93
|
+
case 'right':
|
|
94
|
+
return { border: { right: edge } }
|
|
95
|
+
default:
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** 应用边框预设:整行/整列均匀预设走 applyStyle;其余逐格批量(含邻居同步) */
|
|
79
101
|
function applyBorderPreset(preset: BorderPresetId): void {
|
|
80
102
|
const range = currentRange(props.context)
|
|
81
103
|
if (!range) return
|
|
@@ -84,8 +106,14 @@ function applyBorderPreset(preset: BorderPresetId): void {
|
|
|
84
106
|
width: BORDER_STYLE_WIDTH[borderLineStyle.value],
|
|
85
107
|
color: borderColor.value
|
|
86
108
|
}
|
|
109
|
+
const target = props.context.resolveStyleTarget(range)
|
|
110
|
+
const uniform = target !== 'cell' ? uniformBorderPatch(preset, edge) : null
|
|
111
|
+
if (uniform) {
|
|
112
|
+
props.context.applyStyle(range, uniform)
|
|
113
|
+
return
|
|
114
|
+
}
|
|
87
115
|
const items: SetCellStyleItem[] = buildBorderPresetItems(range, preset, edge, (addr) =>
|
|
88
|
-
props.context.
|
|
116
|
+
props.context.getEffectiveStyle(addr)
|
|
89
117
|
).map(({ addr, patch }) => ({ addr, partial: patch }))
|
|
90
118
|
if (items.length === 0) return
|
|
91
119
|
props.context.executeCommand('sheet.command.set-cell-style', { items })
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
import { message } from '@veltra/desktop'
|
|
14
14
|
import { bem } from '@veltra/utils'
|
|
15
15
|
|
|
16
|
-
import type { SheetContext } from '
|
|
17
|
-
import { exportSheetCsvFile, exportWorkbookFile } from '
|
|
16
|
+
import type { SheetContext } from '../../../tools/context'
|
|
17
|
+
import { exportSheetCsvFile, exportWorkbookFile } from '../../../tools/download'
|
|
18
18
|
|
|
19
19
|
defineOptions({ name: 'USheetExportPopup' })
|
|
20
20
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { UPalette } from '@veltra/desktop'
|
|
7
7
|
import { onMounted, ref } from 'vue'
|
|
8
8
|
|
|
9
|
-
import type { SheetContext } from '
|
|
9
|
+
import type { SheetContext } from '../../../tools/context'
|
|
10
10
|
import { currentRange } from '../popup-helpers'
|
|
11
11
|
|
|
12
12
|
defineOptions({ name: 'USheetFillColorPopup' })
|
|
@@ -26,7 +26,7 @@ const fillColor = ref('')
|
|
|
26
26
|
// 打开时初始化为活动格当前填充色
|
|
27
27
|
onMounted(() => {
|
|
28
28
|
const active = props.context.getSelection().activeCell
|
|
29
|
-
const style = active ? props.context.
|
|
29
|
+
const style = active ? props.context.getEffectiveStyle(active) : undefined
|
|
30
30
|
fillColor.value = style?.fill?.color ?? ''
|
|
31
31
|
})
|
|
32
32
|
|
|
@@ -34,6 +34,6 @@ onMounted(() => {
|
|
|
34
34
|
function applyFillColor(color: string): void {
|
|
35
35
|
const range = currentRange(props.context)
|
|
36
36
|
if (!range) return
|
|
37
|
-
props.context.
|
|
37
|
+
props.context.applyStyle(range, color ? { fill: { color } } : { fill: {} })
|
|
38
38
|
}
|
|
39
39
|
</script>
|
|
@@ -72,7 +72,7 @@ import { UInput } from '@veltra/desktop'
|
|
|
72
72
|
import type { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
73
73
|
import { bem } from '@veltra/utils'
|
|
74
74
|
|
|
75
|
-
import type { SheetContext } from '
|
|
75
|
+
import type { SheetContext } from '../../../tools/context'
|
|
76
76
|
import { useFindReplace } from '../use-find-replace'
|
|
77
77
|
|
|
78
78
|
defineOptions({ name: 'USheetFindPopup' })
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { UPalette } from '@veltra/desktop'
|
|
7
7
|
import { onMounted, ref } from 'vue'
|
|
8
8
|
|
|
9
|
-
import type { SheetContext } from '
|
|
9
|
+
import type { SheetContext } from '../../../tools/context'
|
|
10
10
|
import { currentRange } from '../popup-helpers'
|
|
11
11
|
|
|
12
12
|
defineOptions({ name: 'USheetFontColorPopup' })
|
|
@@ -26,7 +26,7 @@ const fontColor = ref('')
|
|
|
26
26
|
// 打开时初始化为活动格当前字体色
|
|
27
27
|
onMounted(() => {
|
|
28
28
|
const active = props.context.getSelection().activeCell
|
|
29
|
-
const style = active ? props.context.
|
|
29
|
+
const style = active ? props.context.getEffectiveStyle(active) : undefined
|
|
30
30
|
fontColor.value = style?.font?.color ?? ''
|
|
31
31
|
})
|
|
32
32
|
|
|
@@ -34,6 +34,6 @@ onMounted(() => {
|
|
|
34
34
|
function applyFontColor(color: string): void {
|
|
35
35
|
const range = currentRange(props.context)
|
|
36
36
|
if (!range) return
|
|
37
|
-
props.context.
|
|
37
|
+
props.context.applyStyle(range, color ? { font: { color } } : { font: { color: null } })
|
|
38
38
|
}
|
|
39
39
|
</script>
|
|
@@ -20,7 +20,7 @@ import { UScroll } from '@veltra/desktop'
|
|
|
20
20
|
import { bem } from '@veltra/utils'
|
|
21
21
|
import { onMounted, ref } from 'vue'
|
|
22
22
|
|
|
23
|
-
import type { SheetContext } from '
|
|
23
|
+
import type { SheetContext } from '../../../tools/context'
|
|
24
24
|
import { currentRange } from '../popup-helpers'
|
|
25
25
|
|
|
26
26
|
defineOptions({ name: 'USheetFontSizePopup' })
|
|
@@ -39,7 +39,7 @@ const currentSize = ref<number | undefined>(undefined)
|
|
|
39
39
|
|
|
40
40
|
onMounted(() => {
|
|
41
41
|
const active = props.context.getSelection().activeCell
|
|
42
|
-
const style = active ? props.context.
|
|
42
|
+
const style = active ? props.context.getEffectiveStyle(active) : undefined
|
|
43
43
|
currentSize.value = style?.font?.size
|
|
44
44
|
})
|
|
45
45
|
|
|
@@ -47,6 +47,6 @@ function applyFontSize(size: number): void {
|
|
|
47
47
|
const range = currentRange(props.context)
|
|
48
48
|
if (!range) return
|
|
49
49
|
currentSize.value = size
|
|
50
|
-
props.context.
|
|
50
|
+
props.context.applyStyle(range, { font: { size } })
|
|
51
51
|
}
|
|
52
52
|
</script>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { UFilePicker } from '@veltra/desktop'
|
|
16
16
|
import { bem } from '@veltra/utils'
|
|
17
17
|
|
|
18
|
-
import type { SheetContext } from '
|
|
18
|
+
import type { SheetContext } from '../../../tools/context'
|
|
19
19
|
import { INSERT_IMAGE_ACCEPT, insertImageFromFile } from '../insert-image'
|
|
20
20
|
|
|
21
21
|
defineOptions({ name: 'USheetInsertImagePopup' })
|
|
@@ -2,8 +2,8 @@ import type { ContextmenuItem } from '@veltra/desktop'
|
|
|
2
2
|
import { createRange, type CellAddress, type CellRange } from '@veltra/sheet-core/core/address'
|
|
3
3
|
import { defineComponent, h } from 'vue'
|
|
4
4
|
|
|
5
|
-
import type { SheetContext } from '
|
|
6
|
-
import { defaultToolRegistry } from '
|
|
5
|
+
import type { SheetContext } from '../../tools/context'
|
|
6
|
+
import { defaultToolRegistry } from '../../tools/registry'
|
|
7
7
|
import InsertCountMenuItem from './insert-count-menu-item.vue'
|
|
8
8
|
import { pickAndInsertImage } from './insert-image'
|
|
9
9
|
|
|
@@ -39,14 +39,20 @@ export function wholeColRange(col: number, rowCount: number): CellRange {
|
|
|
39
39
|
return createRange({ row: 0, col }, { row: Math.max(rowCount - 1, 0), col })
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* 渲染尺寸:模型已声明时以模型为准(删行可低于 props);未声明时回落 props。
|
|
44
|
+
* 与 SheetGrid / useSheetGrid 一致——避免 ensureTableSize(props) 把删行结果撑回。
|
|
45
|
+
*/
|
|
43
46
|
export function resolveRenderSize(
|
|
44
47
|
propsRows: number | undefined,
|
|
45
48
|
propsCols: number | undefined,
|
|
46
49
|
sheetRows: number,
|
|
47
50
|
sheetCols: number
|
|
48
51
|
): { rows: number; cols: number } {
|
|
49
|
-
return {
|
|
52
|
+
return {
|
|
53
|
+
rows: sheetRows > 0 ? sheetRows : (propsRows ?? 100),
|
|
54
|
+
cols: sheetCols > 0 ? sheetCols : (propsCols ?? 26)
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
function insertCountRender(options: {
|
|
@@ -61,8 +61,8 @@ import { ArrowLeft, ArrowRight } from '@veltra/icons/normal'
|
|
|
61
61
|
import { bem } from '@veltra/utils'
|
|
62
62
|
import { toRef, useTemplateRef } from 'vue'
|
|
63
63
|
|
|
64
|
-
import type { SheetTool } from '
|
|
65
|
-
import type { ToolGroupView } from '
|
|
64
|
+
import type { SheetTool } from '../../tools/registry'
|
|
65
|
+
import type { ToolGroupView } from './use-tool-groups'
|
|
66
66
|
import { useToolbarScroll } from './use-toolbar-scroll'
|
|
67
67
|
|
|
68
68
|
defineOptions({ name: 'USheetToolbar' })
|
|
@@ -77,8 +77,8 @@ import { UDropdown } from '@veltra/desktop'
|
|
|
77
77
|
import { bem } from '@veltra/utils'
|
|
78
78
|
import { computed, ref, useTemplateRef, watch } from 'vue'
|
|
79
79
|
|
|
80
|
-
import type { SheetTool } from '
|
|
81
|
-
import type { SheetEmits, SheetProps, _SheetExposed } from '
|
|
80
|
+
import type { SheetTool } from '../../tools/registry'
|
|
81
|
+
import type { SheetEmits, SheetProps, _SheetExposed } from '../../types'
|
|
82
82
|
import UFormulaBar from './formula-bar.vue'
|
|
83
83
|
import { pickAndImportFile } from './import-file'
|
|
84
84
|
import USheetBorderPopup from './popups/border-popup.vue'
|
|
@@ -102,7 +102,10 @@ const props = withDefaults(defineProps<SheetProps>(), {
|
|
|
102
102
|
cols: 26,
|
|
103
103
|
showToolbar: true,
|
|
104
104
|
showFormulaBar: true,
|
|
105
|
-
showTabs: true
|
|
105
|
+
showTabs: true,
|
|
106
|
+
showRowHeader: true,
|
|
107
|
+
showColHeader: true,
|
|
108
|
+
readonly: false
|
|
106
109
|
})
|
|
107
110
|
|
|
108
111
|
const emit = defineEmits<SheetEmits>()
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import type { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
15
15
|
import { computed, ref, shallowRef, watch } from 'vue'
|
|
16
16
|
|
|
17
|
-
import type { SheetContext } from '
|
|
17
|
+
import type { SheetContext } from '../../tools/context'
|
|
18
18
|
|
|
19
19
|
interface UseFindReplaceOptions {
|
|
20
20
|
/** 目标 sheet(弹层存活期间固定;tab 切换会关闭并销毁弹层) */
|
|
@@ -4,8 +4,8 @@ import type { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
|
4
4
|
import { SheetGrid, type SheetGridContextMenuInfo } from '@veltra/sheet-core/grid/sheet-grid'
|
|
5
5
|
import { onBeforeUnmount, onMounted, watch } from 'vue'
|
|
6
6
|
|
|
7
|
-
import type { SheetContext } from '
|
|
8
|
-
import type { SheetProps } from '
|
|
7
|
+
import type { SheetContext } from '../../tools/context'
|
|
8
|
+
import type { SheetProps } from '../../types'
|
|
9
9
|
import {
|
|
10
10
|
buildBodyMenus,
|
|
11
11
|
buildColHeaderMenus,
|
|
@@ -109,11 +109,19 @@ export function useSheetGrid(options: UseSheetGridOptions) {
|
|
|
109
109
|
const el = document.createElement('div')
|
|
110
110
|
el.className = 'u-sheet__grid-instance'
|
|
111
111
|
host.appendChild(el)
|
|
112
|
+
// 模型已声明尺寸时传入模型值,避免删行后被 props 经 ensureTableSize 撑回
|
|
113
|
+
const { rows, cols } = resolveRenderSize(props.rows, props.cols, sheet.rows, sheet.cols)
|
|
112
114
|
const grid = new SheetGrid({
|
|
113
115
|
container: el,
|
|
114
116
|
sheet,
|
|
115
|
-
rows
|
|
116
|
-
cols
|
|
117
|
+
rows,
|
|
118
|
+
cols,
|
|
119
|
+
readonly: props.readonly,
|
|
120
|
+
showRowHeader: props.showRowHeader,
|
|
121
|
+
showColHeader: props.showColHeader,
|
|
122
|
+
resolveDisplayValue: props.resolveDisplayValue,
|
|
123
|
+
resolveCellStyle: props.resolveCellStyle,
|
|
124
|
+
resolveCellRenderer: props.resolveCellRenderer,
|
|
117
125
|
onContextMenu: handleContextMenu,
|
|
118
126
|
onEditStart: (addr) => formulaBarRef.value?.mirrorGridEdit(addr),
|
|
119
127
|
onEditEnd: (addr) => formulaBarRef.value?.exitMirror(addr),
|
|
@@ -233,7 +241,17 @@ export function useSheetGrid(options: UseSheetGridOptions) {
|
|
|
233
241
|
|
|
234
242
|
onMounted(activateGrid)
|
|
235
243
|
|
|
236
|
-
|
|
244
|
+
// props 尺寸显式增大时先扩张模型,再重建(删行缩小不走这条路径)
|
|
245
|
+
watch(
|
|
246
|
+
() =>
|
|
247
|
+
[props.rows, props.cols, props.readonly, props.showRowHeader, props.showColHeader] as const,
|
|
248
|
+
([nextRows, nextCols]) => {
|
|
249
|
+
const sheet = getActiveSheet()
|
|
250
|
+
if (nextRows != null) sheet.ensureTableSize(nextRows, 0)
|
|
251
|
+
if (nextCols != null) sheet.ensureTableSize(0, nextCols)
|
|
252
|
+
rebuildGrid()
|
|
253
|
+
}
|
|
254
|
+
)
|
|
237
255
|
|
|
238
256
|
onBeforeUnmount(() => {
|
|
239
257
|
invalidateAll()
|
|
@@ -2,9 +2,10 @@ import type { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
|
2
2
|
import { Workbook } from '@veltra/sheet-core/core/workbook'
|
|
3
3
|
import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
|
|
4
4
|
|
|
5
|
-
import { createSheetContext } from '
|
|
6
|
-
import { defaultToolRegistry } from '
|
|
7
|
-
import type { SheetProps } from '
|
|
5
|
+
import { createSheetContext } from '../../tools/context'
|
|
6
|
+
import { defaultToolRegistry } from '../../tools/registry'
|
|
7
|
+
import type { SheetProps } from '../../types'
|
|
8
|
+
import { resolveRenderSize } from './sheet-context-menu'
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* useSheetState 与宿主组件的协作钩子。
|
|
@@ -44,10 +45,14 @@ export function useSheetState(props: SheetProps, emit: Emit, hooks: SheetStateHo
|
|
|
44
45
|
() => sheetList.value[activeIndex.value] ?? workbook.value.activeSheet
|
|
45
46
|
)
|
|
46
47
|
|
|
47
|
-
/** 工具上下文:动态解析活动 sheet
|
|
48
|
+
/** 工具上下文:动态解析活动 sheet / 工作簿 / 渲染尺寸,tab 切换后自动指向最新值 */
|
|
48
49
|
const context = createSheetContext(
|
|
49
50
|
() => activeSheet.value,
|
|
50
|
-
() => workbook.value
|
|
51
|
+
() => workbook.value,
|
|
52
|
+
{
|
|
53
|
+
resolveGridSize: () =>
|
|
54
|
+
resolveRenderSize(props.rows, props.cols, activeSheet.value.rows, activeSheet.value.cols)
|
|
55
|
+
}
|
|
51
56
|
)
|
|
52
57
|
|
|
53
58
|
/** 工具栏状态版本号:visible/disabled/active 是 (ctx) => boolean 纯函数,状态源变化时 bump 触发重算 */
|
|
@@ -80,7 +85,7 @@ export function useSheetState(props: SheetProps, emit: Emit, hooks: SheetStateHo
|
|
|
80
85
|
// 整表内容替换(导入 / undo/redo 回放):restore 静默不发 cell-change,
|
|
81
86
|
// 状态源需 bump(grid 层自行订阅 content-reset 全量刷新,此处不重建)
|
|
82
87
|
sheet.on('content-reset', scheduleBump),
|
|
83
|
-
// 行列插入/删除 →
|
|
88
|
+
// 行列插入/删除 → 重建网格(渲染行列数跟随模型 sheet.rows/cols,
|
|
84
89
|
// 数据/选区/冻结/行高随重建恢复;低频操作直接重建)
|
|
85
90
|
sheet.on('structure-change', hooks.rebuildGrid)
|
|
86
91
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { computed, type ComputedRef, type Ref } from 'vue'
|
|
2
2
|
|
|
3
|
-
import type { SheetContext } from '
|
|
4
|
-
import { defaultToolRegistry, type SheetTool } from '
|
|
3
|
+
import type { SheetContext } from '../../tools/context'
|
|
4
|
+
import { defaultToolRegistry, type SheetTool } from '../../tools/registry'
|
|
5
5
|
|
|
6
6
|
/** 工具栏按钮视图模型 */
|
|
7
7
|
export interface ToolGroupItem {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { onBeforeUnmount, onMounted, shallowRef } from 'vue'
|
|
2
2
|
|
|
3
|
-
import type { SheetContext } from '
|
|
4
|
-
import { defaultToolRegistry, type SheetTool } from '
|
|
3
|
+
import type { SheetContext } from '../../tools/context'
|
|
4
|
+
import { defaultToolRegistry, type SheetTool } from '../../tools/registry'
|
|
5
5
|
|
|
6
6
|
/** 模板 ref 只读形态 */
|
|
7
7
|
type ElRef = { readonly value: HTMLElement | null | undefined }
|