@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,790 @@
1
+ import * as react from 'react';
2
+ import { CSSProperties } from 'react';
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
+ interface PreviewConfig {
57
+ workbook: NupWorkbook;
58
+ activeSheet?: number;
59
+ theme?: NupThemeConfig;
60
+ width?: number | string;
61
+ height?: number | string;
62
+ minRowHeight?: number;
63
+ maxRowHeight?: number;
64
+ defaultRowHeight?: number;
65
+ defaultColWidth?: number;
66
+ showHeaders?: boolean;
67
+ showSheetTabs?: boolean;
68
+ showGridLines?: boolean;
69
+ showScrollbars?: boolean;
70
+ selectable?: boolean;
71
+ resizable?: boolean;
72
+ searchable?: boolean;
73
+ copyable?: boolean;
74
+ contextMenu?: boolean;
75
+ frozenRows?: number;
76
+ frozenCols?: number;
77
+ overscan?: number;
78
+ recycleNodes?: boolean;
79
+ ariaLabel?: string;
80
+ keyboardNavigation?: boolean;
81
+ }
82
+ interface CellClickEvent {
83
+ cell: NupCell | null;
84
+ row: number;
85
+ col: number;
86
+ cellRef: string;
87
+ originalEvent: MouseEvent;
88
+ }
89
+ interface SelectionRange {
90
+ start: {
91
+ row: number;
92
+ col: number;
93
+ };
94
+ end: {
95
+ row: number;
96
+ col: number;
97
+ };
98
+ cells: (NupCell | null)[][];
99
+ cellRefs: string[];
100
+ }
101
+ interface ScrollPosition {
102
+ scrollTop: number;
103
+ scrollLeft: number;
104
+ visibleRows: {
105
+ start: number;
106
+ end: number;
107
+ };
108
+ visibleCols: {
109
+ start: number;
110
+ end: number;
111
+ };
112
+ }
113
+ interface SearchResult {
114
+ row: number;
115
+ col: number;
116
+ cellRef: string;
117
+ value: string;
118
+ matchStart: number;
119
+ matchEnd: number;
120
+ }
121
+ interface ClipboardData {
122
+ text: string;
123
+ html: string;
124
+ cells: (NupCell | null)[][];
125
+ }
126
+ interface PreviewEvents {
127
+ onCellClick?: (event: CellClickEvent) => void;
128
+ onCellDoubleClick?: (event: CellClickEvent) => void;
129
+ onCellRightClick?: (event: CellClickEvent) => void;
130
+ onSelectionChange?: (selection: SelectionRange | null) => void;
131
+ onSheetChange?: (sheetIndex: number) => void;
132
+ onColumnResize?: (colIndex: number, width: number) => void;
133
+ onScroll?: (scroll: ScrollPosition) => void;
134
+ onSearch?: (results: SearchResult[]) => void;
135
+ onCopy?: (data: ClipboardData) => void;
136
+ }
137
+ interface PreviewInstance {
138
+ scrollTo(row: number, col: number): void;
139
+ scrollToCell(cellRef: string): void;
140
+ select(range: SelectionRange): void;
141
+ selectCell(cellRef: string): void;
142
+ selectAll(): void;
143
+ clearSelection(): void;
144
+ getSelection(): SelectionRange | null;
145
+ setActiveSheet(index: number): void;
146
+ getActiveSheet(): number;
147
+ search(query: string): SearchResult[];
148
+ highlightResults(results: SearchResult[]): void;
149
+ clearHighlights(): void;
150
+ getWorkbook(): NupWorkbook;
151
+ getVisibleCells(): (NupCell | null)[][];
152
+ getCellAt(row: number, col: number): NupCell | null;
153
+ copySelection(): Promise<void>;
154
+ setColumnWidth(col: number, width: number): void;
155
+ autoFitColumn(col: number): void;
156
+ autoFitAllColumns(): void;
157
+ refresh(): void;
158
+ destroy(): void;
159
+ }
160
+ interface CellRect {
161
+ top: number;
162
+ left: number;
163
+ width: number;
164
+ height: number;
165
+ }
166
+ interface VisibleRange {
167
+ startRow: number;
168
+ endRow: number;
169
+ startCol: number;
170
+ endCol: number;
171
+ }
172
+ interface MergeInfo {
173
+ startRow: number;
174
+ startCol: number;
175
+ endRow: number;
176
+ endCol: number;
177
+ cellRef: string;
178
+ }
179
+
180
+ /**
181
+ * Virtual Scroll Engine
182
+ * High-performance O(1) lookups using pre-computed positions and binary search
183
+ */
184
+
185
+ interface VirtualScrollConfig {
186
+ rows: number;
187
+ cols: number;
188
+ rowHeights: Record<number, number>;
189
+ colWidths: Record<number, number>;
190
+ defaultRowHeight?: number;
191
+ defaultColWidth?: number;
192
+ overscan?: number;
193
+ frozenRows?: number;
194
+ frozenCols?: number;
195
+ }
196
+ interface FrozenInfo {
197
+ rows: number;
198
+ cols: number;
199
+ frozenRowsHeight: number;
200
+ frozenColsWidth: number;
201
+ }
202
+ declare class VirtualScroll {
203
+ private rowPositions;
204
+ private colPositions;
205
+ private rowHeightCache;
206
+ private colWidthCache;
207
+ totalHeight: number;
208
+ totalWidth: number;
209
+ overscan: number;
210
+ rowCount: number;
211
+ colCount: number;
212
+ frozenRows: number;
213
+ frozenCols: number;
214
+ frozenRowsHeight: number;
215
+ frozenColsWidth: number;
216
+ constructor(config: VirtualScrollConfig);
217
+ /**
218
+ * Get frozen pane info
219
+ */
220
+ getFrozenInfo(): FrozenInfo;
221
+ /**
222
+ * Binary search to find index at a given scroll position
223
+ * O(log n) lookup
224
+ */
225
+ private binarySearch;
226
+ /**
227
+ * Get visible range given scroll position and viewport dimensions
228
+ * Returns the scrollable (non-frozen) visible range
229
+ * Frozen rows/cols are rendered separately by the adapter
230
+ */
231
+ getVisibleRange(scrollTop: number, scrollLeft: number, viewportHeight: number, viewportWidth: number): VisibleRange;
232
+ /**
233
+ * Get frozen rows range (always visible)
234
+ */
235
+ getFrozenRowsRange(): {
236
+ startRow: number;
237
+ endRow: number;
238
+ } | null;
239
+ /**
240
+ * Get frozen cols range (always visible)
241
+ */
242
+ getFrozenColsRange(): {
243
+ startCol: number;
244
+ endCol: number;
245
+ } | null;
246
+ /**
247
+ * Get cell rectangle for absolute positioning
248
+ */
249
+ getCellRect(row: number, col: number): CellRect;
250
+ /**
251
+ * Get row height
252
+ */
253
+ getRowHeight(row: number): number;
254
+ /**
255
+ * Get column width
256
+ */
257
+ getColWidth(col: number): number;
258
+ /**
259
+ * Update column width (for resize)
260
+ */
261
+ setColWidth(col: number, width: number): void;
262
+ /**
263
+ * Find row/col at a given pixel position
264
+ */
265
+ getIndexAtPosition(scrollTop: number, scrollLeft: number): {
266
+ row: number;
267
+ col: number;
268
+ };
269
+ /**
270
+ * Scroll offset to bring a cell into view
271
+ */
272
+ getScrollToPosition(row: number, col: number, viewportHeight: number, viewportWidth: number): {
273
+ scrollTop: number;
274
+ scrollLeft: number;
275
+ };
276
+ }
277
+
278
+ /**
279
+ * Selection Handler
280
+ * Supports click, Shift+Click, Ctrl+Click, and drag selection
281
+ */
282
+
283
+ interface SelectionState {
284
+ anchor: {
285
+ row: number;
286
+ col: number;
287
+ } | null;
288
+ focus: {
289
+ row: number;
290
+ col: number;
291
+ } | null;
292
+ ranges: SelectionRange[];
293
+ }
294
+ declare class SelectionHandler {
295
+ private state;
296
+ private sheet;
297
+ private onChange;
298
+ constructor(sheet: NupWorksheet, onChange?: (selection: SelectionRange | null) => void);
299
+ /**
300
+ * Handle cell click
301
+ */
302
+ handleClick(row: number, col: number, event: {
303
+ shiftKey: boolean;
304
+ ctrlKey: boolean;
305
+ metaKey: boolean;
306
+ }): void;
307
+ /**
308
+ * Handle drag selection
309
+ */
310
+ handleDrag(row: number, col: number): void;
311
+ /**
312
+ * Select a specific cell by reference (e.g., "A1")
313
+ */
314
+ selectCell(cellRef: string): void;
315
+ /**
316
+ * Select a range
317
+ */
318
+ selectRange(startRef: string, endRef: string): void;
319
+ /**
320
+ * Select all cells
321
+ */
322
+ selectAll(): void;
323
+ /**
324
+ * Clear selection
325
+ */
326
+ clear(): void;
327
+ /**
328
+ * Get current selection
329
+ */
330
+ getSelection(): SelectionRange | null;
331
+ /**
332
+ * Get all selections (for multi-select)
333
+ */
334
+ getAllSelections(): SelectionRange[];
335
+ /**
336
+ * Check if a cell is selected
337
+ */
338
+ isCellSelected(row: number, col: number): boolean;
339
+ /**
340
+ * Check if a cell is the anchor (main selected cell)
341
+ */
342
+ isAnchor(row: number, col: number): boolean;
343
+ /**
344
+ * Update sheet reference
345
+ */
346
+ setSheet(sheet: NupWorksheet): void;
347
+ private updateRanges;
348
+ private createRange;
349
+ private notifyChange;
350
+ }
351
+
352
+ /**
353
+ * Keyboard Navigation Handler
354
+ * WCAG AA compliant keyboard navigation for spreadsheet
355
+ */
356
+
357
+ interface KeyboardConfig {
358
+ enabled: boolean;
359
+ wrapNavigation?: boolean;
360
+ tabBehavior?: 'cell' | 'element';
361
+ }
362
+ type KeyboardAction = 'move-up' | 'move-down' | 'move-left' | 'move-right' | 'move-page-up' | 'move-page-down' | 'move-home' | 'move-end' | 'move-ctrl-home' | 'move-ctrl-end' | 'select-all' | 'copy' | 'extend-up' | 'extend-down' | 'extend-left' | 'extend-right';
363
+ declare class KeyboardHandler {
364
+ private selection;
365
+ private virtualScroll;
366
+ private config;
367
+ private onScroll;
368
+ private onCopy;
369
+ constructor(selection: SelectionHandler, virtualScroll: VirtualScroll, config: KeyboardConfig, callbacks?: {
370
+ onScroll?: (row: number, col: number) => void;
371
+ onCopy?: () => void;
372
+ });
373
+ /**
374
+ * Handle keydown event
375
+ * Returns true if event was handled
376
+ */
377
+ handleKeyDown(event: KeyboardEvent): boolean;
378
+ private getAction;
379
+ private executeAction;
380
+ private extendSelection;
381
+ private scrollToSelection;
382
+ /**
383
+ * Update references
384
+ */
385
+ setVirtualScroll(vs: VirtualScroll): void;
386
+ setSelection(sel: SelectionHandler): void;
387
+ }
388
+
389
+ /**
390
+ * Merge Cells Handler
391
+ * Parses and manages merged cell regions
392
+ */
393
+
394
+ declare class MergeHandler {
395
+ private merges;
396
+ private mergeMap;
397
+ constructor(mergeStrings?: string[]);
398
+ /**
399
+ * Parse merge strings like "A1:B2" into structured data
400
+ */
401
+ private parseMerges;
402
+ /**
403
+ * Check if a cell is part of a merge
404
+ */
405
+ getMergeAt(row: number, col: number): MergeInfo | null;
406
+ /**
407
+ * Check if this cell is the top-left of a merge (the "master" cell)
408
+ */
409
+ isMergeMaster(row: number, col: number): boolean;
410
+ /**
411
+ * Check if this cell should be hidden (part of merge but not master)
412
+ */
413
+ isMergeHidden(row: number, col: number): boolean;
414
+ /**
415
+ * Get the master cell for a merged region
416
+ */
417
+ getMergeMaster(row: number, col: number): {
418
+ row: number;
419
+ col: number;
420
+ } | null;
421
+ /**
422
+ * Get merged cell rectangle (spans multiple cells)
423
+ */
424
+ getMergeRect(row: number, col: number, getCellRect: (r: number, c: number) => CellRect): CellRect | null;
425
+ /**
426
+ * Get all merges
427
+ */
428
+ getAllMerges(): MergeInfo[];
429
+ /**
430
+ * Get merges visible in a range
431
+ */
432
+ getVisibleMerges(startRow: number, endRow: number, startCol: number, endCol: number): MergeInfo[];
433
+ /**
434
+ * Update with new merge strings
435
+ */
436
+ update(mergeStrings: string[]): void;
437
+ }
438
+
439
+ /**
440
+ * Clipboard Handler
441
+ * Copy selected cells to clipboard with text and HTML formats
442
+ */
443
+
444
+ declare class ClipboardHandler {
445
+ /**
446
+ * Copy selection to clipboard
447
+ */
448
+ copyToClipboard(selection: SelectionRange): Promise<ClipboardData>;
449
+ /**
450
+ * Format selection as text (TSV) and HTML table
451
+ */
452
+ formatSelection(selection: SelectionRange): ClipboardData;
453
+ private getCellValue;
454
+ private getCellStyle;
455
+ private escapeHtml;
456
+ private copyWithExecCommand;
457
+ }
458
+
459
+ /**
460
+ * Search Handler
461
+ * Search and highlight cells matching a query
462
+ */
463
+
464
+ interface SearchOptions {
465
+ caseSensitive?: boolean;
466
+ regex?: boolean;
467
+ matchWholeCell?: boolean;
468
+ }
469
+ declare class SearchHandler {
470
+ private sheet;
471
+ private results;
472
+ private currentIndex;
473
+ constructor(sheet: NupWorksheet);
474
+ /**
475
+ * Search for a query in the sheet
476
+ */
477
+ search(query: string, options?: SearchOptions): SearchResult[];
478
+ /**
479
+ * Get next search result
480
+ */
481
+ next(): SearchResult | null;
482
+ /**
483
+ * Get previous search result
484
+ */
485
+ previous(): SearchResult | null;
486
+ /**
487
+ * Get current result
488
+ */
489
+ current(): SearchResult | null;
490
+ /**
491
+ * Get all results
492
+ */
493
+ getResults(): SearchResult[];
494
+ /**
495
+ * Get result count
496
+ */
497
+ getCount(): number;
498
+ /**
499
+ * Get current index (1-based for display)
500
+ */
501
+ getCurrentIndex(): number;
502
+ /**
503
+ * Check if a cell is a search result
504
+ */
505
+ isResult(row: number, col: number): boolean;
506
+ /**
507
+ * Check if a cell is the current result
508
+ */
509
+ isCurrent(row: number, col: number): boolean;
510
+ /**
511
+ * Clear search
512
+ */
513
+ clear(): void;
514
+ /**
515
+ * Update sheet reference
516
+ */
517
+ setSheet(sheet: NupWorksheet): void;
518
+ private parseCellRef;
519
+ }
520
+
521
+ /**
522
+ * Column Resize Handler
523
+ * Drag-to-resize column widths
524
+ */
525
+
526
+ interface ResizeState {
527
+ isResizing: boolean;
528
+ colIndex: number;
529
+ startX: number;
530
+ startWidth: number;
531
+ }
532
+ declare class ResizeHandler {
533
+ private state;
534
+ private virtualScroll;
535
+ private onChange;
536
+ private minWidth;
537
+ private maxWidth;
538
+ constructor(virtualScroll: VirtualScroll, onChange?: (colIndex: number, width: number) => void, minWidth?: number, maxWidth?: number);
539
+ /**
540
+ * Start resize operation
541
+ */
542
+ startResize(colIndex: number, clientX: number): void;
543
+ /**
544
+ * Handle mouse move during resize
545
+ */
546
+ private handleMouseMove;
547
+ /**
548
+ * End resize operation
549
+ */
550
+ private handleMouseUp;
551
+ /**
552
+ * Check if currently resizing
553
+ */
554
+ isResizing(): boolean;
555
+ /**
556
+ * Get current resize column
557
+ */
558
+ getResizeColumn(): number | null;
559
+ /**
560
+ * Cancel resize
561
+ */
562
+ cancel(): void;
563
+ /**
564
+ * Cleanup event listeners
565
+ */
566
+ private cleanup;
567
+ /**
568
+ * Update virtual scroll reference
569
+ */
570
+ setVirtualScroll(vs: VirtualScroll): void;
571
+ /**
572
+ * Destroy handler
573
+ */
574
+ destroy(): void;
575
+ }
576
+
577
+ /**
578
+ * Theme Definitions (JS version)
579
+ * For programmatic theme access
580
+ */
581
+
582
+ declare const themes: {
583
+ readonly default: {
584
+ readonly name: "default";
585
+ readonly colors: {
586
+ readonly background: "#ffffff";
587
+ readonly foreground: "#202124";
588
+ readonly grid: "#e0e0e0";
589
+ readonly headerBackground: "#f8f9fa";
590
+ readonly headerForeground: "#5f6368";
591
+ readonly selectionBorder: "#1a73e8";
592
+ readonly selectionBackground: "rgba(26, 115, 232, 0.08)";
593
+ readonly frozenBorder: "#dadce0";
594
+ };
595
+ readonly fonts: {
596
+ readonly family: "'Google Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
597
+ readonly size: "13px";
598
+ readonly headerSize: "11px";
599
+ };
600
+ };
601
+ readonly excel: {
602
+ readonly name: "excel";
603
+ readonly colors: {
604
+ readonly background: "#ffffff";
605
+ readonly foreground: "#000000";
606
+ readonly grid: "#d4d4d4";
607
+ readonly headerBackground: "#f0f0f0";
608
+ readonly headerForeground: "#000000";
609
+ readonly selectionBorder: "#217346";
610
+ readonly selectionBackground: "rgba(33, 115, 70, 0.1)";
611
+ readonly frozenBorder: "#9bc2e6";
612
+ };
613
+ readonly fonts: {
614
+ readonly family: "'Calibri', 'Segoe UI', sans-serif";
615
+ readonly size: "11px";
616
+ readonly headerSize: "11px";
617
+ };
618
+ };
619
+ readonly modern: {
620
+ readonly name: "modern";
621
+ readonly colors: {
622
+ readonly background: "#fafafa";
623
+ readonly foreground: "#18181b";
624
+ readonly grid: "#e4e4e7";
625
+ readonly headerBackground: "#f4f4f5";
626
+ readonly headerForeground: "#71717a";
627
+ readonly selectionBorder: "#3b82f6";
628
+ readonly selectionBackground: "rgba(59, 130, 246, 0.08)";
629
+ readonly frozenBorder: "#a1a1aa";
630
+ };
631
+ readonly fonts: {
632
+ readonly family: "'Inter', -apple-system, BlinkMacSystemFont, sans-serif";
633
+ readonly size: "13px";
634
+ readonly headerSize: "11px";
635
+ };
636
+ };
637
+ readonly minimal: {
638
+ readonly name: "minimal";
639
+ readonly colors: {
640
+ readonly background: "#ffffff";
641
+ readonly foreground: "#27272a";
642
+ readonly grid: "#f4f4f5";
643
+ readonly headerBackground: "#ffffff";
644
+ readonly headerForeground: "#a1a1aa";
645
+ readonly selectionBorder: "#18181b";
646
+ readonly selectionBackground: "rgba(24, 24, 27, 0.04)";
647
+ readonly frozenBorder: "#e4e4e7";
648
+ };
649
+ readonly fonts: {
650
+ readonly family: "'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif";
651
+ readonly size: "13px";
652
+ readonly headerSize: "11px";
653
+ };
654
+ };
655
+ readonly dark: {
656
+ readonly name: "dark";
657
+ readonly colors: {
658
+ readonly background: "#1e1e1e";
659
+ readonly foreground: "#d4d4d4";
660
+ readonly grid: "#3c3c3c";
661
+ readonly headerBackground: "#252526";
662
+ readonly headerForeground: "#858585";
663
+ readonly selectionBorder: "#0078d4";
664
+ readonly selectionBackground: "rgba(0, 120, 212, 0.2)";
665
+ readonly frozenBorder: "#4a4a4a";
666
+ };
667
+ readonly fonts: {
668
+ readonly family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
669
+ readonly size: "13px";
670
+ readonly headerSize: "11px";
671
+ };
672
+ };
673
+ readonly midnight: {
674
+ readonly name: "midnight";
675
+ readonly colors: {
676
+ readonly background: "#0d1117";
677
+ readonly foreground: "#c9d1d9";
678
+ readonly grid: "#21262d";
679
+ readonly headerBackground: "#161b22";
680
+ readonly headerForeground: "#8b949e";
681
+ readonly selectionBorder: "#58a6ff";
682
+ readonly selectionBackground: "rgba(88, 166, 255, 0.15)";
683
+ readonly frozenBorder: "#30363d";
684
+ };
685
+ readonly fonts: {
686
+ readonly family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
687
+ readonly size: "13px";
688
+ readonly headerSize: "11px";
689
+ };
690
+ };
691
+ readonly accessible: {
692
+ readonly name: "accessible";
693
+ readonly colors: {
694
+ readonly background: "#ffffff";
695
+ readonly foreground: "#000000";
696
+ readonly grid: "#000000";
697
+ readonly headerBackground: "#e6e6e6";
698
+ readonly headerForeground: "#000000";
699
+ readonly selectionBorder: "#0000ff";
700
+ readonly selectionBackground: "rgba(0, 0, 255, 0.15)";
701
+ readonly frozenBorder: "#000000";
702
+ };
703
+ readonly fonts: {
704
+ readonly family: "Arial, Helvetica, sans-serif";
705
+ readonly size: "14px";
706
+ readonly headerSize: "12px";
707
+ };
708
+ };
709
+ };
710
+ type ThemeName = keyof typeof themes;
711
+ /**
712
+ * Get theme by name
713
+ */
714
+ declare function getTheme(name: ThemeName): NupThemeConfig;
715
+ /**
716
+ * Apply theme CSS variables to an element
717
+ */
718
+ declare function applyTheme(element: HTMLElement, theme: NupThemeConfig): void;
719
+ /**
720
+ * Get theme class name
721
+ */
722
+ declare function getThemeClass(name: ThemeName): string;
723
+
724
+ /**
725
+ * Cell Utilities
726
+ * Helper functions for cell reference parsing and formatting
727
+ */
728
+ /**
729
+ * Convert column index (0-based) to letter(s) (A, B, ..., Z, AA, AB, ...)
730
+ */
731
+ declare function colIndexToLetter(col: number): string;
732
+ /**
733
+ * Convert column letter(s) to index (0-based)
734
+ */
735
+ declare function letterToColIndex(letters: string): number;
736
+ /**
737
+ * Convert row/col coordinates to cell reference (e.g., 0, 0 -> "A1")
738
+ */
739
+ declare function coordsToCellRef(row: number, col: number): string;
740
+ /**
741
+ * Parse cell reference to row/col coordinates (e.g., "A1" -> { row: 0, col: 0 })
742
+ */
743
+ declare function cellRefToCoords(ref: string): {
744
+ row: number;
745
+ col: number;
746
+ } | null;
747
+ /**
748
+ * Parse range reference (e.g., "A1:B2")
749
+ */
750
+ declare function parseRange(rangeRef: string): {
751
+ start: {
752
+ row: number;
753
+ col: number;
754
+ };
755
+ end: {
756
+ row: number;
757
+ col: number;
758
+ };
759
+ } | null;
760
+ /**
761
+ * Format number for display
762
+ */
763
+ declare function formatCellValue(value: unknown, type?: string): string;
764
+ /**
765
+ * Check if a string looks like a formula
766
+ */
767
+ declare function isFormula(value: string): boolean;
768
+
769
+ interface NupSpreadsheetPreviewProps extends Omit<Partial<PreviewConfig>, 'theme'>, PreviewEvents {
770
+ workbook: NupWorkbook;
771
+ activeSheet?: number;
772
+ theme?: NupThemeConfig | ThemeName;
773
+ width?: number | string;
774
+ height?: number | string;
775
+ className?: string;
776
+ style?: CSSProperties;
777
+ }
778
+ declare const NupSpreadsheetPreview: react.ForwardRefExoticComponent<NupSpreadsheetPreviewProps & react.RefAttributes<PreviewInstance>>;
779
+
780
+ /**
781
+ * Vanilla JS Adapter
782
+ * @aspect/nup-xlsx-preview Vanilla JS API
783
+ */
784
+
785
+ interface CreatePreviewOptions extends Partial<PreviewConfig>, PreviewEvents {
786
+ workbook: NupWorkbook;
787
+ }
788
+ declare function createSpreadsheetPreview(container: HTMLElement | string, options: CreatePreviewOptions): PreviewInstance;
789
+
790
+ export { type CellClickEvent, type CellRect, type ClipboardData, ClipboardHandler, type CreatePreviewOptions, type FrozenInfo, type KeyboardAction, type KeyboardConfig, KeyboardHandler, MergeHandler, type MergeInfo, type NupCell, type NupCol, type NupRow, type NupThemeConfig, type NupWorkbook, type NupWorksheet, type PreviewConfig, type PreviewEvents, type PreviewInstance, NupSpreadsheetPreview as ReactSpreadsheetPreview, type NupSpreadsheetPreviewProps as ReactSpreadsheetPreviewProps, ResizeHandler, type ResizeState, type ScrollPosition, SearchHandler, type SearchOptions, type SearchResult, SelectionHandler, type SelectionRange, type SelectionState, type ThemeName, VirtualScroll, type VirtualScrollConfig, type VisibleRange, applyTheme, cellRefToCoords, colIndexToLetter, coordsToCellRef, createSpreadsheetPreview, createSpreadsheetPreview as default, formatCellValue, getTheme, getThemeClass, isFormula, letterToColIndex, parseRange, themes };