@veltra/sheet 2.5.8 → 2.7.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/sheet/formula-bar.js +6 -1
- package/dist/components/sheet/sheet-context-menu.js +41 -5
- package/dist/components/sheet/sheet.js +19 -6
- package/dist/components/sheet/style2.css +1 -1
- package/dist/components/sheet/use-sheet-grid.js +20 -7
- package/dist/components/sheet/use-sheet-state.js +4 -1
- package/dist/components/sheet/use-tool-popup.js +1 -2
- package/dist/index.d.ts +2 -2
- package/dist/tools/context.d.ts +15 -0
- package/dist/tools/context.js +22 -1
- package/dist/types/sheet.d.ts +25 -5
- package/package.json +5 -2
- package/src/components/sheet/__test__/formula-bar.test.ts +52 -42
- package/src/components/sheet/__test__/functions-popup.test.ts +1 -1
- package/src/components/sheet/__test__/import-file.test.ts +1 -1
- package/src/components/sheet/__test__/insert-count-menu-item.test.ts +1 -1
- package/src/components/sheet/__test__/insert-image-popup.test.ts +1 -1
- package/src/components/sheet/__test__/insert-image.test.ts +1 -1
- package/src/components/sheet/__test__/sheet-component.test.ts +357 -24
- package/src/components/sheet/__test__/sheet-context-menu.test.ts +32 -3
- package/src/components/sheet/__test__/use-formula-ref-select.test.ts +1 -1
- package/src/components/sheet/__test__/use-formula-suggest.test.ts +1 -1
- package/src/components/sheet/formula-bar.vue +14 -1
- package/src/components/sheet/sheet-context-menu.ts +61 -4
- package/src/components/sheet/sheet.vue +9 -4
- package/src/components/sheet/style.scss +2 -2
- package/src/components/sheet/use-sheet-grid.ts +36 -9
- package/src/components/sheet/use-sheet-state.ts +5 -1
- package/src/components/sheet/use-tool-popup.ts +5 -4
- package/src/index.ts +1 -1
- package/src/tools/__test__/apply-style.test.ts +1 -1
- package/src/tools/__test__/builtin.test.ts +1 -1
- package/src/tools/__test__/context.test.ts +66 -2
- package/src/tools/__test__/registry.test.ts +1 -1
- package/src/tools/context.ts +47 -0
- package/src/types/sheet.ts +24 -5
- package/src/components/sheet/parsing.ts +0 -11
|
@@ -14,7 +14,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
14
14
|
__name: "formula-bar",
|
|
15
15
|
props: {
|
|
16
16
|
sheet: {},
|
|
17
|
-
context: {}
|
|
17
|
+
context: {},
|
|
18
|
+
setSelectionAnchor: { type: Function }
|
|
18
19
|
},
|
|
19
20
|
setup(__props, { expose: __expose }) {
|
|
20
21
|
/**
|
|
@@ -233,6 +234,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
233
234
|
mirrorAddr = null;
|
|
234
235
|
editing.value = true;
|
|
235
236
|
editAddr = selection.value.activeCell;
|
|
237
|
+
if (editAddr) props.setSelectionAnchor?.(editAddr);
|
|
236
238
|
syncFxCursor();
|
|
237
239
|
scheduleAutosize();
|
|
238
240
|
}
|
|
@@ -290,6 +292,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
290
292
|
editing.value = false;
|
|
291
293
|
editAddr = null;
|
|
292
294
|
suppressBlurCommit = false;
|
|
295
|
+
props.setSelectionAnchor?.(null);
|
|
293
296
|
closeSuggest();
|
|
294
297
|
if (addr) {
|
|
295
298
|
props.context.setCellValue(addr, fxDraft.value);
|
|
@@ -303,6 +306,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
303
306
|
editing.value = false;
|
|
304
307
|
editAddr = null;
|
|
305
308
|
suppressBlurCommit = false;
|
|
309
|
+
props.setSelectionAnchor?.(null);
|
|
306
310
|
closeSuggest();
|
|
307
311
|
refreshFx();
|
|
308
312
|
}
|
|
@@ -394,6 +398,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
394
398
|
fxDraft.value = text;
|
|
395
399
|
fxCursor.value = cursor;
|
|
396
400
|
suppressBlurCommit = false;
|
|
401
|
+
props.setSelectionAnchor?.(addr);
|
|
397
402
|
closeSuggest();
|
|
398
403
|
nextTick(() => {
|
|
399
404
|
const el = fxRef.value;
|
|
@@ -4,6 +4,8 @@ import _sfc_main from "./insert-count-menu-item.js";
|
|
|
4
4
|
import { createRange } from "@veltra/sheet-core/core/address.js";
|
|
5
5
|
import { defineComponent, h } from "vue";
|
|
6
6
|
const INSERT_COUNT_MAX = 1e3;
|
|
7
|
+
/** 行高/列宽数值项输入上限(下限复用门面 MIN_ROW_COL_SIZE,对齐引擎 resize 最小值) */
|
|
8
|
+
const AXIS_SIZE_MAX = 1e3;
|
|
7
9
|
/** 选区覆盖行/列数 → 插入默认 N(min 1 / max 1000) */
|
|
8
10
|
function defaultInsertCount(range, axis) {
|
|
9
11
|
if (!range) return 1;
|
|
@@ -71,11 +73,33 @@ function insertCountRender(options) {
|
|
|
71
73
|
max: INSERT_COUNT_MAX
|
|
72
74
|
});
|
|
73
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* 行高/列宽菜单项:内嵌数值输入,确认经门面批量应用到选区覆盖行/列。
|
|
78
|
+
* readonly 时降级为禁用文本项——render 内嵌组件自带点击路径,disabled 拦不住。
|
|
79
|
+
*/
|
|
80
|
+
function axisSizeMenuItem(options) {
|
|
81
|
+
if (options.disabled) return {
|
|
82
|
+
label: options.label,
|
|
83
|
+
disabled: true
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
label: options.label,
|
|
87
|
+
keepOpen: true,
|
|
88
|
+
render: menuNumberRender({
|
|
89
|
+
prefix: options.label,
|
|
90
|
+
suffix: "像素",
|
|
91
|
+
defaultValue: options.defaultValue,
|
|
92
|
+
min: 20,
|
|
93
|
+
max: AXIS_SIZE_MAX,
|
|
94
|
+
onConfirm: options.onConfirm
|
|
95
|
+
})
|
|
96
|
+
};
|
|
97
|
+
}
|
|
74
98
|
function primaryRange(ctx) {
|
|
75
99
|
return ctx.getSelection().ranges[0] ?? null;
|
|
76
100
|
}
|
|
77
|
-
/** 行号右键菜单:插入×2 / 删除 / divider / 冻结 / 取消冻结 */
|
|
78
|
-
function buildRowHeaderMenus(ctx) {
|
|
101
|
+
/** 行号右键菜单:插入×2 / 删除 / 行高 / divider / 冻结 / 取消冻结 */
|
|
102
|
+
function buildRowHeaderMenus(ctx, options) {
|
|
79
103
|
const range = primaryRange(ctx);
|
|
80
104
|
const startRow = range?.start.row ?? 0;
|
|
81
105
|
const endRow = range?.end.row ?? startRow;
|
|
@@ -108,6 +132,12 @@ function buildRowHeaderMenus(ctx) {
|
|
|
108
132
|
label: "删除行",
|
|
109
133
|
callback: () => ctx.deleteRows(startRow, deleteCount)
|
|
110
134
|
},
|
|
135
|
+
axisSizeMenuItem({
|
|
136
|
+
label: "行高",
|
|
137
|
+
disabled: options?.readonly === true,
|
|
138
|
+
defaultValue: ctx.getRowHeight(startRow) ?? 28,
|
|
139
|
+
onConfirm: (n) => ctx.setRowHeightBySelection(n)
|
|
140
|
+
}),
|
|
111
141
|
{ divider: true },
|
|
112
142
|
{
|
|
113
143
|
label: freezeActive ? "✓ 冻结到当前行" : "冻结到当前行",
|
|
@@ -120,8 +150,8 @@ function buildRowHeaderMenus(ctx) {
|
|
|
120
150
|
}
|
|
121
151
|
];
|
|
122
152
|
}
|
|
123
|
-
/** 列头右键菜单:插入×2 / 删除 / divider / 冻结 / 取消冻结 */
|
|
124
|
-
function buildColHeaderMenus(ctx) {
|
|
153
|
+
/** 列头右键菜单:插入×2 / 删除 / 列宽 / divider / 冻结 / 取消冻结 */
|
|
154
|
+
function buildColHeaderMenus(ctx, options) {
|
|
125
155
|
const range = primaryRange(ctx);
|
|
126
156
|
const startCol = range?.start.col ?? 0;
|
|
127
157
|
const endCol = range?.end.col ?? startCol;
|
|
@@ -154,6 +184,12 @@ function buildColHeaderMenus(ctx) {
|
|
|
154
184
|
label: "删除列",
|
|
155
185
|
callback: () => ctx.deleteCols(startCol, deleteCount)
|
|
156
186
|
},
|
|
187
|
+
axisSizeMenuItem({
|
|
188
|
+
label: "列宽",
|
|
189
|
+
disabled: options?.readonly === true,
|
|
190
|
+
defaultValue: ctx.getColWidth(startCol) ?? 80,
|
|
191
|
+
onConfirm: (n) => ctx.setColWidthBySelection(n)
|
|
192
|
+
}),
|
|
157
193
|
{ divider: true },
|
|
158
194
|
{
|
|
159
195
|
label: freezeActive ? "✓ 冻结到当前列" : "冻结到当前列",
|
|
@@ -249,4 +285,4 @@ function ensureContextMenuSelection(ctx, info, renderSize) {
|
|
|
249
285
|
}
|
|
250
286
|
}
|
|
251
287
|
//#endregion
|
|
252
|
-
export { INSERT_COUNT_MAX, applyNumFmtToSelection, buildBodyMenus, buildColHeaderMenus, buildRowHeaderMenus, defaultInsertCount, ensureContextMenuSelection, isColInSelection, isRowInSelection, resolveRenderSize, wholeColRange, wholeRowRange };
|
|
288
|
+
export { AXIS_SIZE_MAX, INSERT_COUNT_MAX, applyNumFmtToSelection, buildBodyMenus, buildColHeaderMenus, buildRowHeaderMenus, defaultInsertCount, ensureContextMenuSelection, isColInSelection, isRowInSelection, resolveRenderSize, wholeColRange, wholeRowRange };
|
|
@@ -28,6 +28,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
28
28
|
resolveDisplayValue: {},
|
|
29
29
|
resolveCellStyle: {},
|
|
30
30
|
resolveCellRenderer: {},
|
|
31
|
+
header: {},
|
|
32
|
+
editors: {},
|
|
31
33
|
showToolbar: {
|
|
32
34
|
type: Boolean,
|
|
33
35
|
default: true
|
|
@@ -51,9 +53,13 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
51
53
|
readonly: {
|
|
52
54
|
type: Boolean,
|
|
53
55
|
default: false
|
|
56
|
+
},
|
|
57
|
+
colResize: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: false
|
|
54
60
|
}
|
|
55
61
|
},
|
|
56
|
-
emits: ["active-sheet-change"],
|
|
62
|
+
emits: ["active-sheet-change", "col-resize-end"],
|
|
57
63
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
58
64
|
const props = __props;
|
|
59
65
|
const emit = __emit;
|
|
@@ -64,7 +70,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
64
70
|
onBeforeSheetChange: () => closePopup(),
|
|
65
71
|
rebuildGrid: () => rebuildGrid(),
|
|
66
72
|
activateGrid: () => activateGrid(),
|
|
67
|
-
pruneCache: (sheets) => pruneCache(sheets)
|
|
73
|
+
pruneCache: (sheets) => pruneCache(sheets),
|
|
74
|
+
syncAxisSizes: (axis, indexes) => getGrid()?.applyAxisSizes(axis, indexes)
|
|
68
75
|
});
|
|
69
76
|
const { popupTool, popupAnchor, closePopup, handleToolClick: openOrRunTool } = useToolPopup(context, rootRef);
|
|
70
77
|
const parsing = ref(false);
|
|
@@ -108,13 +115,14 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
108
115
|
const toolGroups = useToolGroups(context, stateTick);
|
|
109
116
|
const gridRef = useTemplateRef("gridRef");
|
|
110
117
|
const formulaBarRef = useTemplateRef("formulaBarRef");
|
|
111
|
-
const { rebuildGrid, activateGrid, pruneCache, getGrid } = useSheetGrid({
|
|
118
|
+
const { rebuildGrid, activateGrid, pruneCache, getGrid, setSelectionAnchor } = useSheetGrid({
|
|
112
119
|
props,
|
|
113
120
|
gridRef,
|
|
114
121
|
getActiveSheet: () => activeSheet.value,
|
|
115
122
|
context,
|
|
116
123
|
formulaBarRef,
|
|
117
|
-
isFunctionPopupOpen: () => popupTool.value?.popup === "functions"
|
|
124
|
+
isFunctionPopupOpen: () => popupTool.value?.popup === "functions",
|
|
125
|
+
onColResizeEnd: (event) => emit("col-resize-end", event)
|
|
118
126
|
});
|
|
119
127
|
__expose({
|
|
120
128
|
workbook,
|
|
@@ -188,8 +196,13 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
188
196
|
ref_key: "formulaBarRef",
|
|
189
197
|
ref: formulaBarRef,
|
|
190
198
|
sheet: unref(activeSheet),
|
|
191
|
-
context: unref(context)
|
|
192
|
-
|
|
199
|
+
context: unref(context),
|
|
200
|
+
"set-selection-anchor": unref(setSelectionAnchor)
|
|
201
|
+
}, null, 8, [
|
|
202
|
+
"sheet",
|
|
203
|
+
"context",
|
|
204
|
+
"set-selection-anchor"
|
|
205
|
+
])) : createCommentVNode("v-if", true),
|
|
193
206
|
createElementVNode("div", {
|
|
194
207
|
ref_key: "gridRef",
|
|
195
208
|
ref: gridRef,
|
|
@@ -5,9 +5,9 @@ import { SheetGrid } from "@veltra/sheet-core/grid";
|
|
|
5
5
|
//#region src/components/sheet/use-sheet-grid.ts
|
|
6
6
|
/**
|
|
7
7
|
* 缓存容量:最近 N 个 sheet 的 SheetGrid 实例常驻(tab 来回切换零重建)。
|
|
8
|
-
* 大文件多 sheet
|
|
8
|
+
* 大文件多 sheet 场景下切换卡顿的主因是每次重建引擎表格(实例创建 + 画布分层
|
|
9
9
|
* 首屏构建 ~300ms);缓存命中时仅切换容器可见性 + 选区回驱(≈0)。
|
|
10
|
-
*
|
|
10
|
+
* 每实例持有一组 [data-layer-kind] 分层画布,容量即内存上限(含隐藏实例的渲染开销)。
|
|
11
11
|
*/
|
|
12
12
|
const GRID_CACHE_CAPACITY = 3;
|
|
13
13
|
/**
|
|
@@ -29,7 +29,7 @@ function useSheetGrid(options) {
|
|
|
29
29
|
const sheet = getActiveSheet();
|
|
30
30
|
const renderSize = resolveRenderSize(props.rows, props.cols, sheet.rows, sheet.cols);
|
|
31
31
|
ensureContextMenuSelection(context, info, renderSize);
|
|
32
|
-
const menus = info.kind === "row-header" ? buildRowHeaderMenus(context) : info.kind === "col-header" ? buildColHeaderMenus(context) : buildBodyMenus(context);
|
|
32
|
+
const menus = info.kind === "row-header" ? buildRowHeaderMenus(context, { readonly: props.readonly }) : info.kind === "col-header" ? buildColHeaderMenus(context, { readonly: props.readonly }) : buildBodyMenus(context);
|
|
33
33
|
contextmenu.pop({
|
|
34
34
|
mousePosition: {
|
|
35
35
|
x: info.x,
|
|
@@ -69,9 +69,13 @@ function useSheetGrid(options) {
|
|
|
69
69
|
resolveDisplayValue: props.resolveDisplayValue,
|
|
70
70
|
resolveCellStyle: props.resolveCellStyle,
|
|
71
71
|
resolveCellRenderer: props.resolveCellRenderer,
|
|
72
|
+
header: props.header,
|
|
73
|
+
editors: props.editors,
|
|
74
|
+
colResize: props.colResize,
|
|
72
75
|
onContextMenu: handleContextMenu,
|
|
73
76
|
onEditStart: (addr) => formulaBarRef.value?.mirrorGridEdit(addr),
|
|
74
77
|
onEditEnd: (addr) => formulaBarRef.value?.exitMirror(addr),
|
|
78
|
+
onColResizeEnd: options.onColResizeEnd,
|
|
75
79
|
interceptSelection: () => (formulaBarRef.value?.isRefSelecting() ?? false) || (formulaBarRef.value?.isFunctionPopupOpen() ?? false) || (options.isFunctionPopupOpen?.() ?? false),
|
|
76
80
|
onSelectionIntercept: (range) => formulaBarRef.value?.handleRefSelect(range)
|
|
77
81
|
});
|
|
@@ -128,12 +132,13 @@ function useSheetGrid(options) {
|
|
|
128
132
|
* 命中时校验实例是否过期(隐藏期间程序化 structure-change——插入/删除/undo
|
|
129
133
|
* 行列——vue 层只绑定激活 sheet 的 structure-change,隐藏实例靠自持订阅标记
|
|
130
134
|
* dirty);过期则释放重建。命中且未过期只翻可见性:隐藏实例的 cell/merge/
|
|
131
|
-
* content-reset 已在
|
|
132
|
-
*
|
|
135
|
+
* content-reset 已在 SheetGrid 内部置脏,setVisible(true) 时一次性全量同步,
|
|
136
|
+
* 无需宿主补推送。
|
|
133
137
|
*/
|
|
134
138
|
function activateGrid() {
|
|
135
139
|
const sheet = getActiveSheet();
|
|
136
140
|
if (!gridRef.value) return;
|
|
141
|
+
if (active && active.sheet !== sheet) active.grid.setSelectionAnchor(null);
|
|
137
142
|
const cached = cache.get(sheet);
|
|
138
143
|
if (cached && !cached.dirty) {
|
|
139
144
|
cached.lastUsed = ++seq;
|
|
@@ -177,7 +182,10 @@ function useSheetGrid(options) {
|
|
|
177
182
|
props.cols,
|
|
178
183
|
props.readonly,
|
|
179
184
|
props.showRowHeader,
|
|
180
|
-
props.showColHeader
|
|
185
|
+
props.showColHeader,
|
|
186
|
+
props.header,
|
|
187
|
+
props.editors,
|
|
188
|
+
props.colResize
|
|
181
189
|
], ([nextRows, nextCols]) => {
|
|
182
190
|
const sheet = getActiveSheet();
|
|
183
191
|
if (nextRows != null) sheet.ensureTableSize(nextRows, 0);
|
|
@@ -187,11 +195,16 @@ function useSheetGrid(options) {
|
|
|
187
195
|
onBeforeUnmount(() => {
|
|
188
196
|
invalidateAll();
|
|
189
197
|
});
|
|
198
|
+
/** fx 引用拾取会话置/清选区锚点(公式栏 → 活动实例透传;无活动实例时静默) */
|
|
199
|
+
function setSelectionAnchor(addr) {
|
|
200
|
+
active?.grid.setSelectionAnchor(addr);
|
|
201
|
+
}
|
|
190
202
|
return {
|
|
191
203
|
rebuildGrid,
|
|
192
204
|
activateGrid,
|
|
193
205
|
pruneCache,
|
|
194
|
-
getGrid: () => active?.grid
|
|
206
|
+
getGrid: () => active?.grid,
|
|
207
|
+
setSelectionAnchor
|
|
195
208
|
};
|
|
196
209
|
}
|
|
197
210
|
//#endregion
|
|
@@ -21,7 +21,10 @@ function useSheetState(props, emit, hooks) {
|
|
|
21
21
|
const sheetList = shallowRef(workbook.value.getSheets());
|
|
22
22
|
const activeSheet = computed(() => sheetList.value[activeIndex.value] ?? workbook.value.activeSheet);
|
|
23
23
|
/** 工具上下文:动态解析活动 sheet / 工作簿 / 渲染尺寸,tab 切换后自动指向最新值 */
|
|
24
|
-
const context = createSheetContext(() => activeSheet.value, () => workbook.value, {
|
|
24
|
+
const context = createSheetContext(() => activeSheet.value, () => workbook.value, {
|
|
25
|
+
resolveGridSize: () => resolveRenderSize(props.rows, props.cols, activeSheet.value.rows, activeSheet.value.cols),
|
|
26
|
+
syncAxisSizes: (axis, indexes) => hooks.syncAxisSizes(axis, indexes)
|
|
27
|
+
});
|
|
25
28
|
/** 工具栏状态版本号:visible/disabled/active 是 (ctx) => boolean 纯函数,状态源变化时 bump 触发重算 */
|
|
26
29
|
const stateTick = ref(0);
|
|
27
30
|
const bump = () => {
|
|
@@ -89,8 +89,7 @@ function useToolPopup(context, rootEl) {
|
|
|
89
89
|
const root = rootEl.value;
|
|
90
90
|
if (root) {
|
|
91
91
|
const target = event.target instanceof Node ? event.target : null;
|
|
92
|
-
|
|
93
|
-
if (!(target !== null && root.contains(target) || active !== null && root.contains(active)) && popupTool.value === null) return;
|
|
92
|
+
if (!(target !== null && root.contains(target)) && popupTool.value === null) return;
|
|
94
93
|
}
|
|
95
94
|
event.preventDefault();
|
|
96
95
|
const findTool = defaultToolRegistry.get("find");
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _sfc_main from "./components/sheet/sheet.js";
|
|
2
2
|
import { SheetContext, createSheetContext } from "./tools/context.js";
|
|
3
3
|
import { SheetTool, SheetToolGroup, SheetToolPopupType, defaultToolRegistry, registerTool, unregisterTool } from "./tools/registry.js";
|
|
4
|
-
import { SheetEmits, SheetExposed, SheetProps
|
|
4
|
+
import { SheetEmits, SheetExposed, SheetProps } from "./types/sheet.js";
|
|
5
5
|
import "./types/index.js";
|
|
6
|
-
export { type SheetContext, type SheetEmits, type SheetExposed, type SheetProps, type SheetTool, type SheetToolGroup, type SheetToolPopupType, _sfc_main as USheet,
|
|
6
|
+
export { type SheetContext, type SheetEmits, type SheetExposed, type SheetProps, type SheetTool, type SheetToolGroup, type SheetToolPopupType, _sfc_main as USheet, createSheetContext, defaultToolRegistry, registerTool, unregisterTool };
|
package/dist/tools/context.d.ts
CHANGED
|
@@ -83,6 +83,14 @@ export interface SheetContext {
|
|
|
83
83
|
readonly frozen: FrozenState;
|
|
84
84
|
/** 设置冻结行列数(不进 undo,同 rowHeights 先例) */
|
|
85
85
|
setFrozen(rows: number, cols: number): void;
|
|
86
|
+
/** 读取自定义行高;未设置返回 undefined(视图层用默认行高) */
|
|
87
|
+
getRowHeight(row: number): number | undefined;
|
|
88
|
+
/** 读取自定义列宽;未设置返回 undefined(视图层用默认列宽) */
|
|
89
|
+
getColWidth(col: number): number | undefined;
|
|
90
|
+
/** 按选区覆盖行批量设置行高(下限钳到 MIN_ROW_COL_SIZE;不进 undo,同 rowHeights 先例) */
|
|
91
|
+
setRowHeightBySelection(height: number): void;
|
|
92
|
+
/** 按选区覆盖列批量设置列宽(下限钳到 MIN_ROW_COL_SIZE;不进 undo,同 colWidths 先例) */
|
|
93
|
+
setColWidthBySelection(width: number): void;
|
|
86
94
|
/** 插入 count 行到 at 行之前 */
|
|
87
95
|
insertRows(at: number, count?: number): void;
|
|
88
96
|
/** 插入 count 列到 at 列之前 */
|
|
@@ -117,6 +125,12 @@ export interface SheetContextOptions {
|
|
|
117
125
|
rows: number;
|
|
118
126
|
cols: number;
|
|
119
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* 行列尺寸写模型后的即时同步钩子:`Sheet.setRowHeight`/`setColWidth` 不发事件,
|
|
130
|
+
* 宿主经此把尺寸落到活动 SheetGrid 引擎 table(菜单数值项画面即时生效);
|
|
131
|
+
* 缺省(无头 / 测试直挂 Sheet)时仅写模型。
|
|
132
|
+
*/
|
|
133
|
+
syncAxisSizes?: (axis: 'row' | 'col', indexes: number[]) => void;
|
|
120
134
|
}
|
|
121
135
|
/**
|
|
122
136
|
* 创建工具上下文。
|
|
@@ -127,6 +141,7 @@ export interface SheetContextOptions {
|
|
|
127
141
|
* 上下文始终解析到**当前**工作簿(#2:旧实现取构造时值快照,宿主切换
|
|
128
142
|
* workbook prop 后导出工具仍导出旧工作簿)
|
|
129
143
|
* @param options.resolveGridSize 渲染尺寸解析器(整行/整列样式路由)
|
|
144
|
+
* @param options.syncAxisSizes 行列尺寸写模型后的即时同步钩子(USheet 接活动 grid)
|
|
130
145
|
*/
|
|
131
146
|
export declare function createSheetContext(resolveSheet: Sheet | (() => Sheet), workbook?: Workbook | (() => Workbook), options?: SheetContextOptions): SheetContext;
|
|
132
147
|
//#endregion
|
package/dist/tools/context.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { axisStyleItemsForRange, classifySelectionStyleTarget } from "./apply-style.js";
|
|
2
|
-
//#region src/tools/context.ts
|
|
3
2
|
/**
|
|
4
3
|
* 创建工具上下文。
|
|
5
4
|
* @param resolveSheet 活动 sheet 解析器(USheet 传 `() => activeSheet`,
|
|
@@ -9,11 +8,13 @@ import { axisStyleItemsForRange, classifySelectionStyleTarget } from "./apply-st
|
|
|
9
8
|
* 上下文始终解析到**当前**工作簿(#2:旧实现取构造时值快照,宿主切换
|
|
10
9
|
* workbook prop 后导出工具仍导出旧工作簿)
|
|
11
10
|
* @param options.resolveGridSize 渲染尺寸解析器(整行/整列样式路由)
|
|
11
|
+
* @param options.syncAxisSizes 行列尺寸写模型后的即时同步钩子(USheet 接活动 grid)
|
|
12
12
|
*/
|
|
13
13
|
function createSheetContext(resolveSheet, workbook, options) {
|
|
14
14
|
const sheet = typeof resolveSheet === "function" ? resolveSheet : () => resolveSheet;
|
|
15
15
|
const resolveWorkbook = typeof workbook === "function" ? workbook : workbook != null ? () => workbook : void 0;
|
|
16
16
|
const resolveGridSize = options?.resolveGridSize;
|
|
17
|
+
const syncAxisSizes = options?.syncAxisSizes;
|
|
17
18
|
const resolveTarget = (range) => {
|
|
18
19
|
const size = resolveGridSize?.();
|
|
19
20
|
return size ? classifySelectionStyleTarget(range, size.rows, size.cols) : "cell";
|
|
@@ -74,6 +75,26 @@ function createSheetContext(resolveSheet, workbook, options) {
|
|
|
74
75
|
return sheet().frozen;
|
|
75
76
|
},
|
|
76
77
|
setFrozen: (rows, cols) => sheet().setFrozen(rows, cols),
|
|
78
|
+
getRowHeight: (row) => sheet().getRowHeight(row),
|
|
79
|
+
getColWidth: (col) => sheet().getColWidth(col),
|
|
80
|
+
setRowHeightBySelection: (height) => {
|
|
81
|
+
const size = Math.max(20, height);
|
|
82
|
+
const rows = [];
|
|
83
|
+
for (const range of sheet().getSelection().ranges) for (let row = range.start.row; row <= range.end.row; row++) {
|
|
84
|
+
sheet().setRowHeight(row, size);
|
|
85
|
+
rows.push(row);
|
|
86
|
+
}
|
|
87
|
+
if (rows.length > 0) syncAxisSizes?.("row", rows);
|
|
88
|
+
},
|
|
89
|
+
setColWidthBySelection: (width) => {
|
|
90
|
+
const size = Math.max(20, width);
|
|
91
|
+
const cols = [];
|
|
92
|
+
for (const range of sheet().getSelection().ranges) for (let col = range.start.col; col <= range.end.col; col++) {
|
|
93
|
+
sheet().setColWidth(col, size);
|
|
94
|
+
cols.push(col);
|
|
95
|
+
}
|
|
96
|
+
if (cols.length > 0) syncAxisSizes?.("col", cols);
|
|
97
|
+
},
|
|
77
98
|
insertRows: (at, count) => sheet().insertRows(at, count),
|
|
78
99
|
insertCols: (at, count) => sheet().insertCols(at, count),
|
|
79
100
|
deleteRows: (at, count) => sheet().deleteRows(at, count),
|
package/dist/types/sheet.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SheetContext } from "../tools/context.js";
|
|
2
2
|
import { ComputedRef } from "vue";
|
|
3
3
|
import { DeconstructValue } from "@veltra/utils";
|
|
4
|
-
import { ResolveCellRenderer, ResolveCellStyleHook, ResolveDisplayValue, SheetGrid } from "@veltra/sheet-core/grid";
|
|
4
|
+
import { ResolveCellRenderer, ResolveCellStyleHook, ResolveDisplayValue, SheetGrid, SheetGridEditorsOptions, SheetGridHeaderOptions } from "@veltra/sheet-core/grid";
|
|
5
5
|
import { Workbook } from "@veltra/sheet-core/core/workbook.js";
|
|
6
6
|
import { Sheet } from "@veltra/sheet-core/core/sheet.js";
|
|
7
7
|
//#region src/types/sheet.d.ts
|
|
@@ -14,7 +14,7 @@ export interface SheetProps {
|
|
|
14
14
|
/** 渲染列数,默认 26(A..Z) */
|
|
15
15
|
cols?: number;
|
|
16
16
|
/**
|
|
17
|
-
* 显示值覆盖(设计态 Binding Placeholder
|
|
17
|
+
* 显示值覆盖(设计态 Binding Placeholder 等):覆盖引擎视口显示文本,不写 CellData.v
|
|
18
18
|
*/
|
|
19
19
|
resolveDisplayValue?: ResolveDisplayValue;
|
|
20
20
|
/**
|
|
@@ -22,11 +22,21 @@ export interface SheetProps {
|
|
|
22
22
|
*/
|
|
23
23
|
resolveCellStyle?: ResolveCellStyleHook;
|
|
24
24
|
/**
|
|
25
|
-
* 动态单元格渲染(ADR-0004
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* 动态单元格渲染(ADR-0004):视口布局时按格自定义渲染形态(返回引擎
|
|
26
|
+
* `CellRenderer`,见 `@veltra/sheet-core/grid`),返回 undefined 回落默认渲染;
|
|
27
|
+
* 不写模型、不进快照
|
|
28
28
|
*/
|
|
29
29
|
resolveCellRenderer?: ResolveCellRenderer;
|
|
30
|
+
/**
|
|
31
|
+
* 列头机制(透传 SheetGrid):按列列头标题与表头自定义 DOM 渲染,不传保持
|
|
32
|
+
* 缺省字母表头;传值变化(引用更替)触发网格重建
|
|
33
|
+
*/
|
|
34
|
+
header?: SheetGridHeaderOptions;
|
|
35
|
+
/**
|
|
36
|
+
* 类型化编辑器机制(透传 SheetGrid):多编辑器注册与按格路由,不传保持统一
|
|
37
|
+
* 文本编辑器;readonly 下忽略;传值变化(引用更替)触发网格重建
|
|
38
|
+
*/
|
|
39
|
+
editors?: SheetGridEditorsOptions;
|
|
30
40
|
/** 是否显示工具栏,默认 true */
|
|
31
41
|
showToolbar?: boolean;
|
|
32
42
|
/** 是否显示顶部公式栏(名称框 + fx 输入栏),默认 true */
|
|
@@ -39,6 +49,11 @@ export interface SheetProps {
|
|
|
39
49
|
showColHeader?: boolean;
|
|
40
50
|
/** 只读预览(关闭编辑回写、填充柄等写入口) */
|
|
41
51
|
readonly?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* 列宽拖拽(透传 SheetGrid):readonly 下置 true 仅放开列头 resize 手柄,编辑仍
|
|
54
|
+
* 关闭;缺省 false 行为不变。变化触发网格重建(构造期选项)
|
|
55
|
+
*/
|
|
56
|
+
colResize?: boolean;
|
|
42
57
|
}
|
|
43
58
|
export interface SheetEmits {
|
|
44
59
|
/** 激活 sheet 切换(点击 tab 或宿主调用 workbook.activateSheet) */
|
|
@@ -46,6 +61,11 @@ export interface SheetEmits {
|
|
|
46
61
|
sheet: Sheet;
|
|
47
62
|
index: number;
|
|
48
63
|
}): void;
|
|
64
|
+
/** 列宽拖拽落定(写模型之后):载荷含列索引与最终宽度 */
|
|
65
|
+
(name: 'col-resize-end', payload: {
|
|
66
|
+
col: number;
|
|
67
|
+
width: number;
|
|
68
|
+
}): void;
|
|
49
69
|
}
|
|
50
70
|
/** 在组件内部引用 */
|
|
51
71
|
export interface _SheetExposed {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veltra/sheet",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"homepage": "https://github.com/cabinet-fe/ultra-ui#readme",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/cabinet-fe/ultra-ui/issues"
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"import": "./dist/*"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"infinitable": "^0.1.0"
|
|
38
|
+
},
|
|
36
39
|
"peerDependencies": {
|
|
37
40
|
"@cat-kit/core": ">=1.2.1",
|
|
38
41
|
"@cat-kit/fe": ">=1.2.1",
|
|
@@ -41,6 +44,6 @@
|
|
|
41
44
|
"@veltra/sheet-core": "^2.5.7",
|
|
42
45
|
"@veltra/styles": "^1.7.14",
|
|
43
46
|
"@veltra/utils": "^1.7.14",
|
|
44
|
-
"vue": ">=3.5.
|
|
47
|
+
"vue": ">=3.5.43"
|
|
45
48
|
}
|
|
46
49
|
}
|