@papernote/ui 1.10.24 → 1.10.26

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.
@@ -123,6 +123,12 @@ export interface DataGridProps {
123
123
  className?: string;
124
124
  /** Density */
125
125
  density?: 'compact' | 'normal' | 'comfortable';
126
+ /** Enable virtual scrolling for large datasets (only renders visible rows) */
127
+ virtualized?: boolean;
128
+ /** Row height in pixels when virtualized (default: 40) */
129
+ virtualRowHeight?: number;
130
+ /** Number of rows to render above/below visible area (default: 5) */
131
+ virtualOverscan?: number;
126
132
  }
127
133
  /**
128
134
  * DataGrid imperative handle
@@ -1 +1 @@
1
- {"version":3,"file":"DataGrid.d.ts","sourceRoot":"","sources":["../../src/components/DataGrid.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DataGrid.d.ts","sourceRoot":"","sources":["../../src/components/DataGrid.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5755,6 +5755,12 @@ interface DataGridProps {
5755
5755
  className?: string;
5756
5756
  /** Density */
5757
5757
  density?: 'compact' | 'normal' | 'comfortable';
5758
+ /** Enable virtual scrolling for large datasets (only renders visible rows) */
5759
+ virtualized?: boolean;
5760
+ /** Row height in pixels when virtualized (default: 40) */
5761
+ virtualRowHeight?: number;
5762
+ /** Number of rows to render above/below visible area (default: 5) */
5763
+ virtualOverscan?: number;
5758
5764
  }
5759
5765
  /**
5760
5766
  * DataGrid imperative handle
package/dist/index.esm.js CHANGED
@@ -39106,9 +39106,10 @@ const buildGroupColorMap = (columns) => {
39106
39106
  * />
39107
39107
  * ```
39108
39108
  */
39109
- const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders = false, frozenRows: frozenRowsProp = 'none', frozenColumns = 0, showFreezeRowToggle = false, zebraStripes = false, formulas = false, readOnly = false, height = 400, width = '100%', showToolbar = false, title, enableExport = false, exportFileName = 'export.csv', enableSave = false, onSave, toolbarActions, className = '', density = 'normal', }, ref) => {
39109
+ const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders = false, frozenRows: frozenRowsProp = 'none', frozenColumns = 0, showFreezeRowToggle = false, zebraStripes = false, formulas = false, readOnly = false, height = 400, width = '100%', showToolbar = false, title, enableExport = false, exportFileName = 'export.csv', enableSave = false, onSave, toolbarActions, className = '', density = 'normal', virtualized = false, virtualRowHeight = 40, virtualOverscan = 5, }, ref) => {
39110
39110
  // State
39111
39111
  const [data, setData] = useState(initialData);
39112
+ const [scrollTop, setScrollTop] = useState(0);
39112
39113
  const [editingCell, setEditingCell] = useState(null);
39113
39114
  const [editValue, setEditValue] = useState('');
39114
39115
  const [sortConfig, setSortConfig] = useState(null);
@@ -39167,23 +39168,16 @@ const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders
39167
39168
  return 'bg-white';
39168
39169
  return '';
39169
39170
  }, [groupColorMap]);
39170
- // Check if a specific row is frozen
39171
- const isRowFrozen = useCallback((rowIndex) => {
39172
- if (frozenRowsState === 'none')
39173
- return false;
39174
- if (frozenRowsState === 'first')
39175
- return rowIndex === 0;
39176
- if (frozenRowsState === 'selected') {
39177
- return selectedCell ? rowIndex === selectedCell.row : false;
39178
- }
39179
- if (typeof frozenRowsState === 'number')
39180
- return rowIndex < frozenRowsState;
39181
- return false;
39182
- }, [frozenRowsState, selectedCell]);
39183
39171
  // Update data when initialData changes
39184
39172
  useEffect(() => {
39185
39173
  setData(initialData);
39186
39174
  }, [initialData]);
39175
+ // Handle scroll for virtualization
39176
+ const handleScroll = useCallback((e) => {
39177
+ if (virtualized) {
39178
+ setScrollTop(e.currentTarget.scrollTop);
39179
+ }
39180
+ }, [virtualized]);
39187
39181
  // Get computed data with formulas evaluated
39188
39182
  // Uses a cache to handle formula dependencies (formulas referencing other formulas)
