@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.
@@ -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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}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