xiaodao-spreader 0.1.11 → 0.1.13
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/README.ZH.md +48 -6
- package/README.md +48 -6
- package/dist/style.css +1 -1
- package/dist/types/components/spreader/components/find-replace-bar.vue.d.ts +25 -0
- package/dist/types/components/spreader/components/pickers/calcPicker.vue.d.ts +1 -1
- package/dist/types/components/spreader/components/toolbar.vue.d.ts +4 -0
- package/dist/types/components/spreader/composables/borders-merge.d.ts +2 -0
- package/dist/types/components/spreader/composables/core-state.d.ts +2 -0
- package/dist/types/components/spreader/composables/find-replace.d.ts +32 -0
- package/dist/types/components/spreader/core/find-replace-core.d.ts +23 -0
- package/dist/types/components/spreader/core/formula.d.ts +13 -4
- package/dist/types/components/spreader/core/types.d.ts +10 -0
- package/dist/xiaodao-spreader.es.js +4366 -3546
- package/dist/xiaodao-spreader.umd.js +9 -9
- package/package.json +3 -2
package/README.ZH.md
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
- [架构设计](#架构设计)
|
|
25
25
|
- [键盘快捷键](#键盘快捷键)
|
|
26
26
|
- [公式引擎](#公式引擎)
|
|
27
|
+
- [数字格式](#数字格式)
|
|
27
28
|
- [主题与国际化](#主题与国际化)
|
|
28
29
|
- [开发指南](#开发指南)
|
|
29
30
|
- [构建发布](#构建发布)
|
|
@@ -40,12 +41,14 @@
|
|
|
40
41
|
|
|
41
42
|
- **Canvas 2D 渲染** — 高 DPI 自适应(DPR 缩放),虚拟视口渲染,支持 200 行 × 26 列
|
|
42
43
|
- **多 Sheet 工作簿** — 标签栏支持新建、重命名、复制、删除、拖拽排序
|
|
43
|
-
- **公式引擎** — 支持 `=SUM()`、`=AVERAGE()
|
|
44
|
+
- **公式引擎** — 支持 `=SUM()`、`=AVERAGE()`、`=COUNT()`、`=IF()`、`=VLOOKUP()`、`=CONCATENATE()`,支持依赖追踪与循环引用检测;工具栏与右键菜单提供一键求和/平均值/计数
|
|
44
45
|
- **合并单元格** — 合并居中、跨列合并、取消合并,边框自动同步
|
|
45
46
|
- **丰富单元格格式** — 字体、字号(5–72)、加粗、斜体、下划线、删除线、文字颜色、填充颜色、水平/垂直对齐、自动换行
|
|
46
47
|
- **边框** — 上/下/左/右/全部/无,5 种预设样式及自定义颜色
|
|
47
48
|
- **撤销 / 重做** — 单元格、列宽、行高的完整状态快照(50 步)
|
|
48
49
|
- **格式刷** — 复制并应用单元格格式到任意区域
|
|
50
|
+
- **数字格式** — Excel 风格数字格式(常规 / 文本 / 数值 / 货币 / 会计 / 百分比 / 科学计数 / 日期 / 时间 / 日期时间 / 持续时间),提供自定义格式对话框;仅影响显示,绝不修改底层单元格值
|
|
51
|
+
- **查找与替换** — 工具栏查找按钮或 `Ctrl/Cmd+F`(含 `Ctrl/Cmd+H`)打开;支持「当前工作表 / 整个工作簿 / 当前选区」三种范围,区分大小写、匹配整个单元格;高亮全部匹配并定位当前项、循环查找;单次与全部替换均接入撤销/重做,仅修改单元格原始 `value`(始终保持字符串),不改动格式 / 边框 / 合并
|
|
49
52
|
|
|
50
53
|
### 交互体验
|
|
51
54
|
|
|
@@ -216,7 +219,8 @@ src/
|
|
|
216
219
|
│ └── pickers/
|
|
217
220
|
│ ├── colorPicker.vue
|
|
218
221
|
│ ├── borderPicker.vue
|
|
219
|
-
│
|
|
222
|
+
│ ├── mergePicker.vue
|
|
223
|
+
│ └── numberFormatDialog.vue
|
|
220
224
|
├── composables/
|
|
221
225
|
│ ├── core-state.ts # Props、cells/merges/selection、字体度量、导航
|
|
222
226
|
│ ├── undo-styles.ts # 撤销重做、格式刷、字体/对齐/颜色
|
|
@@ -227,6 +231,7 @@ src/
|
|
|
227
231
|
├── constants.ts # 布局常量、国际化、主题调色板
|
|
228
232
|
├── types.ts # 全部类型定义
|
|
229
233
|
├── formula.ts # 公式引擎(解析、计算、依赖、缓存)
|
|
234
|
+
├── number-format.ts # 数字格式引擎(Excel 风格显示格式化)
|
|
230
235
|
├── theme.ts # 主题 CSS 变量构建
|
|
231
236
|
└── utils.ts # 纯工具函数(列标签、命中测试、尺寸解析)
|
|
232
237
|
```
|
|
@@ -292,6 +297,10 @@ src/
|
|
|
292
297
|
|------|------|------|
|
|
293
298
|
| `SUM` | `=SUM(A1:B5)` | 区间求和 |
|
|
294
299
|
| `AVERAGE` | `=AVERAGE(A1:B5)` | 区间平均值 |
|
|
300
|
+
| `COUNT` | `=COUNT(A1:B5)` | 统计区域内数值单元格数 |
|
|
301
|
+
| `IF` | `=IF(A1>5, A1*2, 0)` | 条件分支;支持比较运算符(`> < >= <= = <>`)与四则运算 |
|
|
302
|
+
| `VLOOKUP` | `=VLOOKUP(value, A1:C5, 2, FALSE)` | 垂直查找;默认精确匹配,`TRUE` 为近似匹配 |
|
|
303
|
+
| `CONCATENATE` | `=CONCATENATE(A1, " ", B1)` | 将多个值拼接为字符串 |
|
|
295
304
|
| 绝对引用 | `$A$1` | 锁定列与行 |
|
|
296
305
|
| 混合引用 | `$A1`、`A$1` | 仅锁定列或行 |
|
|
297
306
|
|
|
@@ -302,7 +311,7 @@ src/
|
|
|
302
311
|
- **正向**:`formulaKey` → `[depKey, ...]` — 公式引用了哪些单元格
|
|
303
312
|
- **反向**:`depKey` → `Set<formulaKey>` — 哪些公式依赖此单元格
|
|
304
313
|
|
|
305
|
-
|
|
314
|
+
单元格变更时,脏标记通过反向图传播。循环引用通过独立的 `inProgress` 集合检测,返回 `#ERROR`。
|
|
306
315
|
|
|
307
316
|
### 粘贴时的引用偏移
|
|
308
317
|
|
|
@@ -310,6 +319,39 @@ src/
|
|
|
310
319
|
|
|
311
320
|
---
|
|
312
321
|
|
|
322
|
+
## 数字格式
|
|
323
|
+
|
|
324
|
+
一套 Excel 风格的数字格式引擎(`spreader/core/number-format.ts`),控制**单元格值的显示方式**——绝不修改存储的 `value`(始终保持原始字符串)。
|
|
325
|
+
|
|
326
|
+
### 分类
|
|
327
|
+
|
|
328
|
+
| 分类 | 示例显示 | 格式代码 |
|
|
329
|
+
|------|----------|----------|
|
|
330
|
+
| 常规 General | 自动(数值;极大/极小用科学计数法) | ``(空串) |
|
|
331
|
+
| 文本 Text | 原样显示 | `@` |
|
|
332
|
+
| 数值 Number | `1,234.56` | `#,##0.00` |
|
|
333
|
+
| 百分比 Percent | `12.34%` | `0.00%` |
|
|
334
|
+
| 科学计数 Scientific | `1.23E+03` | `0.00E+00` |
|
|
335
|
+
| 货币 Currency | `¥1,234.56` / `$1,234.56` | `¥#,##0.00` |
|
|
336
|
+
| 货币(取整)Currency (rounded) | `¥1,235` | `¥#,##0` |
|
|
337
|
+
| 会计 Accounting | 负数 `(¥1,234.56)` | `¥#,##0.00;(¥#,##0.00);¥"-"` |
|
|
338
|
+
| 财务 Financial | 负数 `[Red](#,##0.00)` | `#,##0.00;[Red](#,##0.00)` |
|
|
339
|
+
| 日期 Date | `2026年8月24日` / `8/24/2026` | `yyyy"年"m"月"d"日"` |
|
|
340
|
+
| 时间 Time | `13:45:30` | `h:mm:ss` |
|
|
341
|
+
| 日期时间 Date & Time | `2026年8月24日 13:45:30` | `yyyy"年"m"月"d"日" h:mm:ss` |
|
|
342
|
+
| 持续时间 Duration | `26:30:00` | `[h]:mm:ss` |
|
|
343
|
+
| 自定义 Custom | 用户自定义 Excel 风格代码 | — |
|
|
344
|
+
|
|
345
|
+
### 工作原理
|
|
346
|
+
|
|
347
|
+
- **存储**:格式代码按单元格存入 `cell.style.numberFormat`(字符串)。省略该属性(或空串)即常规格式。
|
|
348
|
+
- **界面**:工具栏数字格式下拉框将预设应用到当前选区;**「格式…」** 项打开 `numberFormatDialog.vue`,可自定义格式代码、小数位数与千位分隔符。
|
|
349
|
+
- **显示**:`formatNumber(value, format, locale)` 解析代码(带缓存),应用千位分隔 / 小数位 / 百分比缩放 / 日期序列号转换,返回显示字符串。非法的日期/持续时间序列号渲染为 `###`。
|
|
350
|
+
- **对齐**:数值类格式默认右对齐;文本及常规下的非数值保持左对齐——与 Excel 语义一致。
|
|
351
|
+
- **国际化**:货币符号(`¥` / `$`)、月份与星期名称随 `locale` 属性变化。
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
313
355
|
## 主题与国际化
|
|
314
356
|
|
|
315
357
|
### 内置主题
|
|
@@ -400,12 +442,12 @@ pnpm build:demo
|
|
|
400
442
|
|
|
401
443
|
### 近期
|
|
402
444
|
|
|
403
|
-
- [
|
|
445
|
+
- [x] 更多公式:`COUNT`、`IF`、`VLOOKUP`、`CONCATENATE`
|
|
404
446
|
- [ ] 单元格背景颜色选择器
|
|
405
|
-
- [ ]
|
|
447
|
+
- [x] 数字格式(货币、百分比、日期、小数位数)—— *见 [数字格式](#数字格式)*
|
|
406
448
|
- [ ] 条件格式规则
|
|
407
449
|
- [ ] 自动填充拖拽手柄
|
|
408
|
-
- [
|
|
450
|
+
- [x] 查找与替换 —— *见 [查找与替换](#查找与替换)*
|
|
409
451
|
|
|
410
452
|
### 中期
|
|
411
453
|
|
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ A high-performance, canvas-based spreadsheet component for Vue 3 — bringing an
|
|
|
24
24
|
- [Architecture](#architecture)
|
|
25
25
|
- [Keyboard Shortcuts](#keyboard-shortcuts)
|
|
26
26
|
- [Formula Engine](#formula-engine)
|
|
27
|
+
- [Number Format](#number-format)
|
|
27
28
|
- [Theming](#theming)
|
|
28
29
|
- [Development](#development)
|
|
29
30
|
- [Building](#building)
|
|
@@ -39,12 +40,14 @@ A high-performance, canvas-based spreadsheet component for Vue 3 — bringing an
|
|
|
39
40
|
### Core Spreadsheet
|
|
40
41
|
- **Canvas 2D Rendering** — High-DPI aware with DPR scaling, virtual viewport rendering for 200 × 26 sheets
|
|
41
42
|
- **Multi-Sheet Workbook** — Tab bar with add, rename, duplicate, delete, reorder
|
|
42
|
-
- **Formula Engine** — `=SUM()`, `=AVERAGE()
|
|
43
|
+
- **Formula Engine** — `=SUM()`, `=AVERAGE()`, `=COUNT()`, `=IF()`, `=VLOOKUP()`, `=CONCATENATE()` with dependency tracking and circular-reference detection; toolbar and context menu provide one-click sum/average/count
|
|
43
44
|
- **Merge Cells** — Merge & Center, Merge Across, Unmerge with border synchronization
|
|
44
45
|
- **Rich Cell Formatting** — Font family, font size (5–72), bold, italic, underline, strikethrough, text color, fill color, horizontal & vertical alignment, wrap text
|
|
45
46
|
- **Borders** — Top / bottom / left / right / all / none with 5 predefined styles and custom color
|
|
46
47
|
- **Undo / Redo** — Full state snapshots for cells, column widths, and row heights (50 steps)
|
|
47
48
|
- **Format Painter** — Copy & apply cell formatting across ranges
|
|
49
|
+
- **Number Format** — Excel-style number formatting (General / Text / Number / Currency / Accounting / Percent / Scientific / Date / Time / DateTime / Duration) with a custom format dialog; display-only, never mutates the stored cell value
|
|
50
|
+
- **Find & Replace** — Open via the toolbar find button or `Ctrl/Cmd+F` (also `Ctrl/Cmd+H`); three scopes — current sheet / entire workbook / current selection; match case and match entire cell; highlights all matches and locates the active one with wrap-around navigation; single and replace-all both integrate with undo/redo, mutating only the raw `value` (always kept a string), never format / border / merge
|
|
48
51
|
|
|
49
52
|
### Interaction
|
|
50
53
|
- **Smart Selection** — Click, drag, Shift+Click, row/column header select, corner-cell select-all
|
|
@@ -213,7 +216,8 @@ src/
|
|
|
213
216
|
│ └── pickers/
|
|
214
217
|
│ ├── colorPicker.vue
|
|
215
218
|
│ ├── borderPicker.vue
|
|
216
|
-
│
|
|
219
|
+
│ ├── mergePicker.vue
|
|
220
|
+
│ └── numberFormatDialog.vue
|
|
217
221
|
├── composables/
|
|
218
222
|
│ ├── core-state.ts # Props, cells/merges/selection, font metrics, navigation
|
|
219
223
|
│ ├── undo-styles.ts # Undo/redo, format painter, font/alignment/color
|
|
@@ -224,6 +228,7 @@ src/
|
|
|
224
228
|
├── constants.ts # Layout constants, i18n, theme palettes
|
|
225
229
|
├── types.ts # All type definitions
|
|
226
230
|
├── formula.ts # Formula engine (parse, evaluate, deps, cache)
|
|
231
|
+
├── number-format.ts # Number format engine (Excel-style display formatting)
|
|
227
232
|
├── theme.ts # Theme CSS variable construction
|
|
228
233
|
└── utils.ts # Pure utilities (col label, hit test, resolve size)
|
|
229
234
|
```
|
|
@@ -289,6 +294,10 @@ src/
|
|
|
289
294
|
|---------|--------|-------------|
|
|
290
295
|
| `SUM` | `=SUM(A1:B5)` | Range summation |
|
|
291
296
|
| `AVERAGE` | `=AVERAGE(A1:B5)` | Range average |
|
|
297
|
+
| `COUNT` | `=COUNT(A1:B5)` | Count numeric cells in range |
|
|
298
|
+
| `IF` | `=IF(A1>5, A1*2, 0)` | Conditional branching; supports comparison operators (`> < >= <= = <>`) and arithmetic |
|
|
299
|
+
| `VLOOKUP` | `=VLOOKUP(value, A1:C5, 2, FALSE)` | Vertical lookup; exact match by default, `TRUE` for approximate match |
|
|
300
|
+
| `CONCATENATE` | `=CONCATENATE(A1, " ", B1)` | Concatenate multiple values into a string |
|
|
292
301
|
| Absolute ref | `$A$1` | Lock column and row |
|
|
293
302
|
| Mixed ref | `$A1`, `A$1` | Lock column or row only |
|
|
294
303
|
|
|
@@ -299,7 +308,7 @@ The `FormulaDeps` class maintains a bidirectional dependency graph:
|
|
|
299
308
|
- **Forward**: `formulaKey` → `[depKey, ...]` — which cells a formula references
|
|
300
309
|
- **Reverse**: `depKey` → `Set<formulaKey>` — which formulas depend on a cell
|
|
301
310
|
|
|
302
|
-
When a cell changes, dirty flags propagate through the reverse graph. Circular references
|
|
311
|
+
When a cell changes, dirty flags propagate through the reverse graph. Circular references are detected via a separate `inProgress` set and return `#ERROR`.
|
|
303
312
|
|
|
304
313
|
### Reference Offsetting During Paste
|
|
305
314
|
|
|
@@ -307,6 +316,39 @@ When a cell changes, dirty flags propagate through the reverse graph. Circular r
|
|
|
307
316
|
|
|
308
317
|
---
|
|
309
318
|
|
|
319
|
+
## Number Format
|
|
320
|
+
|
|
321
|
+
An Excel-style number formatting engine (`spreader/core/number-format.ts`) that controls **how a cell value is displayed** — it never mutates the stored `value` (which always remains a raw string).
|
|
322
|
+
|
|
323
|
+
### Categories
|
|
324
|
+
|
|
325
|
+
| Category | Example display | Format code |
|
|
326
|
+
|----------|-----------------|-------------|
|
|
327
|
+
| General | Auto (numbers, sci-notation for very large/small) | `` (empty) |
|
|
328
|
+
| Text | Verbatim | `@` |
|
|
329
|
+
| Number | `1,234.56` | `#,##0.00` |
|
|
330
|
+
| Percent | `12.34%` | `0.00%` |
|
|
331
|
+
| Scientific | `1.23E+03` | `0.00E+00` |
|
|
332
|
+
| Currency | `¥1,234.56` / `$1,234.56` | `¥#,##0.00` |
|
|
333
|
+
| Currency (rounded) | `¥1,235` | `¥#,##0` |
|
|
334
|
+
| Accounting | `(¥1,234.56)` for negatives | `¥#,##0.00;(¥#,##0.00);¥"-"` |
|
|
335
|
+
| Financial | `[Red](#,##0.00)` for negatives | `#,##0.00;[Red](#,##0.00)` |
|
|
336
|
+
| Date | `2026年8月24日` / `8/24/2026` | `yyyy"年"m"月"d"日"` |
|
|
337
|
+
| Time | `13:45:30` | `h:mm:ss` |
|
|
338
|
+
| Date & Time | `2026年8月24日 13:45:30` | `yyyy"年"m"月"d"日" h:mm:ss` |
|
|
339
|
+
| Duration | `26:30:00` | `[h]:mm:ss` |
|
|
340
|
+
| Custom | User-defined Excel-style code | — |
|
|
341
|
+
|
|
342
|
+
### How it works
|
|
343
|
+
|
|
344
|
+
- **Storage**: the format code is stored per-cell in `cell.style.numberFormat` (a string). Omitting the property (or empty string) means General.
|
|
345
|
+
- **UI**: the toolbar number-format dropdown applies presets to the current selection; the **「Format…」(格式…)** item opens `numberFormatDialog.vue` for a custom code, decimals, and thousands separator.
|
|
346
|
+
- **Display**: `formatNumber(value, format, locale)` parses the code (cached), applies thousands separators / decimals / percent scaling / date-serial conversion, and returns the display string. Invalid date/duration serials render as `###`.
|
|
347
|
+
- **Alignment**: numeric formats default to right-aligned; Text and General-with-non-numeric keep left alignment — matching Excel semantics.
|
|
348
|
+
- **i18n**: currency symbol (`¥` / `$`), month and weekday names follow the `locale` prop.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
310
352
|
## Theming
|
|
311
353
|
|
|
312
354
|
### Built-in Themes
|
|
@@ -397,12 +439,12 @@ The project includes a GitHub Actions workflow (`.github/workflows/publish.yml`)
|
|
|
397
439
|
|
|
398
440
|
### Near-term
|
|
399
441
|
|
|
400
|
-
- [
|
|
442
|
+
- [x] More formulas: `COUNT`, `IF`, `VLOOKUP`, `CONCATENATE`
|
|
401
443
|
- [ ] Cell background color picker
|
|
402
|
-
- [
|
|
444
|
+
- [x] Number format (currency, percentage, date, number of decimals) — *see [Number Format](#number-format)*
|
|
403
445
|
- [ ] Conditional formatting rules
|
|
404
446
|
- [ ] Auto-fill drag handle
|
|
405
|
-
- [
|
|
447
|
+
- [x] Find & Replace — *see [Find & Replace](#find--replace)*
|
|
406
448
|
|
|
407
449
|
### Mid-term
|
|
408
450
|
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.sp-dropdown[data-v-77df3baf]{position:relative;display:inline-flex;min-width:0}.sp-dropdown__trigger[data-v-77df3baf]{display:flex;align-items:center;justify-content:space-between;gap:4px;width:100%;height:26px;border:1px solid transparent;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;cursor:pointer;padding:0 5px;box-sizing:border-box}.sp-dropdown__trigger[data-v-77df3baf]:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.sp-dropdown__trigger--open[data-v-77df3baf]{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6);border-color:var(--sp-toolbar-border, #d8d8d8)}.sp-dropdown__value[data-v-77df3baf]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.sp-dropdown__caret[data-v-77df3baf]{width:10px;height:10px;min-width:10px;opacity:.7}.sp-dropdown__menu[data-v-77df3baf]{position:fixed;z-index:20000;display:flex;flex-direction:column;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;transform-origin:top center}.sp-dropdown__menu--up[data-v-77df3baf]{transform-origin:bottom center}.menu-pop-enter-active[data-v-77df3baf],.menu-pop-leave-active[data-v-77df3baf]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-77df3baf],.menu-pop-leave-to[data-v-77df3baf]{opacity:0;transform:scaleY(.85)}.sp-dropdown__nav[data-v-77df3baf]{display:flex;align-items:center;justify-content:center;height:15px;min-height:15px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #666);cursor:pointer;padding:0;border-radius:3px}.sp-dropdown__nav[data-v-77df3baf]:hover:not(:disabled){background:#eef3f9}.sp-dropdown__nav[data-v-77df3baf]:disabled{color:#ccc;cursor:default}.sp-dropdown__nav svg[data-v-77df3baf]{width:10px;height:10px}.sp-dropdown__list[data-v-77df3baf]{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.sp-dropdown__icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__icon[data-v-77df3baf] svg{width:18px;height:18px;display:block}.sp-dropdown__item-icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__item-icon[data-v-77df3baf] svg{width:16px;height:16px;display:block}.sp-dropdown__item-label[data-v-77df3baf]{white-space:nowrap}.sp-dropdown__item[data-v-77df3baf]{display:flex;align-items:center;gap:6px;width:100%;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;cursor:pointer;padding:4px 8px;box-sizing:border-box;border-radius:3px}.sp-dropdown__item[data-v-77df3baf]:hover{background:#eef3f9}.sp-dropdown__item--active[data-v-77df3baf]{background:#e5f1fb;color:#0078d7}.color-picker[data-v-f8fac424]{position:relative;display:inline-flex;height:26px}.color-picker__menu[data-v-f8fac424]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;padding:6px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;transform-origin:top right}.menu-pop-enter-active[data-v-f8fac424],.menu-pop-leave-active[data-v-f8fac424]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f8fac424],.menu-pop-leave-to[data-v-f8fac424]{opacity:0;transform:scale(.9)}.color-picker__row[data-v-f8fac424]{display:flex;gap:4px;margin-bottom:4px}.color-picker__row[data-v-f8fac424]:last-child{margin-bottom:0}.color-picker__swatch[data-v-f8fac424]{width:20px;height:20px;padding:0;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .08s,box-shadow .08s;position:relative}.color-picker__swatch[data-v-f8fac424]:hover{transform:scale(1.18);box-shadow:0 0 0 1px #0003;z-index:1}.color-picker__swatch--selected[data-v-f8fac424]{box-shadow:0 0 0 2px #0078d7}.border-picker[data-v-f362abdb]{position:relative;display:inline-flex;height:26px}.border-picker__menu[data-v-f362abdb]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.border-picker__item[data-v-f362abdb]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.border-picker__item[data-v-f362abdb]:hover{background:#eef3f9}.border-picker__icon[data-v-f362abdb]{width:18px;height:18px;flex-shrink:0}.border-picker__label[data-v-f362abdb]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-f362abdb],.menu-pop-leave-active[data-v-f362abdb]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f362abdb],.menu-pop-leave-to[data-v-f362abdb]{opacity:0;transform:scale(.9)}.merge-picker[data-v-67c0f9e3]{position:relative;display:inline-flex;height:26px}.merge-picker__menu[data-v-67c0f9e3]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.merge-picker__item[data-v-67c0f9e3]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.merge-picker__item[data-v-67c0f9e3]:hover{background:#eef3f9}.merge-picker__icon[data-v-67c0f9e3]{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.merge-picker__icon[data-v-67c0f9e3] svg{width:18px;height:18px}.merge-picker__label[data-v-67c0f9e3]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-67c0f9e3],.menu-pop-leave-active[data-v-67c0f9e3]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-67c0f9e3],.menu-pop-leave-to[data-v-67c0f9e3]{opacity:0;transform:scale(.9)}.calc-picker[data-v-08615aee]{position:relative;display:inline-flex;height:26px}.calc-picker__menu[data-v-08615aee]{position:fixed;z-index:9999;min-width:120px;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.calc-picker__item[data-v-08615aee]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.calc-picker__item[data-v-08615aee]:hover:not(.calc-picker__item--disabled){background:#eef3f9}.calc-picker__item--disabled[data-v-08615aee]{color:var(--sp-toolbar-btn-disabled-color, #bbb);cursor:default}.calc-picker__label[data-v-08615aee]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-08615aee],.menu-pop-leave-active[data-v-08615aee]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-08615aee],.menu-pop-leave-to[data-v-08615aee]{opacity:0;transform:scale(.9)}.toolbar[data-v-a33ba577]{position:relative;display:flex;align-items:center;height:32px;min-height:32px;gap:2px;padding:0 6px;background:var(--sp-toolbar-bg);border-bottom:1px solid var(--sp-toolbar-border);-webkit-user-select:none;user-select:none}.tb-item[data-v-a33ba577]{display:flex;align-items:center;flex:0 0 auto}.toolbar-sep[data-v-a33ba577]{width:1px;height:18px;margin:0 4px;background:var(--sp-toolbar-border)}.toolbar-font[data-v-a33ba577],.toolbar-number-format[data-v-a33ba577],.toolbar-align[data-v-a33ba577]{flex:0 0 auto}.toolbar-font-size[data-v-a33ba577]{display:inline-flex;align-items:center;gap:0;height:26px;position:relative}.toolbar-font-size__input[data-v-a33ba577]{width:36px;height:26px;border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px;background:transparent;color:var(--sp-toolbar-btn-color);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;text-align:left;padding:0 5px;outline:none;box-sizing:border-box;-webkit-appearance:none;appearance:none;-moz-appearance:textfield}.toolbar-font-size__input[data-v-a33ba577]::-webkit-outer-spin-button,.toolbar-font-size__input[data-v-a33ba577]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.toolbar-font-size__input[data-v-a33ba577]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__input[data-v-a33ba577]:focus{border-color:var(--sp-toolbar-border);background:#fff}.toolbar-font-size__btn[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-left:none;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-font-size__btn[data-v-a33ba577]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__btn svg[data-v-a33ba577]{width:10px;height:10px}.toolbar-font-size__dropdown[data-v-a33ba577]{position:absolute;width:56px;height:26px;pointer-events:none}.toolbar-btn[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-btn[data-v-a33ba577]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-btn[data-v-a33ba577]:active:not(:disabled){opacity:.7}.toolbar-btn--active[data-v-a33ba577]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-btn--step[data-v-a33ba577]{width:26px;height:26px}.toolbar-btn--step svg[data-v-a33ba577]{width:16px;height:16px}.toolbar-btn[data-v-a33ba577]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.toolbar-btn__icon[data-v-a33ba577]{width:18px;height:18px}.toolbar-btn svg[data-v-a33ba577]:not(.toolbar-btn__icon){width:18px;height:18px}.toolbar-split[data-v-a33ba577]{display:inline-flex;align-items:center;position:relative;height:26px}.toolbar-split__main[data-v-a33ba577]{border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px}.toolbar-split__arrow[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-split__arrow[data-v-a33ba577]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-split__arrow svg[data-v-a33ba577]{width:10px!important;height:10px!important}.toolbar-more[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0;flex:0 0 auto;margin-left:auto}.toolbar-more[data-v-a33ba577]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-more--active[data-v-a33ba577]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-more svg[data-v-a33ba577]{width:18px;height:18px}.overflow-menu[data-v-a33ba577]{min-width:180px;max-width:260px;max-height:calc(100vh - 40px);overflow-y:auto;background:var(--sp-toolbar-bg, #fff);border:1px solid var(--sp-toolbar-border);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px 6px;display:flex;flex-direction:column;gap:2px;z-index:1000;transform-origin:top right}.overflow-menu.no-anim[data-v-a33ba577]{transition:none!important}.overflow-menu .tb-item[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-sep[data-v-a33ba577]{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-split__main[data-v-a33ba577]{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size[data-v-a33ba577]{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font[data-v-a33ba577],.overflow-menu .toolbar-number-format[data-v-a33ba577],.overflow-menu .toolbar-align[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-btn[data-v-a33ba577]:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-wrap[data-v-a33ba577]{width:100%;justify-content:flex-start}.menu-pop-enter-active[data-v-a33ba577],.menu-pop-leave-active[data-v-a33ba577]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-a33ba577],.menu-pop-leave-to[data-v-a33ba577]{opacity:0;transform:scale(.9)}.overflow-menu .tb-item{width:100%}.overflow-menu .toolbar-sep{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split{width:100%}.overflow-menu .toolbar-split__main{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font,.overflow-menu .toolbar-number-format,.overflow-menu .toolbar-align{width:100%}.overflow-menu .toolbar-btn:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color{width:100%}.overflow-menu .toolbar-wrap{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font-size__input{flex:1 1 auto;width:auto;min-width:40px}.overflow-menu .toolbar-btn:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-btn:active:not(:disabled){opacity:.7}.overflow-menu .toolbar-btn--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.overflow-menu .toolbar-btn:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.overflow-menu .toolbar-split__main:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-split__arrow:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:focus{border-color:var(--sp-toolbar-border);background:#fff}.overflow-menu .toolbar-font-size__btn:hover,.overflow-menu .toolbar-more:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-more--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.tab-bar[data-v-454e1a12]{display:flex;align-items:stretch;height:30px;min-height:30px;background:var(--sp-tab-bar-bg);border-top:1px solid var(--sp-tab-bar-border);-webkit-user-select:none;user-select:none;margin-top:4px}.tab-list[data-v-454e1a12]{display:flex;align-items:flex-start;flex:1;overflow:hidden;gap:1px;padding:0 1px}.tab-item[data-v-454e1a12]{display:flex;align-items:center;height:28px;min-width:0;max-width:120px;padding:0 10px;cursor:pointer;border:1px solid var(--sp-tab-inactive-border);background:var(--sp-tab-inactive-bg);color:var(--sp-tab-inactive-color);font-size:14px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap;transition:background .1s}.tab-item[data-v-454e1a12]:hover{background:var(--sp-tab-hover-bg)}.tab-item--active[data-v-454e1a12]{height:28px;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);border-color:var(--sp-tab-active-bg) var(--sp-tab-bar-border) var(--sp-tab-bar-border);border-top:2px solid var(--sp-tab-active-border);font-size:16px}.tab-item--active[data-v-454e1a12]:hover{background:var(--sp-tab-active-bg)}.tab-item__name[data-v-454e1a12]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-rename-input[data-v-454e1a12]{width:100%;height:18px;border:none;border-radius:0;outline:none;padding:0;font-size:16px;font-family:inherit;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);box-sizing:border-box}.tab-bar__add-btn[data-v-454e1a12]{width:24px;min-width:24px;height:24px;margin:0 4px 3px 3px;border:none;background:transparent;color:var(--sp-tab-add-btn-color);font-size:16px;line-height:22px;text-align:center;cursor:pointer;padding:0}.tab-bar__add-btn[data-v-454e1a12]:hover{background:var(--sp-tab-add-btn-hover-bg)}.nf-dialog__mask[data-v-69cb36b7]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:30000;background:rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center}.nf-dialog[data-v-69cb36b7]{width:380px;max-width:calc(100vw - 32px);max-height:calc(100vh - 48px);overflow-y:auto;background:#fff;border:1px solid #d0d0d0;border-radius:6px;box-shadow:0 8px 24px #0000002e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:#1a1a1a;-webkit-user-select:none;user-select:none}.nf-dialog__header[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #ececec}.nf-dialog__title[data-v-69cb36b7]{font-size:13px;font-weight:600}.nf-dialog__close[data-v-69cb36b7]{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:transparent;color:#888;cursor:pointer;border-radius:3px;padding:0}.nf-dialog__close[data-v-69cb36b7]:hover{background:#f0f0f0;color:#444}.nf-dialog__close svg[data-v-69cb36b7]{width:14px;height:14px}.nf-dialog__body[data-v-69cb36b7]{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.nf-field[data-v-69cb36b7]{display:flex;align-items:center;gap:8px}.nf-field--inline[data-v-69cb36b7]{min-height:26px}.nf-field__label[data-v-69cb36b7]{width:88px;min-width:88px;font-size:12px;color:#555}.nf-field__select[data-v-69cb36b7],.nf-field__input[data-v-69cb36b7]{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:0 6px;outline:none;box-sizing:border-box;font-family:inherit}.nf-field__select[data-v-69cb36b7]:focus,.nf-field__input[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-field__textarea[data-v-69cb36b7]{flex:1;min-height:44px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:4px 6px;outline:none;box-sizing:border-box;resize:none;font-family:Consolas,Courier New,monospace}.nf-field__textarea[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-checkbox[data-v-69cb36b7]{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:#333;cursor:pointer}.nf-checkbox input[data-v-69cb36b7]{margin:0;cursor:pointer}.nf-dialog__footer[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 14px;border-top:1px solid #ececec}.nf-preview[data-v-69cb36b7]{display:flex;flex-direction:column;gap:2px;min-width:0}.nf-preview__label[data-v-69cb36b7]{font-size:11px;color:#888}.nf-preview__value[data-v-69cb36b7]{font-size:13px;color:#1a1a1a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.nf-dialog__actions[data-v-69cb36b7]{display:flex;gap:8px}.nf-btn[data-v-69cb36b7]{height:28px;padding:0 16px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-family:inherit}.nf-btn[data-v-69cb36b7]:hover{background:#f0f0f0}.nf-btn--primary[data-v-69cb36b7]{border-color:#0078d7;background:#0078d7;color:#fff}.nf-btn--primary[data-v-69cb36b7]:hover{background:#0069c0}.nf-dialog-enter-active[data-v-69cb36b7],.nf-dialog-leave-active[data-v-69cb36b7]{transition:opacity .14s ease-out}.nf-dialog-enter-from[data-v-69cb36b7],.nf-dialog-leave-to[data-v-69cb36b7]{opacity:0}.nf-dialog-enter-active .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-active .nf-dialog[data-v-69cb36b7]{transition:transform .14s ease-out}.nf-dialog-enter-from .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-to .nf-dialog[data-v-69cb36b7]{transform:scale(.96)}.spreadsheet-outer[data-v-6321c060]{flex:1;display:flex;flex-direction:column;overflow:hidden;height:100%;min-height:400px;width:100%}.formula-bar[data-v-6321c060]{display:flex;align-items:flex-start;min-height:36px;padding:0;gap:0}.formula-bar--expanded[data-v-6321c060]{min-height:72px}.formula-bar__cell-label[data-v-6321c060]{width:48px;min-width:48px;height:28px;line-height:28px;margin-top:4px;text-align:center;font-size:12px;font-weight:600;color:var(--sp-formula-bar-label-color);background:var(--sp-formula-bar-label-bg);border:1px solid var(--sp-formula-bar-label-border);border-radius:2px;-webkit-user-select:none;user-select:none}.formula-bar__buttons[data-v-6321c060]{display:inline-flex;align-items:stretch;margin-top:4px;margin-left:6px;height:28px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;overflow:hidden;background:var(--sp-formula-bar-input-bg)}.formula-bar__btn[data-v-6321c060]{width:22px;height:28px;border:none;border-radius:0;background:transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none;color:inherit}.formula-bar__btn+.formula-bar__btn[data-v-6321c060]{border-left:1px solid var(--sp-formula-bar-input-border)}.formula-bar__btn[data-v-6321c060]:hover{background:var(--sp-scroll-btn-hover-bg, #f0f0f0)}.formula-bar__btn--cancel[data-v-6321c060]:hover{color:#e53935;background:#fdecea}.formula-bar__btn--accept[data-v-6321c060]:hover{color:#2e7d32;background:#e8f5e9}.formula-bar__input[data-v-6321c060]{flex:1;min-height:28px;height:28px;line-height:20px;margin-top:4px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;outline:none;padding:3px 6px;margin-left:4px;font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:var(--sp-formula-bar-input-color);background:var(--sp-formula-bar-input-bg);resize:none;overflow:hidden;box-sizing:border-box}.formula-bar__input--expanded[data-v-6321c060]{height:68px;overflow:auto}.formula-bar__input[data-v-6321c060]:focus{border-color:var(--sp-formula-bar-input-focus-border);box-shadow:0 0 0 1px var(--sp-formula-bar-input-focus-shadow)}.formula-bar__toggle[data-v-6321c060]{width:22px;min-width:22px;height:28px;margin-top:4px;margin-left:2px;margin-right:2px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;background:var(--sp-formula-bar-input-bg);color:var(--sp-formula-bar-input-color);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none}.formula-bar__toggle[data-v-6321c060]:hover{background:var(--sp-scroll-btn-hover-bg, #e8e8e8)}.spreadsheet-wrapper[data-v-6321c060]{flex:1;position:relative;overflow:hidden;background:var(--sp-wrapper-bg)}.grid-canvas[data-v-6321c060]{position:absolute;top:0;left:0;display:block;outline:none;cursor:cell}.grid-canvas[data-v-6321c060]:focus{outline:none}.v-scrollbar[data-v-6321c060]{position:absolute;right:0;top:0;width:11px;height:calc(100% - 11px);display:flex;flex-direction:column;background:var(--sp-wrapper-bg)}.h-scrollbar[data-v-6321c060]{position:absolute;left:0;bottom:0;height:11px;width:calc(100% - 11px);display:flex;background:var(--sp-wrapper-bg)}.sb-corner[data-v-6321c060]{position:absolute;right:0;bottom:0;width:11px;height:11px;background:var(--sp-wrapper-bg)}.sb-btn[data-v-6321c060]{width:11px;height:11px;min-width:11px;min-height:11px;border:none;background:var(--sp-scroll-btn-bg, #e8e8e8);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;-webkit-user-select:none;user-select:none}.sb-btn[data-v-6321c060]:hover{background:var(--sp-scroll-btn-hover-bg, #d0d0d0)}.sb-btn[data-v-6321c060]:active{background:var(--sp-scroll-btn-active-bg, #c0c0c0)}.sb-arrow[data-v-6321c060]{display:block;width:0;height:0}.sb-arrow--up[data-v-6321c060]{border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--down[data-v-6321c060]{border-left:3px solid transparent;border-right:3px solid transparent;border-top:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--left[data-v-6321c060]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-right:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--right[data-v-6321c060]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid var(--sp-scroll-btn-color, #666)}.sb-track[data-v-6321c060]{flex:1;position:relative;background:var(--sp-scroll-track-bg, rgba(0,0,0,.06))}.sb-track--v[data-v-6321c060]{width:11px}.sb-track--h[data-v-6321c060]{height:11px}.sb-thumb[data-v-6321c060]{position:absolute;border-radius:3px;background:var(--sp-scroll-thumb);cursor:default}.sb-thumb[data-v-6321c060]:hover{background:var(--sp-scroll-thumb-hover)}.sb-thumb--v[data-v-6321c060]{left:1px;right:1px;min-height:16px}.sb-thumb--h[data-v-6321c060]{top:1px;bottom:1px;min-width:16px}.cell-editor[data-v-6321c060]{position:absolute;border:2px solid var(--sp-cell-editor-border);outline:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;color:var(--sp-cell-editor-color);background:var(--sp-cell-editor-bg);box-shadow:0 0 0 1px var(--sp-cell-editor-shadow);z-index:10;box-sizing:border-box;min-width:0;overflow:hidden;padding:0;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;resize:none;white-space:pre-wrap;word-break:break-all}.context-menu{position:fixed;z-index:10000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:120px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;transform-origin:top left}.context-menu__item{padding:6px 20px;cursor:pointer;color:#333;white-space:nowrap;position:relative;display:flex;align-items:center;justify-content:space-between}.context-menu__item:hover{background:#e8f0fe}.context-menu__item--disabled{color:#bbb;cursor:default}.context-menu__item--disabled:hover{background:transparent}.context-menu__arrow{margin-left:16px;margin-right:-5px;width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid #888}.context-submenu{display:none;position:absolute;left:100%;top:-4px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:100px;z-index:10001}.context-submenu--left{left:auto;right:100%}.context-menu__item:hover>.context-submenu{display:block}.context-submenu .context-menu__item{justify-content:flex-start}.menu-pop-enter-active,.menu-pop-leave-active{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from,.menu-pop-leave-to{opacity:0;transform:scale(.9)}.dim-panel{position:fixed;z-index:10002;width:220px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:10px 12px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none;transform-origin:top left}.dim-panel__title{font-size:13px;font-weight:600;color:#333;margin-bottom:8px}.dim-panel__body{display:flex;align-items:center;gap:6px}.dim-panel__input{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;outline:none;padding:0 6px;font-size:13px;color:#1a1a1a;background:#fff;box-sizing:border-box}.dim-panel__input:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.dim-panel__input--error{border-color:#d93025;box-shadow:0 0 0 1px #d930254d}.dim-panel__unit{font-size:12px;color:#888}.dim-panel__error{margin-top:6px;font-size:12px;color:#d93025;line-height:1.4}.dim-panel__footer{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.dim-panel__btn{height:26px;padding:0 14px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:13px;cursor:pointer}.dim-panel__btn:hover{background:#f0f0f0}.dim-panel__btn--primary{border-color:#0078d7;background:#0078d7;color:#fff}.dim-panel__btn--primary:hover{background:#0069c0}
|
|
1
|
+
.sp-dropdown[data-v-77df3baf]{position:relative;display:inline-flex;min-width:0}.sp-dropdown__trigger[data-v-77df3baf]{display:flex;align-items:center;justify-content:space-between;gap:4px;width:100%;height:26px;border:1px solid transparent;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;cursor:pointer;padding:0 5px;box-sizing:border-box}.sp-dropdown__trigger[data-v-77df3baf]:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.sp-dropdown__trigger--open[data-v-77df3baf]{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6);border-color:var(--sp-toolbar-border, #d8d8d8)}.sp-dropdown__value[data-v-77df3baf]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.sp-dropdown__caret[data-v-77df3baf]{width:10px;height:10px;min-width:10px;opacity:.7}.sp-dropdown__menu[data-v-77df3baf]{position:fixed;z-index:20000;display:flex;flex-direction:column;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;transform-origin:top center}.sp-dropdown__menu--up[data-v-77df3baf]{transform-origin:bottom center}.menu-pop-enter-active[data-v-77df3baf],.menu-pop-leave-active[data-v-77df3baf]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-77df3baf],.menu-pop-leave-to[data-v-77df3baf]{opacity:0;transform:scaleY(.85)}.sp-dropdown__nav[data-v-77df3baf]{display:flex;align-items:center;justify-content:center;height:15px;min-height:15px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #666);cursor:pointer;padding:0;border-radius:3px}.sp-dropdown__nav[data-v-77df3baf]:hover:not(:disabled){background:#eef3f9}.sp-dropdown__nav[data-v-77df3baf]:disabled{color:#ccc;cursor:default}.sp-dropdown__nav svg[data-v-77df3baf]{width:10px;height:10px}.sp-dropdown__list[data-v-77df3baf]{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.sp-dropdown__icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__icon[data-v-77df3baf] svg{width:18px;height:18px;display:block}.sp-dropdown__item-icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__item-icon[data-v-77df3baf] svg{width:16px;height:16px;display:block}.sp-dropdown__item-label[data-v-77df3baf]{white-space:nowrap}.sp-dropdown__item[data-v-77df3baf]{display:flex;align-items:center;gap:6px;width:100%;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;cursor:pointer;padding:4px 8px;box-sizing:border-box;border-radius:3px}.sp-dropdown__item[data-v-77df3baf]:hover{background:#eef3f9}.sp-dropdown__item--active[data-v-77df3baf]{background:#e5f1fb;color:#0078d7}.color-picker[data-v-f8fac424]{position:relative;display:inline-flex;height:26px}.color-picker__menu[data-v-f8fac424]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;padding:6px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;transform-origin:top right}.menu-pop-enter-active[data-v-f8fac424],.menu-pop-leave-active[data-v-f8fac424]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f8fac424],.menu-pop-leave-to[data-v-f8fac424]{opacity:0;transform:scale(.9)}.color-picker__row[data-v-f8fac424]{display:flex;gap:4px;margin-bottom:4px}.color-picker__row[data-v-f8fac424]:last-child{margin-bottom:0}.color-picker__swatch[data-v-f8fac424]{width:20px;height:20px;padding:0;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .08s,box-shadow .08s;position:relative}.color-picker__swatch[data-v-f8fac424]:hover{transform:scale(1.18);box-shadow:0 0 0 1px #0003;z-index:1}.color-picker__swatch--selected[data-v-f8fac424]{box-shadow:0 0 0 2px #0078d7}.border-picker[data-v-f362abdb]{position:relative;display:inline-flex;height:26px}.border-picker__menu[data-v-f362abdb]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.border-picker__item[data-v-f362abdb]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.border-picker__item[data-v-f362abdb]:hover{background:#eef3f9}.border-picker__icon[data-v-f362abdb]{width:18px;height:18px;flex-shrink:0}.border-picker__label[data-v-f362abdb]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-f362abdb],.menu-pop-leave-active[data-v-f362abdb]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f362abdb],.menu-pop-leave-to[data-v-f362abdb]{opacity:0;transform:scale(.9)}.merge-picker[data-v-67c0f9e3]{position:relative;display:inline-flex;height:26px}.merge-picker__menu[data-v-67c0f9e3]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.merge-picker__item[data-v-67c0f9e3]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.merge-picker__item[data-v-67c0f9e3]:hover{background:#eef3f9}.merge-picker__icon[data-v-67c0f9e3]{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.merge-picker__icon[data-v-67c0f9e3] svg{width:18px;height:18px}.merge-picker__label[data-v-67c0f9e3]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-67c0f9e3],.menu-pop-leave-active[data-v-67c0f9e3]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-67c0f9e3],.menu-pop-leave-to[data-v-67c0f9e3]{opacity:0;transform:scale(.9)}.calc-picker[data-v-9029e58c]{position:relative;display:inline-flex;height:26px}.calc-picker__menu[data-v-9029e58c]{position:fixed;z-index:9999;min-width:120px;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.calc-picker__item[data-v-9029e58c]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.calc-picker__item[data-v-9029e58c]:hover:not(.calc-picker__item--disabled){background:#eef3f9}.calc-picker__item--disabled[data-v-9029e58c]{color:var(--sp-toolbar-btn-disabled-color, #bbb);cursor:default}.calc-picker__label[data-v-9029e58c]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-9029e58c],.menu-pop-leave-active[data-v-9029e58c]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-9029e58c],.menu-pop-leave-to[data-v-9029e58c]{opacity:0;transform:scale(.9)}.toolbar[data-v-a36c59af]{position:relative;display:flex;align-items:center;height:32px;min-height:32px;gap:2px;padding:0 6px;background:var(--sp-toolbar-bg);border-bottom:1px solid var(--sp-toolbar-border);-webkit-user-select:none;user-select:none}.tb-item[data-v-a36c59af]{display:flex;align-items:center;flex:0 0 auto}.toolbar-sep[data-v-a36c59af]{width:1px;height:18px;margin:0 4px;background:var(--sp-toolbar-border)}.toolbar-font[data-v-a36c59af],.toolbar-number-format[data-v-a36c59af],.toolbar-align[data-v-a36c59af]{flex:0 0 auto}.toolbar-font-size[data-v-a36c59af]{display:inline-flex;align-items:center;gap:0;height:26px;position:relative}.toolbar-font-size__input[data-v-a36c59af]{width:36px;height:26px;border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px;background:transparent;color:var(--sp-toolbar-btn-color);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;text-align:left;padding:0 5px;outline:none;box-sizing:border-box;-webkit-appearance:none;appearance:none;-moz-appearance:textfield}.toolbar-font-size__input[data-v-a36c59af]::-webkit-outer-spin-button,.toolbar-font-size__input[data-v-a36c59af]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.toolbar-font-size__input[data-v-a36c59af]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__input[data-v-a36c59af]:focus{border-color:var(--sp-toolbar-border);background:#fff}.toolbar-font-size__btn[data-v-a36c59af]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-left:none;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-font-size__btn[data-v-a36c59af]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__btn svg[data-v-a36c59af]{width:10px;height:10px}.toolbar-font-size__dropdown[data-v-a36c59af]{position:absolute;width:56px;height:26px;pointer-events:none}.toolbar-btn[data-v-a36c59af]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-btn[data-v-a36c59af]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-btn[data-v-a36c59af]:active:not(:disabled){opacity:.7}.toolbar-btn--active[data-v-a36c59af]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-btn--step[data-v-a36c59af]{width:26px;height:26px}.toolbar-btn--step svg[data-v-a36c59af]{width:16px;height:16px}.toolbar-btn[data-v-a36c59af]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.toolbar-btn__icon[data-v-a36c59af]{width:18px;height:18px}.toolbar-btn svg[data-v-a36c59af]:not(.toolbar-btn__icon){width:18px;height:18px}.toolbar-split[data-v-a36c59af]{display:inline-flex;align-items:center;position:relative;height:26px}.toolbar-split__main[data-v-a36c59af]{border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px}.toolbar-split__arrow[data-v-a36c59af]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-split__arrow[data-v-a36c59af]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-split__arrow svg[data-v-a36c59af]{width:10px!important;height:10px!important}.toolbar-more[data-v-a36c59af]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0;flex:0 0 auto;margin-left:auto}.toolbar-more[data-v-a36c59af]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-more--active[data-v-a36c59af]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-more svg[data-v-a36c59af]{width:18px;height:18px}.overflow-menu[data-v-a36c59af]{min-width:180px;max-width:260px;max-height:calc(100vh - 40px);overflow-y:auto;background:var(--sp-toolbar-bg, #fff);border:1px solid var(--sp-toolbar-border);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px 6px;display:flex;flex-direction:column;gap:2px;z-index:1000;transform-origin:top right}.overflow-menu.no-anim[data-v-a36c59af]{transition:none!important}.overflow-menu .tb-item[data-v-a36c59af]{width:100%}.overflow-menu .toolbar-sep[data-v-a36c59af]{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split[data-v-a36c59af]{width:100%}.overflow-menu .toolbar-split__main[data-v-a36c59af]{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size[data-v-a36c59af]{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font[data-v-a36c59af],.overflow-menu .toolbar-number-format[data-v-a36c59af],.overflow-menu .toolbar-align[data-v-a36c59af]{width:100%}.overflow-menu .toolbar-btn[data-v-a36c59af]:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color[data-v-a36c59af]{width:100%}.overflow-menu .toolbar-wrap[data-v-a36c59af]{width:100%;justify-content:flex-start}.menu-pop-enter-active[data-v-a36c59af],.menu-pop-leave-active[data-v-a36c59af]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-a36c59af],.menu-pop-leave-to[data-v-a36c59af]{opacity:0;transform:scale(.9)}.overflow-menu .tb-item{width:100%}.overflow-menu .toolbar-sep{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split{width:100%}.overflow-menu .toolbar-split__main{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font,.overflow-menu .toolbar-number-format,.overflow-menu .toolbar-align{width:100%}.overflow-menu .toolbar-btn:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color{width:100%}.overflow-menu .toolbar-wrap{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font-size__input{flex:1 1 auto;width:auto;min-width:40px}.overflow-menu .toolbar-btn:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-btn:active:not(:disabled){opacity:.7}.overflow-menu .toolbar-btn--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.overflow-menu .toolbar-btn:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.overflow-menu .toolbar-split__main:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-split__arrow:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:focus{border-color:var(--sp-toolbar-border);background:#fff}.overflow-menu .toolbar-font-size__btn:hover,.overflow-menu .toolbar-more:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-more--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.tab-bar[data-v-454e1a12]{display:flex;align-items:stretch;height:30px;min-height:30px;background:var(--sp-tab-bar-bg);border-top:1px solid var(--sp-tab-bar-border);-webkit-user-select:none;user-select:none;margin-top:4px}.tab-list[data-v-454e1a12]{display:flex;align-items:flex-start;flex:1;overflow:hidden;gap:1px;padding:0 1px}.tab-item[data-v-454e1a12]{display:flex;align-items:center;height:28px;min-width:0;max-width:120px;padding:0 10px;cursor:pointer;border:1px solid var(--sp-tab-inactive-border);background:var(--sp-tab-inactive-bg);color:var(--sp-tab-inactive-color);font-size:14px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap;transition:background .1s}.tab-item[data-v-454e1a12]:hover{background:var(--sp-tab-hover-bg)}.tab-item--active[data-v-454e1a12]{height:28px;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);border-color:var(--sp-tab-active-bg) var(--sp-tab-bar-border) var(--sp-tab-bar-border);border-top:2px solid var(--sp-tab-active-border);font-size:16px}.tab-item--active[data-v-454e1a12]:hover{background:var(--sp-tab-active-bg)}.tab-item__name[data-v-454e1a12]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-rename-input[data-v-454e1a12]{width:100%;height:18px;border:none;border-radius:0;outline:none;padding:0;font-size:16px;font-family:inherit;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);box-sizing:border-box}.tab-bar__add-btn[data-v-454e1a12]{width:24px;min-width:24px;height:24px;margin:0 4px 3px 3px;border:none;background:transparent;color:var(--sp-tab-add-btn-color);font-size:16px;line-height:22px;text-align:center;cursor:pointer;padding:0}.tab-bar__add-btn[data-v-454e1a12]:hover{background:var(--sp-tab-add-btn-hover-bg)}.find-bar[data-v-0d187de9]{display:flex;align-items:center;gap:6px;padding:4px 8px;background:var(--sp-toolbar-bg);border-bottom:1px solid var(--sp-toolbar-border);-webkit-user-select:none;user-select:none;flex-wrap:nowrap;overflow-x:auto}.find-bar__input[data-v-0d187de9]{height:24px;width:160px;flex:0 0 auto;border:1px solid var(--sp-toolbar-border);border-radius:3px;padding:0 6px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:var(--sp-formula-bar-input-color, #1a1a1a);background:#fff;outline:none;box-sizing:border-box}.find-bar__input[data-v-0d187de9]:focus{border-color:var(--sp-toolbar-btn-active-color)}.find-bar__select[data-v-0d187de9]{height:24px;flex:0 0 auto;border:1px solid var(--sp-toolbar-border);border-radius:3px;background:#fff;font-size:12px;color:var(--sp-formula-bar-input-color, #1a1a1a);outline:none;padding:0 2px}.find-bar__chk[data-v-0d187de9]{display:flex;align-items:center;gap:3px;flex:0 0 auto;font-size:12px;color:var(--sp-toolbar-btn-color);white-space:nowrap;cursor:pointer}.find-bar__chk input[data-v-0d187de9]{margin:0}.find-bar__count[data-v-0d187de9]{flex:0 0 auto;font-size:12px;color:var(--sp-toolbar-btn-color);min-width:44px;text-align:center;white-space:nowrap}.find-bar__btn[data-v-0d187de9]{height:24px;flex:0 0 auto;border:1px solid var(--sp-toolbar-border);border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;font-size:12px;padding:0 8px;display:inline-flex;align-items:center;justify-content:center}.find-bar__btn[data-v-0d187de9]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.find-bar__btn[data-v-0d187de9]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.find-bar__btn--icon[data-v-0d187de9]{width:26px;padding:0}.find-bar__btn--icon svg[data-v-0d187de9]{width:14px;height:14px}.find-bar__btn--close[data-v-0d187de9]{width:26px;padding:0;margin-left:auto}.find-bar__btn--close svg[data-v-0d187de9]{width:14px;height:14px}.nf-dialog__mask[data-v-69cb36b7]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:30000;background:rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center}.nf-dialog[data-v-69cb36b7]{width:380px;max-width:calc(100vw - 32px);max-height:calc(100vh - 48px);overflow-y:auto;background:#fff;border:1px solid #d0d0d0;border-radius:6px;box-shadow:0 8px 24px #0000002e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:#1a1a1a;-webkit-user-select:none;user-select:none}.nf-dialog__header[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #ececec}.nf-dialog__title[data-v-69cb36b7]{font-size:13px;font-weight:600}.nf-dialog__close[data-v-69cb36b7]{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:transparent;color:#888;cursor:pointer;border-radius:3px;padding:0}.nf-dialog__close[data-v-69cb36b7]:hover{background:#f0f0f0;color:#444}.nf-dialog__close svg[data-v-69cb36b7]{width:14px;height:14px}.nf-dialog__body[data-v-69cb36b7]{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.nf-field[data-v-69cb36b7]{display:flex;align-items:center;gap:8px}.nf-field--inline[data-v-69cb36b7]{min-height:26px}.nf-field__label[data-v-69cb36b7]{width:88px;min-width:88px;font-size:12px;color:#555}.nf-field__select[data-v-69cb36b7],.nf-field__input[data-v-69cb36b7]{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:0 6px;outline:none;box-sizing:border-box;font-family:inherit}.nf-field__select[data-v-69cb36b7]:focus,.nf-field__input[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-field__textarea[data-v-69cb36b7]{flex:1;min-height:44px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:4px 6px;outline:none;box-sizing:border-box;resize:none;font-family:Consolas,Courier New,monospace}.nf-field__textarea[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-checkbox[data-v-69cb36b7]{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:#333;cursor:pointer}.nf-checkbox input[data-v-69cb36b7]{margin:0;cursor:pointer}.nf-dialog__footer[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 14px;border-top:1px solid #ececec}.nf-preview[data-v-69cb36b7]{display:flex;flex-direction:column;gap:2px;min-width:0}.nf-preview__label[data-v-69cb36b7]{font-size:11px;color:#888}.nf-preview__value[data-v-69cb36b7]{font-size:13px;color:#1a1a1a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.nf-dialog__actions[data-v-69cb36b7]{display:flex;gap:8px}.nf-btn[data-v-69cb36b7]{height:28px;padding:0 16px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-family:inherit}.nf-btn[data-v-69cb36b7]:hover{background:#f0f0f0}.nf-btn--primary[data-v-69cb36b7]{border-color:#0078d7;background:#0078d7;color:#fff}.nf-btn--primary[data-v-69cb36b7]:hover{background:#0069c0}.nf-dialog-enter-active[data-v-69cb36b7],.nf-dialog-leave-active[data-v-69cb36b7]{transition:opacity .14s ease-out}.nf-dialog-enter-from[data-v-69cb36b7],.nf-dialog-leave-to[data-v-69cb36b7]{opacity:0}.nf-dialog-enter-active .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-active .nf-dialog[data-v-69cb36b7]{transition:transform .14s ease-out}.nf-dialog-enter-from .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-to .nf-dialog[data-v-69cb36b7]{transform:scale(.96)}.spreadsheet-outer[data-v-daa631b0]{flex:1;display:flex;flex-direction:column;overflow:hidden;height:100%;min-height:400px;width:100%}.formula-bar[data-v-daa631b0]{display:flex;align-items:flex-start;min-height:36px;padding:0;gap:0}.formula-bar--expanded[data-v-daa631b0]{min-height:72px}.formula-bar__cell-label[data-v-daa631b0]{width:48px;min-width:48px;height:28px;line-height:28px;margin-top:4px;text-align:center;font-size:12px;font-weight:600;color:var(--sp-formula-bar-label-color);background:var(--sp-formula-bar-label-bg);border:1px solid var(--sp-formula-bar-label-border);border-radius:2px;-webkit-user-select:none;user-select:none}.formula-bar__buttons[data-v-daa631b0]{display:inline-flex;align-items:stretch;margin-top:4px;margin-left:6px;height:28px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;overflow:hidden;background:var(--sp-formula-bar-input-bg)}.formula-bar__btn[data-v-daa631b0]{width:22px;height:28px;border:none;border-radius:0;background:transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none;color:inherit}.formula-bar__btn+.formula-bar__btn[data-v-daa631b0]{border-left:1px solid var(--sp-formula-bar-input-border)}.formula-bar__btn[data-v-daa631b0]:hover{background:var(--sp-scroll-btn-hover-bg, #f0f0f0)}.formula-bar__btn--cancel[data-v-daa631b0]:hover{color:#e53935;background:#fdecea}.formula-bar__btn--accept[data-v-daa631b0]:hover{color:#2e7d32;background:#e8f5e9}.formula-bar__input[data-v-daa631b0]{flex:1;min-height:28px;height:28px;line-height:20px;margin-top:4px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;outline:none;padding:3px 6px;margin-left:4px;font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:var(--sp-formula-bar-input-color);background:var(--sp-formula-bar-input-bg);resize:none;overflow:hidden;box-sizing:border-box}.formula-bar__input--expanded[data-v-daa631b0]{height:68px;overflow:auto}.formula-bar__input[data-v-daa631b0]:focus{border-color:var(--sp-formula-bar-input-focus-border);box-shadow:0 0 0 1px var(--sp-formula-bar-input-focus-shadow)}.formula-bar__toggle[data-v-daa631b0]{width:22px;min-width:22px;height:28px;margin-top:4px;margin-left:2px;margin-right:2px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;background:var(--sp-formula-bar-input-bg);color:var(--sp-formula-bar-input-color);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none}.formula-bar__toggle[data-v-daa631b0]:hover{background:var(--sp-scroll-btn-hover-bg, #e8e8e8)}.spreadsheet-wrapper[data-v-daa631b0]{flex:1;position:relative;overflow:hidden;background:var(--sp-wrapper-bg)}.grid-canvas[data-v-daa631b0]{position:absolute;top:0;left:0;display:block;outline:none;cursor:cell}.grid-canvas[data-v-daa631b0]:focus{outline:none}.v-scrollbar[data-v-daa631b0]{position:absolute;right:0;top:0;width:11px;height:calc(100% - 11px);display:flex;flex-direction:column;background:var(--sp-wrapper-bg)}.h-scrollbar[data-v-daa631b0]{position:absolute;left:0;bottom:0;height:11px;width:calc(100% - 11px);display:flex;background:var(--sp-wrapper-bg)}.sb-corner[data-v-daa631b0]{position:absolute;right:0;bottom:0;width:11px;height:11px;background:var(--sp-wrapper-bg)}.sb-btn[data-v-daa631b0]{width:11px;height:11px;min-width:11px;min-height:11px;border:none;background:var(--sp-scroll-btn-bg, #e8e8e8);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;-webkit-user-select:none;user-select:none}.sb-btn[data-v-daa631b0]:hover{background:var(--sp-scroll-btn-hover-bg, #d0d0d0)}.sb-btn[data-v-daa631b0]:active{background:var(--sp-scroll-btn-active-bg, #c0c0c0)}.sb-arrow[data-v-daa631b0]{display:block;width:0;height:0}.sb-arrow--up[data-v-daa631b0]{border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--down[data-v-daa631b0]{border-left:3px solid transparent;border-right:3px solid transparent;border-top:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--left[data-v-daa631b0]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-right:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--right[data-v-daa631b0]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid var(--sp-scroll-btn-color, #666)}.sb-track[data-v-daa631b0]{flex:1;position:relative;background:var(--sp-scroll-track-bg, rgba(0,0,0,.06))}.sb-track--v[data-v-daa631b0]{width:11px}.sb-track--h[data-v-daa631b0]{height:11px}.sb-thumb[data-v-daa631b0]{position:absolute;border-radius:3px;background:var(--sp-scroll-thumb);cursor:default}.sb-thumb[data-v-daa631b0]:hover{background:var(--sp-scroll-thumb-hover)}.sb-thumb--v[data-v-daa631b0]{left:1px;right:1px;min-height:16px}.sb-thumb--h[data-v-daa631b0]{top:1px;bottom:1px;min-width:16px}.cell-editor[data-v-daa631b0]{position:absolute;border:2px solid var(--sp-cell-editor-border);outline:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;color:var(--sp-cell-editor-color);background:var(--sp-cell-editor-bg);box-shadow:0 0 0 1px var(--sp-cell-editor-shadow);z-index:10;box-sizing:border-box;min-width:0;overflow:hidden;padding:0;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;resize:none;white-space:pre-wrap;word-break:break-all}.context-menu{position:fixed;z-index:10000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:120px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;transform-origin:top left}.context-menu__item{padding:6px 20px;cursor:pointer;color:#333;white-space:nowrap;position:relative;display:flex;align-items:center;justify-content:space-between}.context-menu__item:hover{background:#e8f0fe}.context-menu__item--disabled{color:#bbb;cursor:default}.context-menu__item--disabled:hover{background:transparent}.context-menu__arrow{margin-left:16px;margin-right:-5px;width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid #888}.context-submenu{display:none;position:absolute;left:100%;top:-4px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:100px;z-index:10001}.context-submenu--left{left:auto;right:100%}.context-menu__item:hover>.context-submenu{display:block}.context-submenu .context-menu__item{justify-content:flex-start}.menu-pop-enter-active,.menu-pop-leave-active{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from,.menu-pop-leave-to{opacity:0;transform:scale(.9)}.dim-panel{position:fixed;z-index:10002;width:220px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:10px 12px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none;transform-origin:top left}.dim-panel__title{font-size:13px;font-weight:600;color:#333;margin-bottom:8px}.dim-panel__body{display:flex;align-items:center;gap:6px}.dim-panel__input{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;outline:none;padding:0 6px;font-size:13px;color:#1a1a1a;background:#fff;box-sizing:border-box}.dim-panel__input:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.dim-panel__input--error{border-color:#d93025;box-shadow:0 0 0 1px #d930254d}.dim-panel__unit{font-size:12px;color:#888}.dim-panel__error{margin-top:6px;font-size:12px;color:#d93025;line-height:1.4}.dim-panel__footer{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.dim-panel__btn{height:26px;padding:0 14px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:13px;cursor:pointer}.dim-panel__btn:hover{background:#f0f0f0}.dim-panel__btn--primary{border-color:#0078d7;background:#0078d7;color:#fff}.dim-panel__btn--primary:hover{background:#0069c0}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FindScope } from '../core/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
open: boolean;
|
|
4
|
+
findText: string;
|
|
5
|
+
replaceText: string;
|
|
6
|
+
scope: FindScope;
|
|
7
|
+
matchCase: boolean;
|
|
8
|
+
matchEntireCell: boolean;
|
|
9
|
+
currentIndex: number;
|
|
10
|
+
total: number;
|
|
11
|
+
message: string;
|
|
12
|
+
focusToken: number;
|
|
13
|
+
locale: string;
|
|
14
|
+
themeVars?: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
17
|
+
[x: string]: any;
|
|
18
|
+
} & {
|
|
19
|
+
[x: string]: any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
21
|
+
[x: `on${Capitalize<any>}`]: ((...args: any[] | unknown[]) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {
|
|
23
|
+
findInputRef: HTMLInputElement;
|
|
24
|
+
}, any>;
|
|
25
|
+
export default _default;
|
|
@@ -57,6 +57,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
57
57
|
"apply-merge": () => void;
|
|
58
58
|
"calc-sum": () => void;
|
|
59
59
|
"calc-avg": () => void;
|
|
60
|
+
"calc-count": () => void;
|
|
60
61
|
"font-family-change": (v: string | number) => void;
|
|
61
62
|
"font-size-change": (v: string | number) => void;
|
|
62
63
|
"h-align-change": (v: string | number) => void;
|
|
@@ -66,6 +67,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
66
67
|
"fill-color-change": (v: string) => void;
|
|
67
68
|
"number-format-change": (v: string) => void;
|
|
68
69
|
"font-size-keydown": (ev: KeyboardEvent) => void;
|
|
70
|
+
find: () => void;
|
|
69
71
|
"update:font-size-menu-open": (v: boolean) => void;
|
|
70
72
|
"update:text-color-menu-open": (v: boolean) => void;
|
|
71
73
|
"update:fill-color-menu-open": (v: boolean) => void;
|
|
@@ -77,6 +79,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
77
79
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
78
80
|
onUndo?: (() => any) | undefined;
|
|
79
81
|
onRedo?: (() => any) | undefined;
|
|
82
|
+
onFind?: (() => any) | undefined;
|
|
80
83
|
"onPaint-format"?: (() => any) | undefined;
|
|
81
84
|
"onClear-format"?: (() => any) | undefined;
|
|
82
85
|
"onFont-size-blur"?: (() => any) | undefined;
|
|
@@ -94,6 +97,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
94
97
|
"onApply-merge"?: (() => any) | undefined;
|
|
95
98
|
"onCalc-sum"?: (() => any) | undefined;
|
|
96
99
|
"onCalc-avg"?: (() => any) | undefined;
|
|
100
|
+
"onCalc-count"?: (() => any) | undefined;
|
|
97
101
|
"onFont-family-change"?: ((v: string | number) => any) | undefined;
|
|
98
102
|
"onFont-size-change"?: ((v: string | number) => any) | undefined;
|
|
99
103
|
"onH-align-change"?: ((v: string | number) => any) | undefined;
|
|
@@ -45,9 +45,11 @@ export interface BordersMergeState {
|
|
|
45
45
|
clearSelected: () => void;
|
|
46
46
|
sumSelected: () => void;
|
|
47
47
|
avgSelected: () => void;
|
|
48
|
+
countSelected: () => void;
|
|
48
49
|
calcMenuOpen: Ref<boolean>;
|
|
49
50
|
onCalcMenuToggle: (v: boolean) => void;
|
|
50
51
|
onCalcSum: () => void;
|
|
51
52
|
onCalcAvg: () => void;
|
|
53
|
+
onCalcCount: () => void;
|
|
52
54
|
}
|
|
53
55
|
export declare function createBordersMerge(s: CoreState, us: UndoStylesState): BordersMergeState;
|
|
@@ -92,6 +92,8 @@ export interface CoreState {
|
|
|
92
92
|
h: number;
|
|
93
93
|
};
|
|
94
94
|
clampScroll?: (sx: number | null, sy: number | null) => void;
|
|
95
|
+
/** 查找高亮钩子:返回某单元格当前的高亮类型(由 find-replace 模块注入) */
|
|
96
|
+
findHighlight?: (col: number, row: number) => 'active' | 'match' | null;
|
|
95
97
|
}
|
|
96
98
|
export declare function createCoreState(rawProps: {
|
|
97
99
|
rowCount?: number;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Ref, type ComputedRef } from 'vue';
|
|
2
|
+
import type { CoreState } from './core-state';
|
|
3
|
+
import type { UndoStylesState } from './undo-styles';
|
|
4
|
+
import type { SheetsOpsState } from './sheets-ops';
|
|
5
|
+
import type { FindResult, FindScope } from '../core/types';
|
|
6
|
+
export interface FindReplaceState {
|
|
7
|
+
open: Ref<boolean>;
|
|
8
|
+
findText: Ref<string>;
|
|
9
|
+
replaceText: Ref<string>;
|
|
10
|
+
scope: Ref<FindScope>;
|
|
11
|
+
matchCase: Ref<boolean>;
|
|
12
|
+
matchEntireCell: Ref<boolean>;
|
|
13
|
+
currentIndex: Ref<number>;
|
|
14
|
+
results: Ref<FindResult[]>;
|
|
15
|
+
message: Ref<string>;
|
|
16
|
+
/** 每次打开/需要聚焦时自增,供 UI 聚焦查找输入框 */
|
|
17
|
+
focusToken: Ref<number>;
|
|
18
|
+
activeSheetMatches: ComputedRef<Set<string>>;
|
|
19
|
+
activeMatchKey: ComputedRef<string | null>;
|
|
20
|
+
openFind: () => void;
|
|
21
|
+
openReplace: () => void;
|
|
22
|
+
close: () => void;
|
|
23
|
+
recompute: () => void;
|
|
24
|
+
findNext: () => void;
|
|
25
|
+
findPrev: () => void;
|
|
26
|
+
replace: () => void;
|
|
27
|
+
replaceAll: () => void;
|
|
28
|
+
setupLifecycle: () => void;
|
|
29
|
+
}
|
|
30
|
+
export declare function createFindReplace(s: CoreState, us: UndoStylesState, so: SheetsOpsState, _lastEmittedDataRef?: {
|
|
31
|
+
value: string;
|
|
32
|
+
}): FindReplaceState;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FindResult, FindScope, SelectionRange } from './types';
|
|
2
|
+
/** 转义正则特殊字符,用于大小写不敏感的全局替换 */
|
|
3
|
+
export declare function escapeRegExp(s: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* 判断单元格原始值是否匹配查找条件。
|
|
6
|
+
* - 始终基于单元格原始 value(string),不基于格式化文本。
|
|
7
|
+
* - 默认不区分大小写、非完整匹配;可开启区分大小写 / 完整匹配。
|
|
8
|
+
*/
|
|
9
|
+
export declare function cellMatches(raw: string, find: string, matchCase: boolean, matchEntireCell: boolean): boolean;
|
|
10
|
+
/** 单次替换:仅替换第一个匹配项(保持单元格其余内容不变) */
|
|
11
|
+
export declare function replaceFirst(raw: string, find: string, replace: string, matchCase: boolean): string;
|
|
12
|
+
/** 全部替换:替换所有匹配项(大小写不敏感时替换函数避免 $ 被当作分组引用) */
|
|
13
|
+
export declare function replaceAllOccurrences(raw: string, find: string, replace: string, matchCase: boolean): string;
|
|
14
|
+
/**
|
|
15
|
+
* 扫描某个 Sheet 的 cells,返回所有匹配坐标。
|
|
16
|
+
* - range 给定时仅扫描该矩形范围(用于「当前选区」)。
|
|
17
|
+
* - range 为空时扫描整张表(用于「当前工作表」/「整个工作簿」)。
|
|
18
|
+
* cells 仅读取 value 字段;key 通过 cellKey(c,r) 构造以匹配 range 扫描。
|
|
19
|
+
*/
|
|
20
|
+
export declare function scanSheetCells(cells: Record<string, {
|
|
21
|
+
value: string;
|
|
22
|
+
}>, sheetIndex: number, cellKey: (c: number, r: number) => string, find: string, matchCase: boolean, matchEntireCell: boolean, range?: SelectionRange): FindResult[];
|
|
23
|
+
export type { FindScope, FindResult, SelectionRange };
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { CellData } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 公式求值结果:
|
|
4
|
+
* - number:SUM / AVERAGE / COUNT 等数值类公式
|
|
5
|
+
* - string:IF / VLOOKUP 文本返回 / CONCATENATE 等文本类公式
|
|
6
|
+
* - null:求值时出现错误(循环引用、参数非法、未找到等),渲染为 #ERROR
|
|
7
|
+
*/
|
|
8
|
+
export type FormulaValue = string | number | null;
|
|
2
9
|
/** 解析区域引用(如 "A1:B5" → {sc, sr, ec, er}) */
|
|
3
10
|
export declare function parseRangeRef(rangeRef: string, colCount: number, rowCount: number): {
|
|
4
11
|
sc: number;
|
|
@@ -6,12 +13,14 @@ export declare function parseRangeRef(rangeRef: string, colCount: number, rowCou
|
|
|
6
13
|
ec: number;
|
|
7
14
|
er: number;
|
|
8
15
|
} | null;
|
|
9
|
-
/**
|
|
16
|
+
/** 获取单元格标量值(用于公式参数求值)。公式单元格会递归求值,空单元格返回 '' */
|
|
17
|
+
export declare function getCellScalar(col: number, row: number, cells: Record<string, CellData>, colCount: number, rowCount: number): FormulaValue;
|
|
18
|
+
/** 获取单元格数值(用于 SUM/AVERAGE/COUNT 等数值上下文),非数值按 0 处理 */
|
|
10
19
|
export declare function getNumericValue(col: number, row: number, cells: Record<string, CellData>, colCount: number, rowCount: number): number;
|
|
11
20
|
export declare function clearEvalCache(): void;
|
|
12
|
-
export declare function getEvalCache(): Map<string,
|
|
13
|
-
/**
|
|
14
|
-
export declare function evalFormula(key: string, cells: Record<string, CellData>, colCount: number, rowCount: number):
|
|
21
|
+
export declare function getEvalCache(): Map<string, FormulaValue>;
|
|
22
|
+
/** 对指定单元格公式求值,返回标量结果;普通值则解析为标量(数字或字符串) */
|
|
23
|
+
export declare function evalFormula(key: string, cells: Record<string, CellData>, colCount: number, rowCount: number): FormulaValue;
|
|
15
24
|
/** 解析公式中引用的单元格列表(用于依赖追踪) */
|
|
16
25
|
export declare function parseFormulaRefs(formula: string, colCount: number, rowCount: number): string[];
|
|
17
26
|
/** 计算单元格显示值(公式则求值,否则返回原值) */
|
|
@@ -12,6 +12,14 @@ export interface CellData {
|
|
|
12
12
|
value: string;
|
|
13
13
|
style: Record<string, unknown> | null;
|
|
14
14
|
}
|
|
15
|
+
/** 搜索范围:当前工作表 / 整个工作簿 / 当前选区 */
|
|
16
|
+
export type FindScope = 'sheet' | 'workbook' | 'selection';
|
|
17
|
+
/** 单次匹配结果:记录所在 Sheet 索引与单元格坐标 */
|
|
18
|
+
export interface FindResult {
|
|
19
|
+
sheetIndex: number;
|
|
20
|
+
col: number;
|
|
21
|
+
row: number;
|
|
22
|
+
}
|
|
15
23
|
export interface Range {
|
|
16
24
|
start: number;
|
|
17
25
|
end: number;
|
|
@@ -116,6 +124,8 @@ export interface ThemeColors {
|
|
|
116
124
|
toolbarBtnHoverBg: string;
|
|
117
125
|
toolbarBtnDisabledColor: string;
|
|
118
126
|
toolbarBtnActiveColor: string;
|
|
127
|
+
findMatchBg: string;
|
|
128
|
+
findActiveBg: string;
|
|
119
129
|
}
|
|
120
130
|
export interface Point {
|
|
121
131
|
x: number;
|