@veltra/sheet 2.6.0 → 2.8.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.
@@ -53,9 +53,17 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
53
53
  readonly: {
54
54
  type: Boolean,
55
55
  default: false
56
+ },
57
+ colResize: {
58
+ type: Boolean,
59
+ default: false
60
+ },
61
+ scrollbar: {
62
+ type: Boolean,
63
+ default: true
56
64
  }
57
65
  },
58
- emits: ["active-sheet-change"],
66
+ emits: ["active-sheet-change", "col-resize-end"],
59
67
  setup(__props, { expose: __expose, emit: __emit }) {
60
68
  const props = __props;
61
69
  const emit = __emit;
@@ -117,7 +125,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
117
125
  getActiveSheet: () => activeSheet.value,
118
126
  context,
119
127
  formulaBarRef,
120
- isFunctionPopupOpen: () => popupTool.value?.popup === "functions"
128
+ isFunctionPopupOpen: () => popupTool.value?.popup === "functions",
129
+ onColResizeEnd: (event) => emit("col-resize-end", event)
121
130
  });
122
131
  __expose({
123
132
  workbook,
@@ -71,9 +71,12 @@ function useSheetGrid(options) {
71
71
  resolveCellRenderer: props.resolveCellRenderer,
72
72
  header: props.header,
73
73
  editors: props.editors,
74
+ colResize: props.colResize,
75
+ scrollbar: props.scrollbar,
74
76
  onContextMenu: handleContextMenu,
75
77
  onEditStart: (addr) => formulaBarRef.value?.mirrorGridEdit(addr),
76
78
  onEditEnd: (addr) => formulaBarRef.value?.exitMirror(addr),
79
+ onColResizeEnd: options.onColResizeEnd,
77
80
  interceptSelection: () => (formulaBarRef.value?.isRefSelecting() ?? false) || (formulaBarRef.value?.isFunctionPopupOpen() ?? false) || (options.isFunctionPopupOpen?.() ?? false),
78
81
  onSelectionIntercept: (range) => formulaBarRef.value?.handleRefSelect(range)
79
82
  });
@@ -182,7 +185,9 @@ function useSheetGrid(options) {
182
185
  props.showRowHeader,
183
186
  props.showColHeader,
184
187
  props.header,
185
- props.editors
188
+ props.editors,
189
+ props.colResize,
190
+ props.scrollbar
186
191
  ], ([nextRows, nextCols]) => {
187
192
  const sheet = getActiveSheet();
188
193
  if (nextRows != null) sheet.ensureTableSize(nextRows, 0);
@@ -49,6 +49,16 @@ export interface SheetProps {
49
49
  showColHeader?: boolean;
50
50
  /** 只读预览(关闭编辑回写、填充柄等写入口) */
51
51
  readonly?: boolean;
52
+ /**
53
+ * 列宽拖拽(透传 SheetGrid):readonly 下置 true 仅放开列头 resize 手柄,编辑仍
54
+ * 关闭;缺省 false 行为不变。变化触发网格重建(构造期选项)
55
+ */
56
+ colResize?: boolean;
57
+ /**
58
+ * 画布滚动条(透传 SheetGrid → 引擎内建):内容溢出的轴在画布右/下缘绘制滚动条
59
+ * (可拖拽 / 点按跳转);缺省 true。变化触发网格重建(构造期选项)
60
+ */
61
+ scrollbar?: boolean;
52
62
  }
53
63
  export interface SheetEmits {
54
64
  /** 激活 sheet 切换(点击 tab 或宿主调用 workbook.activateSheet) */
@@ -56,6 +66,11 @@ export interface SheetEmits {
56
66
  sheet: Sheet;
57
67
  index: number;
58
68
  }): void;
69
+ /** 列宽拖拽落定(写模型之后):载荷含列索引与最终宽度 */
70
+ (name: 'col-resize-end', payload: {
71
+ col: number;
72
+ width: number;
73
+ }): void;
59
74
  }
60
75
  /** 在组件内部引用 */
61
76
  export interface _SheetExposed {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veltra/sheet",
3
- "version": "2.6.0",
3
+ "version": "2.8.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"
@@ -34,7 +34,7 @@
34
34
  }
35
35
  },
