@veltra/sheet 2.8.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/components/sheet/formula-bar.js +1 -1
  2. package/dist/components/sheet/import-file.js +1 -1
  3. package/dist/components/sheet/insert-image.js +1 -1
  4. package/dist/components/sheet/popup-helpers.js +1 -1
  5. package/dist/components/sheet/popups/border-popup.js +1 -2
  6. package/dist/components/sheet/popups/functions-popup.js +3 -3
  7. package/dist/components/sheet/popups/import.worker.d.ts +1 -1
  8. package/dist/components/sheet/popups/import.worker.js +1 -1
  9. package/dist/components/sheet/sheet-context-menu.js +2 -2
  10. package/dist/components/sheet/sheet.js +12 -2
  11. package/dist/components/sheet/use-find-replace.js +1 -2
  12. package/dist/components/sheet/use-formula-suggest.js +5 -4
  13. package/dist/components/sheet/use-sheet-grid.js +4 -2
  14. package/dist/components/sheet/use-sheet-state.js +1 -1
  15. package/dist/components/sheet/use-tool-popup.js +13 -2
  16. package/dist/index.d.ts +2 -2
  17. package/dist/tools/builtin.js +1 -1
  18. package/dist/tools/context.d.ts +1 -11
  19. package/dist/tools/download.js +3 -3
  20. package/dist/tools/export.worker.d.ts +1 -1
  21. package/dist/tools/export.worker.js +1 -1
  22. package/dist/tools/registry.js +1 -1
  23. package/dist/types/sheet.d.ts +15 -7
  24. package/package.json +2 -3
  25. package/src/components/sheet/__test__/canvas-mock.ts +49 -0
  26. package/src/components/sheet/__test__/find-shortcut-anchor.test.ts +117 -0
  27. package/src/components/sheet/__test__/formula-bar.test.ts +11 -9
  28. package/src/components/sheet/__test__/formula-capability.test.ts +160 -0
  29. package/src/components/sheet/__test__/functions-popup.test.ts +7 -7
  30. package/src/components/sheet/__test__/grid-setup.ts +3 -0
  31. package/src/components/sheet/__test__/grid-test-utils.ts +47 -0
  32. package/src/components/sheet/__test__/import-file.test.ts +11 -7
  33. package/src/components/sheet/__test__/insert-image-popup.test.ts +1 -1
  34. package/src/components/sheet/__test__/insert-image.test.ts +1 -1
  35. package/src/components/sheet/__test__/sheet-component.test.ts +9 -19
  36. package/src/components/sheet/__test__/sheet-context-menu.test.ts +2 -2
  37. package/src/components/sheet/__test__/sheet-grow-on-scroll.test.ts +105 -0
  38. package/src/components/sheet/__test__/sheet-scrollbar.test.ts +137 -0
  39. package/src/components/sheet/__test__/use-formula-suggest.test.ts +1 -1
  40. package/src/components/sheet/formula-bar.vue +4 -4
  41. package/src/components/sheet/import-file.ts +3 -7
  42. package/src/components/sheet/insert-image.ts +2 -2
  43. package/src/components/sheet/popup-helpers.ts +3 -3
  44. package/src/components/sheet/popups/border-popup.vue +4 -4
  45. package/src/components/sheet/popups/export-popup.vue +1 -1
  46. package/src/components/sheet/popups/find-popup.vue +1 -1
  47. package/src/components/sheet/popups/functions-popup.vue +3 -9
  48. package/src/components/sheet/popups/import.worker.ts +3 -3
  49. package/src/components/sheet/sheet-context-menu.ts +4 -4
  50. package/src/components/sheet/sheet-tabs.vue +2 -2
  51. package/src/components/sheet/sheet.vue +12 -3
  52. package/src/components/sheet/use-find-replace.ts +3 -7
  53. package/src/components/sheet/use-formula-suggest.ts +6 -8
  54. package/src/components/sheet/use-sheet-grid.ts +6 -4
  55. package/src/components/sheet/use-sheet-state.ts +2 -2
  56. package/src/components/sheet/use-tool-popup.ts +22 -2
  57. package/src/index.ts +3 -1
  58. package/src/tools/__test__/apply-style.test.ts +2 -2
  59. package/src/tools/__test__/builtin.test.ts +4 -4
  60. package/src/tools/__test__/context.test.ts +2 -2
  61. package/src/tools/apply-style.ts +3 -3
  62. package/src/tools/builtin.ts +2 -2
  63. package/src/tools/context.ts +11 -11
  64. package/src/tools/download.ts +4 -4
  65. package/src/tools/export.worker.ts +4 -7
  66. package/src/tools/registry.ts +1 -1
  67. package/src/types/sheet.ts +19 -8
@@ -1,5 +1,5 @@
1
1
  import { message } from '@veltra/desktop'
2
- import type { SheetImageAnchor, SheetImageType } from '@veltra/sheet-core/core/image.js'
2
+ import type { SheetImageAnchor, SheetImageType } from 'infinitable/sheet'
3
3
 
