@veltra/sheet 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/fill.d.ts +34 -0
- package/dist/core/fill.js +320 -0
- package/dist/core/fill.js.map +1 -0
- package/dist/core/formula/dependency-graph.d.ts +1 -1
- package/dist/core/sheet.d.ts +13 -2
- package/dist/core/sheet.js +22 -0
- package/dist/core/sheet.js.map +1 -1
- package/dist/grid/sheet-grid.d.ts +23 -1
- package/dist/grid/sheet-grid.js +109 -8
- package/dist/grid/sheet-grid.js.map +1 -1
- package/dist/grid/vtable-theme.js +80 -0
- package/dist/grid/vtable-theme.js.map +1 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.js +2 -1
- package/dist/tools/context.d.ts +2 -2
- package/dist/vue/sheet.js +27 -1
- package/dist/vue/sheet.js.map +1 -1
- package/dist/vue/style.d.ts +1 -1
- package/dist/vue/style.js +1 -0
- package/package.json +2 -1
- package/src/core/__test__/fill.test.ts +140 -0
- package/src/core/fill.ts +314 -0
- package/src/core/sheet.ts +25 -0
- package/src/env.d.ts +3 -0
- package/src/grid/__test__/sheet-grid.test.ts +98 -0
- package/src/grid/sheet-grid.ts +133 -9
- package/src/grid/vtable-theme.ts +61 -0
- package/src/index.ts +1 -0
- package/src/vue/sheet.vue +42 -2
- package/src/vue/style.ts +1 -0
package/src/grid/sheet-grid.ts
CHANGED
|
@@ -3,10 +3,16 @@ import type { ListTableConstructorOptions } from '@visactor/vtable'
|
|
|
3
3
|
import { InputEditor } from '@visactor/vtable-editors'
|
|
4
4
|
import type { EditContext } from '@visactor/vtable-editors'
|
|
5
5
|
|
|
6
|
-
import type { CellAddress } from '../core/address'
|
|
6
|
+
import type { CellAddress, CellRange } from '../core/address'
|
|
7
7
|
import { cellKey, colIndexToName, createRange } from '../core/address'
|
|
8
8
|
import type { CellValue } from '../core/cell-store'
|
|
9
|
+
import { computeFillTargetRange, generateFill, type FillDirection } from '../core/fill'
|
|
9
10
|
import type { Sheet } from '../core/sheet'
|
|
11
|
+
import {
|
|
12
|
+
SHEET_DEFAULT_ROW_HEIGHT,
|
|
13
|
+
sheetRowSeriesNumberStyle,
|
|
14
|
+
sheetVTableTheme
|
|
15
|
+
} from './vtable-theme'
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
18
|
* VTable 适配层:数据模型完全自持有,ListTable 只做渲染与输入。
|
|
@@ -18,7 +24,10 @@ import type { Sheet } from '../core/sheet'
|
|
|
18
24
|
* 编辑提交期间模型变更(含公式重算派生格)先入待同步队列,提交结束统一回推表格——
|
|
19
25
|
* VTable 自己只更新了被编辑格的 record(还是输入文本),派生格它不知道
|
|
20
26
|
* - 键盘:容器 keydown 绑定 undo/redo(Cmd/Ctrl+Z、Cmd/Ctrl+Shift+Z、Ctrl+Y),
|
|
21
|
-
* 编辑器 input
|
|
27
|
+
* 编辑器 input 打开时不拦截;编辑态方向键不换格(moveEditCellOnArrowKeys: false)
|
|
28
|
+
* - 填充柄:excelOptions.fillHandle + mousedown/drag_end → core/fill → setCells
|
|
29
|
+
* - 行列尺寸:列宽仅列头;行高仅行号列(包装 _canResizeRow)。稀疏存 Sheet.rowHeights,
|
|
30
|
+
* RESIZE_ROW_END 同步,重建时还原
|
|
22
31
|
* - 坐标换算:行号列不计入 rowHeaderLevelCount,偏移量在首个表格实例上
|
|
23
32
|
* 用 columnHeaderLevelCount + isSeriesNumber 实测并缓存(见 getOffsets)
|
|
24
33
|
*/
|
|
@@ -37,6 +46,27 @@ class FormulaAwareInputEditor extends InputEditor {
|
|
|
37
46
|
/** 编辑器按 grid 实例注册(hook 闭包各自 sheet),名称递增防冲突 */
|
|
38
47
|
let editorSeq = 0
|
|
39
48
|
|
|
49
|
+
/** 右键菜单回调参数(vue 层弹 UContextmenu;grid 不依赖 desktop) */
|
|
50
|
+
export interface SheetGridContextMenuInfo {
|
|
51
|
+
x: number
|
|
52
|
+
y: number
|
|
53
|
+
/** body 格地址;行号/列头为 null */
|
|
54
|
+
addr: CellAddress | null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** 从 VTable 事件载荷提取 viewport 坐标(兼容 nativeEvent 嵌套) */
|
|
58
|
+
function clientPointFromEvent(event: unknown): { x: number; y: number } | null {
|
|
59
|
+
let current: unknown = event
|
|
60
|
+
for (let i = 0; i < 3 && current && typeof current === 'object'; i++) {
|
|
61
|
+
if ('clientX' in current && typeof (current as { clientX: unknown }).clientX === 'number') {
|
|
62
|
+
const { clientX, clientY } = current as { clientX: number; clientY: number }
|
|
63
|
+
return { x: clientX, y: clientY }
|
|
64
|
+
}
|
|
65
|
+
current = 'nativeEvent' in current ? (current as { nativeEvent: unknown }).nativeEvent : null
|
|
66
|
+
}
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
40
70
|
export interface SheetGridOptions {
|
|
41
71
|
container: HTMLElement
|
|
42
72
|
sheet: Sheet
|
|
@@ -44,6 +74,8 @@ export interface SheetGridOptions {
|
|
|
44
74
|
rows?: number
|
|
45
75
|
/** 渲染列数,默认 26(A..Z) */
|
|
46
76
|
cols?: number
|
|
77
|
+
/** 单元格右键(已 preventDefault);由 vue 层弹出菜单 */
|
|
78
|
+
onContextMenu?: (info: SheetGridContextMenuInfo) => void
|
|
47
79
|
}
|
|
48
80
|
|
|
49
81
|
export class SheetGrid {
|
|
@@ -53,17 +85,21 @@ export class SheetGrid {
|
|
|
53
85
|
private readonly rows: number
|
|
54
86
|
private readonly cols: number
|
|
55
87
|
private readonly editorName: string
|
|
88
|
+
private readonly onContextMenu?: (info: SheetGridContextMenuInfo) => void
|
|
56
89
|
private readonly disposers: (() => void)[] = []
|
|
57
90
|
/** 编辑提交期间累积的模型变更(提交结束统一回推表格,覆盖公式派生格) */
|
|
58
91
|
private pendingTableSync: Map<number, CellAddress> | null = null
|
|
59
92
|
/** 实测坐标偏移(行号列数 / 列头行数),首次使用时测量 */
|
|
60
93
|
private offsets?: { colOffset: number; rowOffset: number }
|
|
94
|
+
/** 填充柄:mousedown 时的源选区(模型坐标) */
|
|
95
|
+
private fillSourceRange: CellRange | null = null
|
|
61
96
|
|
|
62
97
|
constructor(options: SheetGridOptions) {
|
|
63
98
|
this.sheet = options.sheet
|
|
64
99
|
this.container = options.container
|
|
65
100
|
this.rows = options.rows ?? 100
|
|
66
101
|
this.cols = options.cols ?? 26
|
|
102
|
+
this.onContextMenu = options.onContextMenu
|
|
67
103
|
|
|
68
104
|
// 每个 grid 实例注册自己的编辑器(hook 闭包本实例的 sheet 与坐标换算)
|
|
69
105
|
this.editorName = `veltra-sheet-input-${editorSeq++}`
|
|
@@ -77,6 +113,8 @@ export class SheetGrid {
|
|
|
77
113
|
register.editor(this.editorName, editor)
|
|
78
114
|
|
|
79
115
|
this.table = new ListTable(options.container, this.buildOptions())
|
|
116
|
+
this.restrictRowResizeToSeriesNumber()
|
|
117
|
+
this.applyStoredRowHeights()
|
|
80
118
|
this.bindTableEvents()
|
|
81
119
|
this.bindSheetEvents()
|
|
82
120
|
this.bindKeyboard()
|
|
@@ -163,14 +201,24 @@ export class SheetGrid {
|
|
|
163
201
|
records: this.buildRecords(),
|
|
164
202
|
columns: this.buildColumns(),
|
|
165
203
|
widthMode: 'standard',
|
|
166
|
-
|
|
204
|
+
defaultRowHeight: SHEET_DEFAULT_ROW_HEIGHT,
|
|
205
|
+
// 列宽只在列头(A/B/C…)。行高:VTable rowResizeMode:'header' 以 isHeader()
|
|
206
|
+
// 判定,而行号列 body 格不是 header——设 'header' 会禁用行号列调行高。
|
|
207
|
+
// 因此 row 用 'all',构造后限制到行号列(见 restrictRowResizeToSeriesNumber)。
|
|
208
|
+
resize: { columnResizeMode: 'header', rowResizeMode: 'all' },
|
|
209
|
+
theme: sheetVTableTheme,
|
|
210
|
+
rowSeriesNumber: { width: 46, style: sheetRowSeriesNumberStyle },
|
|
211
|
+
excelOptions: { fillHandle: true },
|
|
212
|
+
// 禁止浏览器默认右键菜单,改由 CONTEXTMENU_CELL → UContextmenu
|
|
213
|
+
eventOptions: { preventDefaultContextMenu: true },
|
|
167
214
|
editor: this.editorName,
|
|
168
215
|
editCellTrigger: 'doubleclick',
|
|
169
216
|
keyboardOptions: {
|
|
170
217
|
moveFocusCellOnTab: true,
|
|
171
218
|
editCellOnEnter: true,
|
|
172
219
|
moveFocusCellOnEnter: true,
|
|
173
|
-
|
|
220
|
+
// 编辑中方向键只移输入光标;未编辑时选区导航不受影响
|
|
221
|
+
moveEditCellOnArrowKeys: false,
|
|
174
222
|
selectAllOnCtrlA: true
|
|
175
223
|
},
|
|
176
224
|
customMergeCell: (col, row, table) => {
|
|
@@ -197,6 +245,24 @@ export class SheetGrid {
|
|
|
197
245
|
}
|
|
198
246
|
}
|
|
199
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 行高只允许在行号列拖拽(Excel 语义)。
|
|
250
|
+
* VTable 无 canResizeRow,且 'header' 不含 rowSeriesNumber body,故包装 _canResizeRow。
|
|
251
|
+
*/
|
|
252
|
+
private restrictRowResizeToSeriesNumber(): void {
|
|
253
|
+
const table = this.table
|
|
254
|
+
const base = table._canResizeRow.bind(table)
|
|
255
|
+
table._canResizeRow = (col, row) => table.isSeriesNumber(col, row) && base(col, row)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** 按 Sheet 稀疏行高还原到 VTable(tab 切换重建后保留) */
|
|
259
|
+
private applyStoredRowHeights(): void {
|
|
260
|
+
for (const [row, height] of this.sheet.getRowHeights()) {
|
|
261
|
+
const tableRow = this.toTableCoord(this.table, { row, col: 0 }).row
|
|
262
|
+
this.table.setRowHeight(tableRow, height)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
200
266
|
// ─── 事件桥接 ─────────────────────────────────────────────
|
|
201
267
|
|
|
202
268
|
private bindTableEvents(): void {
|
|
@@ -225,13 +291,71 @@ export class SheetGrid {
|
|
|
225
291
|
|
|
226
292
|
// 拖选结束 → 选区同步为区域(合并等区域操作的前提)
|
|
227
293
|
this.table.on(ListTable.EVENT_TYPE.DRAG_SELECT_END, () => {
|
|
228
|
-
const range = this.
|
|
294
|
+
const range = this.readSelectedModelRange()
|
|
229
295
|
if (!range) return
|
|
230
|
-
|
|
231
|
-
const end = this.toSheetAddr(this.table, range.end.col, range.end.row)
|
|
232
|
-
if (!start || !end) return
|
|
233
|
-
this.sheet.selectRange(createRange(start, end))
|
|
296
|
+
this.sheet.selectRange(range)
|
|
234
297
|
})
|
|
298
|
+
|
|
299
|
+
// 行高拖拽结束 → 写入模型稀疏表(不进 undo)
|
|
300
|
+
this.table.on(ListTable.EVENT_TYPE.RESIZE_ROW_END, (args) => {
|
|
301
|
+
const addr = this.toSheetAddr(this.table, this.getOffsets(this.table).colOffset, args.row)
|
|
302
|
+
if (!addr) return
|
|
303
|
+
this.sheet.setRowHeight(addr.row, args.rowHeight)
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
// 填充柄:记下源选区
|
|
307
|
+
this.table.on(ListTable.EVENT_TYPE.MOUSEDOWN_FILL_HANDLE, () => {
|
|
308
|
+
this.fillSourceRange = this.readSelectedModelRange()
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
// 填充柄拖拽结束 → generateFill → setCells
|
|
312
|
+
this.table.on(ListTable.EVENT_TYPE.DRAG_FILL_HANDLE_END, (args) => {
|
|
313
|
+
const source = this.fillSourceRange
|
|
314
|
+
this.fillSourceRange = null
|
|
315
|
+
const direction = args.direction as FillDirection | undefined
|
|
316
|
+
if (!source || !direction) return
|
|
317
|
+
const expanded = this.readSelectedModelRange()
|
|
318
|
+
if (!expanded) return
|
|
319
|
+
const target = computeFillTargetRange(source, direction, expanded)
|
|
320
|
+
if (!target) return
|
|
321
|
+
const items = generateFill({
|
|
322
|
+
source,
|
|
323
|
+
target,
|
|
324
|
+
direction,
|
|
325
|
+
getCellData: (addr) => this.sheet.getCellData(addr)
|
|
326
|
+
})
|
|
327
|
+
if (items.length === 0) return
|
|
328
|
+
this.sheet.setCells(items)
|
|
329
|
+
this.sheet.selectRange(createRange(source.start, expanded.end))
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
// 右键 → vue 层 UContextmenu(grid 不依赖 desktop)
|
|
333
|
+
// VTable 在 rightdown 上派发 CONTEXTMENU_CELL(非原生 contextmenu)
|
|
334
|
+
this.table.on(ListTable.EVENT_TYPE.CONTEXTMENU_CELL, (args) => {
|
|
335
|
+
const event = args.event
|
|
336
|
+
if (event && typeof event === 'object' && 'preventDefault' in event) {
|
|
337
|
+
;(event as { preventDefault: () => void }).preventDefault()
|
|
338
|
+
}
|
|
339
|
+
if (!this.onContextMenu) return
|
|
340
|
+
const point = clientPointFromEvent(event)
|
|
341
|
+
// 延后一帧:避开 VTable rightdown 同步阶段,保证菜单挂载后不被同轮指针事件干扰
|
|
342
|
+
const info: SheetGridContextMenuInfo = {
|
|
343
|
+
x: point?.x ?? 0,
|
|
344
|
+
y: point?.y ?? 0,
|
|
345
|
+
addr: this.toSheetAddr(this.table, args.col, args.row)
|
|
346
|
+
}
|
|
347
|
+
queueMicrotask(() => this.onContextMenu?.(info))
|
|
348
|
+
})
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** 当前 VTable 选区 → 规范化模型区域;无有效 body 选区返回 null */
|
|
352
|
+
private readSelectedModelRange(): CellRange | null {
|
|
353
|
+
const range = this.table.getSelectedCellRanges()[0]
|
|
354
|
+
if (!range) return null
|
|
355
|
+
const start = this.toSheetAddr(this.table, range.start.col, range.start.row)
|
|
356
|
+
const end = this.toSheetAddr(this.table, range.end.col, range.end.row)
|
|
357
|
+
if (!start || !end) return null
|
|
358
|
+
return createRange(start, end)
|
|
235
359
|
}
|
|
236
360
|
|
|
237
361
|
private bindSheetEvents(): void {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { themes } from '@visactor/vtable'
|
|
2
|
+
|
|
3
|
+
/** 行号 / 列头浅底(canvas 主题无法读 CSS 变量,固定色贴近 Excel) */
|
|
4
|
+
const CHROME_BG = '#F5F5F5'
|
|
5
|
+
/** body 纯白,覆盖 DEFAULT 斑马底色 */
|
|
6
|
+
const BODY_BG = '#FFF'
|
|
7
|
+
/** 网格线 / 外框:浅灰(勿用 DEFAULTBORDERCOLOR #000) */
|
|
8
|
+
const GRID_BORDER = '#E1E4E8'
|
|
9
|
+
/** 选区边框:清晰蓝(覆盖 DEFAULT 的 #0000ff) */
|
|
10
|
+
const SELECTION_BORDER = '#2170E7'
|
|
11
|
+
/** 选区填充 */
|
|
12
|
+
const SELECTION_BG = 'rgba(33, 112, 231, 0.12)'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 单元格内边距 [上, 右, 下, 左]。
|
|
16
|
+
* VTable DEFAULT 为 `[10, 16, 10, 16]`,配合 `defaultRowHeight: 28` 会挤占文字区;
|
|
17
|
+
* 收紧到贴近 Excel 的密度(仍留少量呼吸空间)。
|
|
18
|
+
*/
|
|
19
|
+
export const SHEET_CELL_PADDING = [2, 6, 2, 6] as const
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Sheet 默认 VTable 主题。
|
|
23
|
+
*
|
|
24
|
+
* 必须基于 `themes.DEFAULT.extends`:传入裸对象时 VTable 不会继承 DEFAULT,
|
|
25
|
+
* 缺省 `borderColor` 会回落到内部 `DEFAULTBORDERCOLOR = '#000'`,出现刺眼黑线。
|
|
26
|
+
*/
|
|
27
|
+
export const sheetVTableTheme = themes.DEFAULT.extends({
|
|
28
|
+
underlayBackgroundColor: BODY_BG,
|
|
29
|
+
defaultStyle: {
|
|
30
|
+
bgColor: CHROME_BG,
|
|
31
|
+
borderColor: GRID_BORDER,
|
|
32
|
+
padding: [...SHEET_CELL_PADDING],
|
|
33
|
+
textOverflow: 'clip'
|
|
34
|
+
},
|
|
35
|
+
headerStyle: { bgColor: CHROME_BG, borderColor: GRID_BORDER, textOverflow: 'clip' },
|
|
36
|
+
cornerHeaderStyle: { bgColor: CHROME_BG, borderColor: GRID_BORDER, textOverflow: 'clip' },
|
|
37
|
+
rowHeaderStyle: { bgColor: CHROME_BG, borderColor: GRID_BORDER, textOverflow: 'clip' },
|
|
38
|
+
bodyStyle: { bgColor: BODY_BG, borderColor: GRID_BORDER, textOverflow: 'clip' },
|
|
39
|
+
frameStyle: {
|
|
40
|
+
borderColor: GRID_BORDER,
|
|
41
|
+
borderLineWidth: 1,
|
|
42
|
+
shadowBlur: 0,
|
|
43
|
+
shadowColor: 'transparent'
|
|
44
|
+
},
|
|
45
|
+
selectionStyle: {
|
|
46
|
+
cellBgColor: SELECTION_BG,
|
|
47
|
+
cellBorderColor: SELECTION_BORDER,
|
|
48
|
+
cellBorderLineWidth: 2
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
/** 行号列默认样式(与主题 chrome 对齐) */
|
|
53
|
+
export const sheetRowSeriesNumberStyle = {
|
|
54
|
+
bgColor: CHROME_BG,
|
|
55
|
+
borderColor: GRID_BORDER,
|
|
56
|
+
padding: [...SHEET_CELL_PADDING],
|
|
57
|
+
textOverflow: 'clip' as const
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 默认行高(比 VTable 默认 40 更接近表格密度;与 SHEET_CELL_PADDING 搭配) */
|
|
61
|
+
export const SHEET_DEFAULT_ROW_HEIGHT = 28
|
package/src/index.ts
CHANGED
package/src/vue/sheet.vue
CHANGED
|
@@ -35,12 +35,14 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<script lang="ts" setup>
|
|
38
|
+
import { contextmenu } from '@veltra/desktop'
|
|
38
39
|
import { bem } from '@veltra/utils'
|
|
39
40
|
import { computed, onBeforeUnmount, onMounted, ref, shallowRef, useTemplateRef, watch } from 'vue'
|
|
40
41
|
|
|
42
|
+
import { rangeContainsAddress } from '../core/address'
|
|
41
43
|
import type { Sheet } from '../core/sheet'
|
|
42
44
|
import { Workbook } from '../core/workbook'
|
|
43
|
-
import { SheetGrid } from '../grid/sheet-grid'
|
|
45
|
+
import { SheetGrid, type SheetGridContextMenuInfo } from '../grid/sheet-grid'
|
|
44
46
|
import { createSheetContext } from '../tools/context'
|
|
45
47
|
import { defaultToolRegistry, type SheetTool } from '../tools/registry'
|
|
46
48
|
import type { SheetEmits, SheetProps, _SheetExposed } from '../types'
|
|
@@ -146,13 +148,51 @@ function handleTabClick(index: number): void {
|
|
|
146
148
|
if (sheet) workbook.value.activateSheet(sheet.name)
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
// ─── 右键菜单(合并 / 取消合并,语义对齐内置工具)────────────
|
|
152
|
+
|
|
153
|
+
function handleContextMenu(info: SheetGridContextMenuInfo): void {
|
|
154
|
+
// body 格:若点击落在当前选区外则先选中该格;行号/列头保留当前选区
|
|
155
|
+
if (info.addr) {
|
|
156
|
+
const inSelection = context
|
|
157
|
+
.getSelection()
|
|
158
|
+
.ranges.some((range) => rangeContainsAddress(range, info.addr!))
|
|
159
|
+
if (!inSelection) context.selectCell(info.addr)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const mergeTool = defaultToolRegistry.get('merge')
|
|
163
|
+
const unmergeTool = defaultToolRegistry.get('unmerge')
|
|
164
|
+
|
|
165
|
+
contextmenu.pop({
|
|
166
|
+
mousePosition: { x: info.x, y: info.y },
|
|
167
|
+
width: 180,
|
|
168
|
+
menus: [
|
|
169
|
+
{
|
|
170
|
+
label: '合并单元格',
|
|
171
|
+
disabled: mergeTool?.disabled?.(context) ?? true,
|
|
172
|
+
callback: () => mergeTool?.onClick(context)
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
label: '取消合并单元格',
|
|
176
|
+
disabled: unmergeTool?.disabled?.(context) ?? true,
|
|
177
|
+
callback: () => unmergeTool?.onClick(context)
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
149
183
|
// ─── grid 生命周期 ──────────────────────────────────────────
|
|
150
184
|
|
|
151
185
|
function rebuildGrid(): void {
|
|
152
186
|
const container = gridRef.value
|
|
153
187
|
if (!container) return
|
|
154
188
|
grid?.release()
|
|
155
|
-
grid = new SheetGrid({
|
|
189
|
+
grid = new SheetGrid({
|
|
190
|
+
container,
|
|
191
|
+
sheet: activeSheet.value,
|
|
192
|
+
rows: props.rows,
|
|
193
|
+
cols: props.cols,
|
|
194
|
+
onContextMenu: handleContextMenu
|
|
195
|
+
})
|
|
156
196
|
}
|
|
157
197
|
|
|
158
198
|
onMounted(() => {
|
package/src/vue/style.ts
CHANGED