xiaodao-spreader 0.1.36 → 0.1.37

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 (24) hide show
  1. package/README.ZH.md +29 -1
  2. package/README.md +29 -1
  3. package/dist/style.css +1 -1
  4. package/dist/types/components/spreader/components/data-validation-input-message.vue.d.ts +2 -2
  5. package/dist/types/components/spreader/components/dropdown.vue.d.ts +4 -1
  6. package/dist/types/components/spreader/components/pickers/border-picker.vue.d.ts +3 -0
  7. package/dist/types/components/spreader/components/pickers/calc-picker.vue.d.ts +2 -0
  8. package/dist/types/components/spreader/components/pickers/color-picker.vue.d.ts +3 -0
  9. package/dist/types/components/spreader/components/pickers/conditional-format-menu.vue.d.ts +8 -0
  10. package/dist/types/components/spreader/components/pickers/data-validation-dropdown.vue.d.ts +5 -3
  11. package/dist/types/components/spreader/components/pickers/filter-popup.vue.d.ts +2 -0
  12. package/dist/types/components/spreader/components/pickers/merge-picker.vue.d.ts +3 -0
  13. package/dist/types/components/spreader/components/pickers/outline-picker.vue.d.ts +6 -0
  14. package/dist/types/components/spreader/components/pickers/sort-picker.vue.d.ts +3 -0
  15. package/dist/types/components/spreader/components/spreader.vue.d.ts +34 -0
  16. package/dist/types/components/spreader/components/tabbar.vue.d.ts +2 -0
  17. package/dist/types/components/spreader/components/toolbar.vue.d.ts +23 -0
  18. package/dist/types/components/spreader/composables/useFloatMenuPosition.d.ts +39 -0
  19. package/dist/types/components/spreader/core/outline-core.d.ts +2 -2
  20. package/dist/types/components/spreader/core/types.d.ts +2 -2
  21. package/dist/types/components/spreader/core/utils.d.ts +20 -0
  22. package/dist/xiaodao-spreader.es.js +8088 -8070
  23. package/dist/xiaodao-spreader.umd.js +9 -9
  24. package/package.json +1 -1
@@ -2,6 +2,10 @@ type __VLS_Props = {
2
2
  modelOpen?: boolean;
3
3
  locale?: string;
4
4
  triggerEl?: HTMLElement | null;
5
+ /** 边界基准元素(通常是表格容器 wrapper):菜单不得越出其可视区,见 bounds() */
6
+ boundaryEl?: HTMLElement | null;
7
+ /** 当前选区轴:'rows'=选中整行,'cols'=选中整列,null=未选中行/列(按钮置灰)。菜单项直接作用于该轴,不再弹「行/列」子菜单。 */
8
+ axis?: 'rows' | 'cols' | null;
5
9
  };
6
10
  declare function openMenu(): void;
7
11
  declare function close(): void;
