@xcelsior/ui-spreadsheets 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/Spreadsheet.tsx
2
- import { useCallback as useCallback11, useEffect as useEffect8, useMemo as useMemo7, useRef as useRef10, useState as useState16, startTransition } from "react";
2
+ import { useCallback as useCallback11, useEffect as useEffect8, useMemo as useMemo8, useRef as useRef10, useState as useState16, startTransition } from "react";
3
3
 
4
4
  // ../../../node_modules/.pnpm/react-icons@4.12.0_react@18.3.1/node_modules/react-icons/lib/esm/iconBase.js
5
5
  import React2 from "react";
@@ -96,6 +96,9 @@ function HiDotsVertical(props) {
96
96
  function HiExclamation(props) {
97
97
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z", "clipRule": "evenodd" } }] })(props);
98
98
  }
99
+ function HiEyeOff(props) {
100
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z", "clipRule": "evenodd" } }, { "tag": "path", "attr": { "d": "M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z" } }] })(props);
101
+ }
99
102
  function HiEye(props) {
100
103
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "d": "M10 12a2 2 0 100-4 2 2 0 000 4z" } }, { "tag": "path", "attr": { "fillRule": "evenodd", "d": "M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z", "clipRule": "evenodd" } }] })(props);
101
104
  }
@@ -1324,6 +1327,9 @@ var SpreadsheetToolbar = ({
1324
1327
  onClearFilter,
1325
1328
  showFiltersPanel,
1326
1329
  onToggleFiltersPanel,
1330
+ hiddenColumnCount = 0,
1331
+ onShowAllColumns,
1332
+ onManageColumns,
1327
1333
  className
1328
1334
  }) => {
1329
1335
  const [showMoreMenu, setShowMoreMenu] = React3.useState(false);
@@ -1543,6 +1549,31 @@ var SpreadsheetToolbar = ({
1543
1549
  ]
1544
1550
  }
1545
1551
  ),