4
4
  import type { SheetContext } from '../../tools/context'
5
5
 
@@ -24,7 +24,7 @@ const EXT_TO_TYPE: Record<string, SheetImageType> = {
24
24
  webp: 'webp'
25
25
  }
26
26
 
27
- /** MIME → sheet-core 图片类型(core/image 的 SheetImageType);MIME 为空时回落扩展名 */
27
+ /** MIME → 引擎图片类型(SheetImageType);MIME 为空时回落扩展名 */
28
28
  export function resolveImageType(file: File): SheetImageType | undefined {
29
29
  const mime = file.type.trim().toLowerCase()
30
30
  if (mime && MIME_TO_TYPE[mime]) return MIME_TO_TYPE[mime]
@@ -1,6 +1,6 @@
1
- import type { CellRange } from '@veltra/sheet-core/core/address.js'
2
- import type { BorderPreset } from '@veltra/sheet-core/core/style/border-presets.js'
3
- import { BORDER_STYLE_WIDTH, type BorderLineStyle } from '@veltra/sheet-core/core/style/types.js'
1
+ import type { CellRange } from 'infinitable/sheet'
2
+ import type { BorderPreset } from 'infinitable/sheet'
3
+ import { BORDER_STYLE_WIDTH, type BorderLineStyle } from 'infinitable/sheet'
4
4
 
5
5
  import type { SheetContext } from '../../tools/context'
6
6
 
@@ -35,15 +35,15 @@
35
35
 
36
36
  <script lang="ts" setup>
37
37
  import { UPalette } from '@veltra/desktop'
38
- import type { SetCellStyleItem } from '@veltra/sheet-core/core/command/set-cell-style.js'
39
- import { buildBorderPresetItems } from '@veltra/sheet-core/core/style/border-presets.js'
38
+ import { bem } from '@veltra/utils'
39
+ import type { SetCellStyleItem } from 'infinitable/sheet'
40
+ import { buildBorderPresetItems } from 'infinitable/sheet'
40
41
  import {
41
42
  BORDER_STYLE_WIDTH,
42
43
  type BorderEdge,
43
44
  type BorderLineStyle,
44
45
  type CellStylePatch
45
- } from '@veltra/sheet-core/core/style/types.js'
46
- import { bem } from '@veltra/utils'
46
+ } from 'infinitable/sheet'
47
47
  import { ref } from 'vue'
48
48
 
49
49
  import type { SheetContext } from '../../../tools/context'
