@xcelsior/ui-spreadsheets 1.0.16 → 1.0.18

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/dist/index.d.mts CHANGED
@@ -303,6 +303,8 @@ interface SpreadsheetProps<T = any> {
303
303
  defaultZoom?: number;
304
304
  /** Whether to auto-save changes */
305
305
  autoSave?: boolean;
306
+ /** Callback when changes are saved (called for both auto-save and manual save) */
307
+ onSave?: () => void | Promise<void>;
306
308
  /** Whether to use compact mode (smaller cells) */
307
309
  compactMode?: boolean;
308
310
  /** Loading state */
@@ -519,7 +521,7 @@ interface SpreadsheetToolbarProps {
519
521
  /** Save status */
520
522
  saveStatus: 'saved' | 'saving' | 'unsaved' | 'error';
521
523
  /** Whether auto-save is enabled */
522
- autoSave: boolean;
524
+ autoSave?: boolean;
523
525
  /** Summary data to display */
524
526
  summary?: {
525
527
  label: string;
@@ -604,7 +606,7 @@ interface SpreadsheetColumnGroupHeaderProps {
604
606
  * />
605
607
  * ```
606
608
  */
607
- declare function Spreadsheet<T extends Record<string, any>>({ data, columns, columnGroups, getRowId, onCellsEdit, onSelectionChange, onSortChange, onFilterChange, onRowClick, onRowDoubleClick, onRowClone, onRowDelete, onAddCellComment, onRowHighlight, showToolbar, showPagination, showRowIndex, enableRowSelection, enableCellEditing, enableComments, enableHighlighting, enableUndoRedo, defaultPageSize, pageSizeOptions, defaultZoom, autoSave, compactMode, isLoading, className, emptyMessage, rowHighlights: externalRowHighlights, cellComments: externalCellComments, rowActions, toolbarMenuItems, serverSide, totalItems, currentPage: controlledCurrentPage, pageSize: controlledPageSize, onPageChange, sortConfig: controlledSortConfig, filters: controlledFilters, }: SpreadsheetProps<T>): react_jsx_runtime.JSX.Element;
609
+ declare function Spreadsheet<T extends Record<string, any>>({ data, columns, columnGroups, getRowId, onCellsEdit, onSelectionChange, onSortChange, onFilterChange, onRowClick, onRowDoubleClick, onRowClone, onRowDelete, onAddCellComment, onRowHighlight, showToolbar, showPagination, showRowIndex, enableRowSelection, enableCellEditing, enableComments, enableHighlighting, enableUndoRedo, defaultPageSize, pageSizeOptions, defaultZoom, autoSave, onSave, compactMode, isLoading, className, emptyMessage, rowHighlights: externalRowHighlights, cellComments: externalCellComments, rowActions, toolbarMenuItems, serverSide, totalItems, currentPage: controlledCurrentPage, pageSize: controlledPageSize, onPageChange, sortConfig: controlledSortConfig, filters: controlledFilters, }: SpreadsheetProps<T>): react_jsx_runtime.JSX.Element;
608
610
  declare namespace Spreadsheet {
609
611
  var displayName: string;
610
612
  }
@@ -677,9 +679,9 @@ interface SpreadsheetSettings {
677
679
  /** Default zoom level */
678
680
  defaultZoom: number;
679
681
  /** Whether auto-save is enabled */
680
- autoSave: boolean;
682
+ autoSave?: boolean;
681
683
  /** Whether compact view is enabled */
682
- compactView: boolean;
684
+ compactView?: boolean;
683
685
  /** Whether to show row index column */
684
686
  showRowIndex?: boolean;
685
687
  /** Whether row index column is pinned */
package/dist/index.d.ts CHANGED
@@ -303,6 +303,8 @@ interface SpreadsheetProps<T = any> {
303
303
  defaultZoom?: number;
304
304
  /** Whether to auto-save changes */
305
305
  autoSave?: boolean;
306
+ /** Callback when changes are saved (called for both auto-save and manual save) */
307
+ onSave?: () => void | Promise<void>;
306
308
  /** Whether to use compact mode (smaller cells) */
307
309
  compactMode?: boolean;
308
310
  /** Loading state */
@@ -519,7 +521,7 @@ interface SpreadsheetToolbarProps {
519
521
  /** Save status */
520
522
  saveStatus: 'saved' | 'saving' | 'unsaved' | 'error';
521
523
  /** Whether auto-save is enabled */
522
- autoSave: boolean;
524
+ autoSave?: boolean;
523
525
  /** Summary data to display */
524
526
  summary?: {
525
527
  label: string;
@@ -604,7 +606,7 @@ interface SpreadsheetColumnGroupHeaderProps {
604
606
  * />
605
607
  * ```
606
608
  */
607
- declare function Spreadsheet<T extends Record<string, any>>({ data, columns, columnGroups, getRowId, onCellsEdit, onSelectionChange, onSortChange, onFilterChange, onRowClick, onRowDoubleClick, onRowClone, onRowDelete, onAddCellComment, onRowHighlight, showToolbar, showPagination, showRowIndex, enableRowSelection, enableCellEditing, enableComments, enableHighlighting, enableUndoRedo, defaultPageSize, pageSizeOptions, defaultZoom, autoSave, compactMode, isLoading, className, emptyMessage, rowHighlights: externalRowHighlights, cellComments: externalCellComments, rowActions, toolbarMenuItems, serverSide, totalItems, currentPage: controlledCurrentPage, pageSize: controlledPageSize, onPageChange, sortConfig: controlledSortConfig, filters: controlledFilters, }: SpreadsheetProps<T>): react_jsx_runtime.JSX.Element;
609
+ declare function Spreadsheet<T extends Record<string, any>>({ data, columns, columnGroups, getRowId, onCellsEdit, onSelectionChange, onSortChange, onFilterChange, onRowClick, onRowDoubleClick, onRowClone, onRowDelete, onAddCellComment, onRowHighlight, showToolbar, showPagination, showRowIndex, enableRowSelection, enableCellEditing, enableComments, enableHighlighting, enableUndoRedo, defaultPageSize, pageSizeOptions, defaultZoom, autoSave, onSave, compactMode, isLoading, className, emptyMessage, rowHighlights: externalRowHighlights, cellComments: externalCellComments, rowActions, toolbarMenuItems, serverSide, totalItems, currentPage: controlledCurrentPage, pageSize: controlledPageSize, onPageChange, sortConfig: controlledSortConfig, filters: controlledFilters, }: SpreadsheetProps<T>): react_jsx_runtime.JSX.Element;
608
610
  declare namespace Spreadsheet {
609
611
  var displayName: string;
610
612
  }
@@ -677,9 +679,9 @@ interface SpreadsheetSettings {
677
679
  /** Default zoom level */
678
680
  defaultZoom: number;
679
681
  /** Whether auto-save is enabled */
680
- autoSave: boolean;
682
+ autoSave?: boolean;
681
683
  /** Whether compact view is enabled */
682
- compactView: boolean;
684
+ compactView?: boolean;
683
685
  /** Whether to show row index column */
684
686
  showRowIndex?: boolean;
685
687
  /** Whether row index column is pinned */
package/dist/index.js CHANGED
@@ -194,7 +194,7 @@ function cn(...inputs) {
194
194
  // src/components/SpreadsheetCell.tsx
195
195
  var import_react3 = require("react");
196
196
  var import_jsx_runtime = require("react/jsx-runtime");
197
- var cellPaddingCompact = "px-1.5 py-0.5";
197
+ var cellPaddingCompact = "px-1 py-px";
198
198
  var cellPaddingNormal = "px-2 py-1";
199
199
  var SpreadsheetCell = ({
200
200
  value,
@@ -370,7 +370,8 @@ var SpreadsheetCell = ({
370
370
  onKeyDown: handleCellKeyDown,
371
371
  "data-cell-id": `${rowId}-${column.id}`,
372
372
  className: cn(
373
- "border border-gray-200 text-xs group cursor-pointer transition-colors select-none",
373
+ "border border-gray-200 group cursor-pointer transition-colors select-none",
374
+ compactMode ? "text-[10px]" : "text-xs",
374
375
  cellPadding,
375
376
  column.align === "right" && "text-right",
376
377
  column.align === "center" && "text-center",
@@ -1189,7 +1190,7 @@ ColumnHeaderActions.displayName = "ColumnHeaderActions";
1189
1190
 
1190
1191
  // src/components/SpreadsheetHeader.tsx
1191
1192
  var import_jsx_runtime5 = require("react/jsx-runtime");
1192
- var cellPaddingCompact2 = "px-1.5 py-1";
1193
+ var cellPaddingCompact2 = "px-1 py-0.5";
1193
1194
  var cellPaddingNormal2 = "px-2 py-1.5";
1194
1195
  var SpreadsheetHeader = ({
1195
1196
  column,
@@ -1225,7 +1226,8 @@ var SpreadsheetHeader = ({
1225
1226
  {
1226
1227
  onClick: column.sortable ? onClick : void 0,
1227
1228
  className: cn(
1228
- "border border-gray-200 text-xs font-semibold text-gray-700 sticky group",
1229
+ "border border-gray-200 font-semibold text-gray-700 sticky group",
1230
+ compactMode ? "text-[10px]" : "text-xs",
1229
1231
  cellPadding,
1230
1232
  column.align === "right" && "text-right",
1231
1233
  column.align === "center" && "text-center",
@@ -1395,6 +1397,8 @@ function useSpreadsheetPinning({
1395
1397
 
1396
1398
  // src/components/RowIndexColumnHeader.tsx
1397
1399
  var import_jsx_runtime6 = require("react/jsx-runtime");
1400
+ var cellPaddingCompact3 = "px-1 py-0.5";
1401
+ var cellPaddingNormal3 = "px-2 py-1.5";
1398
1402
  function RowIndexColumnHeader({
1399
1403
  enableHighlighting = false,
1400
1404
  highlightColor,
@@ -1402,13 +1406,17 @@ function RowIndexColumnHeader({
1402
1406
  onHighlightClick,
1403
1407
  onPinClick,
1404
1408
  hasColumnGroups = false,
1409
+ compactMode = false,
1405
1410
  className
1406
1411
  }) {
1412
+ const cellPadding = compactMode ? cellPaddingCompact3 : cellPaddingNormal3;
1407
1413
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1408
1414
  "th",
1409
1415
  {
1410
1416
  className: cn(
1411
- "border border-gray-200 px-2 py-1.5 text-center font-bold text-gray-700 group",
1417
+ "border border-gray-200 text-center font-bold text-gray-700 group",
1418
+ compactMode ? "text-[10px]" : "text-xs",
1419
+ cellPadding,
1412
1420
  isPinned ? "z-30" : "z-20",
1413
1421
  className
1414
1422
  ),
@@ -2646,12 +2654,15 @@ var import_react13 = require("react");
2646
2654
  function useSpreadsheetUndoRedo({
2647
2655
  enabled = true,
2648
2656
  maxStackSize = 50,
2649
- autoSave = true
2657
+ autoSave = true,
2658
+ onSave
2650
2659
  }) {
2651
2660
  const [undoStack, setUndoStack] = (0, import_react13.useState)([]);
2652
2661
  const [redoStack, setRedoStack] = (0, import_react13.useState)([]);
2653
2662
  const [hasUnsavedChanges, setHasUnsavedChanges] = (0, import_react13.useState)(false);
2654
2663
  const [saveStatus, setSaveStatus] = (0, import_react13.useState)("saved");
2664
+ const onSaveRef = (0, import_react13.useRef)(onSave);
2665
+ onSaveRef.current = onSave;
2655
2666
  const pushToUndoStack = (0, import_react13.useCallback)(
2656
2667
  (snapshot) => {
2657
2668
  if (!enabled) return;
@@ -2692,19 +2703,36 @@ function useSpreadsheetUndoRedo({
2692
2703
  });
2693
2704
  return nextSnapshot;
2694
2705
  }, [enabled, redoStack, maxStackSize]);
2695
- const handleSave = (0, import_react13.useCallback)(() => {
2696
- if (!hasUnsavedChanges) return;
2706
+ const handleSave = (0, import_react13.useCallback)(async () => {
2707
+ if (!hasUnsavedChanges && !autoSave) return;
2697
2708
  setSaveStatus("saving");
2698
- setTimeout(() => {
2709
+ try {
2710
+ if (onSaveRef.current) {
2711
+ await onSaveRef.current();
2712
+ }
2699
2713
  setSaveStatus("saved");
2700
2714
  setHasUnsavedChanges(false);
2701
- }, 500);
2702
- }, [hasUnsavedChanges]);
2715
+ } catch {
2716
+ setSaveStatus("error");
2717
+ }
2718
+ }, [hasUnsavedChanges, autoSave]);
2703
2719
  const markAsChanged = (0, import_react13.useCallback)(() => {
2704
2720
  setHasUnsavedChanges(true);
2705
2721
  if (autoSave) {
2706
2722
  setSaveStatus("saving");
2707
- setTimeout(() => setSaveStatus("saved"), 500);
2723
+ if (onSaveRef.current) {
2724
+ Promise.resolve(onSaveRef.current()).then(() => {
2725
+ setSaveStatus("saved");
2726
+ setHasUnsavedChanges(false);
2727
+ }).catch(() => {
2728
+ setSaveStatus("error");
2729
+ });
2730
+ } else {
2731
+ setTimeout(() => {
2732
+ setSaveStatus("saved");
2733
+ setHasUnsavedChanges(false);
2734
+ }, 500);
2735
+ }
2708
2736
  } else {
2709
2737
  setSaveStatus("unsaved");
2710
2738
  }
@@ -3355,8 +3383,9 @@ function Spreadsheet({
3355
3383
  defaultPageSize = 25,
3356
3384
  pageSizeOptions = [25, 50, 100, 200],
3357
3385
  defaultZoom = 100,
3358
- autoSave = true,
3359
- compactMode = false,
3386
+ autoSave,
3387
+ onSave,
3388
+ compactMode,
3360
3389
  isLoading = false,
3361
3390
  className,
3362
3391
  emptyMessage = "No data available",
@@ -3440,6 +3469,19 @@ function Spreadsheet({
3440
3469
  externalCellComments,
3441
3470
  onAddCellComment
3442
3471
  });
3472
+ const [showSettingsModal, setShowSettingsModal] = (0, import_react16.useState)(false);
3473
+ const [spreadsheetSettings, setSpreadsheetSettings] = (0, import_react16.useState)({
3474
+ defaultPinnedColumns: [],
3475
+ defaultSort: null,
3476
+ defaultPageSize,
3477
+ defaultZoom,
3478
+ autoSave: autoSave ?? true,
3479
+ compactView: compactMode ?? false,
3480
+ showRowIndex,
3481
+ pinRowIndex: false,
3482
+ rowIndexHighlightColor: void 0
3483
+ });
3484
+ const effectiveAutoSave = autoSave ?? spreadsheetSettings.autoSave;
3443
3485
  const {
3444
3486
  canUndo,
3445
3487
  canRedo,
@@ -3454,7 +3496,8 @@ function Spreadsheet({
3454
3496
  markAsChanged
3455
3497
  } = useSpreadsheetUndoRedo({
3456
3498
  enabled: enableUndoRedo,
3457
- autoSave
3499
+ autoSave: effectiveAutoSave,
3500
+ onSave
3458
3501
  });
3459
3502
  const [selectedRows, setSelectedRows] = (0, import_react16.useState)(/* @__PURE__ */ new Set());
3460
3503
  const [lastSelectedRow, setLastSelectedRow] = (0, import_react16.useState)(null);
@@ -3485,18 +3528,6 @@ function Spreadsheet({
3485
3528
  },
3486
3529
  [controlledPageSize, controlledCurrentPage, onPageChange]
3487
3530
  );
3488
- const [showSettingsModal, setShowSettingsModal] = (0, import_react16.useState)(false);
3489
- const [spreadsheetSettings, setSpreadsheetSettings] = (0, import_react16.useState)({
3490
- defaultPinnedColumns: [],
3491
- defaultSort: null,
3492
- defaultPageSize,
3493
- defaultZoom,
3494
- autoSave,
3495
- compactView: compactMode,
3496
- showRowIndex,
3497
- pinRowIndex: false,
3498
- rowIndexHighlightColor: void 0
3499
- });
3500
3531
  (0, import_react16.useEffect)(() => {
3501
3532
  setSpreadsheetSettings((prev) => ({
3502
3533
  ...prev,
@@ -3546,7 +3577,6 @@ function Spreadsheet({
3546
3577
  }, [filteredData, currentPage, pageSize, serverSide]);
3547
3578
  const {
3548
3579
  focusedCell,
3549
- setFocusedCell,
3550
3580
  editingCell,
3551
3581
  setEditingCell,
3552
3582
  handleCellMouseDown,
@@ -3662,6 +3692,7 @@ function Spreadsheet({
3662
3692
  enabled: true
3663
3693
  });
3664
3694
  const effectiveShowRowIndex = spreadsheetSettings.showRowIndex !== false;
3695
+ const effectiveCompactMode = compactMode ?? spreadsheetSettings.compactView;
3665
3696
  const rowIndexHighlightColor = getColumnHighlight(ROW_INDEX_COLUMN_ID);
3666
3697
  const tableRef = (0, import_react16.useRef)(null);
3667
3698
  const effectiveTotalItems = serverSide ? totalItems ?? data.length : filteredData.length;
@@ -3789,7 +3820,7 @@ function Spreadsheet({
3789
3820
  selectedRowCount: selectedRows.size,
3790
3821
  hasUnsavedChanges,
3791
3822
  saveStatus,
3792
- autoSave,
3823
+ autoSave: effectiveAutoSave,
3793
3824
  hasActiveFilters,
3794
3825
  onClearFilters: clearAllFilters,
3795
3826
  onZoomIn: () => setZoom((z) => Math.min(z + 10, 200)),
@@ -3827,7 +3858,8 @@ function Spreadsheet({
3827
3858
  isPinned: isRowIndexPinned,
3828
3859
  onHighlightClick: handleRowIndexHighlightClick,
3829
3860
  onPinClick: handleToggleRowIndexPin,
3830
- hasColumnGroups: true
3861
+ hasColumnGroups: true,
3862
+ compactMode: effectiveCompactMode
3831
3863
  }
3832
3864
  ),
3833
3865
  columnGroups.map((group) => {
@@ -3870,7 +3902,8 @@ function Spreadsheet({
3870
3902
  isPinned: isRowIndexPinned,
3871
3903
  onHighlightClick: handleRowIndexHighlightClick,
3872
3904
  onPinClick: handleToggleRowIndexPin,
3873
- hasColumnGroups: false
3905
+ hasColumnGroups: false,
3906
+ compactMode: effectiveCompactMode
3874
3907
  }
3875
3908
  ),
3876
3909
  visibleColumns.map((column) => {
@@ -3885,7 +3918,7 @@ function Spreadsheet({
3885
3918
  pinSide: getColumnPinSide(column.id),
3886
3919
  leftOffset: isPinnedLeft ? getColumnLeftOffset(column.id) : 0,
3887
3920
  highlightColor: getColumnHighlight(column.id),
3888
- compactMode,
3921
+ compactMode: effectiveCompactMode,
3889
3922
  onClick: () => handleSort(column.id),
3890
3923
  onFilterClick: () => setActiveFilterColumn(
3891
3924
  activeFilterColumn === column.id ? null : column.id
@@ -3947,6 +3980,7 @@ function Spreadsheet({
3947
3980
  onClick: (e) => handleRowSelect(rowId, e),
3948
3981
  className: cn(
3949
3982
  "border border-gray-200 text-center font-semibold cursor-pointer group",
3983
+ effectiveCompactMode ? "text-[10px] px-1 py-px" : "text-xs px-2 py-1",
3950
3984
  isRowIndexPinned ? "z-20" : "z-0",
3951
3985
  isRowSelected && "bg-blue-100",
3952
3986
  !isRowSelected && rowHighlight && "",
@@ -4118,7 +4152,7 @@ function Spreadsheet({
4118
4152
  isRowSelected,
4119
4153
  isRowHovered,
4120
4154
  highlightColor: cellOrRowOrColumnHighlight,
4121
- compactMode,
4155
+ compactMode: effectiveCompactMode,
4122
4156
  isPinned: isColPinned,
4123
4157
  pinSide: colPinSide,
4124
4158
  leftOffset: getColumnLeftOffset(column.id),