1552
+ hiddenColumnCount > 0 && /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5 px-2.5 py-1.5 bg-amber-50 border border-amber-200 rounded text-xs text-amber-700", children: [
1553
+ /* @__PURE__ */ jsxs4("span", { className: "font-medium", children: [
1554
+ hiddenColumnCount,
1555
+ " hidden"
1556
+ ] }),
1557
+ /* @__PURE__ */ jsx4(
1558
+ "button",
1559
+ {
1560
+ type: "button",
1561
+ onClick: onShowAllColumns,
1562
+ className: "text-amber-800 underline hover:text-amber-900 transition-colors",
1563
+ children: "Show"
1564
+ }
1565
+ ),
1566
+ /* @__PURE__ */ jsx4("span", { className: "text-amber-300", children: "|" }),
1567
+ /* @__PURE__ */ jsx4(
1568
+ "button",
1569
+ {
1570
+ type: "button",
1571
+ onClick: onManageColumns,
1572
+ className: "text-amber-800 underline hover:text-amber-900 transition-colors",
1573
+ children: "Manage"
1574
+ }
1575
+ )
1576
+ ] }),
1546
1577
  /* @__PURE__ */ jsxs4("div", { className: "relative", ref: menuRef, children: [
1547
1578
  /* @__PURE__ */ jsxs4(
1548
1579
  "button",
@@ -1557,7 +1588,7 @@ var SpreadsheetToolbar = ({
1557
1588
  ]
1558
1589
  }
1559
1590
  ),
1560
- showMoreMenu && /* @__PURE__ */ jsxs4("div", { className: "absolute right-0 top-full mt-1 bg-white border border-gray-200 shadow-lg rounded py-1 min-w-[180px] z-50", children: [
1591
+ showMoreMenu && /* @__PURE__ */ jsxs4("div", { className: "absolute right-0 top-full mt-1 bg-white border border-gray-200 shadow-lg rounded py-1 min-w-[180px] z-[60]", children: [
1561
1592
  onSettings && /* @__PURE__ */ jsxs4(
1562
1593
  "button",
1563
1594
  {
@@ -1644,7 +1675,7 @@ function MdOutlinePushPin(props) {
1644
1675
  }
1645
1676
 
1646
1677
  // src/components/ColumnHeaderActions.tsx
1647
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1678
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1648
1679
  function ColumnHeaderActions({
1649
1680
  enableFiltering = false,
1650
1681
  enableHighlighting = false,
@@ -1666,7 +1697,8 @@ function ColumnHeaderActions({
1666
1697
  resolvedWidth,
1667
1698
  enableDuplicateCheck = false,
1668
1699
  hasDuplicateCheck = false,
1669
- onDuplicateCheckClick
1700
+ onDuplicateCheckClick,
1701
+ onHideClick
1670
1702
  }) {
1671
1703
  const [overflowOpen, setOverflowOpen] = useState3(false);
1672
1704
  const overflowRef = useRef3(null);
@@ -1814,7 +1846,26 @@ function ColumnHeaderActions({
1814
1846
  "Check Duplicates"
1815
1847
  ]
1816
1848
  }
1817
- )
1849
+ ),
1850
+ onHideClick && /* @__PURE__ */ jsxs5(Fragment3, { children: [
1851
+ /* @__PURE__ */ jsx5("div", { className: "border-t border-gray-100 my-1" }),
1852
+ /* @__PURE__ */ jsxs5(
1853
+ "button",
1854
+ {
1855
+ type: "button",
1856
+ onClick: (e) => {
1857
+ e.stopPropagation();
1858
+ onHideClick();
1859
+ setOverflowOpen(false);
1860
+ },
1861
+ className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-gray-100 text-left text-gray-700",
1862
+ children: [
1863
+ /* @__PURE__ */ jsx5(HiEyeOff, { className: "h-3.5 w-3.5 shrink-0" }),
1864
+ "Hide column"
1865
+ ]
1866
+ }
1867
+ )
1868
+ ] })
1818
1869
  ]
1819
1870
  }
1820
1871
  ),
@@ -1902,6 +1953,19 @@ function ColumnHeaderActions({
1902
1953
  title: "Check duplicates",
1903
1954
  children: /* @__PURE__ */ jsx5(HiExclamation, { className: "h-3 w-3" })
1904
1955
  }
1956
+ ),
1957
+ onHideClick && /* @__PURE__ */ jsx5(
1958
+ "button",
1959
+ {
1960
+ type: "button",
1961
+ onClick: (e) => {
1962
+ e.stopPropagation();
1963
+ onHideClick();
1964
+ },
1965
+ className: "p-0.5 hover:bg-gray-200 rounded text-gray-400 opacity-0 group-hover:opacity-100 transition-opacity",
1966
+ title: "Hide column",
1967
+ children: /* @__PURE__ */ jsx5(HiEyeOff, { className: "h-3 w-3" })
1968
+ }
1905
1969
  )
1906
1970
  ] });
1907
1971
  }
@@ -1930,6 +1994,7 @@ var SpreadsheetHeader = ({
1930
1994
  hasDuplicateCheck = false,
1931
1995
  onDuplicateCheckClick,
1932
1996
  duplicateCount,
1997
+ onHideClick,
1933
1998
  resizeHandleProps,
1934
1999
  resolvedWidth,
1935
2000
  topOffset = 0,
@@ -2013,7 +2078,8 @@ var SpreadsheetHeader = ({
2013
2078
  resolvedWidth,
2014
2079
  enableDuplicateCheck: true,
2015
2080
  hasDuplicateCheck,
2016
- onDuplicateCheckClick
2081
+ onDuplicateCheckClick,
2082
+ onHideClick
2017
2083
  }
2018
2084
  )
2019
2085
  ] }),
@@ -2065,7 +2131,8 @@ function useSpreadsheetPinning({
2065
2131
  showRowIndex = true,
2066
2132
  defaultPinnedColumns = [],
2067
2133
  defaultPinnedRightColumns = [],
2068
- getColumnWidth
2134
+ getColumnWidth,
2135
+ hiddenColumns = []
2069
2136
  }) {
2070
2137
  const [pinnedColumns, setPinnedColumns] = useState4(() => {
2071
2138
  const map = /* @__PURE__ */ new Map();
@@ -2152,9 +2219,13 @@ function useSpreadsheetPinning({
2152
2219
  return newSet;
2153
2220
  });
2154
2221
  }, []);
2222
+ const hiddenColumnsSet = useMemo(() => new Set(hiddenColumns), [hiddenColumns]);
2155
2223
  const visibleColumns = useMemo(() => {
2156
2224
  if (!columns || !Array.isArray(columns) || columns.length === 0) return [];
2157
2225
  let result = [...columns];
2226
+ if (hiddenColumnsSet.size > 0) {
2227
+ result = result.filter((column) => !hiddenColumnsSet.has(column.id));
2228
+ }
2158
2229
  if (columnGroups && Array.isArray(columnGroups)) {
2159
2230
  result = result.filter((column) => {
2160
2231
  const group = columnGroups.find((g) => g.columns.includes(column.id));
@@ -2164,7 +2235,7 @@ function useSpreadsheetPinning({
2164
2235
  });
2165
2236
  }
2166
2237
  return result;
2167
- }, [columns, columnGroups, collapsedGroups, pinnedColumns]);
2238
+ }, [columns, columnGroups, collapsedGroups, pinnedColumns, hiddenColumnsSet]);
2168
2239
  useEffect4(() => {
2169
2240
  requestAnimationFrame(() => measureColumnWidths());
2170
2241
  }, [measureColumnWidths, visibleColumns, pinnedColumns]);
@@ -2418,7 +2489,7 @@ function ColorPickerPopover({
2418
2489
  ColorPickerPopover.displayName = "ColorPickerPopover";
2419
2490
 
2420
2491
  // src/components/SpreadsheetSettingsModal.tsx
2421
- import { useState as useState6, useEffect as useEffect5 } from "react";
2492
+ import { useState as useState6, useEffect as useEffect5, useMemo as useMemo2 } from "react";
2422
2493
  import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2423
2494
  var DEFAULT_SETTINGS = {
2424
2495
  defaultPinnedColumns: [],
@@ -2434,14 +2505,24 @@ var SpreadsheetSettingsModal = ({
2434
2505
  settings,
2435
2506
  onSave,
2436
2507
  columns,
2508
+ columnGroups,
2437
2509
  title = "Spreadsheet Settings",
2438
2510
  pageSizeOptions = [25, 50, 100, 200]
2439
2511
  }) => {
2440
- const [activeTab, setActiveTab] = useState6("columns");
2512
+ const [activeTab, setActiveTab] = useState6("visibility");
2441
2513
  const [localSettings, setLocalSettings] = useState6(settings);
2442
2514
  useEffect5(() => {
2443
2515
  setLocalSettings(settings);
2444
2516
  }, [settings]);
2517
+ const hiddenColumnsSet = useMemo2(
2518
+ () => new Set(localSettings.hiddenColumns ?? []),
2519
+ [localSettings.hiddenColumns]
2520
+ );
2521
+ const ungroupedColumns = useMemo2(() => {
2522
+ if (!columnGroups?.length) return columns;
2523
+ const groupedIds = new Set(columnGroups.flatMap((g) => g.columns));
2524
+ return columns.filter((c) => !groupedIds.has(c.id));
2525
+ }, [columns, columnGroups]);
2445
2526
  if (!isOpen) return null;
2446
2527
  const handleSave = () => {
2447
2528
  onSave(localSettings);
@@ -2489,7 +2570,23 @@ var SpreadsheetSettingsModal = ({
2489
2570
  onSave(newSettings);
2490
2571
  }
2491
2572
  };
2573
+ const hiddenCount = hiddenColumnsSet.size;
2574
+ const toggleColumnVisibility = (columnId) => {
2575
+ const isHidden = hiddenColumnsSet.has(columnId);
2576
+ const newHidden = isHidden ? (localSettings.hiddenColumns ?? []).filter((id) => id !== columnId) : [...localSettings.hiddenColumns ?? [], columnId];
2577
+ setLocalSettings({ ...localSettings, hiddenColumns: newHidden });
2578
+ };
2579
+ const setGroupVisibility = (groupColumnIds, visible) => {
2580
+ const currentHidden = new Set(localSettings.hiddenColumns ?? []);
2581
+ if (visible) {
2582
+ groupColumnIds.forEach((id) => currentHidden.delete(id));
2583
+ } else {
2584
+ groupColumnIds.forEach((id) => currentHidden.add(id));
2585
+ }
2586
+ setLocalSettings({ ...localSettings, hiddenColumns: Array.from(currentHidden) });
2587
+ };
2492
2588
  const tabs = [
2589
+ { id: "visibility", label: `Column Visibility${hiddenCount > 0 ? ` (${hiddenCount})` : ""}`, Icon: HiEyeOff },
2493
2590
  { id: "columns", label: "Pinned Columns", Icon: HiViewBoards },
2494
2591
  { id: "sorting", label: "Default Sorting", Icon: HiSortAscending },
2495
2592
  { id: "display", label: "Display Options", Icon: HiEye }
@@ -2512,7 +2609,7 @@ var SpreadsheetSettingsModal = ({
2512
2609
  "aria-label": "Close settings"
2513
2610
  }
2514
2611
  ),
2515
- /* @__PURE__ */ jsxs9("div", { className: "bg-white rounded-lg w-[90%] max-w-[700px] max-h-[90vh] flex flex-col shadow-xl relative z-10", children: [
2612
+ /* @__PURE__ */ jsxs9("div", { className: "bg-white rounded-lg w-[70%] max-w-1/2 max-h-[70vh] flex flex-col shadow-xl relative z-10", children: [
2516
2613
  /* @__PURE__ */ jsxs9("div", { className: "px-6 py-5 border-b border-gray-200 flex items-center justify-between", children: [
2517
2614
  /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
2518
2615
  /* @__PURE__ */ jsx9(HiCog, { className: "h-6 w-6 text-blue-600" }),
@@ -2542,6 +2639,131 @@ var SpreadsheetSettingsModal = ({
2542
2639
  tab.id
2543
2640
  )) }),
2544
2641
  /* @__PURE__ */ jsxs9("div", { className: "flex-1 overflow-auto p-6", children: [
2642
+ activeTab === "visibility" && /* @__PURE__ */ jsxs9("div", { children: [
2643
+ /* @__PURE__ */ jsxs9("div", { className: "p-4 bg-amber-50 border border-amber-200 rounded-lg mb-4 flex gap-3", children: [
2644
+ /* @__PURE__ */ jsx9(HiEyeOff, { className: "h-4 w-4 text-amber-600 shrink-0 mt-0.5" }),
2645
+ /* @__PURE__ */ jsxs9("div", { children: [
2646
+ /* @__PURE__ */ jsx9("p", { className: "text-sm font-semibold text-gray-900 mb-1", children: "Column Visibility" }),
2647
+ /* @__PURE__ */ jsxs9("p", { className: "text-sm text-gray-600", children: [
2648
+ "Toggle columns on or off. Hidden columns are removed from the table but their data is preserved.",
2649
+ hiddenCount > 0 && /* @__PURE__ */ jsxs9("span", { className: "ml-1 font-medium text-amber-700", children: [
2650
+ hiddenCount,
2651
+ " column",
2652
+ hiddenCount !== 1 ? "s" : "",
2653
+ " hidden."
2654
+ ] })
2655
+ ] })
2656
+ ] })
2657
+ ] }),
2658
+ /* @__PURE__ */ jsxs9("div", { className: "flex gap-2 mb-4", children: [
2659
+ /* @__PURE__ */ jsx9(
2660
+ "button",
2661
+ {
2662
+ type: "button",
2663
+ onClick: () => setLocalSettings({ ...localSettings, hiddenColumns: [] }),
2664
+ className: "px-3 py-1.5 text-xs font-medium text-green-700 bg-green-50 border border-green-200 rounded-lg hover:bg-green-100 transition-colors",
2665
+ children: "Show All"
2666
+ }
2667
+ ),
2668
+ /* @__PURE__ */ jsx9(
2669
+ "button",
2670
+ {
2671
+ type: "button",
2672
+ onClick: () => setLocalSettings({
2673
+ ...localSettings,
2674
+ hiddenColumns: columns.map((c) => c.id)
2675
+ }),
2676
+ className: "px-3 py-1.5 text-xs font-medium text-red-700 bg-red-50 border border-red-200 rounded-lg hover:bg-red-100 transition-colors",
2677
+ children: "Hide All"
2678
+ }
2679
+ )
2680
+ ] }),
2681
+ columnGroups?.map((group) => {
2682
+ const groupCols = columns.filter((c) => group.columns.includes(c.id));
2683
+ if (groupCols.length === 0) return null;
2684
+ const hiddenInGroup = groupCols.filter((c) => hiddenColumnsSet.has(c.id)).length;
2685
+ const allHidden = hiddenInGroup === groupCols.length;
2686
+ const allVisible = hiddenInGroup === 0;
2687
+ return /* @__PURE__ */ jsxs9("div", { className: "mb-4", children: [
2688
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between mb-2", children: [
2689
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
2690
+ /* @__PURE__ */ jsx9(
2691
+ "div",
2692
+ {
2693
+ className: "w-3 h-3 rounded-sm",
2694
+ style: { backgroundColor: group.headerColor }
2695
+ }
2696
+ ),
2697
+ /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-gray-900", children: group.label }),
2698
+ /* @__PURE__ */ jsxs9("span", { className: "text-xs text-gray-500", children: [
2699
+ "(",
2700
+ groupCols.length - hiddenInGroup,
2701
+ "/",
2702
+ groupCols.length,
2703
+ ")"
2704
+ ] })
2705
+ ] }),
2706
+ /* @__PURE__ */ jsxs9("div", { className: "flex gap-1", children: [
2707
+ /* @__PURE__ */ jsx9(
2708
+ "button",
2709
+ {
2710
+ type: "button",
2711
+ onClick: () => setGroupVisibility(group.columns, true),
2712
+ disabled: allVisible,
2713
+ className: "px-2 py-0.5 text-xs text-green-700 hover:bg-green-50 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
2714
+ children: "Show all"
2715
+ }
2716
+ ),
2717
+ /* @__PURE__ */ jsx9(
2718
+ "button",
2719
+ {
2720
+ type: "button",
2721
+ onClick: () => setGroupVisibility(group.columns, false),
2722
+ disabled: allHidden,
2723
+ className: "px-2 py-0.5 text-xs text-red-700 hover:bg-red-50 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
2724
+ children: "Hide all"
2725
+ }
2726
+ )
2727
+ ] })
2728
+ ] }),
2729
+ /* @__PURE__ */ jsx9("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2", children: groupCols.map((column) => {
2730
+ const isHidden = hiddenColumnsSet.has(column.id);
2731
+ return /* @__PURE__ */ jsxs9(
2732
+ "button",
2733
+ {
2734
+ type: "button",
2735
+ onClick: () => toggleColumnVisibility(column.id),
2736
+ className: `flex items-center gap-2 p-3 rounded-lg border transition-colors text-left ${isHidden ? "bg-gray-100 border-gray-200 text-gray-400" : "bg-green-50 border-green-300 text-green-800"}`,
2737
+ children: [
2738
+ isHidden ? /* @__PURE__ */ jsx9(HiEyeOff, { className: "h-4 w-4 shrink-0" }) : /* @__PURE__ */ jsx9(HiEye, { className: "h-4 w-4 shrink-0" }),
2739
+ /* @__PURE__ */ jsx9("span", { className: "text-sm flex-1 truncate", children: column.label })
2740
+ ]
2741
+ },
2742
+ column.id
2743
+ );
2744
+ }) })
2745
+ ] }, group.id);
2746
+ }),
2747
+ ungroupedColumns.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "mb-4", children: [
2748
+ columnGroups?.length ? /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2 mb-2", children: /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-gray-900", children: "Other" }) }) : null,
2749
+ /* @__PURE__ */ jsx9("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2", children: ungroupedColumns.map((column) => {
2750
+ const isHidden = hiddenColumnsSet.has(column.id);
2751
+ return /* @__PURE__ */ jsxs9(
2752
+ "button",
2753
+ {
2754
+ type: "button",
2755
+ onClick: () => toggleColumnVisibility(column.id),
2756
+ className: `flex items-center gap-2 p-3 rounded-lg border transition-colors text-left ${isHidden ? "bg-gray-100 border-gray-200 text-gray-400" : "bg-green-50 border-green-300 text-green-800"}`,
2757
+ children: [
2758
+ isHidden ? /* @__PURE__ */ jsx9(HiEyeOff, { className: "h-4 w-4 shrink-0" }) : /* @__PURE__ */ jsx9(HiEye, { className: "h-4 w-4 shrink-0" }),
2759
+ /* @__PURE__ */ jsx9("span", { className: "text-sm flex-1 truncate", children: column.label })
2760
+ ]
2761
+ },
2762
+ column.id
2763
+ );
2764
+ }) })
2765
+ ] })
2766
+ ] }),
2545
2767
  activeTab === "columns" && /* @__PURE__ */ jsxs9("div", { children: [
2546
2768
  /* @__PURE__ */ jsxs9("div", { className: "p-4 bg-blue-50 border border-blue-200 rounded-lg mb-4 flex gap-3", children: [
2547
2769
  /* @__PURE__ */ jsx9(HiViewBoards, { className: "h-4 w-4 text-blue-600 shrink-0 mt-0.5" }),
@@ -2972,7 +3194,7 @@ function ShortcutRow({ label, keys }) {
2972
3194
  KeyboardShortcutsModal.displayName = "KeyboardShortcutsModal";
2973
3195
 
2974
3196
  // src/components/RowContextMenu.tsx
2975
- import { useMemo as useMemo2 } from "react";
3197
+ import { useMemo as useMemo3 } from "react";
2976
3198
  import { ContextMenu, ContextMenuItem } from "@xcelsior/design-system";
2977
3199
  import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2978
3200
  function RowContextMenu({
@@ -2982,7 +3204,7 @@ function RowContextMenu({
2982
3204
  compactMode = false,
2983
3205
  className
2984
3206
  }) {
2985
- const visibleItems = useMemo2(() => {
3207
+ const visibleItems = useMemo3(() => {
2986
3208
  return items.filter((item) => !item.visible || item.visible(row));
2987
3209
  }, [items, row]);
2988
3210
  if (visibleItems.length === 0) {
@@ -3038,7 +3260,7 @@ RowContextMenu.displayName = "RowContextMenu";
3038
3260
  import { Pagination } from "@xcelsior/design-system";
3039
3261
 
3040
3262
  // src/hooks/useSpreadsheetFiltering.ts
3041
- import { useCallback as useCallback4, useMemo as useMemo3, useState as useState8 } from "react";
3263
+ import { useCallback as useCallback4, useMemo as useMemo4, useState as useState8 } from "react";
3042
3264
  import { FilterChain, LazyArray } from "@xcelsior/utils";
3043
3265
  function useSpreadsheetFiltering({
3044
3266
  data,
@@ -3239,7 +3461,7 @@ function useSpreadsheetFiltering({
3239
3461
  },
3240
3462
  [sortConfig?.columnId]
3241
3463
  );
3242
- const filteredData = useMemo3(() => {
3464
+ const filteredData = useMemo4(() => {
3243
3465
  if (!data || !Array.isArray(data)) return LazyArray.empty();
3244
3466
  if (serverSide) {
3245
3467
  return LazyArray.from(data);
@@ -3340,7 +3562,7 @@ function useSpreadsheetFiltering({
3340
3562
  }
3341
3563
 
3342
3564
  // src/hooks/useSpreadsheetDuplicates.ts
3343
- import { useCallback as useCallback5, useMemo as useMemo4, useState as useState9 } from "react";
3565
+ import { useCallback as useCallback5, useMemo as useMemo5, useState as useState9 } from "react";
3344
3566
  function normalizeValue(value) {
3345
3567
  if (value === null || value === void 0 || value === "") {
3346
3568
  return "__blank__";
@@ -3359,10 +3581,10 @@ function useSpreadsheetDuplicates({
3359
3581
  const [localDuplicateCheckColumns, setLocalDuplicateCheckColumns] = useState9(
3360
3582
  () => new Set(duplicateCheckColumns)
3361
3583
  );
3362
- const duplicateCheckColumnsSet = useMemo4(() => {
3584
+ const duplicateCheckColumnsSet = useMemo5(() => {
3363
3585
  return new Set(duplicateCheckColumns);
3364
3586
  }, [duplicateCheckColumns]);
3365
- const { duplicateRowIds, valueCounts } = useMemo4(() => {
3587
+ const { duplicateRowIds, valueCounts } = useMemo5(() => {
3366
3588
  const duplicateRowIds2 = /* @__PURE__ */ new Map();
3367
3589
  const valueCounts2 = /* @__PURE__ */ new Map();
3368
3590
  const activeColumns = duplicateCheckColumnsSet.size > 0 ? duplicateCheckColumnsSet : localDuplicateCheckColumns;
@@ -3965,7 +4187,7 @@ function useSpreadsheetKeyboardShortcuts({
3965
4187
  }
3966
4188
 
3967
4189
  // src/hooks/useSpreadsheetSelection.ts
3968
- import { useCallback as useCallback9, useState as useState14, useRef as useRef8, useMemo as useMemo5 } from "react";
4190
+ import { useCallback as useCallback9, useState as useState14, useRef as useRef8, useMemo as useMemo6 } from "react";
3969
4191
  function useSpreadsheetSelection({
3970
4192
  data,
3971
4193
  columns,
@@ -3979,14 +4201,14 @@ function useSpreadsheetSelection({
3979
4201
  const [isDragging, setIsDragging] = useState14(false);
3980
4202
  const [clipboardData, setClipboardData] = useState14(null);
3981
4203
  const anchorCell = useRef8(null);
3982
- const rowIndexMap = useMemo5(() => {
4204
+ const rowIndexMap = useMemo6(() => {
3983
4205
  const map = /* @__PURE__ */ new Map();
3984
4206
  data.forEach((row, index) => {
3985
4207
  map.set(getRowId(row), index);
3986
4208
  });
3987
4209
  return map;
3988
4210
  }, [data, getRowId]);
3989
- const columnIndexMap = useMemo5(() => {
4211
+ const columnIndexMap = useMemo6(() => {
3990
4212
  const map = /* @__PURE__ */ new Map();
3991
4213
  columns.forEach((col, index) => {
3992
4214
  map.set(col.id, index);
@@ -4385,12 +4607,12 @@ function useSpreadsheetSelection({
4385
4607
  }
4386
4608
 
4387
4609
  // src/hooks/useSpreadsheetSummary.ts
4388
- import { useMemo as useMemo6 } from "react";
4610
+ import { useMemo as useMemo7 } from "react";
4389
4611
  function useSpreadsheetSummary({
4390
4612
  selectedCellValues,
4391
4613
  columns
4392
4614
  }) {
4393
- const summary = useMemo6(() => {
4615
+ const summary = useMemo7(() => {
4394
4616
  if (selectedCellValues.length === 0) return null;
4395
4617
  const numericValues = [];
4396
4618
  for (const { position, value } of selectedCellValues) {
@@ -4512,7 +4734,7 @@ function useSpreadsheetColumnResize({
4512
4734
  }
4513
4735
 
4514
4736
  // src/components/SelectionSummaryBar.tsx
4515
- import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
4737
+ import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
4516
4738
  function SelectionSummaryBar({
4517
4739
  summary,
4518
4740
  focusedCell,
@@ -4539,7 +4761,7 @@ function SelectionSummaryBar({
4539
4761
  }
4540
4762
  if (!addressDisplay && !summary) return null;
4541
4763
  return /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between px-3 py-1.5 bg-gray-50 border-t border-gray-200 text-xs text-gray-600", children: [
4542
- /* @__PURE__ */ jsx13("div", { className: "flex items-center gap-2 min-w-0", children: addressDisplay && /* @__PURE__ */ jsxs13(Fragment3, { children: [
4764
+ /* @__PURE__ */ jsx13("div", { className: "flex items-center gap-2 min-w-0", children: addressDisplay && /* @__PURE__ */ jsxs13(Fragment4, { children: [
4543
4765
  /* @__PURE__ */ jsx13("span", { className: "font-medium text-gray-500 bg-white px-2 py-0.5 rounded border border-gray-200 shrink-0", children: addressDisplay }),
4544
4766
  valueDisplay && /* @__PURE__ */ jsx13("span", { className: "text-gray-700 truncate", title: valueDisplay, children: valueDisplay })
4545
4767
  ] }) }),
@@ -4626,7 +4848,8 @@ function Spreadsheet({
4626
4848
  defaultPageSize: initialSettings?.defaultPageSize ?? 25,
4627
4849
  defaultZoom: initialSettings?.defaultZoom ?? 100,
4628
4850
  autoSave: initialSettings?.autoSave ?? true,
4629
- compactView: initialSettings?.compactView ?? false
4851
+ compactView: initialSettings?.compactView ?? false,
4852
+ hiddenColumns: initialSettings?.hiddenColumns ?? []
4630
4853
  });
4631
4854
  const {
4632
4855
  isCellDuplicate,
@@ -4653,6 +4876,15 @@ function Spreadsheet({
4653
4876
  },
4654
4877
  [toggleDuplicateCheck, duplicateCheckColumns, onDuplicateCheckChange]
4655
4878
  );
4879
+ const handleHideColumn = useCallback11(
4880
+ (columnId) => {
4881
+ setSpreadsheetSettings((prev) => ({
4882
+ ...prev,
4883
+ hiddenColumns: [...prev.hiddenColumns ?? [], columnId]
4884
+ }));
4885
+ },
4886
+ []
4887
+ );
4656
4888
  const [isProcessing, setIsProcessing] = useState16(false);
4657
4889
  const {
4658
4890
  filters,
@@ -4727,7 +4959,8 @@ function Spreadsheet({
4727
4959
  columnGroups,
4728
4960
  defaultPinnedColumns: initialSettings?.defaultPinnedColumns,
4729
4961
  defaultPinnedRightColumns: initialSettings?.defaultPinnedRightColumns,
4730
- getColumnWidth
4962
+ getColumnWidth,
4963
+ hiddenColumns: spreadsheetSettings.hiddenColumns
4731
4964
  });
4732
4965
  const {
4733
4966
  getCellComments,
@@ -4883,7 +5116,7 @@ function Spreadsheet({
4883
5116
  }
4884
5117
  markAsChanged();
4885
5118
  }, [popRedoEntry, onCellsEdit, markAsChanged]);
4886
- const paginatedData = useMemo7(() => {
5119
+ const paginatedData = useMemo8(() => {
4887
5120
  if (serverSide) {
4888
5121
  return filteredData.toArray();
4889
5122
  }
@@ -4915,7 +5148,7 @@ function Spreadsheet({
4915
5148
  getRowId,
4916
5149
  enableCellEditing
4917
5150
  });
4918
- const selectedCellValues = useMemo7(() => getSelectedCellValues(), [getSelectedCellValues]);
5151
+ const selectedCellValues = useMemo8(() => getSelectedCellValues(), [getSelectedCellValues]);
4919
5152
  const { summary: selectionSummary, hasNumericValues } = useSpreadsheetSummary({
4920
5153
  selectedCellValues,
4921
5154
  columns: visibleColumns
@@ -5154,7 +5387,7 @@ function Spreadsheet({
5154
5387
  const handleRowIndexHighlightClick = useCallback11(() => {
5155
5388
  setHighlightPickerColumn(ROW_INDEX_COLUMN_ID);
5156
5389
  }, [setHighlightPickerColumn]);
5157
- const columnRenderItems = useMemo7(() => {
5390
+ const columnRenderItems = useMemo8(() => {
5158
5391
  if (!columnGroups || columnGroups.length === 0) {
5159
5392
  return visibleColumns.map((col) => ({
5160
5393
  type: "column",
@@ -5184,7 +5417,7 @@ function Spreadsheet({
5184
5417
  }
5185
5418
  return items;
5186
5419
  }, [columnGroups, collapsedGroups, visibleColumns]);
5187
- const groupHeaderItems = useMemo7(() => {
5420
+ const groupHeaderItems = useMemo8(() => {
5188
5421
  if (!columnGroups || columnGroups.length === 0) return null;
5189
5422
  const items = [];
5190
5423
  for (const group of columnGroups) {
@@ -5235,7 +5468,12 @@ function Spreadsheet({
5235
5468
  onSave: handleSave,
5236
5469
  onSettings: () => setShowSettingsModal(true),
5237
5470
  onShowShortcuts: () => setShowKeyboardShortcuts(true),
5238
- menuItems: toolbarMenuItems
5471
+ menuItems: toolbarMenuItems,
5472
+ hiddenColumnCount: spreadsheetSettings.hiddenColumns?.length ?? 0,
5473
+ onShowAllColumns: () => {
5474
+ setSpreadsheetSettings((prev) => ({ ...prev, hiddenColumns: [] }));
5475
+ },
5476
+ onManageColumns: () => setShowSettingsModal(true)
5239
5477
  }
5240
5478
  ),
5241
5479
  /* @__PURE__ */ jsxs14("div", { ref: tableRef, className: cn("flex-1 overflow-auto border border-gray-200 rounded spreadsheet-scroll-container relative", isResizing && "select-none"), onMouseUp: handleMouseUp, children: [
@@ -5343,6 +5581,7 @@ function Spreadsheet({
5343
5581
  activeFilterColumn === column.id ? null : column.id
5344
5582
  ),
5345
5583
  onPinClick: () => handleTogglePin(column.id),
5584
+ onHideClick: () => handleHideColumn(column.id),
5346
5585
  onHighlightClick: enableHighlighting ? () => setHighlightPickerColumn(column.id) : void 0,
5347
5586
  resizeHandleProps: getResizeHandleProps(
5348
5587
  column.id,
@@ -5788,6 +6027,7 @@ function Spreadsheet({
5788
6027
  onSettingsChange?.(newSettings);
5789
6028
  },
5790
6029
  columns: columns || [],
6030
+ columnGroups,
5791
6031
  title: "Spreadsheet Settings",
5792
6032
  pageSizeOptions
5793
6033
  }