@@ -30,7 +30,7 @@ const cls = bem('sheet')
30
30
  function exportXlsx(): void {
31
31
  emit('close')
32
32
  // 大工作簿序列化在 worker 中进行(数秒):给常驻反馈,失败(如 sheet 名含
33
- // Excel 非法字符,sheet-core 写入校验抛 InvalidArgumentError)明确报错,
33
+ // Excel 非法字符,引擎写入校验抛 InvalidArgumentError)明确报错,
34
34
  // 绝不静默失败
35
35
  const loading = message({ message: '正在导出…', duration: 0 })
36
36
  exportWorkbookFile(props.context)
@@ -69,8 +69,8 @@
69
69
 
70
70
  <script lang="ts" setup>
71
71
  import { UInput } from '@veltra/desktop'
72
- import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
73
72
  import { bem } from '@veltra/utils'
73
+ import type { Sheet } from 'infinitable/sheet'
74
74
 
75
75
  import type { SheetContext } from '../../../tools/context'
76
76
  import { useFindReplace } from '../use-find-replace'
@@ -28,9 +28,7 @@
28
28
  @click="emit('select', fn.name)"
29
29
  @mouseenter="activeIndex = index"
30
30
  >
31
- <span :class="cls.e('functions-signature')">{{
32
- formatFunctionSignature(fn.name, fn.params)
33
- }}</span>
31
+ <span :class="cls.e('functions-signature')">{{ fn.signature }}</span>
34
32
  <span v-if="fn.description" :class="cls.e('functions-description')">{{
35
33
  fn.description
36
34
  }}</span>
@@ -44,16 +42,12 @@
44
42
 
45
43
  <script lang="ts" setup>
46
44
  import { UInput, UScroll } from '@veltra/desktop'
47
- import {
48
- listFormulaFunctions,
49
- type FormulaFunctionMeta
50
- } from '@veltra/sheet-core/core/formula/functions.js'
51
45
  import { bem } from '@veltra/utils'
46
+ import { listFormulaFunctions, type FormulaFunctionInfo } from 'infinitable'
52
47
  import { computed, onMounted, ref, useTemplateRef, watch } from 'vue'
53
48
 
54
49
  import {
55
50
  COMMON_FORMULA_NAMES,
56
- formatFunctionSignature,
57
51
  FUNCTION_POPUP_CATEGORIES,
58
52
  moveSuggestIndex,
59
53
  type FunctionPopupCategory
@@ -68,7 +62,7 @@ defineOptions({ name: 'USheetFunctionsPopup' })
68
62
  * 弹框随 v-if 挂载 / 销毁,每次打开都是全新状态(关键词清空、回到「常用」)。
69
63
  */
70
64
 
71
- type FunctionItem = { name: string } & FormulaFunctionMeta
65
+ type FunctionItem = FormulaFunctionInfo
72
66
 
73
67
  const emit = defineEmits<{ select: [name: string] }>()
74
68
 
@@ -8,14 +8,14 @@
8
8
  * - { type: 'done', ok: true, sheets: [{ name, snapshot }], activeIndex }(快照为
9
9
  * 纯数据,可结构化克隆);失败 { type: 'done', ok: false, error }。
10
10
  *
11
- * 解析与构建经 sheet-core importXlsx 完成(hucre 仅由 sheet-core 依赖);
11
+ * 解析与构建经 infinitable/sheet importXlsx 完成(hucre 已内联进引擎统一包);
12
12
  * 名字唯一化与活动表对齐在 worker 内完成,主线程直接把快照替换进目标
13
13
  * (无 undo 历史——替换语义由确认后的 replaceWorkbookWithSnapshots 负责)。
14
14
  *
15
15
  * 注意:必须用**运行时动态 import**——worker 顶层静态 import 在 vite dev 的
16
16
  * worker 上下文中会因模块图加载顺序导致 `Workbook is not defined`(实测)。
17
17
  */
18
- import type { SheetSnapshot } from '@veltra/sheet-core/core/sheet.js'
18
+ import type { SheetSnapshot } from 'infinitable/sheet'
19
19
 
20
20
  export type ImportWorkerResponse =
21
21
  | { type: 'progress'; done: number; total: number }
@@ -31,7 +31,7 @@ self.onmessage = (e: MessageEvent<{ buffer: ArrayBuffer }>): void => {
31
31
  const { buffer } = e.data
32
32
  void (async () => {
33
33
  try {
34
- const { importXlsx } = await import('@veltra/sheet-core/core/io/import.js')
34
+ const { importXlsx } = await import('infinitable/sheet')
35
35
  // 分片构建:按 10% 粒度回报进度(避免 196 条/秒的消息风暴与文字跳变过快;
36
36
  // 模型构建段约 1s,10 次更新肉眼可见数字推进)
37
37
  let lastPercent = -1
@@ -1,6 +1,6 @@
1
1
  import type { ContextmenuItem } from '@veltra/desktop'
2
- import { createRange, type CellAddress, type CellRange } from '@veltra/sheet-core/core/address.js'
3
- import type { NumFmt } from '@veltra/sheet-core/core/style/types.js'
2
+ import { createRange, type CellAddress, type CellRange } from 'infinitable/sheet'
3
+ import type { NumFmt } from 'infinitable/sheet'
4
4
  import { defineComponent, h } from 'vue'
5
5
 
6
6
  import type { SheetContext } from '../../tools/context'
@@ -20,7 +20,7 @@ export const DECIMAL_PLACES_MAX = 10
20
20
  /** 行高/列宽数值项输入上限(下限复用门面 MIN_ROW_COL_SIZE,对齐引擎 resize 最小值) */
21
21
  export const AXIS_SIZE_MAX = 1000
22
22
 
23
- /** 数值项默认值回落:未设置自定义尺寸时展示引擎默认行高/列宽(对齐 sheet-core grid-theme) */
23
+ /** 数值项默认值回落:未设置自定义尺寸时展示引擎默认行高/列宽(对齐引擎 grid-theme) */
24
24
  export const FALLBACK_ROW_HEIGHT = 28
25
25
  export const FALLBACK_COL_WIDTH = 80
26
26
 
@@ -247,7 +247,7 @@ export function buildColHeaderMenus(
247
247
 
248
248
  /**
249
249
  * 对当前选区应用 numFmt(经 applyStyle → 命令系统,天然可 undo/redo)。
250
- * 仅影响显示,单元格恒存原始值(见 sheet-core `core/format.ts`)。
250
+ * 仅影响显示,单元格恒存原始值(引擎 numFmt 显示约定)。
251
251
  */
252
252
  export function applyNumFmtToSelection(ctx: SheetContext, numFmt: NumFmt): void {
253
253
  for (const range of ctx.getSelection().ranges) ctx.applyStyle(range, { numFmt })
@@ -54,9 +54,9 @@
54
54
  <script lang="ts" setup>
55
55
  import { contextmenu, message, messageConfirm, UIcon } from '@veltra/desktop'
56
56
  import { ArrowLeft, ArrowRight } from '@veltra/icons/normal'
57
- import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
58
- import type { Workbook } from '@veltra/sheet-core/core/workbook.js'
59
57
  import { bem } from '@veltra/utils'
58
+ import type { Sheet } from 'infinitable/sheet'
59
+ import type { Workbook } from 'infinitable/sheet'
60
60
  import { nextTick, ref, toRef, useTemplateRef } from 'vue'
61
61
 
62
62
  import { useSheetTabsBar } from './use-sheet-tabs-bar'
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div ref="rootRef" :class="cls.b">
3
- <div :class="cls.e('toolbar-wrap')">
3
+ <div ref="toolbarWrapRef" :class="cls.e('toolbar-wrap')">
4
4
  <u-sheet-toolbar v-if="showToolbar" :groups="toolGroups" @tool-click="handleToolClick" />
5
5
 
6
6
  <!-- 弹层型工具面板(填充/边框/字体色/字号/查找/函数/插入图片/导出):UDropdown(Teleport 到
@@ -113,7 +113,13 @@ const props = withDefaults(defineProps<SheetProps>(), {
113
113
  showColHeader: true,
114
114
  readonly: false,
115
115
  colResize: false,
116
- scrollbar: true
116
+ // 缺省原生档:引擎在 grid 容器内装配真实 DOM 滚动容器(原生滚动条独立
117
+ // gutter,不遮挡单元格),画布悬浮滚动条不再绘制。对象缺省被所有实例共享,
118
+ // 只读透传不改动
119
+ scrollbar: { mode: 'native' },
120
+ // 显式对齐引擎当前缺省(true 近边增长):boolean prop 不写 default 会被
121
+ // Vue 铸成 false,把引擎缺省翻成固定尺寸网格
122
+ growOnScroll: true
117
123
  })
118
124
 
119
125
  const emit = defineEmits<SheetEmits>()
@@ -123,6 +129,9 @@ const cls = bem('sheet')
123
129
  /** 根容器 ref:Ctrl/Cmd+F 判定焦点是否在本实例内(#6,避免劫持浏览器查找) */
124
130
  const rootRef = useTemplateRef<HTMLElement>('rootRef')
125
131
 
132
+ /** 工具栏容器 ref:工具栏隐藏(showToolbar=false)时查找弹层的回退锚点(0 高贴 sheet 顶) */
133
+ const toolbarWrapRef = useTemplateRef<HTMLElement>('toolbarWrapRef')
134
+
126
135
  // ─── 状态源(workbook / sheet 列表 / 活动 sheet / 工具上下文)────────
127
136
  // hooks 引用的 closePopup / rebuildGrid 由下方组合提供:箭头函数在事件触发时才
128
137
  // 求值(彼时已完成全部 setup),组合声明顺序不构成循环依赖。
@@ -144,7 +153,7 @@ const {
144
153
  popupAnchor,
145
154
  closePopup,
146
155
  handleToolClick: openOrRunTool
147
- } = useToolPopup(context, rootRef)
156
+ } = useToolPopup(context, rootRef, () => toolbarWrapRef.value ?? null)
148
157
  // xlsx 解析中(worker):grid 容器显示自绘覆盖层(import-file 写入 parsing /
149
158
  // parseProgress;遮罩 + 动画 + 文字同层——动画在上、文字在下)
150
159
  const parsing = ref(false)
@@ -1,17 +1,13 @@
1
1
  import { debounce } from '@cat-kit/core'
2
- import {
3
- inferCellType,
4
- normalizeInputValue,
5
- type CellData
6
- } from '@veltra/sheet-core/core/cell-store.js'
2
+ import { inferCellType, normalizeInputValue, type CellData } from 'infinitable/sheet'
7
3
  import {
8
4
  findAll,
9
5
  findNextFrom,
10
6
  findPrevFrom,
11
7
  type FindMatch,
12
8
  type FindOptions
13
- } from '@veltra/sheet-core/core/find.js'
14
- import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
9
+ } from 'infinitable/sheet'
10
+ import type { Sheet } from 'infinitable/sheet'
15
11
  import { computed, ref, shallowRef, watch } from 'vue'
16
12
 
17
13
  import type { SheetContext } from '../../tools/context'
@@ -1,7 +1,4 @@
1
- import {
2
- listFormulaFunctions,
3
- type FormulaFunctionMeta
4
- } from '@veltra/sheet-core/core/formula/functions.js'
1
+ import { listFormulaFunctions, type FormulaFunctionInfo } from 'infinitable'
5
2
 
6
3
  /** 补全候选上限 */
7
4
  export const FORMULA_SUGGEST_LIMIT = 10
@@ -26,7 +23,7 @@ export const COMMON_FORMULA_NAMES = [
26
23
  /**
27
24
  * 函数弹框分类导航固定集合(顺序即展示顺序)。
28
25
  * 「常用」「全部」是导航概念(非注册表分类):常用 = COMMON_FORMULA_NAMES 固定清单,
29
- * 全部 = 全部已注册函数;其余与 sheet-core `FormulaFunctionCategory` 对应。
26
+ * 全部 = 全部已注册函数;其余与公式注册表 `FormulaFunctionCategory` 对应。
30
27
  */
31
28
  export const FUNCTION_POPUP_CATEGORIES = [
32
29
  '常用',
@@ -131,12 +128,13 @@ export function filterFormulaSuggestions(prefix: string): FormulaSuggestItem[] {
131
128
  return items
132
129
  }
133
130
 
134
- function toSuggestItem(fn: { name: string } & FormulaFunctionMeta): FormulaSuggestItem {
131
+ function toSuggestItem(fn: FormulaFunctionInfo): FormulaSuggestItem {
132
+ const params = fn.params.map((p) => p.name)
135
133
  return {
136
134
  name: fn.name,
137
- params: fn.params,
135
+ params,
138
136
  description: fn.description,
139
- signature: formatFunctionSignature(fn.name, fn.params)
137
+ signature: formatFunctionSignature(fn.name, params)
140
138
  }
141
139
  }
142
140
 
@@ -1,7 +1,7 @@
1
1
  import { contextmenu } from '@veltra/desktop'
2
- import type { CellAddress, CellRange } from '@veltra/sheet-core/core/address.js'
3
- import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
4
- import { SheetGrid, type SheetGridContextMenuInfo } from '@veltra/sheet-core/grid'
2
+ import type { CellAddress, CellRange } from 'infinitable/sheet'
3
+ import type { Sheet } from 'infinitable/sheet'
4
+ import { SheetGrid, type SheetGridContextMenuInfo } from 'infinitable/sheet'
5
5
  import { onBeforeUnmount, onMounted, watch } from 'vue'
6
6
 
7
7
  import type { SheetContext } from '../../tools/context'
@@ -132,6 +132,7 @@ export function useSheetGrid(options: UseSheetGridOptions) {
132
132
  editors: props.editors,
133
133
  colResize: props.colResize,
134
134
  scrollbar: props.scrollbar,
135
+ growOnScroll: props.growOnScroll,
135
136
  onContextMenu: handleContextMenu,
136
137
  onEditStart: (addr) => formulaBarRef.value?.mirrorGridEdit(addr),
137
138
  onEditEnd: (addr) => formulaBarRef.value?.exitMirror(addr),
@@ -275,7 +276,8 @@ export function useSheetGrid(options: UseSheetGridOptions) {
275
276
  props.header,
276
277
  props.editors,
277
278
  props.colResize,
278
- props.scrollbar
279
+ props.scrollbar,
280
+ props.growOnScroll
279
281
  ] as const,
280
282
  ([nextRows, nextCols]) => {
281
283
  const sheet = getActiveSheet()
@@ -1,5 +1,5 @@
1
- import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
2
- import { Workbook } from '@veltra/sheet-core/core/workbook.js'
1
+ import type { Sheet } from 'infinitable/sheet'
2
+ import { Workbook } from 'infinitable/sheet'
3
3
  import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
4
4
 
5
5
  import { createSheetContext } from '../../tools/context'
@@ -31,7 +31,15 @@ function joinsTransaction(tool: SheetTool): boolean {
31
31
  * 函数面板选中只进入公式栏编辑态(无直接模型写入),与查找 / 导出一样不参与事务。
32
32
  * 导入在 sheet.vue 特殊处理(直接系统文件选择),不经弹层。
33
33
  */
34
- export function useToolPopup(context: SheetContext, rootEl: ElRef) {
34
+ export function useToolPopup(
35
+ context: SheetContext,
36
+ rootEl: ElRef,
37
+ /**
38
+ * 查找弹层回退锚点(工具栏隐藏时 find 按钮不可达,取 sheet 顶部容器:
39
+ * 0 高贴 sheet 顶,bottom-start 定位下弹层自 sheet 左上角展开,落在 sheet 视口内)
40
+ */
41
+ getFallbackAnchor?: () => HTMLElement | null | undefined
42
+ ) {
35
43
  /** 当前打开的弹层工具(null = 未打开) */
36
44
  const popupTool = shallowRef<SheetTool | null>(null)
37
45
  /** 触发按钮元素(打开时的 currentTarget;用于面板 left 对齐按钮) */
@@ -104,6 +112,18 @@ export function useToolPopup(context: SheetContext, rootEl: ElRef) {
104
112
  closePopup()
105
113
  }
106
114
 
115
+ /**
116
+ * Ctrl/Cmd+F 的锚点解析:优先工具栏「查找与替换」按钮(与按钮入口完全同锚点,
117
+ * 弹层同样锚定按钮下方);按钮不可达(showToolbar 隐藏)时回退 sheet 顶部容器。
118
+ */
119
+ function resolveFindAnchor(): HTMLElement | null {
120
+ const root = rootEl.value
121
+ if (!root) return null
122
+ const button = root.querySelector<HTMLElement>('[data-tool-id="find"]')
123
+ if (button) return button
124
+ return getFallbackAnchor?.() ?? null
125
+ }
126
+
107
127
  /** Ctrl/Cmd+F 打开 / 关闭查找条(与工具按钮同一 toggle 逻辑) */
108
128
  function onGlobalKeydown(event: KeyboardEvent): void {
109
129
  if (!(event.metaKey || event.ctrlKey) || event.key.toLowerCase() !== 'f') return
@@ -131,7 +151,7 @@ export function useToolPopup(context: SheetContext, rootEl: ElRef) {
131
151
  closePopup()
132
152
  return
133
153
  }
134
- scheduleOpen(findTool)
154
+ scheduleOpen(findTool, resolveFindAnchor())
135
155
  }
136
156
 
137
157
  onMounted(() => {
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import './tools/builtin'
2
2
 
3
- export { createSheetContext, type SheetContext } from './tools/context'
3
+ // SheetContextOptions:createSheetContext(公共导出)的第三参类型——导出函数
4
+ // 签名引用的稳定类型须随函数可达(无头场景宿主需引用该类型),不属引擎符号
5
+ export { createSheetContext, type SheetContext, type SheetContextOptions } from './tools/context'
4
6
 
5
7
  export {
6
8
  defaultToolRegistry,
@@ -1,5 +1,5 @@
1
- import { createRange } from '@veltra/sheet-core/core/address.js'
2
- import { Sheet } from '@veltra/sheet-core/core/sheet.js'
1
+ import { createRange } from 'infinitable/sheet'
2
+ import { Sheet } from 'infinitable/sheet'
3
3
  import { describe, expect, it } from 'vite-plus/test'
4
4
 
5
5
  import { classifySelectionStyleTarget, type SelectionStyleTarget } from '../apply-style'
@@ -1,8 +1,8 @@
1
- import { createRange } from '@veltra/sheet-core/core/address.js'
1
+ import { createRange } from 'infinitable/sheet'
2
2
 
3
3
  import '../builtin'
4
- import { Sheet } from '@veltra/sheet-core/core/sheet.js'
5
- import { Workbook } from '@veltra/sheet-core/core/workbook.js'
4
+ import { Sheet } from 'infinitable/sheet'
5
+ import { Workbook } from 'infinitable/sheet'
6
6
  import { describe, expect, it, vi } from 'vite-plus/test'
7
7
 
8
8
  import { createSheetContext } from '../context'
@@ -122,7 +122,7 @@ describe('内置工具(dogfood 扩展机制)', () => {
122
122
  }
123
123
  })
124
124
 
125
- it('导出 xlsx:sheet 名含 Excel 非法字符时 reject(sheet-core 写入校验,错误传播给调用方)', async () => {
125
+ it('导出 xlsx:sheet 名含 Excel 非法字符时 reject(引擎写入校验,错误传播给调用方)', async () => {
126
126
  const workbook = new Workbook()
127
127
  workbook.renameSheet('Sheet1', 'a:b')
128
128
  const ctx = createSheetContext(workbook.activeSheet, workbook)
@@ -1,5 +1,5 @@
1
- import { createRange } from '@veltra/sheet-core/core/address.js'
2
- import { Sheet } from '@veltra/sheet-core/core/sheet.js'
1
+ import { createRange } from 'infinitable/sheet'
2
+ import { Sheet } from 'infinitable/sheet'
3
3
  import { describe, expect, it, vi } from 'vite-plus/test'
4
4
 
5
5
  import { createSheetContext, MIN_ROW_COL_SIZE } from '../context'
@@ -1,6 +1,6 @@
1
- import type { CellRange } from '@veltra/sheet-core/core/address.js'
2
- import type { SetAxisStyleItem } from '@veltra/sheet-core/core/command/set-axis-style.js'
3
- import type { CellStylePatch } from '@veltra/sheet-core/core/style/types.js'
1
+ import type { CellRange } from 'infinitable/sheet'
2
+ import type { SetAxisStyleItem } from 'infinitable/sheet'
3
+ import type { CellStylePatch } from 'infinitable/sheet'
4
4
 
5
5
  /** 样式写入目标:整行 / 整列默认样式,或逐格 */
6
6
  export type SelectionStyleTarget = 'row' | 'col' | 'cell'
@@ -24,8 +24,8 @@ import {
24
24
  VerticalAlignRight,
25
25
  Wrap
26
26
  } from '@veltra/icons/normal'
27
- import { rangesEqual } from '@veltra/sheet-core/core/address.js'
28
- import type { HorizontalAlign, VerticalAlign } from '@veltra/sheet-core/core/style/types.js'
27
+ import { rangesEqual } from 'infinitable/sheet'
28
+ import type { HorizontalAlign, VerticalAlign } from 'infinitable/sheet'
29
29
 
30
30
  import type { SheetContext } from './context'
31
31
  import { registerTool } from './registry'
@@ -1,14 +1,14 @@
1
- import type { CellAddress, CellRange } from '@veltra/sheet-core/core/address.js'
2
- import type { CellData, CellValue } from '@veltra/sheet-core/core/cell-store.js'
3
- import type { HistoryState } from '@veltra/sheet-core/core/command/history.js'
4
- import type { ImageUpdateFields } from '@veltra/sheet-core/core/command/image.js'
5
- import type { SetCellValueItem } from '@veltra/sheet-core/core/command/set-cell-value.js'
6
- import type { ImageInput, SheetImage } from '@veltra/sheet-core/core/image.js'
7
- import type { CellInfo } from '@veltra/sheet-core/core/merge-manager.js'
8
- import type { SelectionState } from '@veltra/sheet-core/core/selection.js'
9
- import type { FrozenState, Sheet } from '@veltra/sheet-core/core/sheet.js'
10
- import type { CellStyle, CellStylePatch } from '@veltra/sheet-core/core/style/types.js'
11
- import type { Workbook } from '@veltra/sheet-core/core/workbook.js'
1
+ import type { CellAddress, CellRange } from 'infinitable/sheet'
2
+ import type { CellData, CellValue } from 'infinitable/sheet'
3
+ import type { HistoryState } from 'infinitable/sheet'
4
+ import type { ImageUpdateFields } from 'infinitable/sheet'
5
+ import type { SetCellValueItem } from 'infinitable/sheet'
6
+ import type { ImageInput, SheetImage } from 'infinitable/sheet'
7
+ import type { CellInfo } from 'infinitable/sheet'
8
+ import type { SelectionState } from 'infinitable/sheet'
9
+ import type { FrozenState, Sheet } from 'infinitable/sheet'
10
+ import type { CellStyle, CellStylePatch } from 'infinitable/sheet'
11
+ import type { Workbook } from 'infinitable/sheet'
12
12
 
13
13
  import { axisStyleItemsForRange, classifySelectionStyleTarget } from './apply-style'
14
14
 
@@ -1,12 +1,12 @@
1
1
  import { saveBlob } from '@cat-kit/fe'
2
- import { exportSheetCsv, exportWorkbookXlsx } from '@veltra/sheet-core/core/io/export.js'
3
- import type { Workbook } from '@veltra/sheet-core/core/workbook.js'
2
+ import { exportSheetCsv, exportWorkbookXlsx } from 'infinitable/sheet'
3
+ import type { Workbook } from 'infinitable/sheet'
4
4
 
5
5
  import type { SheetContext } from './context'
6
6
  import type { ExportWorkerPayload, ExportWorkerResponse } from './export.worker'
7
7
 
8
8
  /**
9
- * 大工作簿的 XLSX 导出(sheet-core 序列化 + ZIP 压缩为秒级同步重活)移入 Web Worker:
9
+ * 大工作簿的 XLSX 导出(引擎序列化 + ZIP 压缩为秒级同步重活)移入 Web Worker:
10
10
  * 主线程只采集快照(结构化克隆友好的纯数据,行高随 SheetSnapshot.rowHeights
11
11
  * 携带),序列化与压缩在 worker 线程进行。worker 不可用(极端环境 / 打包产物
12
12
  * 缺文件)回退主线程导出——与导入侧 parseXlsxAsync 同一模式。
@@ -55,7 +55,7 @@ async function exportWorkbookXlsxAsync(workbook: Workbook): Promise<Uint8Array>
55
55
  /**
56
56
  * 导出当前工作簿为 .xlsx(无 workbook 时空操作)。
57
57
  * 下载动作复用 @cat-kit/fe 的 saveBlob(#28:不再自研 Object URL + a.click)。
58
- * 导出侧 sheet-core 的 writeXlsx 会校验 sheet 名(Excel 非法字符 / 超长 / 保留名)并抛
58
+ * 导出侧引擎的 writeXlsx 会校验 sheet 名(Excel 非法字符 / 超长 / 保留名)并抛
59
59
  * InvalidArgumentError——失败经返回的 Promise 传播,调用方(导出面板)负责提示。
60
60
  */
61
61
  export async function exportWorkbookFile(ctx: SheetContext): Promise<void> {
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="webworker" />
2
2
  /**
3
- * XLSX 导出 Worker:sheet-core exportWorkbookXlsx(模型序列化 + ZIP 压缩,
3
+ * XLSX 导出 Worker:infinitable/sheet exportWorkbookXlsx(模型序列化 + ZIP 压缩,
4
4
  * 大工作簿为秒级同步重活)移到独立线程,主线程保持空闲。
5
5
  *
6
6
  * 协议:主线程 postMessage({ sheets: [{ name, snapshot }], activeIndex })
@@ -12,7 +12,7 @@
12
12
  * 静态 import 在 vite dev 的 worker 上下文中会因模块图加载顺序导致
13
13
  * `Workbook is not defined`(实测)。
14
14
  */
15
- import type { SheetSnapshot } from '@veltra/sheet-core/core/sheet.js'
15
+ import type { SheetSnapshot } from 'infinitable/sheet'
16
16
 
17
17
  export interface ExportWorkerPayload {
18
18
  sheets: { name: string; snapshot: SheetSnapshot }[]
@@ -26,17 +26,14 @@ export interface ExportWorkerResponse {
26
26
  }
27
27
 
28
28
  self.onmessage = (e: MessageEvent<ExportWorkerPayload>): void => {
29
- void Promise.all([
30
- import('@veltra/sheet-core/core/io/export.js'),
31
- import('@veltra/sheet-core/core/workbook.js')
32
- ])
29
+ void Promise.all([import('infinitable/sheet'), import('infinitable/sheet')])
33
30
  .then(([{ exportWorkbookXlsx }, { Workbook }]) => {
34
31
  const wb = new Workbook()
35
32
  const sheets = e.data.sheets
36
33
  for (let i = 0; i < sheets.length; i++) {
37
34
  const { name, snapshot } = sheets[i]!
38
35
  // 首个 sheet 复用 Workbook 自带的默认表:先改名对齐(空名/重名保持原名,
39
- // 导出侧 sheet-core 的 writeXlsx 会校验表名合法性)
36
+ // 导出侧引擎的 writeXlsx 会校验表名合法性)
40
37
  const sheet = i === 0 ? wb.activeSheet : wb.addSheet(name)
41
38
  if (i === 0 && sheet.name !== name) wb.renameSheet(sheet.name, name)
42
39
  sheet.restore(snapshot)
@@ -1,4 +1,4 @@
1
- import { TypedEventEmitter } from '@veltra/sheet-core/core/events.js'
1
+ import { TypedEventEmitter } from 'infinitable/sheet'
2
2
 
3
3
  import type { SheetContext } from './context'
4
4
 
@@ -1,14 +1,15 @@
1
- import type { Sheet } from '@veltra/sheet-core/core/sheet.js'
2
- import type { Workbook } from '@veltra/sheet-core/core/workbook.js'
1
+ import type { DeconstructValue } from '@veltra/utils'
2
+ import type { Sheet } from 'infinitable/sheet'
3
+ import type { Workbook } from 'infinitable/sheet'
3
4
  import type {
4
5
  ResolveCellRenderer,
5
6
  ResolveCellStyleHook,
6
7
  ResolveDisplayValue,
8
+ ScrollbarOptions,
7
9
  SheetGrid,
8
10
  SheetGridEditorsOptions,
9
11
  SheetGridHeaderOptions
10
- } from '@veltra/sheet-core/grid'
11
- import type { DeconstructValue } from '@veltra/utils'
12
+ } from 'infinitable/sheet'
12
13
  import type { ComputedRef } from 'vue'
13
14
 
14
15
  import type { SheetContext } from '../tools/context'
@@ -31,7 +32,7 @@ export interface SheetProps {
31
32
  resolveCellStyle?: ResolveCellStyleHook
32
33
  /**
33
34
  * 动态单元格渲染(ADR-0004):视口布局时按格自定义渲染形态(返回引擎
34
- * `CellRenderer`,见 `@veltra/sheet-core/grid`),返回 undefined 回落默认渲染;
35
+ * `CellRenderer`,见 `infinitable/sheet`),返回 undefined 回落默认渲染;
35
36
  * 不写模型、不进快照
36
37
  */
37
38
  resolveCellRenderer?: ResolveCellRenderer
@@ -63,10 +64,20 @@ export interface SheetProps {
63
64
  */
64
65
  colResize?: boolean
65
66
  /**
66
- * 画布滚动条(透传 SheetGrid → 引擎内建):内容溢出的轴在画布右/下缘绘制滚动条
67
- * (可拖拽 / 点按跳转);缺省 true。变化触发网格重建(构造期选项)
67
+ * 滚动条(透传 SheetGrid → 引擎内建,构造期选项):false 整体关闭(不显示任何
68
+ * 滚动条);缺省原生档 `{ mode: 'native' }`——浏览器原生滚动条在独立 gutter
69
+ * 渲染、不遮挡最底行/最右列;true 与对象形态按引擎语义透传(对象可配
70
+ * `mode: 'canvas'` 回画布悬浮滚动条,及 visibility / hideDelay / reserve 等
71
+ * canvas 档显示策略)。对象形态引用更替触发网格重建——沿用 header / editors
72
+ * 的稳定引用约定,宿主勿在模板内联对象字面量
73
+ */
74
+ scrollbar?: boolean | ScrollbarOptions
75
+ /**
76
+ * 滚动近端动态增长(透传 SheetGrid,构造期选项):滚动缓冲末端触到当前行列数
77
+ * 时模型与引擎同步扩容(引擎缺省 true);false 为固定尺寸网格——内容定尺寸的
78
+ * 报表 / 表单宿主置 false 后不再滚入空白增长区。变化触发网格重建
68
79
  */
69
- scrollbar?: boolean
80
+ growOnScroll?: boolean
70
81
  }
71
82
 
72
83
  export interface SheetEmits {