xiaodao-spreader 0.1.19 → 0.1.21
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 +41 -12
- package/README.md +41 -12
- package/dist/style.css +1 -1
- package/dist/types/components/spreader/components/pickers/numberFormatDialog.vue.d.ts +3 -0
- package/dist/types/components/spreader/components/tabbar.vue.d.ts +2 -0
- package/dist/types/components/spreader/components/toolbar.vue.d.ts +6 -0
- package/dist/types/components/spreader/composables/borders-merge.d.ts +5 -17
- package/dist/types/components/spreader/composables/core-state.d.ts +27 -2
- package/dist/types/components/spreader/composables/undo-styles.d.ts +9 -2
- package/dist/types/components/spreader/core/border-pool.d.ts +101 -0
- package/dist/types/components/spreader/core/border-resolve.d.ts +48 -0
- package/dist/types/components/spreader/core/number-format.d.ts +47 -0
- package/dist/types/components/spreader/core/style-pool.d.ts +84 -0
- package/dist/types/components/spreader/core/types.d.ts +63 -3
- package/dist/types/components/spreader/index.d.ts +2 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/xiaodao-spreader.es.js +4705 -3984
- package/dist/xiaodao-spreader.umd.js +9 -9
- package/package.json +2 -2
package/README.ZH.md
CHANGED
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
- **Canvas 2D 渲染** — 高 DPI 自适应(DPR 缩放),虚拟视口渲染,支持 200 行 × 26 列
|
|
22
22
|
- **多 Sheet 工作簿** — 标签栏支持新建、重命名、复制、删除、拖拽排序
|
|
23
23
|
- **公式引擎** — 支持 `=SUM()`、`=AVERAGE()`、`=COUNT()`、`=IF()`、`=VLOOKUP()`、`=CONCATENATE()`,支持依赖追踪与循环引用检测;工具栏与右键菜单提供一键求和/平均值/计数
|
|
24
|
-
- **合并单元格** —
|
|
24
|
+
- **合并单元格** — 合并居中、跨列合并、取消合并;合并区域边框按锚点存储、公共边渲染时统一解析
|
|
25
25
|
- **丰富单元格格式** — 字体、字号(5–72)、加粗、斜体、下划线、删除线、文字颜色、填充颜色、水平/垂直对齐、自动换行
|
|
26
|
-
- **边框** —
|
|
26
|
+
- **边框** — 上/下/左/右/外边框/全部/无,5 种预设样式及自定义颜色;独立边框池存储、公共边渲染时统一解析
|
|
27
27
|
- **撤销 / 重做** — 单元格、列宽、行高的完整状态快照(50 步)
|
|
28
28
|
- **格式刷** — 复制并应用单元格格式到任意区域
|
|
29
29
|
- **数字格式** — Excel 风格数字格式(常规 / 文本 / 数值 / 货币 / 会计 / 百分比 / 科学计数 / 日期 / 时间 / 日期时间 / 持续时间),提供自定义格式对话框;仅影响显示,绝不修改底层单元格值
|
|
@@ -108,10 +108,11 @@ import type { SheetModelData } from 'xiaodao-spreader';
|
|
|
108
108
|
const myData = ref<SheetModelData[]>([
|
|
109
109
|
{
|
|
110
110
|
name: 'Sheet1',
|
|
111
|
+
styles: [{}, { fontSize: 14, fontWeight: 'bold' }],
|
|
111
112
|
cells: {
|
|
112
113
|
'0,0': { value: '姓名' },
|
|
113
114
|
'0,1': { value: '年龄' },
|
|
114
|
-
'1,0': { value: '张三',
|
|
115
|
+
'1,0': { value: '张三', styleId: 1 },
|
|
115
116
|
'1,1': { value: '28' },
|
|
116
117
|
},
|
|
117
118
|
colWidths: { 0: 120, 1: 80 },
|
|
@@ -145,9 +146,11 @@ const myData = ref<SheetModelData[]>([
|
|
|
145
146
|
```typescript
|
|
146
147
|
interface SheetModelData {
|
|
147
148
|
name: string;
|
|
149
|
+
styles?: CellStyle[];
|
|
150
|
+
borders?: BorderStyle[];
|
|
148
151
|
cells: Record<string, {
|
|
149
152
|
value: string;
|
|
150
|
-
|
|
153
|
+
styleId?: number;
|
|
151
154
|
}>;
|
|
152
155
|
merges?: Record<string, SelectionRange>;
|
|
153
156
|
colWidths?: Record<number, number>;
|
|
@@ -155,8 +158,9 @@ interface SheetModelData {
|
|
|
155
158
|
}
|
|
156
159
|
```
|
|
157
160
|
|
|
158
|
-
- **`
|
|
159
|
-
- **`
|
|
161
|
+
- **`styles`**:样式池 —— `styles[0]` 始终为默认空样式 `{}`。单元格通过下标(`styleId`)引用样式。
|
|
162
|
+
- **`borders`**:边框池 —— `borders[0]` 始终为默认空边框 `{}`。样式通过下标(`borderId`)引用边框;省略时由旧版内联边框属性自动迁移。
|
|
163
|
+
- **`cells`**:键为 `"列,行"` 格式(如 `"0,0"` 代表 A1 单元格)。`styleId` 引用 `styles` 数组;`styleId=0` 或省略表示默认样式。
|
|
160
164
|
- **`merges`**:合并单元格定义,以合并锚点单元格为键。
|
|
161
165
|
- **`colWidths` / `rowHeights`**:稀疏映射 — 仅存储非默认值。
|
|
162
166
|
|
|
@@ -166,7 +170,11 @@ interface SheetModelData {
|
|
|
166
170
|
import type {
|
|
167
171
|
CellCoord, // { col: number; row: number }
|
|
168
172
|
SelectionRange, // { startCol; startRow; endCol; endRow }
|
|
169
|
-
CellData, // { value: string;
|
|
173
|
+
CellData, // { value: string; styleId?: number }
|
|
174
|
+
CellStyle, // 类型化样式接口(字体、颜色、边框、对齐等)
|
|
175
|
+
BorderStyle, // 四边边框组合 { top; right; bottom; left }
|
|
176
|
+
BorderSide, // 单边边框 { width; color; style }
|
|
177
|
+
BorderSource, // 边框来源 'cell' | 'merge'
|
|
170
178
|
Range, // { start: number; end: number }
|
|
171
179
|
SpreadsheetOptions,
|
|
172
180
|
SpreadsheetData,
|
|
@@ -177,6 +185,9 @@ import type {
|
|
|
177
185
|
ThemeColors,
|
|
178
186
|
Point,
|
|
179
187
|
} from 'xiaodao-spreader';
|
|
188
|
+
|
|
189
|
+
// 运行时工具函数
|
|
190
|
+
import { StylePool, resolveStyle, migrateCells, cloneCells } from 'xiaodao-spreader';
|
|
180
191
|
```
|
|
181
192
|
|
|
182
193
|
---
|
|
@@ -203,16 +214,21 @@ src/
|
|
|
203
214
|
├── composables/
|
|
204
215
|
│ ├── core-state.ts # Props、cells/merges/selection、字体度量、导航
|
|
205
216
|
│ ├── undo-styles.ts # 撤销重做、格式刷、字体/对齐/颜色
|
|
206
|
-
│ ├── borders-merge.ts #
|
|
217
|
+
│ ├── borders-merge.ts # 边框操作、合并操作、剪贴板、求和
|
|
207
218
|
│ ├── sheets-ops.ts # 行列增删、多 Sheet、v-model 发射、主题、refs
|
|
219
|
+
│ ├── find-replace.ts # 查找替换状态与交互(依赖 Vue)
|
|
208
220
|
│ └── interactions.ts # 渲染器、编辑栏、标签栏、右键菜单、滚动条、事件
|
|
209
221
|
└── core/
|
|
210
222
|
├── constants.ts # 布局常量、国际化、主题调色板
|
|
211
223
|
├── types.ts # 全部类型定义
|
|
212
|
-
├──
|
|
213
|
-
├──
|
|
224
|
+
├── style-pool.ts # 样式池:去重、注册、解析、迁移、GC
|
|
225
|
+
├── border-pool.ts # 边框池:去重、注册、解析、迁移、GC
|
|
226
|
+
├── border-resolve.ts # 公共边冲突解析(resolveSharedBorder)
|
|
227
|
+
├── formula.ts # 公式引擎(解析、计算、依赖、缓存)
|
|
228
|
+
├── find-replace-core.ts # 查找替换纯算法(零 Vue 依赖,可单测)
|
|
229
|
+
├── number-format.ts # 数字格式引擎(Excel 风格显示格式化)
|
|
214
230
|
├── theme.ts # 主题 CSS 变量构建
|
|
215
|
-
└── utils.ts
|
|
231
|
+
└── utils.ts # 纯工具函数(列标签、命中测试、尺寸解析)
|
|
216
232
|
```
|
|
217
233
|
|
|
218
234
|
### 设计原则
|
|
@@ -221,6 +237,8 @@ src/
|
|
|
221
237
|
- **Barrel 导出**:`spreader/index.ts` 集中导出组件和全部类型,`src/index.ts` 再统一 re-export,外部统一从 `xiaodao-spreader` 引入
|
|
222
238
|
- **Canvas 2D 渲染**:仅绘制可视区域(虚拟渲染),大表流畅
|
|
223
239
|
- **无脏标记**:在交互结束点手动调用 `scheduleRender()`;`requestAnimationFrame` 自动合并同一帧的多次调用
|
|
240
|
+
- **样式池**:每个 Sheet 维护 `styles: CellStyle[]` 数组,单元格通过 `styleId`(数组下标)引用样式。相同样式自动去重。运行时通过 `resolveStyle()` / `registerStyle()` 解析样式;GC(`compactStyles`)仅在保存/导出时执行
|
|
241
|
+
- **边框池**:边框独立于普通样式,存入每 Sheet 的 `borders: BorderStyle[]` 池,样式通过 `borderId`(数组下标)引用。相邻公共边在渲染时经 `resolveSharedBorder()` 统一解析,设置边框不再同步修改相邻单元格
|
|
224
242
|
- **共享状态**:将 `CoreState` 注入每个 composable,实现跨模块通信而不产生紧耦合
|
|
225
243
|
- **Reactive 包装**:composable 返回值通过 `reactive()` 包装,模板中自动解包 ref/computed
|
|
226
244
|
|
|
@@ -323,7 +341,7 @@ src/
|
|
|
323
341
|
|
|
324
342
|
### 工作原理
|
|
325
343
|
|
|
326
|
-
-
|
|
344
|
+
- **存储**:格式代码按单元格存入解析后样式的 `numberFormat` 属性(字符串)。省略该属性(或空串)即常规格式。
|
|
327
345
|
- **界面**:工具栏数字格式下拉框将预设应用到当前选区;**「格式…」** 项打开 `numberFormatDialog.vue`,可自定义格式代码、小数位数与千位分隔符。
|
|
328
346
|
- **显示**:`formatNumber(value, format, locale)` 解析代码(带缓存),应用千位分隔 / 小数位 / 百分比缩放 / 日期序列号转换,返回显示字符串。非法的日期/持续时间序列号渲染为 `###`。
|
|
329
347
|
- **对齐**:数值类格式默认右对齐;文本及常规下的非数值保持左对齐——与 Excel 语义一致。
|
|
@@ -331,6 +349,17 @@ src/
|
|
|
331
349
|
|
|
332
350
|
---
|
|
333
351
|
|
|
352
|
+
## 边框系统
|
|
353
|
+
|
|
354
|
+
一套独立的边框存储与渲染机制(`spreader/core/border-pool.ts` + `border-resolve.ts`)。
|
|
355
|
+
|
|
356
|
+
- **独立边框池**:每个 Sheet 维护 `borders: BorderStyle[]` 池(`borders[0]` 恒为空边框 `{}`),样式通过 `borderId`(数组下标)引用边框,相同边框自动去重。
|
|
357
|
+
- **公共边统一解析**:相邻单元格的公共边在渲染时经 `resolveSharedBorder()` 解析——宽者优先、同宽取先侧;设置边框**不再**同步修改相邻单元格。
|
|
358
|
+
- **合并单元格**:合并区域边框统一存储在锚点(左上角),内部边屏蔽,外边界按行/列分段与相邻区域解析,四角补齐角方块。
|
|
359
|
+
- **旧数据兼容**:旧版内联边框属性(`borderTopWidth` 等,已废弃)在加载时经 `migrateBordersInStyles()` 自动迁移。
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
334
363
|
## 主题与国际化
|
|
335
364
|
|
|
336
365
|
### 内置主题
|
package/README.md
CHANGED
|
@@ -20,9 +20,9 @@ A high-performance, canvas-based spreadsheet component for Vue 3 — bringing an
|
|
|
20
20
|
- **Canvas 2D Rendering** — High-DPI aware with DPR scaling, virtual viewport rendering for 200 × 26 sheets
|
|
21
21
|
- **Multi-Sheet Workbook** — Tab bar with add, rename, duplicate, delete, reorder
|
|
22
22
|
- **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
|
|
23
|
-
- **Merge Cells** — Merge & Center, Merge Across, Unmerge
|
|
23
|
+
- **Merge Cells** — Merge & Center, Merge Across, Unmerge; merged-region borders stored at the anchor, shared borders resolved at render time
|
|
24
24
|
- **Rich Cell Formatting** — Font family, font size (5–72), bold, italic, underline, strikethrough, text color, fill color, horizontal & vertical alignment, wrap text
|
|
25
|
-
- **Borders** — Top / bottom / left / right / all / none with 5 predefined styles and custom color
|
|
25
|
+
- **Borders** — Top / bottom / left / right / outside / all / none with 5 predefined styles and custom color; stored in a dedicated border pool, shared borders resolved at render time
|
|
26
26
|
- **Undo / Redo** — Full state snapshots for cells, column widths, and row heights (50 steps)
|
|
27
27
|
- **Format Painter** — Copy & apply cell formatting across ranges
|
|
28
28
|
- **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
|
|
@@ -105,10 +105,11 @@ import type { SheetModelData } from 'xiaodao-spreader';
|
|
|
105
105
|
const myData = ref<SheetModelData[]>([
|
|
106
106
|
{
|
|
107
107
|
name: 'Sheet1',
|
|
108
|
+
styles: [{}, { fontSize: 14, fontWeight: 'bold' }],
|
|
108
109
|
cells: {
|
|
109
110
|
'0,0': { value: 'Name' },
|
|
110
111
|
'0,1': { value: 'Age' },
|
|
111
|
-
'1,0': { value: 'Alice',
|
|
112
|
+
'1,0': { value: 'Alice', styleId: 1 },
|
|
112
113
|
'1,1': { value: '28' },
|
|
113
114
|
},
|
|
114
115
|
colWidths: { 0: 120, 1: 80 },
|
|
@@ -142,9 +143,11 @@ The external data format used for v-model two-way binding:
|
|
|
142
143
|
```typescript
|
|
143
144
|
interface SheetModelData {
|
|
144
145
|
name: string;
|
|
146
|
+
styles?: CellStyle[];
|
|
147
|
+
borders?: BorderStyle[];
|
|
145
148
|
cells: Record<string, {
|
|
146
149
|
value: string;
|
|
147
|
-
|
|
150
|
+
styleId?: number;
|
|
148
151
|
}>;
|
|
149
152
|
merges?: Record<string, SelectionRange>;
|
|
150
153
|
colWidths?: Record<number, number>;
|
|
@@ -152,8 +155,9 @@ interface SheetModelData {
|
|
|
152
155
|
}
|
|
153
156
|
```
|
|
154
157
|
|
|
155
|
-
- **`
|
|
156
|
-
- **`
|
|
158
|
+
- **`styles`**: Style pool — `styles[0]` is always the default empty style `{}`. Cells reference styles by index (`styleId`).
|
|
159
|
+
- **`borders`**: Border pool — `borders[0]` is always the default empty border `{}`. Styles reference borders by index (`borderId`); auto-migrated from legacy inline border props when omitted.
|
|
160
|
+
- **`cells`**: Key is `"col,row"` (e.g., `"0,0"` for cell A1). `styleId` references into the `styles` array; `styleId=0` or omitted means default style.
|
|
157
161
|
- **`merges`**: Merge cell definitions, keyed by merge anchor cell.
|
|
158
162
|
- **`colWidths` / `rowHeights`**: Sparse maps — only stores non-default values.
|
|
159
163
|
|
|
@@ -163,7 +167,11 @@ interface SheetModelData {
|
|
|
163
167
|
import type {
|
|
164
168
|
CellCoord, // { col: number; row: number }
|
|
165
169
|
SelectionRange, // { startCol; startRow; endCol; endRow }
|
|
166
|
-
CellData, // { value: string;
|
|
170
|
+
CellData, // { value: string; styleId?: number }
|
|
171
|
+
CellStyle, // Typed style interface (font, color, border, alignment, etc.)
|
|
172
|
+
BorderStyle, // Four-side border { top; right; bottom; left }
|
|
173
|
+
BorderSide, // Single border side { width; color; style }
|
|
174
|
+
BorderSource, // Border source 'cell' | 'merge'
|
|
167
175
|
Range, // { start: number; end: number }
|
|
168
176
|
SpreadsheetOptions,
|
|
169
177
|
SpreadsheetData,
|
|
@@ -174,6 +182,9 @@ import type {
|
|
|
174
182
|
ThemeColors,
|
|
175
183
|
Point,
|
|
176
184
|
} from 'xiaodao-spreader';
|
|
185
|
+
|
|
186
|
+
// Runtime utilities
|
|
187
|
+
import { StylePool, resolveStyle, migrateCells, cloneCells } from 'xiaodao-spreader';
|
|
177
188
|
```
|
|
178
189
|
|
|
179
190
|
---
|
|
@@ -200,16 +211,21 @@ src/
|
|
|
200
211
|
├── composables/
|
|
201
212
|
│ ├── core-state.ts # Props, cells/merges/selection, font metrics, navigation
|
|
202
213
|
│ ├── undo-styles.ts # Undo/redo, format painter, font/alignment/color
|
|
203
|
-
│ ├── borders-merge.ts # Border
|
|
214
|
+
│ ├── borders-merge.ts # Border ops, merge ops, clipboard, sum
|
|
204
215
|
│ ├── sheets-ops.ts # Row/col ops, multi-sheet, v-model emit, theme, refs
|
|
216
|
+
│ ├── find-replace.ts # Find/replace state & interaction (Vue-dependent)
|
|
205
217
|
│ └── interactions.ts # Renderer, formula bar, tab bar, context menu, scrollbar, events
|
|
206
218
|
└── core/
|
|
207
219
|
├── constants.ts # Layout constants, i18n, theme palettes
|
|
208
220
|
├── types.ts # All type definitions
|
|
209
|
-
├──
|
|
210
|
-
├──
|
|
221
|
+
├── style-pool.ts # Style pool: dedup, registration, resolve, migration, GC
|
|
222
|
+
├── border-pool.ts # Border pool: dedup, registration, resolve, migration, GC
|
|
223
|
+
├── border-resolve.ts # Shared-border conflict resolution (resolveSharedBorder)
|
|
224
|
+
├── formula.ts # Formula engine (parse, evaluate, deps, cache)
|
|
225
|
+
├── find-replace-core.ts # Find/replace pure algorithms (zero Vue deps, unit-testable)
|
|
226
|
+
├── number-format.ts # Number format engine (Excel-style display formatting)
|
|
211
227
|
├── theme.ts # Theme CSS variable construction
|
|
212
|
-
└── utils.ts
|
|
228
|
+
└── utils.ts # Pure utilities (col label, hit test, resolve size)
|
|
213
229
|
```
|
|
214
230
|
|
|
215
231
|
### Design Principles
|
|
@@ -218,6 +234,8 @@ src/
|
|
|
218
234
|
- **Barrel Export**: `spreader/index.ts` centralizes all component and type exports; `src/index.ts` re-exports everything, so consumers import uniformly from `xiaodao-spreader`
|
|
219
235
|
- **Canvas 2D Rendering**: Only visible cells are drawn (virtual rendering), ensuring smooth performance on large sheets
|
|
220
236
|
- **No Dirty Flags**: Manual `scheduleRender()` calls at interaction end-points; `requestAnimationFrame` automatically merges multiple calls within the same frame
|
|
237
|
+
- **Style Pool**: Each sheet maintains a `styles: CellStyle[]` array; cells reference styles via `styleId` (array index). Identical styles are automatically deduplicated. Runtime style resolution via `resolveStyle()` / `registerStyle()`; GC (`compactStyles`) runs only at save/export time
|
|
238
|
+
- **Border Pool**: Borders are stored separately from regular styles in a per-sheet `borders: BorderStyle[]` pool; styles reference borders via `borderId` (array index). Adjacent shared borders are resolved at render time via `resolveSharedBorder()`; setting a border no longer mutates neighboring cells
|
|
221
239
|
- **Shared State**: A central `CoreState` object is injected into each composable, enabling cross-module communication without tight coupling
|
|
222
240
|
- **Reactive Wrap**: Composable return values are wrapped in `reactive()` for automatic ref/computed unwrapping in templates
|
|
223
241
|
|
|
@@ -320,7 +338,7 @@ An Excel-style number formatting engine (`spreader/core/number-format.ts`) that
|
|
|
320
338
|
|
|
321
339
|
### How it works
|
|
322
340
|
|
|
323
|
-
- **Storage**: the format code is stored per-cell in `
|
|
341
|
+
- **Storage**: the format code is stored per-cell in the resolved style's `numberFormat` property (a string). Omitting the property (or empty string) means General.
|
|
324
342
|
- **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.
|
|
325
343
|
- **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 `###`.
|
|
326
344
|
- **Alignment**: numeric formats default to right-aligned; Text and General-with-non-numeric keep left alignment — matching Excel semantics.
|
|
@@ -328,6 +346,17 @@ An Excel-style number formatting engine (`spreader/core/number-format.ts`) that
|
|
|
328
346
|
|
|
329
347
|
---
|
|
330
348
|
|
|
349
|
+
## Border System
|
|
350
|
+
|
|
351
|
+
A dedicated border storage & rendering mechanism (`spreader/core/border-pool.ts` + `border-resolve.ts`).
|
|
352
|
+
|
|
353
|
+
- **Dedicated border pool**: each sheet maintains a `borders: BorderStyle[]` pool (`borders[0]` is always the empty border `{}`); styles reference borders by index (`borderId`), and identical borders are deduplicated.
|
|
354
|
+
- **Shared-border resolution**: adjacent cells' shared border is resolved at render time via `resolveSharedBorder()` — wider wins, then the first side on equal width; setting a border no longer mutates neighboring cells.
|
|
355
|
+
- **Merged cells**: merged-region borders are stored at the anchor (top-left); internal borders are masked, outer boundaries are resolved segment-wise against neighbors, and the four corners fill in corner blocks.
|
|
356
|
+
- **Legacy compatibility**: legacy inline border props (`borderTopWidth`, etc., deprecated) are auto-migrated via `migrateBordersInStyles()` on load.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
331
360
|
## Theming
|
|
332
361
|
|
|
333
362
|
### Built-in Themes
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.sp-dropdown[data-v-0152ad1e]{position:relative;display:inline-flex;min-width:0}.sp-dropdown__trigger[data-v-0152ad1e]{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-0152ad1e]:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.sp-dropdown__trigger--open[data-v-0152ad1e]{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6);border-color:var(--sp-toolbar-border, #d8d8d8)}.sp-dropdown__value[data-v-0152ad1e]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.sp-dropdown__caret[data-v-0152ad1e]{width:10px;height:10px;min-width:10px;opacity:.7}.sp-dropdown__menu[data-v-0152ad1e]{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-0152ad1e]{transform-origin:bottom center}.menu-pop-enter-active[data-v-0152ad1e],.menu-pop-leave-active[data-v-0152ad1e]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-0152ad1e],.menu-pop-leave-to[data-v-0152ad1e]{opacity:0;transform:scaleY(.85)}.sp-dropdown__nav[data-v-0152ad1e]{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-0152ad1e]:hover:not(:disabled){background:#eef3f9}.sp-dropdown__nav[data-v-0152ad1e]:disabled{color:#ccc;cursor:default}.sp-dropdown__nav svg[data-v-0152ad1e]{width:10px;height:10px}.sp-dropdown__list[data-v-0152ad1e]{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.sp-dropdown__icon[data-v-0152ad1e]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__icon[data-v-0152ad1e] svg{width:18px;height:18px;display:block}.sp-dropdown__item-icon[data-v-0152ad1e]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__item-icon[data-v-0152ad1e] svg{width:16px;height:16px;display:block}.sp-dropdown__item-label[data-v-0152ad1e]{white-space:nowrap}.sp-dropdown__item[data-v-0152ad1e]{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-0152ad1e]:hover{background:#eef3f9}.sp-dropdown__item--active[data-v-0152ad1e]{background:#e5f1fb;color:#0078d7}.color-picker[data-v-70f3dfdc]{position:relative;display:inline-flex;height:26px}.color-picker__menu[data-v-70f3dfdc]{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-70f3dfdc],.menu-pop-leave-active[data-v-70f3dfdc]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-70f3dfdc],.menu-pop-leave-to[data-v-70f3dfdc]{opacity:0;transform:scale(.9)}.color-picker__row[data-v-70f3dfdc]{display:flex;gap:4px;margin-bottom:4px}.color-picker__row[data-v-70f3dfdc]:last-child{margin-bottom:0}.color-picker__swatch[data-v-70f3dfdc]{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-70f3dfdc]:hover{transform:scale(1.18);box-shadow:0 0 0 1px #0003;z-index:1}.color-picker__swatch--selected[data-v-70f3dfdc]{box-shadow:0 0 0 2px #0078d7}.border-picker[data-v-551c0ffe]{position:relative;display:inline-flex;height:26px}.border-picker__menu[data-v-551c0ffe]{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-551c0ffe]{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-551c0ffe]:hover{background:#eef3f9}.border-picker__icon[data-v-551c0ffe]{width:18px;height:18px;flex-shrink:0}.border-picker__label[data-v-551c0ffe]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-551c0ffe],.menu-pop-leave-active[data-v-551c0ffe]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-551c0ffe],.menu-pop-leave-to[data-v-551c0ffe]{opacity:0;transform:scale(.9)}.merge-picker[data-v-edd36208]{position:relative;display:inline-flex;height:26px}.merge-picker__menu[data-v-edd36208]{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-edd36208]{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-edd36208]:hover{background:#eef3f9}.merge-picker__icon[data-v-edd36208]{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.merge-picker__icon[data-v-edd36208] svg{width:18px;height:18px}.merge-picker__label[data-v-edd36208]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-edd36208],.menu-pop-leave-active[data-v-edd36208]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-edd36208],.menu-pop-leave-to[data-v-edd36208]{opacity:0;transform:scale(.9)}.calc-picker[data-v-01a18e00]{position:relative;display:inline-flex;height:26px}.calc-picker__menu[data-v-01a18e00]{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-01a18e00]{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-01a18e00]:hover:not(.calc-picker__item--disabled){background:#eef3f9}.calc-picker__item--disabled[data-v-01a18e00]{color:var(--sp-toolbar-btn-disabled-color, #bbb);cursor:default}.calc-picker__label[data-v-01a18e00]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-01a18e00],.menu-pop-leave-active[data-v-01a18e00]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-01a18e00],.menu-pop-leave-to[data-v-01a18e00]{opacity:0;transform:scale(.9)}.toolbar[data-v-d0b03fba]{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-d0b03fba]{display:flex;align-items:center;flex:0 0 auto}.toolbar-sep[data-v-d0b03fba]{width:1px;height:18px;margin:0 4px;background:var(--sp-toolbar-border)}.toolbar-font[data-v-d0b03fba],.toolbar-number-format[data-v-d0b03fba],.toolbar-align[data-v-d0b03fba]{flex:0 0 auto}.toolbar-font-size[data-v-d0b03fba]{display:inline-flex;align-items:center;gap:0;height:26px;position:relative}.toolbar-font-size__input[data-v-d0b03fba]{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-d0b03fba]::-webkit-outer-spin-button,.toolbar-font-size__input[data-v-d0b03fba]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.toolbar-font-size__input[data-v-d0b03fba]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__input[data-v-d0b03fba]:focus{border-color:var(--sp-toolbar-border);background:#fff}.toolbar-font-size__btn[data-v-d0b03fba]{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-d0b03fba]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__btn svg[data-v-d0b03fba]{width:10px;height:10px}.toolbar-font-size__dropdown[data-v-d0b03fba]{position:absolute;width:56px;height:26px;pointer-events:none}.toolbar-btn[data-v-d0b03fba]{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-d0b03fba]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-btn[data-v-d0b03fba]:active:not(:disabled){opacity:.7}.toolbar-btn--active[data-v-d0b03fba]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-btn--step[data-v-d0b03fba]{width:26px;height:26px}.toolbar-btn--step svg[data-v-d0b03fba]{width:16px;height:16px}.toolbar-btn[data-v-d0b03fba]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.toolbar-btn__icon[data-v-d0b03fba]{width:18px;height:18px}.toolbar-btn svg[data-v-d0b03fba]:not(.toolbar-btn__icon){width:18px;height:18px}.toolbar-split[data-v-d0b03fba]{display:inline-flex;align-items:center;position:relative;height:26px}.toolbar-split__main[data-v-d0b03fba]{border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px}.toolbar-split__arrow[data-v-d0b03fba]{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-d0b03fba]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-split__arrow svg[data-v-d0b03fba]{width:10px!important;height:10px!important}.toolbar-more[data-v-d0b03fba]{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-d0b03fba]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-more--active[data-v-d0b03fba]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-more svg[data-v-d0b03fba]{width:18px;height:18px}.overflow-menu[data-v-d0b03fba]{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-d0b03fba]{transition:none!important}.overflow-menu .tb-item[data-v-d0b03fba]{width:100%}.overflow-menu .toolbar-sep[data-v-d0b03fba]{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split[data-v-d0b03fba]{width:100%}.overflow-menu .toolbar-split__main[data-v-d0b03fba]{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size[data-v-d0b03fba]{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font[data-v-d0b03fba],.overflow-menu .toolbar-number-format[data-v-d0b03fba],.overflow-menu .toolbar-align[data-v-d0b03fba]{width:100%}.overflow-menu .toolbar-btn[data-v-d0b03fba]:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color[data-v-d0b03fba]{width:100%}.overflow-menu .toolbar-wrap[data-v-d0b03fba]{width:100%;justify-content:flex-start}.menu-pop-enter-active[data-v-d0b03fba],.menu-pop-leave-active[data-v-d0b03fba]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-d0b03fba],.menu-pop-leave-to[data-v-d0b03fba]{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-ab2b4b0b]{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-ab2b4b0b]{display:flex;align-items:flex-start;flex:1;overflow:hidden;gap:1px;padding:0 1px}.tab-item[data-v-ab2b4b0b]{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-ab2b4b0b]:hover{background:var(--sp-tab-hover-bg)}.tab-item--active[data-v-ab2b4b0b]{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-ab2b4b0b]:hover{background:var(--sp-tab-active-bg)}.tab-item__name[data-v-ab2b4b0b]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-rename-input[data-v-ab2b4b0b]{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__list-btn[data-v-ab2b4b0b]{display:flex;align-items:center;justify-content:center;width:24px;min-width:24px;height:24px;margin:0 2px 3px 3px;border:none;background:transparent;color:var(--sp-tab-add-btn-color);cursor:pointer;padding:0;align-self:flex-end}.tab-bar__list-btn[data-v-ab2b4b0b]:hover,.tab-bar__list-btn--active[data-v-ab2b4b0b]{background:var(--sp-tab-add-btn-hover-bg)}.tab-bar__list-btn svg[data-v-ab2b4b0b]{width:14px;height:14px}.tab-bar__add-btn[data-v-ab2b4b0b]{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-ab2b4b0b]:hover{background:var(--sp-tab-add-btn-hover-bg)}.tab-list-menu{position:fixed;display:flex;flex-direction:column;background:var(--sp-toolbar-bg, #fff);border:1px solid var(--sp-toolbar-border, #d8d8d8);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px;z-index:1000;transform-origin:bottom left;min-width:140px;max-width:260px;box-sizing:border-box}.tab-list-menu__nav{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}.tab-list-menu__nav:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg, #eef3f9)}.tab-list-menu__nav:disabled{color:#ccc;cursor:default}.tab-list-menu__nav svg{width:10px;height:10px}.tab-list-menu__list{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.tab-list-menu__item{display:flex;align-items:center;width:100%;height:28px;padding:0 10px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;cursor:pointer;text-align:left;white-space:nowrap;border-radius:3px;box-sizing:border-box}.tab-list-menu__item:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.tab-list-menu__item--active{color:var(--sp-tab-active-border, #0078d7);font-weight:500}.tab-list-menu__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.find-bar[data-v-8d54f890]{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-8d54f890]{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-8d54f890]:focus{border-color:var(--sp-toolbar-btn-active-color)}.find-bar__select[data-v-8d54f890]{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-8d54f890]{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-8d54f890]{margin:0}.find-bar__count[data-v-8d54f890]{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-8d54f890]{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-8d54f890]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.find-bar__btn[data-v-8d54f890]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.find-bar__btn--icon[data-v-8d54f890]{width:26px;padding:0}.find-bar__btn--icon svg[data-v-8d54f890]{width:14px;height:14px}.find-bar__btn--close[data-v-8d54f890]{width:26px;padding:0;margin-left:auto}.find-bar__btn--close svg[data-v-8d54f890]{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}
|
|
1
|
+
.sp-dropdown[data-v-0152ad1e]{position:relative;display:inline-flex;min-width:0}.sp-dropdown__trigger[data-v-0152ad1e]{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-0152ad1e]:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.sp-dropdown__trigger--open[data-v-0152ad1e]{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6);border-color:var(--sp-toolbar-border, #d8d8d8)}.sp-dropdown__value[data-v-0152ad1e]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.sp-dropdown__caret[data-v-0152ad1e]{width:10px;height:10px;min-width:10px;opacity:.7}.sp-dropdown__menu[data-v-0152ad1e]{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-0152ad1e]{transform-origin:bottom center}.menu-pop-enter-active[data-v-0152ad1e],.menu-pop-leave-active[data-v-0152ad1e]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-0152ad1e],.menu-pop-leave-to[data-v-0152ad1e]{opacity:0;transform:scaleY(.85)}.sp-dropdown__nav[data-v-0152ad1e]{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-0152ad1e]:hover:not(:disabled){background:#eef3f9}.sp-dropdown__nav[data-v-0152ad1e]:disabled{color:#ccc;cursor:default}.sp-dropdown__nav svg[data-v-0152ad1e]{width:10px;height:10px}.sp-dropdown__list[data-v-0152ad1e]{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.sp-dropdown__icon[data-v-0152ad1e]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__icon[data-v-0152ad1e] svg{width:18px;height:18px;display:block}.sp-dropdown__item-icon[data-v-0152ad1e]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__item-icon[data-v-0152ad1e] svg{width:16px;height:16px;display:block}.sp-dropdown__item-label[data-v-0152ad1e]{white-space:nowrap}.sp-dropdown__item[data-v-0152ad1e]{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-0152ad1e]:hover{background:#eef3f9}.sp-dropdown__item--active[data-v-0152ad1e]{background:#e5f1fb;color:#0078d7}.color-picker[data-v-70f3dfdc]{position:relative;display:inline-flex;height:26px}.color-picker__menu[data-v-70f3dfdc]{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-70f3dfdc],.menu-pop-leave-active[data-v-70f3dfdc]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-70f3dfdc],.menu-pop-leave-to[data-v-70f3dfdc]{opacity:0;transform:scale(.9)}.color-picker__row[data-v-70f3dfdc]{display:flex;gap:4px;margin-bottom:4px}.color-picker__row[data-v-70f3dfdc]:last-child{margin-bottom:0}.color-picker__swatch[data-v-70f3dfdc]{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-70f3dfdc]:hover{transform:scale(1.18);box-shadow:0 0 0 1px #0003;z-index:1}.color-picker__swatch--selected[data-v-70f3dfdc]{box-shadow:0 0 0 2px #0078d7}.border-picker[data-v-551c0ffe]{position:relative;display:inline-flex;height:26px}.border-picker__menu[data-v-551c0ffe]{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-551c0ffe]{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-551c0ffe]:hover{background:#eef3f9}.border-picker__icon[data-v-551c0ffe]{width:18px;height:18px;flex-shrink:0}.border-picker__label[data-v-551c0ffe]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-551c0ffe],.menu-pop-leave-active[data-v-551c0ffe]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-551c0ffe],.menu-pop-leave-to[data-v-551c0ffe]{opacity:0;transform:scale(.9)}.merge-picker[data-v-edd36208]{position:relative;display:inline-flex;height:26px}.merge-picker__menu[data-v-edd36208]{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-edd36208]{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-edd36208]:hover{background:#eef3f9}.merge-picker__icon[data-v-edd36208]{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.merge-picker__icon[data-v-edd36208] svg{width:18px;height:18px}.merge-picker__label[data-v-edd36208]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-edd36208],.menu-pop-leave-active[data-v-edd36208]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-edd36208],.menu-pop-leave-to[data-v-edd36208]{opacity:0;transform:scale(.9)}.calc-picker[data-v-01a18e00]{position:relative;display:inline-flex;height:26px}.calc-picker__menu[data-v-01a18e00]{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-01a18e00]{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-01a18e00]:hover:not(.calc-picker__item--disabled){background:#eef3f9}.calc-picker__item--disabled[data-v-01a18e00]{color:var(--sp-toolbar-btn-disabled-color, #bbb);cursor:default}.calc-picker__label[data-v-01a18e00]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-01a18e00],.menu-pop-leave-active[data-v-01a18e00]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-01a18e00],.menu-pop-leave-to[data-v-01a18e00]{opacity:0;transform:scale(.9)}.toolbar[data-v-94d2ccc1]{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-94d2ccc1]{display:flex;align-items:center;flex:0 0 auto}.toolbar-sep[data-v-94d2ccc1]{width:1px;height:18px;margin:0 4px;background:var(--sp-toolbar-border)}.toolbar-font[data-v-94d2ccc1],.toolbar-number-format[data-v-94d2ccc1],.toolbar-align[data-v-94d2ccc1]{flex:0 0 auto}.toolbar-font-size[data-v-94d2ccc1]{display:inline-flex;align-items:center;gap:0;height:26px;position:relative}.toolbar-font-size__input[data-v-94d2ccc1]{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-94d2ccc1]::-webkit-outer-spin-button,.toolbar-font-size__input[data-v-94d2ccc1]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.toolbar-font-size__input[data-v-94d2ccc1]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__input[data-v-94d2ccc1]:focus{border-color:var(--sp-toolbar-border);background:#fff}.toolbar-font-size__btn[data-v-94d2ccc1]{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-94d2ccc1]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__btn svg[data-v-94d2ccc1]{width:10px;height:10px}.toolbar-font-size__dropdown[data-v-94d2ccc1]{position:absolute;width:56px;height:26px;pointer-events:none}.toolbar-btn[data-v-94d2ccc1]{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-94d2ccc1]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-btn[data-v-94d2ccc1]:active:not(:disabled){opacity:.7}.toolbar-btn--active[data-v-94d2ccc1]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-btn--step[data-v-94d2ccc1]{width:26px;height:26px}.toolbar-btn--step svg[data-v-94d2ccc1]{width:16px;height:16px}.toolbar-btn[data-v-94d2ccc1]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.toolbar-btn__icon[data-v-94d2ccc1]{width:18px;height:18px}.toolbar-btn svg[data-v-94d2ccc1]:not(.toolbar-btn__icon){width:18px;height:18px}.toolbar-split[data-v-94d2ccc1]{display:inline-flex;align-items:center;position:relative;height:26px}.toolbar-split__main[data-v-94d2ccc1]{border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px}.toolbar-split__arrow[data-v-94d2ccc1]{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-94d2ccc1]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-split__arrow svg[data-v-94d2ccc1]{width:10px!important;height:10px!important}.toolbar-more[data-v-94d2ccc1]{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-94d2ccc1]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-more--active[data-v-94d2ccc1]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-more svg[data-v-94d2ccc1]{width:18px;height:18px}.overflow-menu[data-v-94d2ccc1]{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-94d2ccc1]{transition:none!important}.overflow-menu .tb-item[data-v-94d2ccc1]{width:100%}.overflow-menu .toolbar-sep[data-v-94d2ccc1]{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split[data-v-94d2ccc1]{width:100%}.overflow-menu .toolbar-split__main[data-v-94d2ccc1]{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size[data-v-94d2ccc1]{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font[data-v-94d2ccc1],.overflow-menu .toolbar-number-format[data-v-94d2ccc1],.overflow-menu .toolbar-align[data-v-94d2ccc1]{width:100%}.overflow-menu .toolbar-btn[data-v-94d2ccc1]:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color[data-v-94d2ccc1]{width:100%}.overflow-menu .toolbar-wrap[data-v-94d2ccc1]{width:100%;justify-content:flex-start}.menu-pop-enter-active[data-v-94d2ccc1],.menu-pop-leave-active[data-v-94d2ccc1]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-94d2ccc1],.menu-pop-leave-to[data-v-94d2ccc1]{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-ec10bade]{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-ec10bade]{display:flex;align-items:flex-start;flex:1;overflow:hidden;gap:1px;padding:0 1px}.tab-item[data-v-ec10bade]{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-ec10bade]:hover{background:var(--sp-tab-hover-bg)}.tab-item--active[data-v-ec10bade]{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-ec10bade]:hover{background:var(--sp-tab-active-bg)}.tab-item__name[data-v-ec10bade]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-rename-input[data-v-ec10bade]{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__list-btn[data-v-ec10bade]{display:flex;align-items:center;justify-content:center;width:24px;min-width:24px;height:24px;margin:0 2px 3px 3px;border:none;background:transparent;color:var(--sp-tab-add-btn-color);cursor:pointer;padding:0;align-self:flex-end}.tab-bar__list-btn[data-v-ec10bade]:hover,.tab-bar__list-btn--active[data-v-ec10bade]{background:var(--sp-tab-add-btn-hover-bg)}.tab-bar__list-btn svg[data-v-ec10bade]{width:14px;height:14px}.tab-bar__add-btn[data-v-ec10bade]{display:flex;align-items:center;justify-content:center;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;align-self:flex-end}.tab-bar__add-btn[data-v-ec10bade]:hover{background:var(--sp-tab-add-btn-hover-bg)}.tab-list-menu{position:fixed;display:flex;flex-direction:column;background:var(--sp-toolbar-bg, #fff);border:1px solid var(--sp-toolbar-border, #d8d8d8);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px;z-index:1000;transform-origin:bottom left;min-width:140px;max-width:260px;box-sizing:border-box}.tab-list-menu__nav{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}.tab-list-menu__nav:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg, #eef3f9)}.tab-list-menu__nav:disabled{color:#ccc;cursor:default}.tab-list-menu__nav svg{width:10px;height:10px}.tab-list-menu__list{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.tab-list-menu__item{display:flex;align-items:center;gap:4px;width:100%;height:28px;padding:0 6px 0 10px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;cursor:pointer;white-space:nowrap;border-radius:3px;box-sizing:border-box}.tab-list-menu__item:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.tab-list-menu__item--active{color:var(--sp-tab-active-border, #0078d7);font-weight:500}.tab-list-menu__name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-list-menu__del{display:flex;align-items:center;justify-content:center;width:18px;height:18px;flex:0 0 auto;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #999);cursor:pointer;padding:0;border-radius:3px;opacity:.55}.tab-list-menu__item:hover .tab-list-menu__del{opacity:1}.tab-list-menu__del:hover:not(:disabled){background:rgba(0,0,0,.08);color:#d9534f}.tab-list-menu__del:disabled{cursor:default;opacity:.25}.tab-list-menu__del svg{width:12px;height:12px}.find-bar[data-v-8d54f890]{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-8d54f890]{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-8d54f890]:focus{border-color:var(--sp-toolbar-btn-active-color)}.find-bar__select[data-v-8d54f890]{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-8d54f890]{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-8d54f890]{margin:0}.find-bar__count[data-v-8d54f890]{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-8d54f890]{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-8d54f890]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.find-bar__btn[data-v-8d54f890]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.find-bar__btn--icon[data-v-8d54f890]{width:26px;padding:0}.find-bar__btn--icon svg[data-v-8d54f890]{width:14px;height:14px}.find-bar__btn--close[data-v-8d54f890]{width:26px;padding:0;margin-left:auto}.find-bar__btn--close svg[data-v-8d54f890]{width:14px;height:14px}.nf-dialog__mask[data-v-75101bf8]{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-75101bf8]{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-75101bf8]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #ececec}.nf-dialog__title[data-v-75101bf8]{font-size:13px;font-weight:600}.nf-dialog__close[data-v-75101bf8]{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-75101bf8]:hover{background:#f0f0f0;color:#444}.nf-dialog__close svg[data-v-75101bf8]{width:14px;height:14px}.nf-dialog__body[data-v-75101bf8]{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.nf-field[data-v-75101bf8]{display:flex;align-items:center;gap:8px}.nf-field--inline[data-v-75101bf8]{min-height:26px}.nf-field__label[data-v-75101bf8]{width:88px;min-width:88px;font-size:12px;color:#555}.nf-field__select[data-v-75101bf8],.nf-field__input[data-v-75101bf8]{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-75101bf8]:focus,.nf-field__input[data-v-75101bf8]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-field__textarea[data-v-75101bf8]{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-75101bf8]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-checkbox[data-v-75101bf8]{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:#333;cursor:pointer}.nf-checkbox input[data-v-75101bf8]{margin:0;cursor:pointer}.nf-dialog__footer[data-v-75101bf8]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 14px;border-top:1px solid #ececec}.nf-preview[data-v-75101bf8]{display:flex;flex-direction:column;gap:2px;min-width:0}.nf-preview__label[data-v-75101bf8]{font-size:11px;color:#888}.nf-preview__value[data-v-75101bf8]{font-size:13px;color:#1a1a1a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.nf-dialog__actions[data-v-75101bf8]{display:flex;gap:8px}.nf-btn[data-v-75101bf8]{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-75101bf8]:hover{background:#f0f0f0}.nf-btn--primary[data-v-75101bf8]{border-color:#0078d7;background:#0078d7;color:#fff}.nf-btn--primary[data-v-75101bf8]:hover{background:#0069c0}.nf-dialog-enter-active[data-v-75101bf8],.nf-dialog-leave-active[data-v-75101bf8]{transition:opacity .14s ease-out}.nf-dialog-enter-from[data-v-75101bf8],.nf-dialog-leave-to[data-v-75101bf8]{opacity:0}.nf-dialog-enter-active .nf-dialog[data-v-75101bf8],.nf-dialog-leave-active .nf-dialog[data-v-75101bf8]{transition:transform .14s ease-out}.nf-dialog-enter-from .nf-dialog[data-v-75101bf8],.nf-dialog-leave-to .nf-dialog[data-v-75101bf8]{transform:scale(.96)}.spreadsheet-outer[data-v-e9e7c7f1]{flex:1;display:flex;flex-direction:column;overflow:hidden;height:100%;min-height:400px;width:100%}.formula-bar[data-v-e9e7c7f1]{display:flex;align-items:flex-start;min-height:36px;padding:0;gap:0}.formula-bar--expanded[data-v-e9e7c7f1]{min-height:72px}.formula-bar__cell-label[data-v-e9e7c7f1]{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-e9e7c7f1]{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-e9e7c7f1]{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-e9e7c7f1]{border-left:1px solid var(--sp-formula-bar-input-border)}.formula-bar__btn[data-v-e9e7c7f1]:hover{background:var(--sp-scroll-btn-hover-bg, #f0f0f0)}.formula-bar__btn--cancel[data-v-e9e7c7f1]:hover{color:#e53935;background:#fdecea}.formula-bar__btn--accept[data-v-e9e7c7f1]:hover{color:#2e7d32;background:#e8f5e9}.formula-bar__input[data-v-e9e7c7f1]{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-e9e7c7f1]{height:68px;overflow:auto}.formula-bar__input[data-v-e9e7c7f1]: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-e9e7c7f1]{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-e9e7c7f1]:hover{background:var(--sp-scroll-btn-hover-bg, #e8e8e8)}.spreadsheet-wrapper[data-v-e9e7c7f1]{flex:1;position:relative;overflow:hidden;background:var(--sp-wrapper-bg)}.grid-canvas[data-v-e9e7c7f1]{position:absolute;top:0;left:0;display:block;outline:none;cursor:cell}.grid-canvas[data-v-e9e7c7f1]:focus{outline:none}.v-scrollbar[data-v-e9e7c7f1]{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-e9e7c7f1]{position:absolute;left:0;bottom:0;height:11px;width:calc(100% - 11px);display:flex;background:var(--sp-wrapper-bg)}.sb-corner[data-v-e9e7c7f1]{position:absolute;right:0;bottom:0;width:11px;height:11px;background:var(--sp-wrapper-bg)}.sb-btn[data-v-e9e7c7f1]{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-e9e7c7f1]:hover{background:var(--sp-scroll-btn-hover-bg, #d0d0d0)}.sb-btn[data-v-e9e7c7f1]:active{background:var(--sp-scroll-btn-active-bg, #c0c0c0)}.sb-arrow[data-v-e9e7c7f1]{display:block;width:0;height:0}.sb-arrow--up[data-v-e9e7c7f1]{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-e9e7c7f1]{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-e9e7c7f1]{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-e9e7c7f1]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid var(--sp-scroll-btn-color, #666)}.sb-track[data-v-e9e7c7f1]{flex:1;position:relative;background:var(--sp-scroll-track-bg, rgba(0,0,0,.06))}.sb-track--v[data-v-e9e7c7f1]{width:11px}.sb-track--h[data-v-e9e7c7f1]{height:11px}.sb-thumb[data-v-e9e7c7f1]{position:absolute;border-radius:3px;background:var(--sp-scroll-thumb);cursor:default}.sb-thumb[data-v-e9e7c7f1]:hover{background:var(--sp-scroll-thumb-hover)}.sb-thumb--v[data-v-e9e7c7f1]{left:1px;right:1px;min-height:16px}.sb-thumb--h[data-v-e9e7c7f1]{top:1px;bottom:1px;min-width:16px}.cell-editor[data-v-e9e7c7f1]{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}
|
|
@@ -3,6 +3,8 @@ type __VLS_Props = {
|
|
|
3
3
|
locale?: string;
|
|
4
4
|
/** 当前选区格式(混合时由父组件传入空串,从常规开始) */
|
|
5
5
|
currentFormat?: string;
|
|
6
|
+
/** 选区数字格式带自定义分类标记(常规单元格经小数位按钮生成):打开时分类直接显示为「自定义」 */
|
|
7
|
+
isCustom?: boolean;
|
|
6
8
|
/** 预览样例值(默认 1234.5) */
|
|
7
9
|
sampleValue?: string;
|
|
8
10
|
};
|
|
@@ -16,6 +18,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
16
18
|
modelOpen: boolean;
|
|
17
19
|
locale: string;
|
|
18
20
|
currentFormat: string;
|
|
21
|
+
isCustom: boolean;
|
|
19
22
|
sampleValue: string;
|
|
20
23
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {
|
|
21
24
|
customCodeRef: HTMLTextAreaElement;
|
|
@@ -9,6 +9,7 @@ type __VLS_Props = {
|
|
|
9
9
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
10
|
"tab-click": (i: number) => void;
|
|
11
11
|
"tab-dblclick": (i: number) => void;
|
|
12
|
+
"delete-sheet": (i: number) => void;
|
|
12
13
|
"tab-contextmenu": (payload: {
|
|
13
14
|
ev: MouseEvent;
|
|
14
15
|
i: number;
|
|
@@ -21,6 +22,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
21
22
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
22
23
|
"onTab-click"?: ((i: number) => any) | undefined;
|
|
23
24
|
"onTab-dblclick"?: ((i: number) => any) | undefined;
|
|
25
|
+
"onDelete-sheet"?: ((i: number) => any) | undefined;
|
|
24
26
|
"onTab-contextmenu"?: ((payload: {
|
|
25
27
|
ev: MouseEvent;
|
|
26
28
|
i: number;
|
|
@@ -36,6 +36,8 @@ type __VLS_Props = {
|
|
|
36
36
|
themeVars?: Record<string, string>;
|
|
37
37
|
selNumberFormat: string;
|
|
38
38
|
nfOptions: NFOption[];
|
|
39
|
+
canIncreaseDecimals: boolean;
|
|
40
|
+
canDecreaseDecimals: boolean;
|
|
39
41
|
};
|
|
40
42
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
41
43
|
undo: () => void;
|
|
@@ -59,6 +61,8 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
59
61
|
"calc-sum": () => void;
|
|
60
62
|
"calc-avg": () => void;
|
|
61
63
|
"calc-count": () => void;
|
|
64
|
+
"increase-decimals": () => void;
|
|
65
|
+
"decrease-decimals": () => void;
|
|
62
66
|
"font-family-change": (v: string | number) => void;
|
|
63
67
|
"font-size-change": (v: string | number) => void;
|
|
64
68
|
"h-align-change": (v: string | number) => void;
|
|
@@ -98,6 +102,8 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
98
102
|
"onCalc-sum"?: (() => any) | undefined;
|
|
99
103
|
"onCalc-avg"?: (() => any) | undefined;
|
|
100
104
|
"onCalc-count"?: (() => any) | undefined;
|
|
105
|
+
"onIncrease-decimals"?: (() => any) | undefined;
|
|
106
|
+
"onDecrease-decimals"?: (() => any) | undefined;
|
|
101
107
|
"onFont-family-change"?: ((v: string | number) => any) | undefined;
|
|
102
108
|
"onFont-size-change"?: ((v: string | number) => any) | undefined;
|
|
103
109
|
"onH-align-change"?: ((v: string | number) => any) | undefined;
|
|
@@ -3,26 +3,14 @@ import type { CoreState } from './core-state';
|
|
|
3
3
|
import type { UndoStylesState } from './undo-styles';
|
|
4
4
|
import type { BorderType } from '../components/pickers/borderPicker.vue';
|
|
5
5
|
import type { MergeType } from '../core/constants';
|
|
6
|
-
import type { SelectionRange } from '../core/types';
|
|
6
|
+
import type { SelectionRange, BorderStyle, BorderSide } from '../core/types';
|
|
7
7
|
export interface BordersMergeState {
|
|
8
8
|
cachedBorder: Ref<BorderType>;
|
|
9
9
|
borderMenuOpen: Ref<boolean>;
|
|
10
10
|
BORDER_COLOR: string;
|
|
11
|
-
borderTypeToWidths: (bt: BorderType, col: number, row: number, sel: SelectionRange) => {
|
|
12
|
-
top: number;
|
|
13
|
-
bottom: number;
|
|
14
|
-
left: number;
|
|
15
|
-
right: number;
|
|
16
|
-
};
|
|
17
11
|
onBorderChange: (bt: BorderType) => void;
|
|
18
|
-
setCellBorderSide: (col: number, row: number, side: '
|
|
19
|
-
|
|
20
|
-
applyBorderToCell: (col: number, row: number, w: {
|
|
21
|
-
top: number;
|
|
22
|
-
bottom: number;
|
|
23
|
-
left: number;
|
|
24
|
-
right: number;
|
|
25
|
-
}, clearZero?: boolean) => void;
|
|
12
|
+
setCellBorderSide: (col: number, row: number, side: 'top' | 'right' | 'bottom' | 'left', borderSide: BorderSide | undefined) => void;
|
|
13
|
+
applyBorderToCell: (col: number, row: number, border: BorderStyle) => void;
|
|
26
14
|
applyCachedBorder: () => void;
|
|
27
15
|
cellBorderWidth: (col: number, row: number, side: 'Top' | 'Bottom' | 'Left' | 'Right') => number;
|
|
28
16
|
mergeMenuOpen: Ref<boolean>;
|
|
@@ -35,9 +23,9 @@ export interface BordersMergeState {
|
|
|
35
23
|
onApplyMerge: () => void;
|
|
36
24
|
onMergeChange: (v: MergeType) => void;
|
|
37
25
|
copySourceRange: SelectionRange | null;
|
|
38
|
-
copySourceStyles:
|
|
26
|
+
copySourceStyles: number[][];
|
|
39
27
|
captureStyles: (cS: number, cE: number, rS: number, rE: number) => void;
|
|
40
|
-
setCellWithStyle: (c: number, r: number, val: string,
|
|
28
|
+
setCellWithStyle: (c: number, r: number, val: string, styleId: number | null) => void;
|
|
41
29
|
copyToClipboard: () => void;
|
|
42
30
|
copyRowCol: () => void;
|
|
43
31
|
pasteFromClipboard: () => Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ComputedRef, type Ref } from 'vue';
|
|
2
2
|
import { FormulaDeps } from '../core/formula';
|
|
3
|
-
import type { CellCoord, CellData, SelectionRange } from '../core/types';
|
|
3
|
+
import type { CellCoord, CellData, CellStyle, SelectionRange, BorderStyle, BorderSide } from '../core/types';
|
|
4
4
|
/** 选区触发方式,影响「合并单元格是否扩大选区」。
|
|
5
5
|
* - 'cell':单元格点击/拖动(默认)→ 保持现有 expandSelectionForMerges 行为
|
|
6
6
|
* - 'row' :行头点击/拖动 → Excel 风格「穿透」合并,选区矩形保持用户点击的行范围
|
|
@@ -21,6 +21,10 @@ export interface CoreState {
|
|
|
21
21
|
colCount: number;
|
|
22
22
|
rowCount: number;
|
|
23
23
|
cells: Record<string, CellData>;
|
|
24
|
+
/** 表格级样式池(reactive 数组),styles[0] 始终为默认空样式 */
|
|
25
|
+
styles: CellStyle[];
|
|
26
|
+
/** 表格级边框池(reactive 数组),borders[0] 始终为默认空边框 */
|
|
27
|
+
borders: BorderStyle[];
|
|
24
28
|
merges: Record<string, SelectionRange>;
|
|
25
29
|
formulaDeps: FormulaDeps;
|
|
26
30
|
selection: Ref<SelectionRange | null>;
|
|
@@ -83,10 +87,31 @@ export interface CoreState {
|
|
|
83
87
|
ensureVisible: (c: number, r: number) => void;
|
|
84
88
|
hitCol: (x: number) => number;
|
|
85
89
|
hitRow: (y: number) => number;
|
|
90
|
+
/** 注册样式到池中,返回 styleId(去重) */
|
|
91
|
+
registerStyle: (style: CellStyle) => number;
|
|
92
|
+
/** 解析单元格样式(通过 styleId 查 styles 数组) */
|
|
93
|
+
resolveStyle: (cell: CellData | undefined) => CellStyle | null;
|
|
94
|
+
/** 重建 styleIndex(从当前 styles 数组) */
|
|
95
|
+
rebuildStyleIndex: () => void;
|
|
96
|
+
/** 同步 styles 数组内容(用于 sheet 切换/加载) */
|
|
97
|
+
syncStyles: (newStyles: CellStyle[]) => void;
|
|
98
|
+
/** 注册边框到池中,返回 borderId(去重) */
|
|
99
|
+
registerBorder: (border: BorderStyle) => number;
|
|
100
|
+
/** 解析边框(通过 borderId 查 borders 数组) */
|
|
101
|
+
resolveBorder: (borderId: number) => BorderStyle;
|
|
102
|
+
/** 重建 borderIndex(从当前 borders 数组) */
|
|
103
|
+
rebuildBorderIndex: () => void;
|
|
104
|
+
/** 同步 borders 数组内容(用于 sheet 切换/加载) */
|
|
105
|
+
syncBorders: (newBorders: BorderStyle[]) => void;
|
|
106
|
+
/** 获取单元格的某一侧 BorderSide */
|
|
107
|
+
getCellBorderSide: (cell: CellData | undefined, side: 'top' | 'right' | 'bottom' | 'left') => BorderSide | undefined;
|
|
108
|
+
/** 获取某 grid cell 所属 merge 的 owner key(左上角),不属于 merge 返回 null */
|
|
109
|
+
getMergeOwner: (c: number, r: number) => string | null;
|
|
110
|
+
/** 判断两个 grid cell 是否属于同一 merge 内部 */
|
|
111
|
+
isSameMergeInternal: (c1: number, r1: number, c2: number, r2: number) => boolean;
|
|
86
112
|
saveUndo?: () => void;
|
|
87
113
|
scheduleRender?: () => void;
|
|
88
114
|
emitModelData?: () => void;
|
|
89
|
-
syncCellBorders?: (col: number, row: number) => void;
|
|
90
115
|
viewSize?: {
|
|
91
116
|
w: number;
|
|
92
117
|
h: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ComputedRef, type Ref } from 'vue';
|
|
2
2
|
import type { FontOption } from '../core/constants';
|
|
3
3
|
import type { CoreState } from './core-state';
|
|
4
|
-
import type { CellData, SheetState } from '../core/types';
|
|
4
|
+
import type { CellData, CellStyle, SheetState } from '../core/types';
|
|
5
5
|
import { type NFOption } from '../core/number-format';
|
|
6
6
|
export interface UndoStylesState {
|
|
7
7
|
undoStack: Ref<UndoSnap[]>;
|
|
@@ -16,7 +16,7 @@ export interface UndoStylesState {
|
|
|
16
16
|
canRedo: ComputedRef<boolean>;
|
|
17
17
|
hasSelection: ComputedRef<boolean>;
|
|
18
18
|
paintFmt: Ref<{
|
|
19
|
-
styles: Record<string,
|
|
19
|
+
styles: Record<string, number>;
|
|
20
20
|
} | null>;
|
|
21
21
|
onPaintFormat: () => void;
|
|
22
22
|
applyPaintFormat: () => void;
|
|
@@ -70,14 +70,21 @@ export interface UndoStylesState {
|
|
|
70
70
|
mergeMenuOpen?: Ref<boolean>;
|
|
71
71
|
nfOptions: ComputedRef<NFOption[]>;
|
|
72
72
|
selNumberFormat: ComputedRef<string>;
|
|
73
|
+
/** 仅供工具栏下拉回显:非预设代码归类到对应预设,避免回显为空 */
|
|
74
|
+
selNumberFormatDisplay: ComputedRef<string>;
|
|
73
75
|
NF_NUMBER_FORMAT_MIXED: string;
|
|
74
76
|
nfDialogOpen: Ref<boolean>;
|
|
75
77
|
onNumberFormatChange: (v: string) => void;
|
|
76
78
|
openNumberFormatDialog: () => void;
|
|
77
79
|
applyNumberFormatCode: (code: string) => void;
|
|
80
|
+
canIncreaseDecimals: ComputedRef<boolean>;
|
|
81
|
+
canDecreaseDecimals: ComputedRef<boolean>;
|
|
82
|
+
onIncreaseDecimals: () => void;
|
|
83
|
+
onDecreaseDecimals: () => void;
|
|
78
84
|
}
|
|
79
85
|
interface UndoSnap {
|
|
80
86
|
sheets: SheetState[];
|
|
87
|
+
styles: CellStyle[];
|
|
81
88
|
activeSheetIndex: number;
|
|
82
89
|
}
|
|
83
90
|
export declare function createUndoStyles(s: CoreState, sheetsCtx: {
|