36
36
  "dependencies": {
37
- "infinitable": "^0.1.0"
37
+ "infinitable": "^0.1.2"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@cat-kit/core": ">=1.2.1",
@@ -84,6 +84,19 @@ afterEach(() => {
84
84
  })
85
85
 
86
86
  describe('USheet 组件', () => {
87
+ it('scrollbar 透传引擎内建滚动条(缺省开启,false 关闭并触发重建)', async () => {
88
+ const exposedOn: { value: SheetExposed | undefined } = { value: undefined }
89
+ mount(() => ({}), exposedOn)
90
+ await nextTick()
91
+ // 引擎缺省 true(undefined 即开启),无需显式下发
92
+ expect(exposedOn.value!.getGrid()!.getTable().options.scrollbar).toBeUndefined()
93
+
94
+ const exposedOff: { value: SheetExposed | undefined } = { value: undefined }
95
+ mount(() => ({ scrollbar: false }), exposedOff)
96
+ await nextTick()
97
+ expect(exposedOff.value!.getGrid()!.getTable().options.scrollbar).toBe(false)
98
+ })
99
+
87
100
  it('挂载后默认选区 A1:名称框显示 A1、fx 输入栏可用', async () => {
88
101
  const workbook = createWorkbook()
89
102
  const { el } = mount(() => ({ workbook, rows: 10, cols: 6 }))
@@ -1186,6 +1199,52 @@ describe('USheet 行高/列宽右键菜单', () => {
1186
1199
  })
1187
1200
  })
1188
1201
 
1202
+ describe('USheet colResize(readonly 列宽拖拽)', () => {
1203
+ it('readonly + colResize:列头拖宽写模型并 emit col-resize-end(col + 最终宽度)', async () => {
1204
+ const workbook = createWorkbook()
1205
+ const events: Array<{ col: number; width: number }> = []
1206
+ const { el } = mount(() => ({
1207
+ workbook,
1208
+ rows: 10,
1209
+ cols: 6,
1210
+ readonly: true,
1211
+ colResize: true,
1212
+ onColResizeEnd: (event: { col: number; width: number }) => events.push(event)
1213
+ }))
1214
+ await nextTick()
1215
+
1216
+ // 第 0 列右缘(46 + 80 = 126,±4 手柄区)列头带内拖拽:宽 = 起始 80 + 指针位移 42
1217
+ const instance = el.querySelector<HTMLElement>('.u-sheet__grid-instance')!
1218
+ fire(instance, 'pointerdown', { clientX: 124, clientY: 10 })
1219
+ fire(instance, 'pointermove', { clientX: 166, clientY: 10 })
1220
+ fire(instance, 'pointerup', { clientX: 166, clientY: 10 })
1221
+ await nextTick()
1222
+ expect(events).toEqual([{ col: 0, width: 122 }])
1223
+ expect(workbook.activeSheet.getColWidth(0)).toBe(122)
1224
+ })
1225
+
1226
+ it('缺省 readonly 仍禁列宽拖拽(不 emit)', async () => {
1227
+ const workbook = createWorkbook()
1228
+ const events: Array<{ col: number; width: number }> = []
1229
+ const { el } = mount(() => ({
1230
+ workbook,
1231
+ rows: 10,
1232
+ cols: 6,
1233
+ readonly: true,
1234
+ onColResizeEnd: (event: { col: number; width: number }) => events.push(event)
1235
+ }))
1236
+ await nextTick()
1237
+
1238
+ const instance = el.querySelector<HTMLElement>('.u-sheet__grid-instance')!
1239
+ fire(instance, 'pointerdown', { clientX: 124, clientY: 10 })
1240
+ fire(instance, 'pointermove', { clientX: 166, clientY: 10 })
1241
+ fire(instance, 'pointerup', { clientX: 166, clientY: 10 })
1242
+ await nextTick()
1243
+ expect(events).toEqual([])
1244
+ expect(workbook.activeSheet.getColWidth(0)).toBeUndefined()
1245
+ })
1246
+ })
1247
+
1189
1248
  describe('fx 选区锚点', () => {
1190
1249
  const A1_ANCHOR = { minCol: 0, minRow: 0, maxCol: 0, maxRow: 0 }
1191
1250
 
@@ -111,7 +111,9 @@ const props = withDefaults(defineProps<SheetProps>(), {
111
111
  showTabs: true,
112
112
  showRowHeader: true,
113
113
  showColHeader: true,
114
- readonly: false
114
+ readonly: false,
115
+ colResize: false,
116
+ scrollbar: true
115
117
  })
116
118
 
117
119
  const emit = defineEmits<SheetEmits>()
@@ -215,7 +217,8 @@ const { rebuildGrid, activateGrid, pruneCache, getGrid, setSelectionAnchor } = u
215
217
  context,
216
218
  formulaBarRef,
217
219
  // 工具栏「函数」弹框打开期间与 fx 入口一致:画布点击不清除目标格高亮
218
- isFunctionPopupOpen: () => popupTool.value?.popup === 'functions'
220
+ isFunctionPopupOpen: () => popupTool.value?.popup === 'functions',
221
+ onColResizeEnd: (event) => emit('col-resize-end', event)
219
222
  })
220
223
 
221
224
  const exposed: _SheetExposed = {
@@ -39,6 +39,8 @@ interface UseSheetGridOptions {
39
39
  formulaBarRef: ElRef<FormulaBarMirror>
40
40
  /** 函数弹框打开中(宿主侧入口,如工具栏「函数」按钮) */
41
41
  isFunctionPopupOpen?: () => boolean
42
+ /** 列宽拖拽落定(SheetGrid 透传 → 宿主 emit col-resize-end) */
43
+ onColResizeEnd?: (event: { col: number; width: number }) => void
42
44
  }
43
45
 
44
46
  /** 缓存实例(LRU 淘汰):每个 sheet 一个独立容器 div,非激活容器 visibility:hidden 堆叠 */
@@ -128,9 +130,12 @@ export function useSheetGrid(options: UseSheetGridOptions) {
128
130
  resolveCellRenderer: props.resolveCellRenderer,
129
131
  header: props.header,
130
132
  editors: props.editors,
133
+ colResize: props.colResize,
134
+ scrollbar: props.scrollbar,
131
135
  onContextMenu: handleContextMenu,
132
136
  onEditStart: (addr) => formulaBarRef.value?.mirrorGridEdit(addr),
133
137
  onEditEnd: (addr) => formulaBarRef.value?.exitMirror(addr),
138
+ onColResizeEnd: options.onColResizeEnd,
134
139
  // 引用选择:不回写模型选区,序列化为 A1 / A1:B2 交给公式栏;
135
140
  // 函数弹框打开期间(fx / 工具栏两入口)同样拦截,画布点击不离开目标格
136
141
  interceptSelection: () =>
@@ -268,7 +273,9 @@ export function useSheetGrid(options: UseSheetGridOptions) {
268
273
  props.showRowHeader,
269
274
  props.showColHeader,
270
275
  props.header,
271
- props.editors
276
+ props.editors,
277
+ props.colResize,
278
+ props.scrollbar
272
279
  ] as const,
273
280
  ([nextRows, nextCols]) => {
274
281
  const sheet = getActiveSheet()
@@ -57,11 +57,23 @@ export interface SheetProps {
57
57
  showColHeader?: boolean
58
58
  /** 只读预览(关闭编辑回写、填充柄等写入口) */
59
59
  readonly?: boolean
60
+ /**
61
+ * 列宽拖拽(透传 SheetGrid):readonly 下置 true 仅放开列头 resize 手柄,编辑仍
62
+ * 关闭;缺省 false 行为不变。变化触发网格重建(构造期选项)
63
+ */
64
+ colResize?: boolean
65
+ /**
66
+ * 画布滚动条(透传 SheetGrid → 引擎内建):内容溢出的轴在画布右/下缘绘制滚动条
67
+ * (可拖拽 / 点按跳转);缺省 true。变化触发网格重建(构造期选项)
68
+ */
69
+ scrollbar?: boolean
60
70
  }
61
71
 
62
72
  export interface SheetEmits {
63
73
  /** 激活 sheet 切换(点击 tab 或宿主调用 workbook.activateSheet) */
64
74
  (name: 'active-sheet-change', payload: { sheet: Sheet; index: number }): void
75
+ /** 列宽拖拽落定(写模型之后):载荷含列索引与最终宽度 */
76
+ (name: 'col-resize-end', payload: { col: number; width: number }): void
65
77
  }
66
78
 
67
79
  /** 在组件内部引用 */