39189
39183
  const computedData = useMemo(() => {
@@ -39286,6 +39280,30 @@ const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders
39286
39280
  });
39287
39281
  return [...frozenData, ...filtered];
39288
39282
  }, [sortedData, filters, columns, frozenRows]);
39283
+ // Calculate visible rows for virtualization
39284
+ const visibleRowRange = useMemo(() => {
39285
+ if (!virtualized) {
39286
+ return { startIndex: 0, endIndex: filteredData.length, paddingTop: 0, paddingBottom: 0, frozenRowCount: 0 };
39287
+ }
39288
+ const containerHeight = typeof height === 'number' ? height : 400;
39289
+ const headerHeight = 40; // Approximate header height
39290
+ const availableHeight = containerHeight - headerHeight;
39291
+ // Account for frozen rows
39292
+ const frozenRowCount = frozenRows;
39293
+ const scrollableData = filteredData.slice(frozenRowCount);
39294
+ const visibleCount = Math.ceil(availableHeight / virtualRowHeight);
39295
+ const startIndex = Math.max(0, Math.floor(scrollTop / virtualRowHeight) - virtualOverscan);
39296
+ const endIndex = Math.min(scrollableData.length, startIndex + visibleCount + (virtualOverscan * 2));
39297
+ const paddingTop = startIndex * virtualRowHeight;
39298
+ const paddingBottom = Math.max(0, (scrollableData.length - endIndex) * virtualRowHeight);
39299
+ return {
39300
+ startIndex: startIndex + frozenRowCount,
39301
+ endIndex: endIndex + frozenRowCount,
39302
+ paddingTop,
39303
+ paddingBottom,
39304
+ frozenRowCount
39305
+ };
39306
+ }, [virtualized, filteredData.length, scrollTop, height, virtualRowHeight, virtualOverscan, frozenRows]);
39289
39307
  // Handle cell edit start
39290
39308
  const handleCellDoubleClick = useCallback((rowIndex, colIndex, cellElement) => {
39291
39309
  if (readOnly)
@@ -39510,17 +39528,15 @@ const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders
39510
39528
  if (column.type === 'currency' && !isNaN(numVal)) {
39511
39529
  const decimals = column.format?.decimals ?? 2;
39512
39530
  const prefix = column.format?.prefix ?? '$';
39513
- return `${prefix}${numVal.toFixed(decimals)}`;
39531
+ return `${prefix}${numVal.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}`;
39514
39532
  }
39515
39533
  if (column.type === 'percent' && !isNaN(numVal)) {
39516
- const decimals = column.format?.decimals ?? 1;
39517
- return `${(numVal * 100).toFixed(decimals)}%`;
39534
+ const decimals = column.format?.decimals ?? 2;
39535
+ return `${(numVal * 100).toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}%`;
39518
39536
  }
39519
39537
  if (column.type === 'number' && !isNaN(numVal)) {
39520
- const decimals = column.format?.decimals;
39521
- if (decimals !== undefined) {
39522
- return numVal.toFixed(decimals);
39523
- }
39538
+ const decimals = column.format?.decimals ?? 0;
39539
+ return numVal.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
39524
39540
  }
39525
39541
  return String(value);
39526
39542
  }, []);
