@nuptechs/nup-xlsx-preview 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -0
- package/dist/adapters/react.cjs +10 -0
- package/dist/adapters/react.cjs.map +1 -0
- package/dist/adapters/react.d.cts +307 -0
- package/dist/adapters/react.d.ts +307 -0
- package/dist/adapters/react.js +10 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/vanilla.cjs +55 -0
- package/dist/adapters/vanilla.cjs.map +1 -0
- package/dist/adapters/vanilla.d.cts +168 -0
- package/dist/adapters/vanilla.d.ts +168 -0
- package/dist/adapters/vanilla.js +55 -0
- package/dist/adapters/vanilla.js.map +1 -0
- package/dist/adapters/vue.cjs +10 -0
- package/dist/adapters/vue.cjs.map +1 -0
- package/dist/adapters/vue.d.cts +369 -0
- package/dist/adapters/vue.d.ts +369 -0
- package/dist/adapters/vue.js +10 -0
- package/dist/adapters/vue.js.map +1 -0
- package/dist/index.cjs +55 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +790 -0
- package/dist/index.d.ts +790 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/base.css +346 -0
- package/dist/styles/index.css +730 -0
- package/dist/styles/print.css +182 -0
- package/dist/styles/themes.css +202 -0
- package/package.json +131 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { PropType } from 'vue';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @aspect/nup-xlsx-preview - Types
|
|
6
|
+
* Ultra-light Excel visualization component
|
|
7
|
+
*/
|
|
8
|
+
interface NupCell {
|
|
9
|
+
v?: string | number | boolean | null;
|
|
10
|
+
f?: string;
|
|
11
|
+
s?: number | string;
|
|
12
|
+
t?: 's' | 'n' | 'b' | 'e' | 'd';
|
|
13
|
+
}
|
|
14
|
+
interface NupRow {
|
|
15
|
+
h?: number;
|
|
16
|
+
hidden?: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface NupCol {
|
|
19
|
+
w?: number;
|
|
20
|
+
hidden?: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface NupWorksheet {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
cells: Record<string, NupCell>;
|
|
26
|
+
rows: Record<number, NupRow>;
|
|
27
|
+
cols: Record<number, NupCol>;
|
|
28
|
+
merges?: string[];
|
|
29
|
+
rowCount: number;
|
|
30
|
+
colCount: number;
|
|
31
|
+
}
|
|
32
|
+
interface NupThemeConfig {
|
|
33
|
+
name: string;
|
|
34
|
+
colors: {
|
|
35
|
+
background: string;
|
|
36
|
+
foreground: string;
|
|
37
|
+
grid: string;
|
|
38
|
+
headerBackground: string;
|
|
39
|
+
headerForeground: string;
|
|
40
|
+
selectionBorder: string;
|
|
41
|
+
selectionBackground: string;
|
|
42
|
+
frozenBorder: string;
|
|
43
|
+
};
|
|
44
|
+
fonts: {
|
|
45
|
+
family: string;
|
|
46
|
+
size: string;
|
|
47
|
+
headerSize: string;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
interface NupWorkbook {
|
|
51
|
+
sheets: NupWorksheet[];
|
|
52
|
+
activeSheet: number;
|
|
53
|
+
styles?: Record<string, unknown>;
|
|
54
|
+
theme?: NupThemeConfig;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Theme Definitions (JS version)
|
|
59
|
+
* For programmatic theme access
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
declare const themes: {
|
|
63
|
+
readonly default: {
|
|
64
|
+
readonly name: "default";
|
|
65
|
+
readonly colors: {
|
|
66
|
+
readonly background: "#ffffff";
|
|
67
|
+
readonly foreground: "#202124";
|
|
68
|
+
readonly grid: "#e0e0e0";
|
|
69
|
+
readonly headerBackground: "#f8f9fa";
|
|
70
|
+
readonly headerForeground: "#5f6368";
|
|
71
|
+
readonly selectionBorder: "#1a73e8";
|
|
72
|
+
readonly selectionBackground: "rgba(26, 115, 232, 0.08)";
|
|
73
|
+
readonly frozenBorder: "#dadce0";
|
|
74
|
+
};
|
|
75
|
+
readonly fonts: {
|
|
76
|
+
readonly family: "'Google Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
77
|
+
readonly size: "13px";
|
|
78
|
+
readonly headerSize: "11px";
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
readonly excel: {
|
|
82
|
+
readonly name: "excel";
|
|
83
|
+
readonly colors: {
|
|
84
|
+
readonly background: "#ffffff";
|
|
85
|
+
readonly foreground: "#000000";
|
|
86
|
+
readonly grid: "#d4d4d4";
|
|
87
|
+
readonly headerBackground: "#f0f0f0";
|
|
88
|
+
readonly headerForeground: "#000000";
|
|
89
|
+
readonly selectionBorder: "#217346";
|
|
90
|
+
readonly selectionBackground: "rgba(33, 115, 70, 0.1)";
|
|
91
|
+
readonly frozenBorder: "#9bc2e6";
|
|
92
|
+
};
|
|
93
|
+
readonly fonts: {
|
|
94
|
+
readonly family: "'Calibri', 'Segoe UI', sans-serif";
|
|
95
|
+
readonly size: "11px";
|
|
96
|
+
readonly headerSize: "11px";
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
readonly modern: {
|
|
100
|
+
readonly name: "modern";
|
|
101
|
+
readonly colors: {
|
|
102
|
+
readonly background: "#fafafa";
|
|
103
|
+
readonly foreground: "#18181b";
|
|
104
|
+
readonly grid: "#e4e4e7";
|
|
105
|
+
readonly headerBackground: "#f4f4f5";
|
|
106
|
+
readonly headerForeground: "#71717a";
|
|
107
|
+
readonly selectionBorder: "#3b82f6";
|
|
108
|
+
readonly selectionBackground: "rgba(59, 130, 246, 0.08)";
|
|
109
|
+
readonly frozenBorder: "#a1a1aa";
|
|
110
|
+
};
|
|
111
|
+
readonly fonts: {
|
|
112
|
+
readonly family: "'Inter', -apple-system, BlinkMacSystemFont, sans-serif";
|
|
113
|
+
readonly size: "13px";
|
|
114
|
+
readonly headerSize: "11px";
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
readonly minimal: {
|
|
118
|
+
readonly name: "minimal";
|
|
119
|
+
readonly colors: {
|
|
120
|
+
readonly background: "#ffffff";
|
|
121
|
+
readonly foreground: "#27272a";
|
|
122
|
+
readonly grid: "#f4f4f5";
|
|
123
|
+
readonly headerBackground: "#ffffff";
|
|
124
|
+
readonly headerForeground: "#a1a1aa";
|
|
125
|
+
readonly selectionBorder: "#18181b";
|
|
126
|
+
readonly selectionBackground: "rgba(24, 24, 27, 0.04)";
|
|
127
|
+
readonly frozenBorder: "#e4e4e7";
|
|
128
|
+
};
|
|
129
|
+
readonly fonts: {
|
|
130
|
+
readonly family: "'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif";
|
|
131
|
+
readonly size: "13px";
|
|
132
|
+
readonly headerSize: "11px";
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
readonly dark: {
|
|
136
|
+
readonly name: "dark";
|
|
137
|
+
readonly colors: {
|
|
138
|
+
readonly background: "#1e1e1e";
|
|
139
|
+
readonly foreground: "#d4d4d4";
|
|
140
|
+
readonly grid: "#3c3c3c";
|
|
141
|
+
readonly headerBackground: "#252526";
|
|
142
|
+
readonly headerForeground: "#858585";
|
|
143
|
+
readonly selectionBorder: "#0078d4";
|
|
144
|
+
readonly selectionBackground: "rgba(0, 120, 212, 0.2)";
|
|
145
|
+
readonly frozenBorder: "#4a4a4a";
|
|
146
|
+
};
|
|
147
|
+
readonly fonts: {
|
|
148
|
+
readonly family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
149
|
+
readonly size: "13px";
|
|
150
|
+
readonly headerSize: "11px";
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
readonly midnight: {
|
|
154
|
+
readonly name: "midnight";
|
|
155
|
+
readonly colors: {
|
|
156
|
+
readonly background: "#0d1117";
|
|
157
|
+
readonly foreground: "#c9d1d9";
|
|
158
|
+
readonly grid: "#21262d";
|
|
159
|
+
readonly headerBackground: "#161b22";
|
|
160
|
+
readonly headerForeground: "#8b949e";
|
|
161
|
+
readonly selectionBorder: "#58a6ff";
|
|
162
|
+
readonly selectionBackground: "rgba(88, 166, 255, 0.15)";
|
|
163
|
+
readonly frozenBorder: "#30363d";
|
|
164
|
+
};
|
|
165
|
+
readonly fonts: {
|
|
166
|
+
readonly family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
167
|
+
readonly size: "13px";
|
|
168
|
+
readonly headerSize: "11px";
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
readonly accessible: {
|
|
172
|
+
readonly name: "accessible";
|
|
173
|
+
readonly colors: {
|
|
174
|
+
readonly background: "#ffffff";
|
|
175
|
+
readonly foreground: "#000000";
|
|
176
|
+
readonly grid: "#000000";
|
|
177
|
+
readonly headerBackground: "#e6e6e6";
|
|
178
|
+
readonly headerForeground: "#000000";
|
|
179
|
+
readonly selectionBorder: "#0000ff";
|
|
180
|
+
readonly selectionBackground: "rgba(0, 0, 255, 0.15)";
|
|
181
|
+
readonly frozenBorder: "#000000";
|
|
182
|
+
};
|
|
183
|
+
readonly fonts: {
|
|
184
|
+
readonly family: "Arial, Helvetica, sans-serif";
|
|
185
|
+
readonly size: "14px";
|
|
186
|
+
readonly headerSize: "12px";
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
type ThemeName = keyof typeof themes;
|
|
191
|
+
|
|
192
|
+
declare const NupSpreadsheetPreview: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
193
|
+
workbook: {
|
|
194
|
+
type: PropType<NupWorkbook>;
|
|
195
|
+
required: true;
|
|
196
|
+
};
|
|
197
|
+
activeSheet: {
|
|
198
|
+
type: NumberConstructor;
|
|
199
|
+
default: number;
|
|
200
|
+
};
|
|
201
|
+
theme: {
|
|
202
|
+
type: PropType<NupThemeConfig | ThemeName>;
|
|
203
|
+
default: string;
|
|
204
|
+
};
|
|
205
|
+
width: {
|
|
206
|
+
type: (NumberConstructor | StringConstructor)[];
|
|
207
|
+
default: string;
|
|
208
|
+
};
|
|
209
|
+
height: {
|
|
210
|
+
type: (NumberConstructor | StringConstructor)[];
|
|
211
|
+
default: string;
|
|
212
|
+
};
|
|
213
|
+
showHeaders: {
|
|
214
|
+
type: BooleanConstructor;
|
|
215
|
+
default: boolean;
|
|
216
|
+
};
|
|
217
|
+
showGridLines: {
|
|
218
|
+
type: BooleanConstructor;
|
|
219
|
+
default: boolean;
|
|
220
|
+
};
|
|
221
|
+
showSheetTabs: {
|
|
222
|
+
type: BooleanConstructor;
|
|
223
|
+
default: boolean;
|
|
224
|
+
};
|
|
225
|
+
selectable: {
|
|
226
|
+
type: BooleanConstructor;
|
|
227
|
+
default: boolean;
|
|
228
|
+
};
|
|
229
|
+
resizable: {
|
|
230
|
+
type: BooleanConstructor;
|
|
231
|
+
default: boolean;
|
|
232
|
+
};
|
|
233
|
+
searchable: {
|
|
234
|
+
type: BooleanConstructor;
|
|
235
|
+
default: boolean;
|
|
236
|
+
};
|
|
237
|
+
copyable: {
|
|
238
|
+
type: BooleanConstructor;
|
|
239
|
+
default: boolean;
|
|
240
|
+
};
|
|
241
|
+
keyboardNavigation: {
|
|
242
|
+
type: BooleanConstructor;
|
|
243
|
+
default: boolean;
|
|
244
|
+
};
|
|
245
|
+
frozenRows: {
|
|
246
|
+
type: NumberConstructor;
|
|
247
|
+
default: number;
|
|
248
|
+
};
|
|
249
|
+
frozenCols: {
|
|
250
|
+
type: NumberConstructor;
|
|
251
|
+
default: number;
|
|
252
|
+
};
|
|
253
|
+
overscan: {
|
|
254
|
+
type: NumberConstructor;
|
|
255
|
+
default: number;
|
|
256
|
+
};
|
|
257
|
+
defaultRowHeight: {
|
|
258
|
+
type: NumberConstructor;
|
|
259
|
+
default: number;
|
|
260
|
+
};
|
|
261
|
+
defaultColWidth: {
|
|
262
|
+
type: NumberConstructor;
|
|
263
|
+
default: number;
|
|
264
|
+
};
|
|
265
|
+
ariaLabel: {
|
|
266
|
+
type: StringConstructor;
|
|
267
|
+
default: string;
|
|
268
|
+
};
|
|
269
|
+
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
270
|
+
[key: string]: any;
|
|
271
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, "cellClick" | "cellDoubleClick" | "cellRightClick" | "selectionChange" | "sheetChange" | "columnResize" | "scroll" | "search" | "copy", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
272
|
+
workbook: {
|
|
273
|
+
type: PropType<NupWorkbook>;
|
|
274
|
+
required: true;
|
|
275
|
+
};
|
|
276
|
+
activeSheet: {
|
|
277
|
+
type: NumberConstructor;
|
|
278
|
+
default: number;
|
|
279
|
+
};
|
|
280
|
+
theme: {
|
|
281
|
+
type: PropType<NupThemeConfig | ThemeName>;
|
|
282
|
+
default: string;
|
|
283
|
+
};
|
|
284
|
+
width: {
|
|
285
|
+
type: (NumberConstructor | StringConstructor)[];
|
|
286
|
+
default: string;
|
|
287
|
+
};
|
|
288
|
+
height: {
|
|
289
|
+
type: (NumberConstructor | StringConstructor)[];
|
|
290
|
+
default: string;
|
|
291
|
+
};
|
|
292
|
+
showHeaders: {
|
|
293
|
+
type: BooleanConstructor;
|
|
294
|
+
default: boolean;
|
|
295
|
+
};
|
|
296
|
+
showGridLines: {
|
|
297
|
+
type: BooleanConstructor;
|
|
298
|
+
default: boolean;
|
|
299
|
+
};
|
|
300
|
+
showSheetTabs: {
|
|
301
|
+
type: BooleanConstructor;
|
|
302
|
+
default: boolean;
|
|
303
|
+
};
|
|
304
|
+
selectable: {
|
|
305
|
+
type: BooleanConstructor;
|
|
306
|
+
default: boolean;
|
|
307
|
+
};
|
|
308
|
+
resizable: {
|
|
309
|
+
type: BooleanConstructor;
|
|
310
|
+
default: boolean;
|
|
311
|
+
};
|
|
312
|
+
searchable: {
|
|
313
|
+
type: BooleanConstructor;
|
|
314
|
+
default: boolean;
|
|
315
|
+
};
|
|
316
|
+
copyable: {
|
|
317
|
+
type: BooleanConstructor;
|
|
318
|
+
default: boolean;
|
|
319
|
+
};
|
|
320
|
+
keyboardNavigation: {
|
|
321
|
+
type: BooleanConstructor;
|
|
322
|
+
default: boolean;
|
|
323
|
+
};
|
|
324
|
+
frozenRows: {
|
|
325
|
+
type: NumberConstructor;
|
|
326
|
+
default: number;
|
|
327
|
+
};
|
|
328
|
+
frozenCols: {
|
|
329
|
+
type: NumberConstructor;
|
|
330
|
+
default: number;
|
|
331
|
+
};
|
|
332
|
+
overscan: {
|
|
333
|
+
type: NumberConstructor;
|
|
334
|
+
default: number;
|
|
335
|
+
};
|
|
336
|
+
defaultRowHeight: {
|
|
337
|
+
type: NumberConstructor;
|
|
338
|
+
default: number;
|
|
339
|
+
};
|
|
340
|
+
defaultColWidth: {
|
|
341
|
+
type: NumberConstructor;
|
|
342
|
+
default: number;
|
|
343
|
+
};
|
|
344
|
+
ariaLabel: {
|
|
345
|
+
type: StringConstructor;
|
|
346
|
+
default: string;
|
|
347
|
+
};
|
|
348
|
+
}>> & Readonly<{}>, {
|
|
349
|
+
activeSheet: number;
|
|
350
|
+
theme: NupThemeConfig | "default" | "excel" | "modern" | "minimal" | "dark" | "midnight" | "accessible";
|
|
351
|
+
width: string | number;
|
|
352
|
+
height: string | number;
|
|
353
|
+
showHeaders: boolean;
|
|
354
|
+
showGridLines: boolean;
|
|
355
|
+
showSheetTabs: boolean;
|
|
356
|
+
selectable: boolean;
|
|
357
|
+
resizable: boolean;
|
|
358
|
+
searchable: boolean;
|
|
359
|
+
copyable: boolean;
|
|
360
|
+
keyboardNavigation: boolean;
|
|
361
|
+
frozenRows: number;
|
|
362
|
+
frozenCols: number;
|
|
363
|
+
overscan: number;
|
|
364
|
+
defaultRowHeight: number;
|
|
365
|
+
defaultColWidth: number;
|
|
366
|
+
ariaLabel: string;
|
|
367
|
+
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
368
|
+
|
|
369
|
+
export { NupSpreadsheetPreview, NupSpreadsheetPreview as default };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {defineComponent,ref,computed,onMounted,onUnmounted,watch,h}from'vue';var P=class{rowPositions;colPositions;rowHeightCache;colWidthCache;totalHeight;totalWidth;overscan;rowCount;colCount;frozenRows;frozenCols;frozenRowsHeight;frozenColsWidth;constructor(e){let{rows:t,cols:o,rowHeights:n,colWidths:r,defaultRowHeight:s=24,defaultColWidth:a=100,overscan:u=5,frozenRows:c=0,frozenCols:g=0}=e;this.frozenRows=c,this.frozenCols=g,this.rowCount=t,this.colCount=o,this.overscan=u,this.rowPositions=new Array(t+1),this.rowHeightCache=new Array(t),this.rowPositions[0]=0;for(let h=0;h<t;h++){let f=n[h]??s;this.rowHeightCache[h]=f,this.rowPositions[h+1]=this.rowPositions[h]+f;}this.totalHeight=this.rowPositions[t],this.frozenRowsHeight=c>0?this.rowPositions[c]??0:0,this.colPositions=new Array(o+1),this.colWidthCache=new Array(o),this.colPositions[0]=0;for(let h=0;h<o;h++){let f=r[h]??a;this.colWidthCache[h]=f,this.colPositions[h+1]=this.colPositions[h]+f;}this.totalWidth=this.colPositions[o],this.frozenColsWidth=g>0?this.colPositions[g]??0:0;}getFrozenInfo(){return {rows:this.frozenRows,cols:this.frozenCols,frozenRowsHeight:this.frozenRowsHeight,frozenColsWidth:this.frozenColsWidth}}binarySearch(e,t){let o=0,n=e.length-2;for(;o<=n;){let r=o+n>>>1,s=e[r],a=e[r+1];if(t>=s&&t<a)return r;t<s?n=r-1:o=r+1;}return Math.max(0,Math.min(o,e.length-2))}getVisibleRange(e,t,o,n){let r=e+this.frozenRowsHeight,s=t+this.frozenColsWidth,a=this.binarySearch(this.rowPositions,r),u=this.binarySearch(this.rowPositions,r+Math.max(0,o)),c=this.binarySearch(this.colPositions,s),g=this.binarySearch(this.colPositions,s+Math.max(0,n)),h=Math.max(this.frozenRows,a-this.overscan),f=Math.min(this.rowCount-1,u+this.overscan),T=Math.max(this.frozenCols,c-this.overscan),C=Math.min(this.colCount-1,g+this.overscan);return {startRow:h,endRow:f,startCol:T,endCol:C}}getFrozenRowsRange(){return this.frozenRows===0?null:{startRow:0,endRow:this.frozenRows-1}}getFrozenColsRange(){return this.frozenCols===0?null:{startCol:0,endCol:this.frozenCols-1}}getCellRect(e,t){return {top:this.rowPositions[e]??0,left:this.colPositions[t]??0,width:this.colWidthCache[t]??100,height:this.rowHeightCache[e]??24}}getRowHeight(e){return this.rowHeightCache[e]??24}getColWidth(e){return this.colWidthCache[e]??100}setColWidth(e,t){if(e<0||e>=this.colCount)return;let o=this.colWidthCache[e],n=t-o;this.colWidthCache[e]=t;for(let r=e+1;r<=this.colCount;r++)this.colPositions[r]+=n;this.totalWidth+=n;}getIndexAtPosition(e,t){return {row:this.binarySearch(this.rowPositions,e),col:this.binarySearch(this.colPositions,t)}}getScrollToPosition(e,t,o,n){let r=this.rowPositions[e]??0,s=this.colPositions[t]??0;return {scrollTop:Math.max(0,r-o/2),scrollLeft:Math.max(0,s-n/2)}}};function q(i){let e="",t=i;for(;t>=0;)e=String.fromCharCode(t%26+65)+e,t=Math.floor(t/26)-1;return e}function ee(i){let e=0,t=i.toUpperCase();for(let o=0;o<t.length;o++)e=e*26+(t.charCodeAt(o)-64);return e-1}function M(i,e){return `${q(e)}${i+1}`}function S(i){let e=i.match(/^([A-Z]+)(\d+)$/i);if(!e)return null;let t=ee(e[1]),o=parseInt(e[2],10)-1;return o<0||t<0?null:{row:o,col:t}}var I=class{state;sheet;onChange;constructor(e,t){this.sheet=e,this.onChange=t??null,this.state={anchor:null,focus:null,ranges:[]};}handleClick(e,t,o){let{shiftKey:n,ctrlKey:r,metaKey:s}=o;n&&this.state.anchor?(this.state.focus={row:e,col:t},this.updateRanges()):r||s?(this.state.anchor={row:e,col:t},this.state.focus={row:e,col:t},this.state.ranges.push(this.createRange(this.state.anchor,this.state.focus))):(this.state.anchor={row:e,col:t},this.state.focus={row:e,col:t},this.state.ranges=[this.createRange(this.state.anchor,this.state.focus)]),this.notifyChange();}handleDrag(e,t){this.state.anchor&&(this.state.focus={row:e,col:t},this.updateRanges(),this.notifyChange());}selectCell(e){let t=S(e);t&&(this.state.anchor=t,this.state.focus=t,this.state.ranges=[this.createRange(t,t)],this.notifyChange());}selectRange(e,t){let o=S(e),n=S(t);!o||!n||(this.state.anchor=o,this.state.focus=n,this.state.ranges=[this.createRange(o,n)],this.notifyChange());}selectAll(){this.state.anchor={row:0,col:0},this.state.focus={row:this.sheet.rowCount-1,col:this.sheet.colCount-1},this.state.ranges=[this.createRange(this.state.anchor,this.state.focus)],this.notifyChange();}clear(){this.state.anchor=null,this.state.focus=null,this.state.ranges=[],this.notifyChange();}getSelection(){return this.state.ranges.length===0?null:this.state.ranges[0]}getAllSelections(){return [...this.state.ranges]}isCellSelected(e,t){return this.state.ranges.some(o=>e>=o.start.row&&e<=o.end.row&&t>=o.start.col&&t<=o.end.col)}isAnchor(e,t){return this.state.anchor?.row===e&&this.state.anchor?.col===t}setSheet(e){this.sheet=e,this.clear();}updateRanges(){if(!this.state.anchor||!this.state.focus)return;let e=this.createRange(this.state.anchor,this.state.focus);this.state.ranges.length>0?this.state.ranges[this.state.ranges.length-1]=e:this.state.ranges.push(e);}createRange(e,t){let o=Math.min(e.row,t.row),n=Math.max(e.row,t.row),r=Math.min(e.col,t.col),s=Math.max(e.col,t.col),a=[],u=[];for(let c=o;c<=n;c++){let g=[];for(let h=r;h<=s;h++){let f=M(c,h);u.push(f),g.push(this.sheet.cells[f]??null);}a.push(g);}return {start:{row:o,col:r},end:{row:n,col:s},cells:a,cellRefs:u}}notifyChange(){this.onChange&&this.onChange(this.getSelection());}};var B=class{selection;virtualScroll;config;onScroll;onCopy;constructor(e,t,o,n){this.selection=e,this.virtualScroll=t,this.config=o,this.onScroll=n?.onScroll??null,this.onCopy=n?.onCopy??null;}handleKeyDown(e){if(!this.config.enabled)return false;let t=this.getAction(e);return t?(e.preventDefault(),this.executeAction(t),true):false}getAction(e){let{key:t,shiftKey:o,ctrlKey:n,metaKey:r}=e,s=n||r;if(s&&t==="c")return "copy";if(s&&t==="a")return "select-all";if(o)switch(t){case "ArrowUp":return "extend-up";case "ArrowDown":return "extend-down";case "ArrowLeft":return "extend-left";case "ArrowRight":return "extend-right"}if(s)switch(t){case "Home":return "move-ctrl-home";case "End":return "move-ctrl-end"}switch(t){case "ArrowUp":return "move-up";case "ArrowDown":return "move-down";case "ArrowLeft":return "move-left";case "ArrowRight":return "move-right";case "PageUp":return "move-page-up";case "PageDown":return "move-page-down";case "Home":return "move-home";case "End":return "move-end";case "Tab":return o?"move-left":"move-right";case "Enter":return o?"move-up":"move-down"}return null}executeAction(e){let t=this.selection.getSelection();if(!t&&!["select-all","move-ctrl-home"].includes(e)){this.selection.selectCell("A1"),this.scrollToSelection();return}let{row:o,col:n}=t?.start??{row:0,col:0},r=o,s=n;switch(e){case "move-up":r=Math.max(0,o-1);break;case "move-down":r=Math.min(this.virtualScroll.rowCount-1,o+1);break;case "move-left":s=Math.max(0,n-1);break;case "move-right":s=Math.min(this.virtualScroll.colCount-1,n+1);break;case "move-page-up":r=Math.max(0,o-20);break;case "move-page-down":r=Math.min(this.virtualScroll.rowCount-1,o+20);break;case "move-home":s=0;break;case "move-end":s=this.virtualScroll.colCount-1;break;case "move-ctrl-home":r=0,s=0;break;case "move-ctrl-end":r=this.virtualScroll.rowCount-1,s=this.virtualScroll.colCount-1;break;case "select-all":this.selection.selectAll();return;case "copy":this.onCopy?.();return;case "extend-up":case "extend-down":case "extend-left":case "extend-right":this.extendSelection(e);return}this.selection.handleClick(r,s,{shiftKey:false,ctrlKey:false,metaKey:false}),this.scrollToSelection();}extendSelection(e){let t=this.selection.getSelection();if(!t)return;let{row:o,col:n}=t.end;switch(e){case "extend-up":o=Math.max(0,o-1);break;case "extend-down":o=Math.min(this.virtualScroll.rowCount-1,o+1);break;case "extend-left":n=Math.max(0,n-1);break;case "extend-right":n=Math.min(this.virtualScroll.colCount-1,n+1);break}this.selection.handleDrag(o,n),this.scrollToSelection();}scrollToSelection(){let e=this.selection.getSelection();!e||!this.onScroll||this.onScroll(e.start.row,e.start.col);}setVirtualScroll(e){this.virtualScroll=e;}setSelection(e){this.selection=e;}};var A=class{merges;mergeMap;constructor(e=[]){this.merges=[],this.mergeMap=new Map,this.parseMerges(e);}parseMerges(e){for(let t of e){let[o,n]=t.split(":");if(!o||!n)continue;let r=S(o),s=S(n);if(!r||!s)continue;let a={startRow:Math.min(r.row,s.row),startCol:Math.min(r.col,s.col),endRow:Math.max(r.row,s.row),endCol:Math.max(r.col,s.col),cellRef:o};this.merges.push(a);for(let u=a.startRow;u<=a.endRow;u++)for(let c=a.startCol;c<=a.endCol;c++){let g=`${u},${c}`;this.mergeMap.set(g,a);}}}getMergeAt(e,t){return this.mergeMap.get(`${e},${t}`)??null}isMergeMaster(e,t){let o=this.getMergeAt(e,t);return o?o.startRow===e&&o.startCol===t:false}isMergeHidden(e,t){let o=this.getMergeAt(e,t);return o?!(o.startRow===e&&o.startCol===t):false}getMergeMaster(e,t){let o=this.getMergeAt(e,t);return o?{row:o.startRow,col:o.startCol}:null}getMergeRect(e,t,o){let n=this.getMergeAt(e,t);if(!n||!this.isMergeMaster(e,t))return null;let r=o(n.startRow,n.startCol),s=o(n.endRow,n.endCol);return {top:r.top,left:r.left,width:s.left+s.width-r.left,height:s.top+s.height-r.top}}getAllMerges(){return [...this.merges]}getVisibleMerges(e,t,o,n){return this.merges.filter(r=>r.endRow>=e&&r.startRow<=t&&r.endCol>=o&&r.startCol<=n)}update(e){this.merges=[],this.mergeMap.clear(),this.parseMerges(e);}};var N=class{async copyToClipboard(e){let t=this.formatSelection(e);try{if(navigator.clipboard&&typeof ClipboardItem<"u"){let o=new Blob([t.html],{type:"text/html"}),n=new Blob([t.text],{type:"text/plain"});await navigator.clipboard.write([new ClipboardItem({"text/html":o,"text/plain":n})]);}else await this.copyWithExecCommand(t.text);}catch{await this.copyWithExecCommand(t.text);}return t}formatSelection(e){let{cells:t}=e,o=[];for(let a of t){let u=a.map(c=>this.getCellValue(c));o.push(u.join(" "));}let n=o.join(`
|
|
2
|
+
`),r=[];for(let a of t){let u=a.map(c=>{let g=this.escapeHtml(this.getCellValue(c));return `<td style="${this.getCellStyle(c)}">${g}</td>`});r.push(`<tr>${u.join("")}</tr>`);}let s=`
|
|
3
|
+
<table style="border-collapse: collapse; font-family: Arial, sans-serif; font-size: 12px;">
|
|
4
|
+
<tbody>
|
|
5
|
+
${r.join(`
|
|
6
|
+
`)}
|
|
7
|
+
</tbody>
|
|
8
|
+
</table>
|
|
9
|
+
`.trim();return {text:n,html:s,cells:t}}getCellValue(e){return !e||e.v===void 0||e.v===null?"":String(e.v)}getCellStyle(e){let t=["border: 1px solid #ccc","padding: 4px 8px"];return e?.t==="n"&&t.push("text-align: right"),t.join("; ")}escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}async copyWithExecCommand(e){let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.left="-9999px",document.body.appendChild(t),t.select();try{document.execCommand("copy");}finally{document.body.removeChild(t);}}};var K=class{sheet;results;currentIndex;constructor(e){this.sheet=e,this.results=[],this.currentIndex=-1;}search(e,t={}){if(!e)return this.results=[],this.currentIndex=-1,[];let{caseSensitive:o=false,regex:n=false,matchWholeCell:r=false}=t,s;try{if(n)s=new RegExp(e,o?"g":"gi");else {let u=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=r?`^${u}$`:u;s=new RegExp(c,o?"g":"gi");}}catch{let u=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");s=new RegExp(u,o?"g":"gi");}let a=[];for(let[u,c]of Object.entries(this.sheet.cells)){if(c.v===void 0||c.v===null)continue;let g=String(c.v);s.lastIndex=0;let h=s.exec(g);if(h){let f=this.parseCellRef(u);f&&a.push({row:f.row,col:f.col,cellRef:u,value:g,matchStart:h.index,matchEnd:h.index+h[0].length});}}return a.sort((u,c)=>u.row!==c.row?u.row-c.row:u.col-c.col),this.results=a,this.currentIndex=a.length>0?0:-1,a}next(){return this.results.length===0?null:(this.currentIndex=(this.currentIndex+1)%this.results.length,this.results[this.currentIndex])}previous(){return this.results.length===0?null:(this.currentIndex=(this.currentIndex-1+this.results.length)%this.results.length,this.results[this.currentIndex])}current(){return this.currentIndex<0||this.currentIndex>=this.results.length?null:this.results[this.currentIndex]}getResults(){return [...this.results]}getCount(){return this.results.length}getCurrentIndex(){return this.currentIndex+1}isResult(e,t){return this.results.some(o=>o.row===e&&o.col===t)}isCurrent(e,t){let o=this.current();return o?.row===e&&o?.col===t}clear(){this.results=[],this.currentIndex=-1;}setSheet(e){this.sheet=e,this.clear();}parseCellRef(e){let t=e.match(/^([A-Z]+)(\d+)$/i);if(!t)return null;let o=t[1].toUpperCase(),n=parseInt(t[2],10)-1,r=0;for(let s=0;s<o.length;s++)r=r*26+(o.charCodeAt(s)-64);return r-=1,{row:n,col:r}}};var E=class{state=null;virtualScroll;onChange;minWidth;maxWidth;constructor(e,t,o=30,n=500){this.virtualScroll=e,this.onChange=t??null,this.minWidth=o,this.maxWidth=n;}startResize(e,t){let o=this.virtualScroll.getColWidth(e);this.state={isResizing:true,colIndex:e,startX:t,startWidth:o},document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp),document.body.style.cursor="col-resize",document.body.style.userSelect="none";}handleMouseMove=e=>{if(!this.state)return;let t=e.clientX-this.state.startX,o=Math.min(this.maxWidth,Math.max(this.minWidth,this.state.startWidth+t));this.virtualScroll.setColWidth(this.state.colIndex,o),this.onChange?.(this.state.colIndex,o);};handleMouseUp=()=>{this.cleanup();};isResizing(){return this.state?.isResizing??false}getResizeColumn(){return this.state?.colIndex??null}cancel(){this.state&&(this.virtualScroll.setColWidth(this.state.colIndex,this.state.startWidth),this.onChange?.(this.state.colIndex,this.state.startWidth)),this.cleanup();}cleanup(){document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.body.style.cursor="",document.body.style.userSelect="",this.state=null;}setVirtualScroll(e){this.virtualScroll=e;}destroy(){this.cleanup();}};var V={default:{name:"default",colors:{background:"#ffffff",foreground:"#202124",grid:"#e0e0e0",headerBackground:"#f8f9fa",headerForeground:"#5f6368",selectionBorder:"#1a73e8",selectionBackground:"rgba(26, 115, 232, 0.08)",frozenBorder:"#dadce0"},fonts:{family:"'Google Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",size:"13px",headerSize:"11px"}},excel:{name:"excel",colors:{background:"#ffffff",foreground:"#000000",grid:"#d4d4d4",headerBackground:"#f0f0f0",headerForeground:"#000000",selectionBorder:"#217346",selectionBackground:"rgba(33, 115, 70, 0.1)",frozenBorder:"#9bc2e6"},fonts:{family:"'Calibri', 'Segoe UI', sans-serif",size:"11px",headerSize:"11px"}},modern:{name:"modern",colors:{background:"#fafafa",foreground:"#18181b",grid:"#e4e4e7",headerBackground:"#f4f4f5",headerForeground:"#71717a",selectionBorder:"#3b82f6",selectionBackground:"rgba(59, 130, 246, 0.08)",frozenBorder:"#a1a1aa"},fonts:{family:"'Inter', -apple-system, BlinkMacSystemFont, sans-serif",size:"13px",headerSize:"11px"}},minimal:{name:"minimal",colors:{background:"#ffffff",foreground:"#27272a",grid:"#f4f4f5",headerBackground:"#ffffff",headerForeground:"#a1a1aa",selectionBorder:"#18181b",selectionBackground:"rgba(24, 24, 27, 0.04)",frozenBorder:"#e4e4e7"},fonts:{family:"'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif",size:"13px",headerSize:"11px"}},dark:{name:"dark",colors:{background:"#1e1e1e",foreground:"#d4d4d4",grid:"#3c3c3c",headerBackground:"#252526",headerForeground:"#858585",selectionBorder:"#0078d4",selectionBackground:"rgba(0, 120, 212, 0.2)",frozenBorder:"#4a4a4a"},fonts:{family:"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",size:"13px",headerSize:"11px"}},midnight:{name:"midnight",colors:{background:"#0d1117",foreground:"#c9d1d9",grid:"#21262d",headerBackground:"#161b22",headerForeground:"#8b949e",selectionBorder:"#58a6ff",selectionBackground:"rgba(88, 166, 255, 0.15)",frozenBorder:"#30363d"},fonts:{family:"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",size:"13px",headerSize:"11px"}},accessible:{name:"accessible",colors:{background:"#ffffff",foreground:"#000000",grid:"#000000",headerBackground:"#e6e6e6",headerForeground:"#000000",selectionBorder:"#0000ff",selectionBackground:"rgba(0, 0, 255, 0.15)",frozenBorder:"#000000"},fonts:{family:"Arial, Helvetica, sans-serif",size:"14px",headerSize:"12px"}}};function D(i,e){let t=i.style;t.setProperty("--nup-background",e.colors.background),t.setProperty("--nup-foreground",e.colors.foreground),t.setProperty("--nup-grid",e.colors.grid),t.setProperty("--nup-header-bg",e.colors.headerBackground),t.setProperty("--nup-header-fg",e.colors.headerForeground),t.setProperty("--nup-selection-border",e.colors.selectionBorder),t.setProperty("--nup-selection-bg",e.colors.selectionBackground),t.setProperty("--nup-frozen-border",e.colors.frozenBorder),t.setProperty("--nup-font-family",e.fonts.family),t.setProperty("--nup-font-size",e.fonts.size);}function G(i){return `nup-theme-${i}`}var ne=defineComponent({name:"NupSpreadsheetPreview",props:{workbook:{type:Object,required:true},activeSheet:{type:Number,default:0},theme:{type:[Object,String],default:"default"},width:{type:[Number,String],default:"100%"},height:{type:[Number,String],default:"400px"},showHeaders:{type:Boolean,default:true},showGridLines:{type:Boolean,default:true},showSheetTabs:{type:Boolean,default:true},selectable:{type:Boolean,default:true},resizable:{type:Boolean,default:true},searchable:{type:Boolean,default:false},copyable:{type:Boolean,default:true},keyboardNavigation:{type:Boolean,default:true},frozenRows:{type:Number,default:0},frozenCols:{type:Number,default:0},overscan:{type:Number,default:5},defaultRowHeight:{type:Number,default:24},defaultColWidth:{type:Number,default:100},ariaLabel:{type:String,default:"Spreadsheet"}},emits:["cellClick","cellDoubleClick","cellRightClick","selectionChange","sheetChange","columnResize","scroll","search","copy"],setup(i,{emit:e,expose:t}){let o=ref(null),n=ref(null),r=ref(i.activeSheet),s=ref({top:0,left:0}),a=ref({width:0,height:0}),u=ref(null),c=ref([]),g=ref(""),h$1=ref(0),f=computed(()=>i.workbook.sheets[r.value]??i.workbook.sheets[0]),T=computed(()=>typeof i.theme=="string"?V[i.theme]??V.default:i.theme),C,y,$,U,L,F,j,O=()=>{let l=f.value,d={},w={};Object.entries(l.rows).forEach(([m,p])=>{p.h&&(d[parseInt(m)]=p.h);}),Object.entries(l.cols).forEach(([m,p])=>{p.w&&(w[parseInt(m)]=p.w);}),C=new P({rows:l.rowCount,cols:l.colCount,rowHeights:d,colWidths:w,defaultRowHeight:i.defaultRowHeight,defaultColWidth:i.defaultColWidth,overscan:i.overscan}),y=new I(l,m=>{u.value=m,e("selectionChange",m);}),$=new A(l.merges??[]),U=new K(l),L=new N,F=new E(C,(m,p)=>{h$1.value++,e("columnResize",m,p);}),j=new B(y,C,{enabled:i.keyboardNavigation},{onScroll:(m,p)=>{let H=C.getScrollToPosition(m,p,a.value.height,a.value.width);n.value?.scrollTo({top:H.scrollTop,left:H.scrollLeft,behavior:"smooth"});},onCopy:async()=>{let m=y.getSelection();if(m&&i.copyable){let p=await L.copyToClipboard(m);e("copy",p);}}});};return onMounted(()=>{O();let l=n.value;l&&(new ResizeObserver(w=>{let m=w[0];m&&(a.value={width:m.contentRect.width,height:m.contentRect.height});}).observe(l),a.value={width:l.clientWidth,height:l.clientHeight}),o.value&&D(o.value,T.value);}),onUnmounted(()=>{F?.destroy();}),watch(()=>i.activeSheet,l=>{r.value=l,O();}),watch(T,l=>{o.value&&D(o.value,l);}),t({scrollTo:(l,d)=>{let w=C.getScrollToPosition(l,d,a.value.height,a.value.width);n.value?.scrollTo({top:w.scrollTop,left:w.scrollLeft,behavior:"smooth"});},scrollToCell:l=>{let d=S(l);if(d){let w=C.getScrollToPosition(d.row,d.col,a.value.height,a.value.width);n.value?.scrollTo({top:w.scrollTop,left:w.scrollLeft,behavior:"smooth"});}},select:l=>{u.value=l;},selectCell:l=>{y.selectCell(l);},selectAll:()=>{y.selectAll();},clearSelection:()=>{y.clear();},getSelection:()=>u.value,setActiveSheet:l=>{r.value=l,e("sheetChange",l);},getActiveSheet:()=>r.value,search:l=>{g.value=l;let d=U.search(l);return c.value=d,e("search",d),d},highlightResults:l=>{c.value=l;},clearHighlights:()=>{c.value=[],g.value="";},getWorkbook:()=>i.workbook,getVisibleCells:()=>{let l=C.getVisibleRange(s.value.top,s.value.left,a.value.height,a.value.width),d=[];for(let w=l.startRow;w<=l.endRow;w++){let m=[];for(let p=l.startCol;p<=l.endCol;p++)m.push(f.value.cells[M(w,p)]??null);d.push(m);}return d},getCellAt:(l,d)=>f.value.cells[M(l,d)]??null,copySelection:async()=>{let l=y.getSelection();if(l){let d=await L.copyToClipboard(l);e("copy",d);}},setColumnWidth:(l,d)=>{C.setColWidth(l,d),h$1.value++;},autoFitColumn:()=>{},autoFitAllColumns:()=>{},refresh:()=>{h$1.value++;},destroy:()=>{F?.destroy();}}),()=>{let l=f.value,d=i.showHeaders?24:0,w=i.showHeaders?40:0,m=C?.getVisibleRange(s.value.top,s.value.left,a.value.height,a.value.width)??{startRow:0,endRow:0,startCol:0,endCol:0},p=[];for(let b=m.startRow;b<=m.endRow;b++)for(let v=m.startCol;v<=m.endCol;v++){if($?.isMergeHidden(b,v))continue;let z=$?.getMergeRect(b,v,(k,_)=>C.getCellRect(k,_))??C?.getCellRect(b,v);if(!z)continue;let X=M(b,v),W=l.cells[X],J=y?.isCellSelected(b,v),Y=y?.isAnchor(b,v);p.push(h("div",{key:`${b}-${v}`,class:["nup-cell",{"nup-cell-number":W?.t==="n"},{"nup-cell-selected":J},{"nup-cell-anchor":Y}],style:{top:`${z.top}px`,left:`${z.left}px`,width:`${z.width}px`,height:`${z.height}px`},onClick:k=>{i.selectable&&(y?.handleClick(b,v,{shiftKey:k.shiftKey,ctrlKey:k.ctrlKey,metaKey:k.metaKey}),e("cellClick",{cell:W,row:b,col:v,cellRef:X,originalEvent:k}));}},W?.v!==void 0&&W?.v!==null?String(W.v):""));}let H=typeof i.theme=="string"?G(i.theme):"";return h("div",{ref:o,class:["nup-spreadsheet",H,{"nup-no-gridlines":!i.showGridLines}],style:{width:i.width,height:i.height},tabindex:0,onKeydown:b=>j?.handleKeyDown(b)},[i.showHeaders&&h("div",{class:"nup-corner",style:{width:`${w}px`,height:`${d}px`}}),h("div",{ref:n,class:"nup-scroll-container",style:{top:`${d}px`,left:`${w}px`,right:0,bottom:i.showSheetTabs?"32px":0},onScroll:b=>{let v=b.target;s.value={top:v.scrollTop,left:v.scrollLeft};}},[h("div",{class:"nup-content",style:{width:`${C?.totalWidth??0}px`,height:`${C?.totalHeight??0}px`}},p)]),i.showSheetTabs&&i.workbook.sheets.length>1&&h("div",{class:"nup-sheet-tabs"},i.workbook.sheets.map((b,v)=>h("button",{key:b.id,class:["nup-sheet-tab",{"nup-sheet-tab-active":v===r.value}],onClick:()=>{r.value=v,e("sheetChange",v);}},b.name)))])}}}),ze=ne;export{ne as NupSpreadsheetPreview,ze as default};//# sourceMappingURL=vue.js.map
|
|
10
|
+
//# sourceMappingURL=vue.js.map
|