@@ -18,7 +22,9 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
18
22
  }>, {
19
23
  modelOpen: boolean;
20
24
  triggerEl: HTMLElement | null;
25
+ boundaryEl: HTMLElement | null;
21
26
  locale: string;
27
+ axis: "rows" | "cols" | null;
22
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {
23
29
  rootRef: HTMLDivElement;
24
30
  menuRef: HTMLDivElement;
@@ -4,6 +4,8 @@ type __VLS_Props = {
4
4
  locale?: string;
5
5
  currentSort?: SortOrder;
6
6
  triggerEl?: HTMLElement | null;
7
+ /** 边界基准元素(通常是表格容器 wrapper):菜单不得越出其可视区,见 getFloatBounds */
8
+ boundaryEl?: HTMLElement | null;
7
9
  };
8
10
  declare function openMenu(): void;
9
11
  declare function close(): void;
@@ -20,6 +22,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
20
22
  }>, {
21
23
  modelOpen: boolean;
22
24
  triggerEl: HTMLElement | null;
25
+ boundaryEl: HTMLElement | null;
23
26
  locale: string;
24
27
  currentSort: SortOrder;
25
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {
@@ -48,6 +48,7 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
48
48
  cachedSortOrder: import("@/components/spreader/core/sort-core.ts").SortOrder;
49
49
  canSort: boolean;
50
50
  outlineMenuOpen: boolean;
51
+ outlineAxis?: "rows" | "cols" | null | undefined;
51
52
  canFilter: boolean;
52
53
  filterActive: boolean;
53
54
  selHAlign: string;
@@ -57,6 +58,12 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
57
58
  vAlignOptions: import("../core/constants").FontOption[];
58
59
  mergeMenuOpen: boolean;
59
60
  calcMenuOpen: boolean;
61
+ cfMenuOpen: boolean;
62
+ freezeMenuOpen: boolean;
63
+ fontMenuOpen: boolean;
64
+ hAlignMenuOpen: boolean;
65
+ vAlignMenuOpen: boolean;
66
+ numFmtMenuOpen: boolean;
60
67
  isSingleCell: boolean;
61
68
  hasFreeze: boolean;
62
69
  freezePanesDisabled: boolean;
@@ -65,6 +72,7 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
65
72
  nfOptions: import("../core/number-format").NFOption[];
66
73
  canIncreaseDecimals: boolean;
67
74
  canDecreaseDecimals: boolean;
75
+ boundaryEl?: HTMLElement | null | undefined;
68
76
  }> & Readonly<{
69
77
  onUndo?: (() => any) | undefined;
70
78
  onRedo?: (() => any) | undefined;
@@ -114,6 +122,12 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
114
122
  "onUpdate:outline-menu-open"?: ((v: boolean) => any) | undefined;
115
123
  "onUpdate:merge-menu-open"?: ((v: boolean) => any) | undefined;
116
124
  "onUpdate:calc-menu-open"?: ((v: boolean) => any) | undefined;
125
+ "onUpdate:cf-menu-open"?: ((v: boolean) => any) | undefined;
126
+ "onUpdate:freeze-menu-open"?: ((v: boolean) => any) | undefined;
127
+ "onUpdate:font-menu-open"?: ((v: boolean) => any) | undefined;
128
+ "onUpdate:h-align-menu-open"?: ((v: boolean) => any) | undefined;
129
+ "onUpdate:v-align-menu-open"?: ((v: boolean) => any) | undefined;
130
+ "onUpdate:num-fmt-menu-open"?: ((v: boolean) => any) | undefined;
117
131
  "onBorder-change"?: ((v: import("@/components/spreader/components/pickers/border-picker.vue").BorderType) => any) | undefined;
118
132
  "onSort-change"?: ((v: import("@/components/spreader/core/sort-core.ts").SortOrder) => any) | undefined;
119
133
  "onMerge-change"?: ((v: import("../core/constants").MergeType) => any) | undefined;
@@ -169,6 +183,12 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
169
183
  "update:outline-menu-open": (v: boolean) => void;
170
184
  "update:merge-menu-open": (v: boolean) => void;
171
185
  "update:calc-menu-open": (v: boolean) => void;
186
+ "update:cf-menu-open": (v: boolean) => void;
187
+ "update:freeze-menu-open": (v: boolean) => void;
188
+ "update:font-menu-open": (v: boolean) => void;
189
+ "update:h-align-menu-open": (v: boolean) => void;
190
+ "update:v-align-menu-open": (v: boolean) => void;
191
+ "update:num-fmt-menu-open": (v: boolean) => void;
172
192
  "border-change": (v: import("@/components/spreader/components/pickers/border-picker.vue").BorderType) => void;
173
193
  "sort-change": (v: import("@/components/spreader/core/sort-core.ts").SortOrder) => void;
174
194
  "merge-change": (v: import("../core/constants").MergeType) => void;
@@ -220,6 +240,7 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
220
240
  cachedSortOrder: import("@/components/spreader/core/sort-core.ts").SortOrder;
221
241
  canSort: boolean;
222
242
  outlineMenuOpen: boolean;
243
+ outlineAxis?: "rows" | "cols" | null | undefined;
223
244
  canFilter: boolean;
224
245
  filterActive: boolean;
225
246
  selHAlign: string;
@@ -229,6 +250,12 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
229
250
  vAlignOptions: import("../core/constants").FontOption[];
230
251
  mergeMenuOpen: boolean;
231
252
  calcMenuOpen: boolean;
253
+ cfMenuOpen: boolean;
254
+ freezeMenuOpen: boolean;
255
+ fontMenuOpen: boolean;
256
+ hAlignMenuOpen: boolean;
257
+ vAlignMenuOpen: boolean;
258
+ numFmtMenuOpen: boolean;
232
259
  isSingleCell: boolean;
233
260
  hasFreeze: boolean;
234
261
  freezePanesDisabled: boolean;
@@ -237,6 +264,7 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
237
264
  nfOptions: import("../core/number-format").NFOption[];
238
265
  canIncreaseDecimals: boolean;
239
266
  canDecreaseDecimals: boolean;
267
+ boundaryEl?: HTMLElement | null | undefined;
240
268
  }> & Readonly<{
241
269
  onUndo?: (() => any) | undefined;
242
270
  onRedo?: (() => any) | undefined;
@@ -286,6 +314,12 @@ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {},
286
314
  "onUpdate:outline-menu-open"?: ((v: boolean) => any) | undefined;
287
315
  "onUpdate:merge-menu-open"?: ((v: boolean) => any) | undefined;
288
316
  "onUpdate:calc-menu-open"?: ((v: boolean) => any) | undefined;
317
+ "onUpdate:cf-menu-open"?: ((v: boolean) => any) | undefined;
318
+ "onUpdate:freeze-menu-open"?: ((v: boolean) => any) | undefined;
319
+ "onUpdate:font-menu-open"?: ((v: boolean) => any) | undefined;
320
+ "onUpdate:h-align-menu-open"?: ((v: boolean) => any) | undefined;
321
+ "onUpdate:v-align-menu-open"?: ((v: boolean) => any) | undefined;
322
+ "onUpdate:num-fmt-menu-open"?: ((v: boolean) => any) | undefined;
289
323
  "onBorder-change"?: ((v: import("@/components/spreader/components/pickers/border-picker.vue").BorderType) => any) | undefined;
290
324
  "onSort-change"?: ((v: import("@/components/spreader/core/sort-core.ts").SortOrder) => any) | undefined;
291
325
  "onMerge-change"?: ((v: import("../core/constants").MergeType) => any) | undefined;
@@ -5,6 +5,8 @@ type __VLS_Props = {
5
5
  activeSheetIndex: number;
6
6
  renTab: number | null;
7
7
  renTabVal: string;
8
+ /** 边界基准元素(通常是表格容器 wrapper):列表菜单不得越出其可视区,见 getFloatBounds */
9
+ boundaryEl?: HTMLElement | null;
8
10
  };
9
11
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
12
  "tab-click": (i: number) => void;
@@ -31,6 +31,8 @@ type __VLS_Props = {
31
31
  cachedSortOrder: SortOrder;
32
32
  canSort: boolean;
33
33
  outlineMenuOpen: boolean;
34
+ /** 当前选区轴:'rows'=选中整行,'cols'=选中整列,null=未选中行/列。决定「分组」按钮是否可用(置灰提示先选行/列) */
35
+ outlineAxis?: 'rows' | 'cols' | null;
34
36
  /** 工具栏「筛选」按钮是否可用(单选合并单元格且无筛选态时禁用) */
35
37
  canFilter: boolean;
36
38
  /** 当前 worksheet 是否已启用筛选 */
@@ -42,6 +44,12 @@ type __VLS_Props = {
42
44
  vAlignOptions: FontOption[];
43
45
  mergeMenuOpen: boolean;
44
46
  calcMenuOpen: boolean;
47
+ cfMenuOpen: boolean;
48
+ freezeMenuOpen: boolean;
49
+ fontMenuOpen: boolean;
50
+ hAlignMenuOpen: boolean;
51
+ vAlignMenuOpen: boolean;
52
+ numFmtMenuOpen: boolean;
45
53
  isSingleCell: boolean;
46
54
  /** 当前 worksheet 是否已有冻结行或列 */
47
55
  hasFreeze: boolean;
@@ -52,6 +60,9 @@ type __VLS_Props = {
52
60
  nfOptions: NFOption[];
53
61
  canIncreaseDecimals: boolean;
54
62
  canDecreaseDecimals: boolean;
63
+ /** 边界基准元素(通常是表格容器 wrapper):弹出菜单不得越出其可视区。
64
+ * 组件嵌入宿主 Vue 页面时必需——否则菜单会越界盖住宿主内容。缺省时退化为纯视口判定。 */
65
+ boundaryEl?: HTMLElement | null;
55
66
  };
56
67
  declare const _default: import("vue").DefineComponent<__VLS_Props, {
57
68
  closeOverflow: typeof closeOverflow;
@@ -104,6 +115,12 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
104
115
  "update:outline-menu-open": (v: boolean) => void;
105
116
  "update:merge-menu-open": (v: boolean) => void;
106
117
  "update:calc-menu-open": (v: boolean) => void;
118
+ "update:cf-menu-open": (v: boolean) => void;
119
+ "update:freeze-menu-open": (v: boolean) => void;
120
+ "update:font-menu-open": (v: boolean) => void;
121
+ "update:h-align-menu-open": (v: boolean) => void;
122
+ "update:v-align-menu-open": (v: boolean) => void;
123
+ "update:num-fmt-menu-open": (v: boolean) => void;
107
124
  "border-change": (v: BorderType) => void;
108
125
  "sort-change": (v: SortOrder) => void;
109
126
  "merge-change": (v: MergeType) => void;
@@ -157,6 +174,12 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
157
174
  "onUpdate:outline-menu-open"?: ((v: boolean) => any) | undefined;
158
175
  "onUpdate:merge-menu-open"?: ((v: boolean) => any) | undefined;
159
176
  "onUpdate:calc-menu-open"?: ((v: boolean) => any) | undefined;
177
+ "onUpdate:cf-menu-open"?: ((v: boolean) => any) | undefined;
178
+ "onUpdate:freeze-menu-open"?: ((v: boolean) => any) | undefined;
179
+ "onUpdate:font-menu-open"?: ((v: boolean) => any) | undefined;
180
+ "onUpdate:h-align-menu-open"?: ((v: boolean) => any) | undefined;
181
+ "onUpdate:v-align-menu-open"?: ((v: boolean) => any) | undefined;
182
+ "onUpdate:num-fmt-menu-open"?: ((v: boolean) => any) | undefined;
160
183
  "onBorder-change"?: ((v: BorderType) => any) | undefined;
161
184
  "onSort-change"?: ((v: SortOrder) => any) | undefined;
162
185
  "onMerge-change"?: ((v: MergeType) => any) | undefined;
@@ -0,0 +1,39 @@
1
+ export interface FloatMenuPosition {
2
+ /** fixed 定位:右缘(px),与 trigger 右缘对齐后夹回有效右边界 */
3
+ right?: number;
4
+ /** fixed 定位:左缘(px)。默认不使用,仅当右缘锚定不可用时的兜底 */
5
+ left?: number;
6
+ /** fixed 定位:上缘(px) */
7
+ top: number;
8
+ /** 是否向上翻向弹出(trigger 下方放不下且上方有空间) */
9
+ up: boolean;
10
+ }
11
+ /**
12
+ * 主弹出菜单(工具栏下拉框:条件格式 / 分组等)的统一定位逻辑。
13
+ *
14
+ * 与 conditional-format-menu.vue 原实现完全同构,抽出来让所有工具栏下拉框复用同一套,
15
+ * 不再各写一套:
16
+ * - 右缘锚定 trigger 右缘(Math.min(r.right, b.right) 夹回有效右边界),top 先落 trigger 下缘 +4;
17
+ * - 传入 menuEl(已挂载、可量高度)后,按「容器∩视口」有效区做上下翻向 + 夹紧:
18
+ * 下方放得下就向下;下方放不下但上方有空间就向上;两边都放不下→夹紧贴顶/贴底兜底。
19
+ * 夹紧下界取 min(b.top + 8, trigger 下缘 + 4):工具栏按钮在 boundaryEl(表格容器)之上,
20
+ * 此时 b.top + 8 落在按钮下方,若仍以它为下界会把菜单硬推离按钮数十像素(主栏下拉整体下移),
21
+ * 故下界不得高于「紧贴 trigger 下方」这一理想位置。
22
+ *
23
+ * 调用约定(与 cf-menu 一致):先 place(trigger, boundary) 做初始下落放置,
24
+ * 再于 nextTick 后 place(trigger, boundary, menuEl) 量高翻向。
25
+ */
26
+ export declare function useFloatMenuPosition(): {
27
+ pos: import("vue").Ref<{
28
+ right?: number | undefined;
29
+ left?: number | undefined;
30
+ top: number;
31
+ up: boolean;
32
+ }, FloatMenuPosition | {
33
+ right?: number | undefined;
34
+ left?: number | undefined;
35
+ top: number;
36
+ up: boolean;
37
+ }>;
38
+ place: (triggerEl: HTMLElement, boundaryEl: HTMLElement | null | undefined, menuEl?: HTMLElement | null) => void;
39
+ };
@@ -14,8 +14,8 @@ export declare function countContaining(outlines: DimensionOutline[], start: num
14
14
  * 规则:
15
15
  * - start <= end
16
16
  * - 至少连续 2 个维度
17
- * - 与既有分组要么不相交要么完全包含,禁止部分重叠
18
- * - 层级(countContaining + 1)不超过 MAX_OUTLINE_LEVEL
17
+ * - 与既有分组必须完全不相交,禁止部分重叠与嵌套(仅支持一层分组)
18
+ * - 层级恒为 1(countContaining 必须为 0)
19
19
  */
20
20
  export declare function validateGroup(existing: DimensionOutline[], start: number, end: number): OutlineValidationResult;
21
21
  /** 创建分组后的新集合(校验失败返回原集合,同时给出校验结果供调用方提示) */
@@ -252,8 +252,8 @@ export interface DataValidationResult {
252
252
  title?: string;
253
253
  message?: string;
254
254
  }
255
- /** 单个行列分组的最大支持层级(与 Excel 一致,最多 8 级) */
256
- export declare const MAX_OUTLINE_LEVEL = 8;
255
+ /** 单个行列分组的最大支持层级:固定为 1,即仅支持一层分组(分组之间互不嵌套) */
256
+ export declare const MAX_OUTLINE_LEVEL = 1;
257
257
  /** 维度分组:属于 Sheet 的结构元数据。start/end 为 0-based 闭区间,且 start <= end */
258
258
  export interface DimensionOutline {
259
259
  /** 稳定唯一 ID(禁止数组 index) */
@@ -24,3 +24,23 @@ export declare function getCanvasXY(e: MouseEvent, canvas: HTMLCanvasElement | n
24
24
  export declare function gridViewW(viewW: number, sbSize: number): number;
25
25
  /** 网格可视区域高度(减去行头和滚动条) */
26
26
  export declare function gridViewH(viewH: number, sbSize: number): number;
27
+ /** 浮层可用的有效边界(视口坐标系)。
28
+ *
29
+ * 取「组件容器(boundaryEl)」∩「浏览器视口」的交集,两者都不能单独作为判据:
30
+ * - 浏览器视口:浮层 Teleport 到 body + position:fixed,挂在视口坐标系,越出视口一定看不见(硬边界)。
31
+ * 但组件作为子组件嵌入宿主页面时只占页面一部分,纯视口判定会漏算两侧留白 → 越界盖住宿主内容。
32
+ * - 组件容器:嵌入场景下把浮层夹在表格可视区内。但容器可能大于视口(页面滚动、边缘在视口外),
33
+ * 纯容器判定会把「其实已在视口外」当成有空间 → 浮层照样看不见。
34
+ *
35
+ * 取交集后:组件全屏时容器≈视口,自然退化为纯视口判定;boundaryEl 为空时同样退化为纯视口。
36
+ */
37
+ export interface FloatBounds {
38
+ left: number;
39
+ right: number;
40
+ top: number;
41
+ bottom: number;
42
+ }
43
+ export declare function getFloatBounds(boundaryEl?: HTMLElement | null): FloatBounds;
44
+ /** 把「视口坐标 x」换算成 fixed 定位的 CSS `right` 值(相对视口右缘的偏移)。
45
+ * 浮层以 position:fixed 挂在视口坐标系,故换算基准恒为 window.innerWidth,与有效边界无关。 */
46
+ export declare function cssRightFromX(x: number): number;