@@ -39538,7 +39554,7 @@ const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders
39538
39554
  : 'Freeze Row' }) })), enableExport && (jsx(Button, { variant: "ghost", size: "sm", icon: jsx(Download, { className: "h-4 w-4" }), onClick: exportToCSV, children: "Export" })), enableSave && onSave && (jsx(Button, { variant: "primary", size: "sm", icon: jsx(Save, { className: "h-4 w-4" }), onClick: handleSave, loading: isSaving, children: "Save" })), toolbarActions] })), filters.length > 0 && (jsx(Stack, { direction: "horizontal", spacing: "sm", className: "mb-2 px-1 flex-wrap", children: filters.map((filter) => {
39539
39555
  const column = columns.find((c) => c.key === filter.key);
39540
39556
  return (jsxs("div", { className: "inline-flex items-center gap-1 px-2 py-1 bg-primary-100 text-primary-700 rounded text-xs", children: [jsxs("span", { className: "font-medium", children: [column?.header, ":"] }), jsx("span", { children: filter.value }), jsx("button", { onClick: () => clearFilter(filter.key), className: "ml-1 hover:bg-primary-200 rounded p-0.5", children: jsx(X, { className: "h-3 w-3" }) })] }, filter.key));
39541
- }) })), jsx("div", { ref: tableRef, className: "relative overflow-auto border border-stone-200 rounded-lg bg-white", style: { height }, onKeyDown: handleKeyDown, tabIndex: 0, children: jsxs("table", { className: "border-collapse", style: { tableLayout: 'auto' }, children: [jsx("thead", { className: "sticky top-0 z-20 bg-stone-100", children: jsxs("tr", { children: [rowHeaders && (jsx("th", { className: `${cellPadding} border-b border-r border-stone-200 bg-stone-100 text-left font-semibold text-ink-600 sticky left-0 z-30`, style: { width: 50, minWidth: 50, maxWidth: 50 }, children: "#" })), columns.map((column, colIndex) => {
39557
+ }) })), jsx("div", { ref: tableRef, className: "relative overflow-auto border border-stone-200 rounded-lg bg-white", style: { height }, onKeyDown: handleKeyDown, onScroll: handleScroll, tabIndex: 0, children: jsxs("table", { className: "border-collapse", style: { tableLayout: 'auto' }, children: [jsx("thead", { className: "sticky top-0 z-20 bg-stone-100", children: jsxs("tr", { children: [rowHeaders && (jsx("th", { className: `${cellPadding} border-b border-r border-stone-200 bg-stone-100 text-left font-semibold text-ink-600 sticky left-0 z-30`, style: { width: 50, minWidth: 50, maxWidth: 50 }, children: "#" })), columns.map((column, colIndex) => {
39542
39558
  const isFrozen = colIndex < frozenColumns;
39543
39559
  const leftOffset = rowHeaders ? 50 + columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0) : columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0);
39544
39560
  const headerBgClass = getHeaderBgClass(column);
@@ -39554,27 +39570,51 @@ const DataGrid = forwardRef(({ data: initialData, columns, onChange, rowHeaders
39554
39570
  if (e.key === 'Escape')
39555
39571
  setActiveFilter(null);
39556
39572
  }, autoFocus: true }), jsxs(Stack, { direction: "horizontal", spacing: "sm", className: "mt-2", children: [jsx(Button, { size: "sm", variant: "ghost", onClick: () => setActiveFilter(null), children: "Cancel" }), jsx(Button, { size: "sm", variant: "primary", onClick: applyFilter, children: "Apply" })] })] }))] }))] }) }, column.key));
39557
- })] }) }), jsx("tbody", { children: filteredData.map((row, rowIndex) => {
39558
- const isFrozen = isRowFrozen(rowIndex);
39559
- const isZebra = zebraStripes && rowIndex % 2 === 1;
39560
- return (jsxs("tr", { className: `${isZebra ? 'bg-paper-50' : 'bg-white'} ${isFrozen ? 'sticky z-10' : ''} ${isFrozen ? 'shadow-sm' : ''}`, style: {
39561
- top: isFrozen ? `${40 + rowIndex * 40}px` : undefined,
39562
- }, children: [rowHeaders && (jsx("td", { className: `${cellPadding} border-b border-r border-stone-200 bg-stone-50 text-ink-500 font-medium sticky left-0 z-10`, style: { width: 50, minWidth: 50, maxWidth: 50 }, children: Array.isArray(rowHeaders) ? rowHeaders[rowIndex] : rowIndex + 1 })), row.map((cell, colIndex) => {
39563
- const column = columns[colIndex];
39564
- const isFrozenCol = colIndex < frozenColumns;
39565
- const isEditing = editingCell?.row === rowIndex && editingCell?.col === colIndex;
39566
- const isSelected = selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
39567
- const hasFormula = !!cell?.formula;
39568
- const leftOffset = rowHeaders
39569
- ? 50 + columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0)
39570
- : columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0);
39571
- const cellBgClass = getCellBgClass(column, isZebra, isFrozenCol);
39572
- return (jsx("td", { className: `${cellPadding} border-b border-r border-stone-200 text-${column?.align || 'left'} ${isFrozenCol ? 'sticky z-10' : ''} ${cellBgClass} ${isSelected ? 'ring-2 ring-inset ring-primary-500' : ''} ${hasFormula ? 'bg-blue-50' : ''} ${cell?.className || ''}`, style: {
39573
- left: isFrozenCol ? leftOffset : undefined,
39574
- minWidth: column?.minWidth || 80,
39575
- }, onClick: () => handleCellClick(rowIndex, colIndex), onDoubleClick: (e) => handleCellDoubleClick(rowIndex, colIndex, e.currentTarget), children: isEditing ? (formulas ? (jsx(FormulaAutocomplete, { value: editValue, onChange: setEditValue, onComplete: handleEditComplete, onCancel: handleEditCancel, anchorRect: editingCellRect, autoFocus: true })) : (jsx("input", { ref: inputRef, type: "text", value: editValue, onChange: (e) => setEditValue(e.target.value), onBlur: handleEditComplete, onKeyDown: handleEditKeyDown, className: "w-full h-full border-none outline-none bg-transparent", style: { margin: '-4px', padding: '4px' } }))) : (formatValue(cell?.value, column)) }, colIndex));
39576
- })] }, rowIndex));
39577
- }) })] }) }), jsxs("div", { className: "flex items-center justify-between px-2 py-1 text-xs text-ink-500 border-t border-stone-200 bg-stone-50 rounded-b-lg", children: [jsxs("span", { children: [filteredData.length, " row", filteredData.length !== 1 ? 's' : '', filters.length > 0 && ` (filtered)`] }), selectedCell && (jsxs("span", { children: [colIndexToLetter(selectedCell.col), selectedCell.row + 1, data[selectedCell.row]?.[selectedCell.col]?.formula && (jsx("span", { className: "ml-2 text-blue-600", children: data[selectedCell.row][selectedCell.col].formula }))] }))] })] }));
39573
+ })] }) }), jsxs("tbody", { children: [virtualized && visibleRowRange.paddingTop > 0 && (jsx("tr", { style: { height: visibleRowRange.paddingTop }, children: jsx("td", { colSpan: columns.length + (rowHeaders ? 1 : 0) }) })), filteredData.slice(0, visibleRowRange.frozenRowCount).map((row, rowIndex) => {
39574
+ const isZebra = zebraStripes && rowIndex % 2 === 1;
39575
+ return (jsxs("tr", { className: `${isZebra ? 'bg-paper-50' : 'bg-white'} sticky z-10 shadow-sm`, style: {
39576
+ top: `${40 + rowIndex * virtualRowHeight}px`,
39577
+ }, children: [rowHeaders && (jsx("td", { className: `${cellPadding} border-b border-r border-stone-200 bg-stone-50 text-ink-500 font-medium sticky left-0 z-10`, style: { width: 50, minWidth: 50, maxWidth: 50 }, children: Array.isArray(rowHeaders) ? rowHeaders[rowIndex] : rowIndex + 1 })), row.map((cell, colIndex) => {
39578
+ const column = columns[colIndex];
39579
+ const isFrozenCol = colIndex < frozenColumns;
39580
+ const isEditing = editingCell?.row === rowIndex && editingCell?.col === colIndex;
39581
+ const isSelected = selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
39582
+ const hasFormula = !!cell?.formula;
39583
+ const leftOffset = rowHeaders
39584
+ ? 50 + columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0)
39585
+ : columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0);
39586
+ const cellBgClass = getCellBgClass(column, isZebra, isFrozenCol);
39587
+ return (jsx("td", { className: `${cellPadding} border-b border-r border-stone-200 text-${column?.align || 'left'} ${isFrozenCol ? 'sticky z-10' : ''} ${cellBgClass} ${isSelected ? 'ring-2 ring-inset ring-primary-500' : ''} ${hasFormula ? 'bg-blue-50' : ''} ${cell?.className || ''}`, style: {
39588
+ left: isFrozenCol ? leftOffset : undefined,
39589
+ minWidth: column?.minWidth || 80,
39590
+ height: virtualized ? virtualRowHeight : undefined,
39591
+ }, onClick: () => handleCellClick(rowIndex, colIndex), onDoubleClick: (e) => handleCellDoubleClick(rowIndex, colIndex, e.currentTarget), children: isEditing ? (formulas ? (jsx(FormulaAutocomplete, { value: editValue, onChange: setEditValue, onComplete: handleEditComplete, onCancel: handleEditCancel, anchorRect: editingCellRect, autoFocus: true })) : (jsx("input", { ref: inputRef, type: "text", value: editValue, onChange: (e) => setEditValue(e.target.value), onBlur: handleEditComplete, onKeyDown: handleEditKeyDown, className: "w-full h-full border-none outline-none bg-transparent", style: { margin: '-4px', padding: '4px' } }))) : (formatValue(cell?.value, column)) }, colIndex));
39592
+ })] }, `frozen-${rowIndex}`));
39593
+ }), filteredData
39594
+ .slice(virtualized ? Math.max(visibleRowRange.startIndex, visibleRowRange.frozenRowCount) : visibleRowRange.frozenRowCount, virtualized ? visibleRowRange.endIndex : filteredData.length)
39595
+ .map((row, idx) => {
39596
+ const rowIndex = virtualized
39597
+ ? Math.max(visibleRowRange.startIndex, visibleRowRange.frozenRowCount) + idx
39598
+ : visibleRowRange.frozenRowCount + idx;
39599
+ const isZebra = zebraStripes && rowIndex % 2 === 1;
39600
+ return (jsxs("tr", { className: `${isZebra ? 'bg-paper-50' : 'bg-white'}`, style: {
39601
+ height: virtualized ? virtualRowHeight : undefined,
39602
+ }, children: [rowHeaders && (jsx("td", { className: `${cellPadding} border-b border-r border-stone-200 bg-stone-50 text-ink-500 font-medium sticky left-0 z-10`, style: { width: 50, minWidth: 50, maxWidth: 50 }, children: Array.isArray(rowHeaders) ? rowHeaders[rowIndex] : rowIndex + 1 })), row.map((cell, colIndex) => {
39603
+ const column = columns[colIndex];
39604
+ const isFrozenCol = colIndex < frozenColumns;
39605
+ const isEditing = editingCell?.row === rowIndex && editingCell?.col === colIndex;
39606
+ const isSelected = selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
39607
+ const hasFormula = !!cell?.formula;
39608
+ const leftOffset = rowHeaders
39609
+ ? 50 + columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0)
39610
+ : columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0);
39611
+ const cellBgClass = getCellBgClass(column, isZebra, isFrozenCol);
39612
+ return (jsx("td", { className: `${cellPadding} border-b border-r border-stone-200 text-${column?.align || 'left'} ${isFrozenCol ? 'sticky z-10' : ''} ${cellBgClass} ${isSelected ? 'ring-2 ring-inset ring-primary-500' : ''} ${hasFormula ? 'bg-blue-50' : ''} ${cell?.className || ''}`, style: {
39613
+ left: isFrozenCol ? leftOffset : undefined,
39614
+ minWidth: column?.minWidth || 80,
39615
+ }, onClick: () => handleCellClick(rowIndex, colIndex), onDoubleClick: (e) => handleCellDoubleClick(rowIndex, colIndex, e.currentTarget), children: isEditing ? (formulas ? (jsx(FormulaAutocomplete, { value: editValue, onChange: setEditValue, onComplete: handleEditComplete, onCancel: handleEditCancel, anchorRect: editingCellRect, autoFocus: true })) : (jsx("input", { ref: inputRef, type: "text", value: editValue, onChange: (e) => setEditValue(e.target.value), onBlur: handleEditComplete, onKeyDown: handleEditKeyDown, className: "w-full h-full border-none outline-none bg-transparent", style: { margin: '-4px', padding: '4px' } }))) : (formatValue(cell?.value, column)) }, colIndex));
39616
+ })] }, rowIndex));
39617
+ }), virtualized && visibleRowRange.paddingBottom > 0 && (jsx("tr", { style: { height: visibleRowRange.paddingBottom }, children: jsx("td", { colSpan: columns.length + (rowHeaders ? 1 : 0) }) }))] })] }) }), jsxs("div", { className: "flex items-center justify-between px-2 py-1 text-xs text-ink-500 border-t border-stone-200 bg-stone-50 rounded-b-lg", children: [jsxs("span", { children: [filteredData.length, " row", filteredData.length !== 1 ? 's' : '', filters.length > 0 && ` (filtered)`] }), selectedCell && (jsxs("span", { children: [colIndexToLetter(selectedCell.col), selectedCell.row + 1, data[selectedCell.row]?.[selectedCell.col]?.formula && (jsx("span", { className: "ml-2 text-blue-600", children: data[selectedCell.row][selectedCell.col].formula }))] }))] })] }));
39578
39618
  });
39579
39619
  DataGrid.displayName = 'DataGrid';
39580
39620