@xcelsior/ui-spreadsheets 1.1.13 → 1.1.15

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.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ ActiveFiltersDisplay: () => ActiveFiltersDisplay,
33
34
  RowContextMenu: () => RowContextMenu,
34
35
  Spreadsheet: () => Spreadsheet,
35
36
  SpreadsheetCell: () => MemoizedSpreadsheetCell,
@@ -187,7 +188,162 @@ function cn(...inputs) {
187
188
  }
188
189
 
189
190
  // src/components/SpreadsheetCell.tsx
191
+ var import_react4 = require("react");
192
+
193
+ // src/hooks/useSpreadsheetPinning.ts
190
194
  var import_react3 = require("react");
195
+ var ROW_INDEX_COLUMN_ID = "__row_index__";
196
+ var ROW_INDEX_COLUMN_WIDTH = 80;
197
+ var MIN_PINNED_COLUMN_WIDTH = 150;
198
+ function useSpreadsheetPinning({
199
+ columns,
200
+ columnGroups,
201
+ showRowIndex = true,
202
+ defaultPinnedColumns = [],
203
+ defaultPinnedRightColumns = []
204
+ }) {
205
+ const [pinnedColumns, setPinnedColumns] = (0, import_react3.useState)(() => {
206
+ const map = /* @__PURE__ */ new Map();
207
+ defaultPinnedColumns.forEach((col) => {
208
+ map.set(col, "left");
209
+ });
210
+ defaultPinnedRightColumns.forEach((col) => {
211
+ map.set(col, "right");
212
+ });
213
+ return map;
214
+ });
215
+ const [collapsedGroups, setCollapsedGroups] = (0, import_react3.useState)(/* @__PURE__ */ new Set());
216
+ const isRowIndexPinned = pinnedColumns.has(ROW_INDEX_COLUMN_ID);
217
+ const handleTogglePin = (0, import_react3.useCallback)((columnId) => {
218
+ setPinnedColumns((prev) => {
219
+ const newMap = new Map(prev);
220
+ if (newMap.has(columnId)) {
221
+ newMap.delete(columnId);
222
+ } else {
223
+ newMap.set(columnId, "left");
224
+ }
225
+ return newMap;
226
+ });
227
+ }, []);
228
+ const setPinnedColumnsFromIds = (0, import_react3.useCallback)((columnIds) => {
229
+ const map = /* @__PURE__ */ new Map();
230
+ columnIds.forEach((col) => {
231
+ map.set(col, "left");
232
+ });
233
+ setPinnedColumns(map);
234
+ }, []);
235
+ const handleToggleGroupCollapse = (0, import_react3.useCallback)((groupId) => {
236
+ setCollapsedGroups((prev) => {
237
+ const newSet = new Set(prev);
238
+ if (newSet.has(groupId)) {
239
+ newSet.delete(groupId);
240
+ } else {
241
+ newSet.add(groupId);
242
+ }
243
+ return newSet;
244
+ });
245
+ }, []);
246
+ const visibleColumns = (0, import_react3.useMemo)(() => {
247
+ if (!columns || !Array.isArray(columns) || columns.length === 0) {
248
+ return [];
249
+ }
250
+ let result = [...columns];
251
+ if (columnGroups && Array.isArray(columnGroups)) {
252
+ result = result.filter((column) => {
253
+ const group = columnGroups.find((g) => g.columns.includes(column.id));
254
+ if (!group) return true;
255
+ if (!collapsedGroups.has(group.id)) return true;
256
+ return pinnedColumns.has(column.id);
257
+ });
258
+ }
259
+ const nonRowIndexPinned = Array.from(pinnedColumns.keys()).filter(
260
+ (id) => id !== ROW_INDEX_COLUMN_ID
261
+ );
262
+ if (nonRowIndexPinned.length === 0) {
263
+ return result;
264
+ }
265
+ const leftPinned = [];
266
+ const unpinned = [];
267
+ const rightPinned = [];
268
+ const pinnedLeftIds = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "left" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
269
+ const pinnedRightIds = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "right" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
270
+ for (const column of result) {
271
+ const pinSide = pinnedColumns.get(column.id);
272
+ if (pinSide === "left") {
273
+ leftPinned.push(column);
274
+ } else if (pinSide === "right") {
275
+ rightPinned.push(column);
276
+ } else {
277
+ unpinned.push(column);
278
+ }
279
+ }
280
+ leftPinned.sort((a, b) => pinnedLeftIds.indexOf(a.id) - pinnedLeftIds.indexOf(b.id));
281
+ rightPinned.sort((a, b) => pinnedRightIds.indexOf(a.id) - pinnedRightIds.indexOf(b.id));
282
+ return [...leftPinned, ...unpinned, ...rightPinned];
283
+ }, [columns, columnGroups, collapsedGroups, pinnedColumns]);
284
+ const getColumnLeftOffset = (0, import_react3.useCallback)(
285
+ (columnId) => {
286
+ if (columnId === ROW_INDEX_COLUMN_ID) {
287
+ return 0;
288
+ }
289
+ const pinnedLeft = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "left" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
290
+ const index = pinnedLeft.indexOf(columnId);
291
+ const isRowIndexPinnedNow = pinnedColumns.has(ROW_INDEX_COLUMN_ID);
292
+ const baseOffset = showRowIndex && isRowIndexPinnedNow ? ROW_INDEX_COLUMN_WIDTH : 0;
293
+ if (index === -1) return baseOffset;
294
+ let offset = baseOffset;
295
+ for (let i = 0; i < index; i++) {
296
+ const col = columns.find((c) => c.id === pinnedLeft[i]);
297
+ const configuredWidth = col?.minWidth || col?.width || MIN_PINNED_COLUMN_WIDTH;
298
+ offset += Math.max(configuredWidth, MIN_PINNED_COLUMN_WIDTH);
299
+ }
300
+ return offset;
301
+ },
302
+ [pinnedColumns, columns, showRowIndex]
303
+ );
304
+ const isColumnPinned = (0, import_react3.useCallback)(
305
+ (columnId) => {
306
+ return pinnedColumns.has(columnId);
307
+ },
308
+ [pinnedColumns]
309
+ );
310
+ const getColumnPinSide = (0, import_react3.useCallback)(
311
+ (columnId) => {
312
+ return pinnedColumns.get(columnId);
313
+ },
314
+ [pinnedColumns]
315
+ );
316
+ const getColumnRightOffset = (0, import_react3.useCallback)(
317
+ (columnId) => {
318
+ const pinnedRight = Array.from(pinnedColumns.entries()).filter(([, side]) => side === "right").map(([id]) => id);
319
+ const index = pinnedRight.indexOf(columnId);
320
+ if (index === -1) return 0;
321
+ let offset = 0;
322
+ for (let i = pinnedRight.length - 1; i > index; i--) {
323
+ const col = columns.find((c) => c.id === pinnedRight[i]);
324
+ const configuredWidth = col?.minWidth || col?.width || MIN_PINNED_COLUMN_WIDTH;
325
+ offset += Math.max(configuredWidth, MIN_PINNED_COLUMN_WIDTH);
326
+ }
327
+ return offset;
328
+ },
329
+ [pinnedColumns, columns]
330
+ );
331
+ return {
332
+ pinnedColumns,
333
+ isRowIndexPinned,
334
+ collapsedGroups,
335
+ visibleColumns,
336
+ handleTogglePin,
337
+ handleToggleGroupCollapse,
338
+ setPinnedColumnsFromIds,
339
+ getColumnLeftOffset,
340
+ getColumnRightOffset,
341
+ isColumnPinned,
342
+ getColumnPinSide
343
+ };
344
+ }
345
+
346
+ // src/components/SpreadsheetCell.tsx
191
347
  var import_jsx_runtime = require("react/jsx-runtime");
192
348
  var cellPaddingCompact = "px-1 py-px";
193
349
  var cellPaddingNormal = "px-2 py-1";
@@ -224,13 +380,13 @@ var SpreadsheetCell = ({
224
380
  onViewComments,
225
381
  className
226
382
  }) => {
227
- const [localValue, setLocalValue] = (0, import_react3.useState)(value);
228
- const inputRef = (0, import_react3.useRef)(null);
229
- const selectRef = (0, import_react3.useRef)(null);
230
- (0, import_react3.useEffect)(() => {
383
+ const [localValue, setLocalValue] = (0, import_react4.useState)(value);
384
+ const inputRef = (0, import_react4.useRef)(null);
385
+ const selectRef = (0, import_react4.useRef)(null);
386
+ (0, import_react4.useEffect)(() => {
231
387
  setLocalValue(value);
232
388
  }, [value]);
233
- (0, import_react3.useEffect)(() => {
389
+ (0, import_react4.useEffect)(() => {
234
390
  if (isEditing) {
235
391
  if (column.type === "select") {
236
392
  selectRef.current?.focus();
@@ -403,6 +559,18 @@ var SpreadsheetCell = ({
403
559
  style: {
404
560
  backgroundColor: isInSelection ? "rgb(239 246 255)" : getBackgroundColor(),
405
561
  minWidth: column.minWidth || column.width,
562
+ // Pinned columns must have a fixed width so sticky offsets stay correct.
563
+ // Enforce MIN_PINNED_COLUMN_WIDTH so header actions always fit.
564
+ ...isPinned && {
565
+ width: Math.max(
566
+ column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH,
567
+ MIN_PINNED_COLUMN_WIDTH
568
+ ),
569
+ maxWidth: Math.max(
570
+ column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH,
571
+ MIN_PINNED_COLUMN_WIDTH
572
+ )
573
+ },
406
574
  ...positionStyles,
407
575
  ...selectionBorderStyles
408
576
  },
@@ -474,7 +642,7 @@ var SpreadsheetCell = ({
474
642
  );
475
643
  };
476
644
  SpreadsheetCell.displayName = "SpreadsheetCell";
477
- var MemoizedSpreadsheetCell = (0, import_react3.memo)(SpreadsheetCell, (prevProps, nextProps) => {
645
+ var MemoizedSpreadsheetCell = (0, import_react4.memo)(SpreadsheetCell, (prevProps, nextProps) => {
478
646
  if (prevProps.isEditing !== nextProps.isEditing) return false;
479
647
  if (prevProps.isFocused !== nextProps.isFocused) return false;
480
648
  if (prevProps.value !== nextProps.value) return false;
@@ -503,7 +671,7 @@ var MemoizedSpreadsheetCell = (0, import_react3.memo)(SpreadsheetCell, (prevProp
503
671
  MemoizedSpreadsheetCell.displayName = "MemoizedSpreadsheetCell";
504
672
 
505
673
  // src/components/SpreadsheetFilterDropdown.tsx
506
- var import_react4 = require("react");
674
+ var import_react5 = require("react");
507
675
  var import_jsx_runtime2 = require("react/jsx-runtime");
508
676
  var TEXT_OPERATORS = [
509
677
  { value: "contains", label: "Contains" },
@@ -549,28 +717,28 @@ var SpreadsheetFilterDropdown = ({
549
717
  onClose,
550
718
  className
551
719
  }) => {
552
- const [textOperator, setTextOperator] = (0, import_react4.useState)(
720
+ const [textOperator, setTextOperator] = (0, import_react5.useState)(
553
721
  filter?.textCondition?.operator || "contains"
554
722
  );
555
- const [textValue, setTextValue] = (0, import_react4.useState)(filter?.textCondition?.value || "");
556
- const [numberOperator, setNumberOperator] = (0, import_react4.useState)(
723
+ const [textValue, setTextValue] = (0, import_react5.useState)(filter?.textCondition?.value || "");
724
+ const [numberOperator, setNumberOperator] = (0, import_react5.useState)(
557
725
  filter?.numberCondition?.operator || "equals"
558
726
  );
559
- const [numberValue, setNumberValue] = (0, import_react4.useState)(
727
+ const [numberValue, setNumberValue] = (0, import_react5.useState)(
560
728
  filter?.numberCondition?.value?.toString() || ""
561
729
  );
562
- const [numberValueTo, setNumberValueTo] = (0, import_react4.useState)(
730
+ const [numberValueTo, setNumberValueTo] = (0, import_react5.useState)(
563
731
  filter?.numberCondition?.valueTo?.toString() || ""
564
732
  );
565
- const [dateOperator, setDateOperator] = (0, import_react4.useState)(
733
+ const [dateOperator, setDateOperator] = (0, import_react5.useState)(
566
734
  filter?.dateCondition?.operator || "equals"
567
735
  );
568
- const [dateValue, setDateValue] = (0, import_react4.useState)(filter?.dateCondition?.value || "");
569
- const [dateValueTo, setDateValueTo] = (0, import_react4.useState)(filter?.dateCondition?.valueTo || "");
570
- const dropdownRef = (0, import_react4.useRef)(null);
736
+ const [dateValue, setDateValue] = (0, import_react5.useState)(filter?.dateCondition?.value || "");
737
+ const [dateValueTo, setDateValueTo] = (0, import_react5.useState)(filter?.dateCondition?.valueTo || "");
738
+ const dropdownRef = (0, import_react5.useRef)(null);
571
739
  const isNumeric = column.type === "number";
572
740
  const isDate = column.type === "date";
573
- (0, import_react4.useEffect)(() => {
741
+ (0, import_react5.useEffect)(() => {
574
742
  const handleClickOutside = (event) => {
575
743
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
576
744
  onClose();
@@ -808,8 +976,199 @@ var SpreadsheetFilterDropdown = ({
808
976
  SpreadsheetFilterDropdown.displayName = "SpreadsheetFilterDropdown";
809
977
 
810
978
  // src/components/SpreadsheetToolbar.tsx
811
- var import_react5 = __toESM(require("react"));
979
+ var import_react6 = __toESM(require("react"));
980
+
981
+ // src/components/ActiveFiltersDisplay.tsx
812
982
  var import_jsx_runtime3 = require("react/jsx-runtime");
983
+ var TEXT_OPERATOR_LABELS = {
984
+ contains: "contains",
985
+ notContains: "does not contain",
986
+ equals: "equals",
987
+ notEquals: "does not equal",
988
+ startsWith: "starts with",
989
+ endsWith: "ends with",
990
+ isEmpty: "is empty",
991
+ isNotEmpty: "is not empty"
992
+ };
993
+ var NUMBER_OPERATOR_LABELS = {
994
+ equals: "=",
995
+ notEquals: "\u2260",
996
+ greaterThan: ">",
997
+ greaterThanOrEqual: "\u2265",
998
+ lessThan: "<",
999
+ lessThanOrEqual: "\u2264",
1000
+ between: "between",
1001
+ isEmpty: "is empty",
1002
+ isNotEmpty: "is not empty"
1003
+ };
1004
+ var DATE_OPERATOR_LABELS = {
1005
+ equals: "is",
1006
+ notEquals: "is not",
1007
+ before: "before",
1008
+ after: "after",
1009
+ between: "between",
1010
+ today: "is today",
1011
+ yesterday: "is yesterday",
1012
+ thisWeek: "is this week",
1013
+ lastWeek: "is last week",
1014
+ thisMonth: "is this month",
1015
+ lastMonth: "is last month",
1016
+ thisYear: "is this year",
1017
+ isEmpty: "is empty",
1018
+ isNotEmpty: "is not empty"
1019
+ };
1020
+ function formatFilter(filter, _column) {
1021
+ const parts = [];
1022
+ if (filter.textCondition) {
1023
+ const { operator, value } = filter.textCondition;
1024
+ const label = TEXT_OPERATOR_LABELS[operator];
1025
+ if (["isEmpty", "isNotEmpty"].includes(operator)) {
1026
+ parts.push(label);
1027
+ } else if (value) {
1028
+ parts.push(`${label} "${value}"`);
1029
+ }
1030
+ }
1031
+ if (filter.numberCondition) {
1032
+ const { operator, value, valueTo } = filter.numberCondition;
1033
+ const label = NUMBER_OPERATOR_LABELS[operator];
1034
+ if (["isEmpty", "isNotEmpty"].includes(operator)) {
1035
+ parts.push(label);
1036
+ } else if (operator === "between" && value !== void 0 && valueTo !== void 0) {
1037
+ parts.push(`${label} ${value} and ${valueTo}`);
1038
+ } else if (value !== void 0) {
1039
+ parts.push(`${label} ${value}`);
1040
+ }
1041
+ }
1042
+ if (filter.dateCondition) {
1043
+ const { operator, value, valueTo } = filter.dateCondition;
1044
+ const label = DATE_OPERATOR_LABELS[operator];
1045
+ const noValueOperators = [
1046
+ "isEmpty",
1047
+ "isNotEmpty",
1048
+ "today",
1049
+ "yesterday",
1050
+ "thisWeek",
1051
+ "lastWeek",
1052
+ "thisMonth",
1053
+ "lastMonth",
1054
+ "thisYear"
1055
+ ];
1056
+ if (noValueOperators.includes(operator)) {
1057
+ parts.push(label);
1058
+ } else if (operator === "between" && value && valueTo) {
1059
+ parts.push(`${label} ${formatDate(value)} and ${formatDate(valueTo)}`);
1060
+ } else if (value) {
1061
+ parts.push(`${label} ${formatDate(value)}`);
1062
+ }
1063
+ }
1064
+ if (filter.text) {
1065
+ parts.push(`contains "${filter.text}"`);
1066
+ }
1067
+ if (filter.selectedValues && filter.selectedValues.length > 0) {
1068
+ if (filter.selectedValues.length === 1) {
1069
+ parts.push(`is "${filter.selectedValues[0]}"`);
1070
+ } else {
1071
+ parts.push(`is one of ${filter.selectedValues.length} values`);
1072
+ }
1073
+ }
1074
+ if (filter.min !== void 0 && filter.max !== void 0) {
1075
+ parts.push(`between ${filter.min} and ${filter.max}`);
1076
+ } else if (filter.min !== void 0) {
1077
+ parts.push(`\u2265 ${filter.min}`);
1078
+ } else if (filter.max !== void 0) {
1079
+ parts.push(`\u2264 ${filter.max}`);
1080
+ }
1081
+ if (filter.includeBlanks) {
1082
+ parts.push("includes blanks");
1083
+ }
1084
+ if (filter.excludeBlanks) {
1085
+ parts.push("excludes blanks");
1086
+ }
1087
+ return parts.join(", ") || "filtered";
1088
+ }
1089
+ function formatDate(dateStr) {
1090
+ try {
1091
+ const date = new Date(dateStr);
1092
+ return date.toLocaleDateString("en-US", {
1093
+ month: "short",
1094
+ day: "numeric",
1095
+ year: "numeric"
1096
+ });
1097
+ } catch {
1098
+ return dateStr;
1099
+ }
1100
+ }
1101
+ var ActiveFiltersDisplay = ({
1102
+ filters,
1103
+ columns,
1104
+ onClearFilter,
1105
+ onClearAllFilters,
1106
+ className
1107
+ }) => {
1108
+ const activeFilters = Object.entries(filters).filter(([_, filter]) => {
1109
+ return filter.textCondition || filter.numberCondition || filter.dateCondition || filter.text || filter.selectedValues && filter.selectedValues.length > 0 || filter.min !== void 0 || filter.max !== void 0 || filter.includeBlanks || filter.excludeBlanks;
1110
+ });
1111
+ if (activeFilters.length === 0) {
1112
+ return null;
1113
+ }
1114
+ const getColumnLabel = (columnId) => {
1115
+ const column = columns.find((c) => c.id === columnId);
1116
+ return column?.label || columnId;
1117
+ };
1118
+ const getColumn = (columnId) => {
1119
+ return columns.find((c) => c.id === columnId);
1120
+ };
1121
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1122
+ "div",
1123
+ {
1124
+ className: cn(
1125
+ "flex flex-wrap items-center gap-2 px-4 py-2 bg-amber-50 border-b border-amber-200",
1126
+ className
1127
+ ),
1128
+ children: [
1129
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs font-medium text-amber-700 mr-1", children: "Active filters:" }),
1130
+ activeFilters.map(([columnId, filter]) => {
1131
+ const column = getColumn(columnId);
1132
+ const filterDescription = column ? formatFilter(filter, column) : formatFilter(filter, { id: columnId, label: columnId });
1133
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1134
+ "div",
1135
+ {
1136
+ className: "inline-flex items-center gap-1.5 px-2.5 py-1 bg-white border border-amber-300 rounded-full shadow-sm",
1137
+ children: [
1138
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs font-medium text-gray-700", children: getColumnLabel(columnId) }),
1139
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs text-gray-500", children: filterDescription }),
1140
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1141
+ "button",
1142
+ {
1143
+ type: "button",
1144
+ onClick: () => onClearFilter(columnId),
1145
+ className: "p-0.5 hover:bg-amber-100 rounded-full transition-colors",
1146
+ title: `Clear filter for ${getColumnLabel(columnId)}`,
1147
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiX, { className: "h-3 w-3 text-amber-600 hover:text-amber-800" })
1148
+ }
1149
+ )
1150
+ ]
1151
+ },
1152
+ columnId
1153
+ );
1154
+ }),
1155
+ activeFilters.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1156
+ "button",
1157
+ {
1158
+ type: "button",
1159
+ onClick: onClearAllFilters,
1160
+ className: "text-xs text-amber-700 hover:text-amber-900 underline ml-2 transition-colors",
1161
+ children: "Clear all"
1162
+ }
1163
+ )
1164
+ ]
1165
+ }
1166
+ );
1167
+ };
1168
+ ActiveFiltersDisplay.displayName = "ActiveFiltersDisplay";
1169
+
1170
+ // src/components/SpreadsheetToolbar.tsx
1171
+ var import_jsx_runtime4 = require("react/jsx-runtime");
813
1172
  var SpreadsheetToolbar = ({
814
1173
  zoom,
815
1174
  canUndo,
@@ -833,11 +1192,16 @@ var SpreadsheetToolbar = ({
833
1192
  onShowShortcuts,
834
1193
  hasActiveFilters,
835
1194
  onClearFilters,
1195
+ filters,
1196
+ columns,
1197
+ onClearFilter,
1198
+ showFiltersPanel,
1199
+ onToggleFiltersPanel,
836
1200
  className
837
1201
  }) => {
838
- const [showMoreMenu, setShowMoreMenu] = import_react5.default.useState(false);
839
- const menuRef = import_react5.default.useRef(null);
840
- import_react5.default.useEffect(() => {
1202
+ const [showMoreMenu, setShowMoreMenu] = import_react6.default.useState(false);
1203
+ const menuRef = import_react6.default.useRef(null);
1204
+ import_react6.default.useEffect(() => {
841
1205
  const handleClickOutside = (event) => {
842
1206
  if (menuRef.current && !menuRef.current.contains(event.target)) {
843
1207
  setShowMoreMenu(false);
@@ -886,231 +1250,253 @@ var SpreadsheetToolbar = ({
886
1250
  return "bg-blue-50 border-blue-200 text-blue-700";
887
1251
  }
888
1252
  };
889
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
890
- "div",
891
- {
892
- className: cn(
893
- "flex flex-wrap items-center justify-between gap-2 px-4 py-2 border-b border-gray-200 bg-white",
894
- className
895
- ),
896
- children: [
897
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2", children: [
898
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-1", children: [
899
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
900
- "button",
901
- {
902
- type: "button",
903
- onClick: onUndo,
904
- disabled: !canUndo,
905
- className: cn(
906
- buttonBaseClasses,
907
- canUndo ? "bg-gray-100 text-gray-700 hover:bg-gray-200" : "bg-gray-50 text-gray-400"
908
- ),
909
- title: `Undo (${undoCount} changes)`,
910
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiReply, { className: "h-4 w-4" })
911
- }
912
- ),
913
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1253
+ const activeFilterCount = filters ? Object.values(filters).filter(
1254
+ (f) => f.textCondition || f.numberCondition || f.dateCondition || f.text || f.selectedValues && f.selectedValues.length > 0 || f.min !== void 0 || f.max !== void 0 || f.includeBlanks || f.excludeBlanks
1255
+ ).length : 0;
1256
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col", children: [
1257
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1258
+ "div",
1259
+ {
1260
+ className: cn(
1261
+ "flex flex-wrap items-center justify-between gap-2 px-4 py-2 border-b border-gray-200 bg-white",
1262
+ className
1263
+ ),
1264
+ children: [
1265
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
1266
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1", children: [
1267
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1268
+ "button",
1269
+ {
1270
+ type: "button",
1271
+ onClick: onUndo,
1272
+ disabled: !canUndo,
1273
+ className: cn(
1274
+ buttonBaseClasses,
1275
+ canUndo ? "bg-gray-100 text-gray-700 hover:bg-gray-200" : "bg-gray-50 text-gray-400"
1276
+ ),
1277
+ title: `Undo (${undoCount} changes)`,
1278
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiReply, { className: "h-4 w-4" })
1279
+ }
1280
+ ),
1281
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1282
+ "button",
1283
+ {
1284
+ type: "button",
1285
+ onClick: onRedo,
1286
+ disabled: !canRedo,
1287
+ className: cn(
1288
+ buttonBaseClasses,
1289
+ canRedo ? "bg-gray-100 text-gray-700 hover:bg-gray-200" : "bg-gray-50 text-gray-400"
1290
+ ),
1291
+ title: `Redo (${redoCount} changes)`,
1292
+ style: { transform: "scaleX(-1)" },
1293
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiReply, { className: "h-4 w-4" })
1294
+ }
1295
+ )
1296
+ ] }),
1297
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1 px-1.5 py-1 bg-gray-100 rounded", children: [
1298
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1299
+ "button",
1300
+ {
1301
+ type: "button",
1302
+ onClick: onZoomOut,
1303
+ className: "p-1 hover:bg-white rounded",
1304
+ title: "Zoom out",
1305
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiZoomOut, { className: "h-4 w-4 text-gray-600" })
1306
+ }
1307
+ ),
1308
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1309
+ "button",
1310
+ {
1311
+ type: "button",
1312
+ onClick: onZoomReset,
1313
+ className: "px-2 py-0.5 hover:bg-white rounded text-xs min-w-[45px] text-center text-gray-600",
1314
+ title: "Reset zoom",
1315
+ children: [
1316
+ zoom,
1317
+ "%"
1318
+ ]
1319
+ }
1320
+ ),
1321
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1322
+ "button",
1323
+ {
1324
+ type: "button",
1325
+ onClick: onZoomIn,
1326
+ className: "p-1 hover:bg-white rounded",
1327
+ title: "Zoom in",
1328
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiZoomIn, { className: "h-4 w-4 text-gray-600" })
1329
+ }
1330
+ )
1331
+ ] })
1332
+ ] }),
1333
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
1334
+ selectedRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 px-2.5 py-1.5 bg-blue-600 text-white rounded", children: [
1335
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "text-xs font-medium whitespace-nowrap", children: [
1336
+ selectedRowCount,
1337
+ " row",
1338
+ selectedRowCount !== 1 ? "s" : "",
1339
+ " selected"
1340
+ ] }),
1341
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1342
+ "button",
1343
+ {
1344
+ type: "button",
1345
+ onClick: onClearSelection,
1346
+ className: "p-0.5 hover:bg-blue-700 rounded",
1347
+ title: "Clear selection",
1348
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiX, { className: "h-3 w-3" })
1349
+ }
1350
+ )
1351
+ ] }),
1352
+ hasActiveFilters && onToggleFiltersPanel && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
914
1353
  "button",
915
1354
  {
916
1355
  type: "button",
917
- onClick: onRedo,
918
- disabled: !canRedo,
1356
+ onClick: onToggleFiltersPanel,
919
1357
  className: cn(
920
- buttonBaseClasses,
921
- canRedo ? "bg-gray-100 text-gray-700 hover:bg-gray-200" : "bg-gray-50 text-gray-400"
1358
+ "flex items-center gap-2 px-2.5 py-1.5 rounded transition-colors",
1359
+ showFiltersPanel ? "bg-amber-600 text-white hover:bg-amber-700" : "bg-amber-500 text-white hover:bg-amber-600"
922
1360
  ),
923
- title: `Redo (${redoCount} changes)`,
924
- style: { transform: "scaleX(-1)" },
925
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiReply, { className: "h-4 w-4" })
926
- }
927
- )
928
- ] }),
929
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-1 px-1.5 py-1 bg-gray-100 rounded", children: [
930
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
931
- "button",
932
- {
933
- type: "button",
934
- onClick: onZoomOut,
935
- className: "p-1 hover:bg-white rounded",
936
- title: "Zoom out",
937
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiZoomOut, { className: "h-4 w-4 text-gray-600" })
938
- }
939
- ),
940
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
941
- "button",
942
- {
943
- type: "button",
944
- onClick: onZoomReset,
945
- className: "px-2 py-0.5 hover:bg-white rounded text-xs min-w-[45px] text-center text-gray-600",
946
- title: "Reset zoom",
1361
+ title: showFiltersPanel ? "Hide active filters" : "Show active filters",
947
1362
  children: [
948
- zoom,
949
- "%"
1363
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiFilter, { className: "h-3.5 w-3.5" }),
1364
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "text-xs font-medium whitespace-nowrap", children: [
1365
+ activeFilterCount,
1366
+ " filter",
1367
+ activeFilterCount !== 1 ? "s" : "",
1368
+ " active"
1369
+ ] }),
1370
+ showFiltersPanel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiChevronUp, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiChevronDown, { className: "h-3 w-3" })
950
1371
  ]
951
1372
  }
952
1373
  ),
953
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
954
- "button",
955
- {
956
- type: "button",
957
- onClick: onZoomIn,
958
- className: "p-1 hover:bg-white rounded",
959
- title: "Zoom in",
960
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiZoomIn, { className: "h-4 w-4 text-gray-600" })
961
- }
962
- )
963
- ] })
964
- ] }),
965
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
966
- selectedRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 px-2.5 py-1.5 bg-blue-600 text-white rounded", children: [
967
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "text-xs font-medium whitespace-nowrap", children: [
968
- selectedRowCount,
969
- " row",
970
- selectedRowCount !== 1 ? "s" : "",
971
- " selected"
972
- ] }),
973
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
974
- "button",
1374
+ summary && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1375
+ "div",
975
1376
  {
976
- type: "button",
977
- onClick: onClearSelection,
978
- className: "p-0.5 hover:bg-blue-700 rounded",
979
- title: "Clear selection",
980
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiX, { className: "h-3 w-3" })
1377
+ className: cn(
1378
+ "flex items-center gap-2 px-2.5 py-1.5 rounded border text-xs",
1379
+ getSummaryVariantClasses(summary.variant)
1380
+ ),
1381
+ children: [
1382
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "font-semibold whitespace-nowrap", children: [
1383
+ summary.label,
1384
+ ":"
1385
+ ] }),
1386
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "font-bold whitespace-nowrap", children: summary.value })
1387
+ ]
981
1388
  }
982
1389
  )
983
1390
  ] }),
984
- hasActiveFilters && onClearFilters && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 px-2.5 py-1.5 bg-amber-500 text-white rounded", children: [
985
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiFilter, { className: "h-3.5 w-3.5" }),
986
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs font-medium whitespace-nowrap", children: "Filters active" }),
987
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
988
- "button",
1391
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
1392
+ saveStatusDisplay && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1393
+ "span",
989
1394
  {
990
- type: "button",
991
- onClick: onClearFilters,
992
- className: "p-0.5 hover:bg-amber-600 rounded",
993
- title: "Clear all filters",
994
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiX, { className: "h-3 w-3" })
1395
+ className: cn(
1396
+ "text-xs flex items-center gap-1",
1397
+ saveStatusDisplay.className
1398
+ ),
1399
+ children: saveStatusDisplay.text
995
1400
  }
996
- )
997
- ] }),
998
- summary && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
999
- "div",
1000
- {
1001
- className: cn(
1002
- "flex items-center gap-2 px-2.5 py-1.5 rounded border text-xs",
1003
- getSummaryVariantClasses(summary.variant)
1004
- ),
1005
- children: [
1006
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "font-semibold whitespace-nowrap", children: [
1007
- summary.label,
1008
- ":"
1009
- ] }),
1010
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "font-bold whitespace-nowrap", children: summary.value })
1011
- ]
1012
- }
1013
- )
1014
- ] }),
1015
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2", children: [
1016
- saveStatusDisplay && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1017
- "span",
1018
- {
1019
- className: cn(
1020
- "text-xs flex items-center gap-1",
1021
- saveStatusDisplay.className
1022
- ),
1023
- children: saveStatusDisplay.text
1024
- }
1025
- ),
1026
- !autoSave && onSave && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1027
- "button",
1028
- {
1029
- type: "button",
1030
- onClick: onSave,
1031
- disabled: !hasUnsavedChanges,
1032
- className: cn(
1033
- "px-3 py-1.5 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors flex items-center gap-1.5",
1034
- "disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-blue-600"
1035
- ),
1036
- children: [
1037
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiCheck, { className: "h-3.5 w-3.5" }),
1038
- "Save"
1039
- ]
1040
- }
1041
- ),
1042
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", ref: menuRef, children: [
1043
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1401
+ ),
1402
+ !autoSave && onSave && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1044
1403
  "button",
1045
1404
  {
1046
1405
  type: "button",
1047
- onClick: () => setShowMoreMenu(!showMoreMenu),
1048
- className: "px-2.5 py-1.5 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 transition-colors flex items-center gap-1.5 text-xs",
1049
- title: "More actions",
1406
+ onClick: onSave,
1407
+ disabled: !hasUnsavedChanges,
1408
+ className: cn(
1409
+ "px-3 py-1.5 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors flex items-center gap-1.5",
1410
+ "disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-blue-600"
1411
+ ),
1050
1412
  children: [
1051
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiDotsVertical, { className: "h-3.5 w-3.5" }),
1052
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hidden lg:inline", children: "More" })
1413
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiCheck, { className: "h-3.5 w-3.5" }),
1414
+ "Save"
1053
1415
  ]
1054
1416
  }
1055
1417
  ),
1056
- showMoreMenu && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "absolute right-0 top-full mt-1 bg-white border border-gray-200 shadow-lg rounded py-1 min-w-[180px] z-20", children: [
1057
- onSettings && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1058
- "button",
1059
- {
1060
- type: "button",
1061
- onClick: () => {
1062
- onSettings();
1063
- setShowMoreMenu(false);
1064
- },
1065
- className: "w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-xs transition-colors",
1066
- children: [
1067
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiCog, { className: "h-3.5 w-3.5 text-gray-500" }),
1068
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-gray-700", children: "Settings" })
1069
- ]
1070
- }
1071
- ),
1072
- onShowShortcuts && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1418
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative", ref: menuRef, children: [
1419
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1073
1420
  "button",
1074
1421
  {
1075
1422
  type: "button",
1076
- onClick: () => {
1077
- onShowShortcuts();
1078
- setShowMoreMenu(false);
1079
- },
1080
- className: "w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-xs transition-colors",
1423
+ onClick: () => setShowMoreMenu(!showMoreMenu),
1424
+ className: "px-2.5 py-1.5 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 transition-colors flex items-center gap-1.5 text-xs",
1425
+ title: "More actions",
1081
1426
  children: [
1082
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HiOutlineQuestionMarkCircle, { className: "h-3.5 w-3.5 text-gray-500" }),
1083
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-gray-700", children: "Keyboard Shortcuts" })
1427
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiDotsVertical, { className: "h-3.5 w-3.5" }),
1428
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "hidden lg:inline", children: "More" })
1084
1429
  ]
1085
1430
  }
1086
1431
  ),
1087
- menuItems && menuItems.length > 0 && (onSettings || onShowShortcuts) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-t border-gray-100 my-1" }),
1088
- menuItems?.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1089
- "button",
1090
- {
1091
- type: "button",
1092
- disabled: item.disabled,
1093
- onClick: () => {
1094
- item.onClick();
1095
- setShowMoreMenu(false);
1432
+ showMoreMenu && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "absolute right-0 top-full mt-1 bg-white border border-gray-200 shadow-lg rounded py-1 min-w-[180px] z-20", children: [
1433
+ onSettings && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1434
+ "button",
1435
+ {
1436
+ type: "button",
1437
+ onClick: () => {
1438
+ onSettings();
1439
+ setShowMoreMenu(false);
1440
+ },
1441
+ className: "w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-xs transition-colors",
1442
+ children: [
1443
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiCog, { className: "h-3.5 w-3.5 text-gray-500" }),
1444
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-gray-700", children: "Settings" })
1445
+ ]
1446
+ }
1447
+ ),
1448
+ onShowShortcuts && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1449
+ "button",
1450
+ {
1451
+ type: "button",
1452
+ onClick: () => {
1453
+ onShowShortcuts();
1454
+ setShowMoreMenu(false);
1455
+ },
1456
+ className: "w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-xs transition-colors",
1457
+ children: [
1458
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiOutlineQuestionMarkCircle, { className: "h-3.5 w-3.5 text-gray-500" }),
1459
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-gray-700", children: "Keyboard Shortcuts" })
1460
+ ]
1461
+ }
1462
+ ),
1463
+ menuItems && menuItems.length > 0 && (onSettings || onShowShortcuts) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "border-t border-gray-100 my-1" }),
1464
+ menuItems?.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1465
+ "button",
1466
+ {
1467
+ type: "button",
1468
+ disabled: item.disabled,
1469
+ onClick: () => {
1470
+ item.onClick();
1471
+ setShowMoreMenu(false);
1472
+ },
1473
+ className: cn(
1474
+ "w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-xs transition-colors",
1475
+ item.disabled && "opacity-50 cursor-not-allowed"
1476
+ ),
1477
+ children: [
1478
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "h-3.5 w-3.5 text-gray-500 flex items-center justify-center", children: item.icon }),
1479
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-gray-700", children: item.label })
1480
+ ]
1096
1481
  },
1097
- className: cn(
1098
- "w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-xs transition-colors",
1099
- item.disabled && "opacity-50 cursor-not-allowed"
1100
- ),
1101
- children: [
1102
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "h-3.5 w-3.5 text-gray-500 flex items-center justify-center", children: item.icon }),
1103
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-gray-700", children: item.label })
1104
- ]
1105
- },
1106
- item.id
1107
- ))
1482
+ item.id
1483
+ ))
1484
+ ] })
1108
1485
  ] })
1109
1486
  ] })
1110
- ] })
1111
- ]
1112
- }
1113
- );
1487
+ ]
1488
+ }
1489
+ ),
1490
+ showFiltersPanel && filters && columns && onClearFilter && onClearFilters && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1491
+ ActiveFiltersDisplay,
1492
+ {
1493
+ filters,
1494
+ columns,
1495
+ onClearFilter,
1496
+ onClearAllFilters: onClearFilters
1497
+ }
1498
+ )
1499
+ ] });
1114
1500
  };
1115
1501
  SpreadsheetToolbar.displayName = "SpreadsheetToolbar";
1116
1502
 
@@ -1123,7 +1509,7 @@ function MdOutlinePushPin(props) {
1123
1509
  }
1124
1510
 
1125
1511
  // src/components/ColumnHeaderActions.tsx
1126
- var import_jsx_runtime4 = require("react/jsx-runtime");
1512
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1127
1513
  function ColumnHeaderActions({
1128
1514
  enableFiltering = false,
1129
1515
  enableHighlighting = false,
@@ -1140,8 +1526,8 @@ function ColumnHeaderActions({
1140
1526
  unpinnedTitle = "Pin column",
1141
1527
  className
1142
1528
  }) {
1143
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("flex items-center gap-0.5", className), children: [
1144
- enableFiltering && onFilterClick && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1529
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("flex items-center gap-0.5", className), children: [
1530
+ enableFiltering && onFilterClick && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1145
1531
  "button",
1146
1532
  {
1147
1533
  type: "button",
@@ -1154,10 +1540,10 @@ function ColumnHeaderActions({
1154
1540
  hasActiveFilter ? "text-blue-600 opacity-100" : "text-gray-400 opacity-0 group-hover:opacity-100"
1155
1541
  ),
1156
1542
  title: filterTitle,
1157
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiFilter, { className: "h-3 w-3" })
1543
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HiFilter, { className: "h-3 w-3" })
1158
1544
  }
1159
1545
  ),
1160
- enableHighlighting && onHighlightClick && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1546
+ enableHighlighting && onHighlightClick && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1161
1547
  "button",
1162
1548
  {
1163
1549
  type: "button",
@@ -1170,10 +1556,10 @@ function ColumnHeaderActions({
1170
1556
  hasActiveHighlight ? "text-amber-500 opacity-100" : "text-gray-400 opacity-0 group-hover:opacity-100"
1171
1557
  ),
1172
1558
  title: highlightTitle,
1173
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AiFillHighlight, { className: "h-3 w-3" })
1559
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AiFillHighlight, { className: "h-3 w-3" })
1174
1560
  }
1175
1561
  ),
1176
- enablePinning && onPinClick && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1562
+ enablePinning && onPinClick && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1177
1563
  "button",
1178
1564
  {
1179
1565
  type: "button",
@@ -1186,7 +1572,7 @@ function ColumnHeaderActions({
1186
1572
  isPinned ? "text-blue-600 opacity-100" : "text-gray-400 opacity-0 group-hover:opacity-100"
1187
1573
  ),
1188
1574
  title: isPinned ? pinnedTitle : unpinnedTitle,
1189
- children: isPinned ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MdPushPin, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MdOutlinePushPin, { className: "h-3 w-3" })
1575
+ children: isPinned ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MdPushPin, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MdOutlinePushPin, { className: "h-3 w-3" })
1190
1576
  }
1191
1577
  )
1192
1578
  ] });
@@ -1194,7 +1580,7 @@ function ColumnHeaderActions({
1194
1580
  ColumnHeaderActions.displayName = "ColumnHeaderActions";
1195
1581
 
1196
1582
  // src/components/SpreadsheetHeader.tsx
1197
- var import_jsx_runtime5 = require("react/jsx-runtime");
1583
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1198
1584
  var cellPaddingCompact2 = "px-1 py-0.5";
1199
1585
  var cellPaddingNormal2 = "px-2 py-1.5";
1200
1586
  var SpreadsheetHeader = ({
@@ -1226,7 +1612,7 @@ var SpreadsheetHeader = ({
1226
1612
  positionStyles.right = `${rightOffset}px`;
1227
1613
  }
1228
1614
  }
1229
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1615
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1230
1616
  "th",
1231
1617
  {
1232
1618
  onClick: column.sortable ? onClick : void 0,
@@ -1244,17 +1630,29 @@ var SpreadsheetHeader = ({
1244
1630
  backgroundColor: highlightColor || "rgb(243 244 246)",
1245
1631
  // gray-100
1246
1632
  minWidth: column.minWidth || column.width,
1633
+ // Pinned columns must have a fixed width so sticky offsets stay correct.
1634
+ // Enforce MIN_PINNED_COLUMN_WIDTH so header actions (pin/filter/highlight) always fit.
1635
+ ...isPinned && {
1636
+ width: Math.max(
1637
+ column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH,
1638
+ MIN_PINNED_COLUMN_WIDTH
1639
+ ),
1640
+ maxWidth: Math.max(
1641
+ column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH,
1642
+ MIN_PINNED_COLUMN_WIDTH
1643
+ )
1644
+ },
1247
1645
  top: 0,
1248
1646
  // For sticky header
1249
1647
  ...positionStyles
1250
1648
  },
1251
1649
  children: [
1252
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between gap-1", children: [
1253
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex-1 flex items-center gap-1", children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between gap-1", children: [
1651
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex-1 flex items-center gap-1", children: [
1254
1652
  column.label,
1255
- isSorted && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-blue-600", children: sortDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HiChevronUp, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HiChevronDown, { className: "h-3 w-3" }) })
1653
+ isSorted && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-blue-600", children: sortDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(HiChevronUp, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(HiChevronDown, { className: "h-3 w-3" }) })
1256
1654
  ] }),
1257
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1655
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1258
1656
  ColumnHeaderActions,
1259
1657
  {
1260
1658
  enableFiltering: column.filterable,
@@ -1276,158 +1674,8 @@ var SpreadsheetHeader = ({
1276
1674
  };
1277
1675
  SpreadsheetHeader.displayName = "SpreadsheetHeader";
1278
1676
 
1279
- // src/hooks/useSpreadsheetPinning.ts
1280
- var import_react6 = require("react");
1281
- var ROW_INDEX_COLUMN_ID = "__row_index__";
1282
- var ROW_INDEX_COLUMN_WIDTH = 80;
1283
- function useSpreadsheetPinning({
1284
- columns,
1285
- columnGroups,
1286
- showRowIndex = true,
1287
- defaultPinnedColumns = [],
1288
- defaultPinnedRightColumns = []
1289
- }) {
1290
- const [pinnedColumns, setPinnedColumns] = (0, import_react6.useState)(() => {
1291
- const map = /* @__PURE__ */ new Map();
1292
- defaultPinnedColumns.forEach((col) => {
1293
- map.set(col, "left");
1294
- });
1295
- defaultPinnedRightColumns.forEach((col) => {
1296
- map.set(col, "right");
1297
- });
1298
- return map;
1299
- });
1300
- const [collapsedGroups, setCollapsedGroups] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
1301
- const isRowIndexPinned = pinnedColumns.has(ROW_INDEX_COLUMN_ID);
1302
- const handleTogglePin = (0, import_react6.useCallback)((columnId) => {
1303
- setPinnedColumns((prev) => {
1304
- const newMap = new Map(prev);
1305
- if (newMap.has(columnId)) {
1306
- newMap.delete(columnId);
1307
- } else {
1308
- newMap.set(columnId, "left");
1309
- }
1310
- return newMap;
1311
- });
1312
- }, []);
1313
- const setPinnedColumnsFromIds = (0, import_react6.useCallback)((columnIds) => {
1314
- const map = /* @__PURE__ */ new Map();
1315
- columnIds.forEach((col) => {
1316
- map.set(col, "left");
1317
- });
1318
- setPinnedColumns(map);
1319
- }, []);
1320
- const handleToggleGroupCollapse = (0, import_react6.useCallback)((groupId) => {
1321
- setCollapsedGroups((prev) => {
1322
- const newSet = new Set(prev);
1323
- if (newSet.has(groupId)) {
1324
- newSet.delete(groupId);
1325
- } else {
1326
- newSet.add(groupId);
1327
- }
1328
- return newSet;
1329
- });
1330
- }, []);
1331
- const visibleColumns = (0, import_react6.useMemo)(() => {
1332
- if (!columns || !Array.isArray(columns) || columns.length === 0) {
1333
- return [];
1334
- }
1335
- let result = [...columns];
1336
- if (columnGroups && Array.isArray(columnGroups)) {
1337
- result = result.filter((column) => {
1338
- const group = columnGroups.find((g) => g.columns.includes(column.id));
1339
- if (!group) return true;
1340
- if (!collapsedGroups.has(group.id)) return true;
1341
- return pinnedColumns.has(column.id);
1342
- });
1343
- }
1344
- const nonRowIndexPinned = Array.from(pinnedColumns.keys()).filter(
1345
- (id) => id !== ROW_INDEX_COLUMN_ID
1346
- );
1347
- if (nonRowIndexPinned.length === 0) {
1348
- return result;
1349
- }
1350
- const leftPinned = [];
1351
- const unpinned = [];
1352
- const rightPinned = [];
1353
- const pinnedLeftIds = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "left" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
1354
- const pinnedRightIds = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "right" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
1355
- for (const column of result) {
1356
- const pinSide = pinnedColumns.get(column.id);
1357
- if (pinSide === "left") {
1358
- leftPinned.push(column);
1359
- } else if (pinSide === "right") {
1360
- rightPinned.push(column);
1361
- } else {
1362
- unpinned.push(column);
1363
- }
1364
- }
1365
- leftPinned.sort((a, b) => pinnedLeftIds.indexOf(a.id) - pinnedLeftIds.indexOf(b.id));
1366
- rightPinned.sort((a, b) => pinnedRightIds.indexOf(a.id) - pinnedRightIds.indexOf(b.id));
1367
- return [...leftPinned, ...unpinned, ...rightPinned];
1368
- }, [columns, columnGroups, collapsedGroups, pinnedColumns]);
1369
- const getColumnLeftOffset = (0, import_react6.useCallback)(
1370
- (columnId) => {
1371
- if (columnId === ROW_INDEX_COLUMN_ID) {
1372
- return 0;
1373
- }
1374
- const pinnedLeft = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "left" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
1375
- const index = pinnedLeft.indexOf(columnId);
1376
- const isRowIndexPinnedNow = pinnedColumns.has(ROW_INDEX_COLUMN_ID);
1377
- const baseOffset = showRowIndex && isRowIndexPinnedNow ? ROW_INDEX_COLUMN_WIDTH : 0;
1378
- if (index === -1) return baseOffset;
1379
- let offset = baseOffset;
1380
- for (let i = 0; i < index; i++) {
1381
- const col = columns.find((c) => c.id === pinnedLeft[i]);
1382
- offset += col?.minWidth || col?.width || 100;
1383
- }
1384
- return offset;
1385
- },
1386
- [pinnedColumns, columns, showRowIndex]
1387
- );
1388
- const isColumnPinned = (0, import_react6.useCallback)(
1389
- (columnId) => {
1390
- return pinnedColumns.has(columnId);
1391
- },
1392
- [pinnedColumns]
1393
- );
1394
- const getColumnPinSide = (0, import_react6.useCallback)(
1395
- (columnId) => {
1396
- return pinnedColumns.get(columnId);
1397
- },
1398
- [pinnedColumns]
1399
- );
1400
- const getColumnRightOffset = (0, import_react6.useCallback)(
1401
- (columnId) => {
1402
- const pinnedRight = Array.from(pinnedColumns.entries()).filter(([, side]) => side === "right").map(([id]) => id);
1403
- const index = pinnedRight.indexOf(columnId);
1404
- if (index === -1) return 0;
1405
- let offset = 0;
1406
- for (let i = pinnedRight.length - 1; i > index; i--) {
1407
- const col = columns.find((c) => c.id === pinnedRight[i]);
1408
- offset += col?.minWidth || col?.width || 100;
1409
- }
1410
- return offset;
1411
- },
1412
- [pinnedColumns, columns]
1413
- );
1414
- return {
1415
- pinnedColumns,
1416
- isRowIndexPinned,
1417
- collapsedGroups,
1418
- visibleColumns,
1419
- handleTogglePin,
1420
- handleToggleGroupCollapse,
1421
- setPinnedColumnsFromIds,
1422
- getColumnLeftOffset,
1423
- getColumnRightOffset,
1424
- isColumnPinned,
1425
- getColumnPinSide
1426
- };
1427
- }
1428
-
1429
1677
  // src/components/RowIndexColumnHeader.tsx
1430
- var import_jsx_runtime6 = require("react/jsx-runtime");
1678
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1431
1679
  var cellPaddingCompact3 = "px-1 py-0.5";
1432
1680
  var cellPaddingNormal3 = "px-2 py-1.5";
1433
1681
  function RowIndexColumnHeader({
@@ -1441,7 +1689,7 @@ function RowIndexColumnHeader({
1441
1689
  className
1442
1690
  }) {
1443
1691
  const cellPadding = compactMode ? cellPaddingCompact3 : cellPaddingNormal3;
1444
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1692
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1445
1693
  "th",
1446
1694
  {
1447
1695
  className: cn(
@@ -1460,9 +1708,9 @@ function RowIndexColumnHeader({
1460
1708
  left: isPinned ? 0 : void 0,
1461
1709
  backgroundColor: highlightColor || "rgb(243 244 246)"
1462
1710
  },
1463
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
1464
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "#" }),
1465
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1711
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
1712
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "#" }),
1713
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1466
1714
  ColumnHeaderActions,
1467
1715
  {
1468
1716
  enableHighlighting,
@@ -1665,7 +1913,7 @@ function useSpreadsheetHighlighting({
1665
1913
  }
1666
1914
 
1667
1915
  // src/components/ColorPickerPopover.tsx
1668
- var import_jsx_runtime7 = require("react/jsx-runtime");
1916
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1669
1917
  function ColorPickerPopover({
1670
1918
  title,
1671
1919
  paletteType = "column",
@@ -1675,9 +1923,9 @@ function ColorPickerPopover({
1675
1923
  className
1676
1924
  }) {
1677
1925
  const colorPalette = colors ?? [...HIGHLIGHT_COLORS[paletteType], null];
1678
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("bg-white rounded-lg shadow-xl p-4 w-64", className), children: [
1679
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "text-sm font-semibold mb-3", children: title }),
1680
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "grid grid-cols-5 gap-2", children: colorPalette.map((color) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1926
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("bg-white rounded-lg shadow-xl p-4 w-64", className), children: [
1927
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "text-sm font-semibold mb-3", children: title }),
1928
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "grid grid-cols-5 gap-2", children: colorPalette.map((color) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1681
1929
  "button",
1682
1930
  {
1683
1931
  type: "button",
@@ -1692,7 +1940,7 @@ function ColorPickerPopover({
1692
1940
  },
1693
1941
  color || "clear"
1694
1942
  )) }),
1695
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex justify-end mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1943
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex justify-end mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1696
1944
  "button",
1697
1945
  {
1698
1946
  type: "button",
@@ -1707,7 +1955,7 @@ ColorPickerPopover.displayName = "ColorPickerPopover";
1707
1955
 
1708
1956
  // src/components/SpreadsheetSettingsModal.tsx
1709
1957
  var import_react8 = require("react");
1710
- var import_jsx_runtime8 = require("react/jsx-runtime");
1958
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1711
1959
  var DEFAULT_SETTINGS = {
1712
1960
  defaultPinnedColumns: [],
1713
1961
  defaultSort: null,
@@ -1782,7 +2030,7 @@ var SpreadsheetSettingsModal = ({
1782
2030
  { id: "sorting", label: "Default Sorting", Icon: HiSortAscending },
1783
2031
  { id: "display", label: "Display Options", Icon: HiEye }
1784
2032
  ];
1785
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2033
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1786
2034
  "div",
1787
2035
  {
1788
2036
  className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50",
@@ -1790,7 +2038,7 @@ var SpreadsheetSettingsModal = ({
1790
2038
  "aria-modal": "true",
1791
2039
  "aria-labelledby": "settings-modal-title",
1792
2040
  children: [
1793
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2041
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1794
2042
  "button",
1795
2043
  {
1796
2044
  type: "button",
@@ -1800,55 +2048,55 @@ var SpreadsheetSettingsModal = ({
1800
2048
  "aria-label": "Close settings"
1801
2049
  }
1802
2050
  ),
1803
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "bg-white rounded-lg w-[90%] max-w-[700px] max-h-[90vh] flex flex-col shadow-xl relative z-10", children: [
1804
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "px-6 py-5 border-b border-gray-200 flex items-center justify-between", children: [
1805
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-3", children: [
1806
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HiCog, { className: "h-6 w-6 text-blue-600" }),
1807
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { id: "settings-modal-title", className: "text-xl font-bold text-gray-900", children: title })
2051
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "bg-white rounded-lg w-[90%] max-w-[700px] max-h-[90vh] flex flex-col shadow-xl relative z-10", children: [
2052
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "px-6 py-5 border-b border-gray-200 flex items-center justify-between", children: [
2053
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3", children: [
2054
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HiCog, { className: "h-6 w-6 text-blue-600" }),
2055
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { id: "settings-modal-title", className: "text-xl font-bold text-gray-900", children: title })
1808
2056
  ] }),
1809
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2057
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1810
2058
  "button",
1811
2059
  {
1812
2060
  type: "button",
1813
2061
  onClick: onClose,
1814
2062
  className: "p-2 hover:bg-gray-100 rounded-lg transition-colors text-gray-500 hover:text-gray-700",
1815
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HiX, { className: "h-5 w-5" })
2063
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HiX, { className: "h-5 w-5" })
1816
2064
  }
1817
2065
  )
1818
2066
  ] }),
1819
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex border-b border-gray-200 px-6", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2067
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex border-b border-gray-200 px-6", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1820
2068
  "button",
1821
2069
  {
1822
2070
  type: "button",
1823
2071
  onClick: () => setActiveTab(tab.id),
1824
2072
  className: `px-4 py-3 flex items-center gap-2 text-sm font-medium transition-colors border-b-2 ${activeTab === tab.id ? "text-blue-600 border-blue-600" : "text-gray-500 border-transparent hover:text-gray-700"}`,
1825
2073
  children: [
1826
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(tab.Icon, { className: "h-4 w-4" }),
2074
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(tab.Icon, { className: "h-4 w-4" }),
1827
2075
  tab.label
1828
2076
  ]
1829
2077
  },
1830
2078
  tab.id
1831
2079
  )) }),
1832
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex-1 overflow-auto p-6", children: [
1833
- activeTab === "columns" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1834
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "p-4 bg-blue-50 border border-blue-200 rounded-lg mb-4 flex gap-3", children: [
1835
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HiViewBoards, { className: "h-4 w-4 text-blue-600 shrink-0 mt-0.5" }),
1836
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1837
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm font-semibold text-gray-900 mb-1", children: "About Pinned Columns" }),
1838
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600", children: "Pinned columns stay visible while you scroll horizontally through the table." })
2080
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1 overflow-auto p-6", children: [
2081
+ activeTab === "columns" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2082
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "p-4 bg-blue-50 border border-blue-200 rounded-lg mb-4 flex gap-3", children: [
2083
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HiViewBoards, { className: "h-4 w-4 text-blue-600 shrink-0 mt-0.5" }),
2084
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2085
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm font-semibold text-gray-900 mb-1", children: "About Pinned Columns" }),
2086
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-gray-600", children: "Pinned columns stay visible while you scroll horizontally through the table." })
1839
2087
  ] })
1840
2088
  ] }),
1841
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: "Select which columns should be pinned to the left by default." }),
1842
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2", children: [
1843
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2089
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: "Select which columns should be pinned to the left by default." }),
2090
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2", children: [
2091
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1844
2092
  "button",
1845
2093
  {
1846
2094
  type: "button",
1847
2095
  onClick: () => togglePinnedColumn("__row_index__"),
1848
2096
  className: `flex items-center gap-2 p-3 rounded-lg border transition-colors text-left ${localSettings.defaultPinnedColumns.includes("__row_index__") ? "bg-blue-50 border-blue-300 text-blue-700" : "bg-gray-50 border-gray-200 text-gray-700 hover:border-blue-300"}`,
1849
2097
  children: [
1850
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HiViewBoards, { className: "h-4 w-4 shrink-0" }),
1851
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm flex-1 truncate", children: "# (Row Index)" })
2098
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HiViewBoards, { className: "h-4 w-4 shrink-0" }),
2099
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm flex-1 truncate", children: "# (Row Index)" })
1852
2100
  ]
1853
2101
  }
1854
2102
  ),
@@ -1856,15 +2104,15 @@ var SpreadsheetSettingsModal = ({
1856
2104
  const isPinned = localSettings.defaultPinnedColumns.includes(
1857
2105
  column.id
1858
2106
  );
1859
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2107
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1860
2108
  "button",
1861
2109
  {
1862
2110
  type: "button",
1863
2111
  onClick: () => togglePinnedColumn(column.id),
1864
2112
  className: `flex items-center gap-2 p-3 rounded-lg border transition-colors text-left ${isPinned ? "bg-blue-50 border-blue-300 text-blue-700" : "bg-gray-50 border-gray-200 text-gray-700 hover:border-blue-300"}`,
1865
2113
  children: [
1866
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HiViewBoards, { className: "h-4 w-4 shrink-0" }),
1867
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm flex-1 truncate", children: column.label })
2114
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HiViewBoards, { className: "h-4 w-4 shrink-0" }),
2115
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm flex-1 truncate", children: column.label })
1868
2116
  ]
1869
2117
  },
1870
2118
  column.id
@@ -1872,12 +2120,12 @@ var SpreadsheetSettingsModal = ({
1872
2120
  })
1873
2121
  ] })
1874
2122
  ] }),
1875
- activeTab === "sorting" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1876
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: "Set the default column sorting when opening the spreadsheet." }),
1877
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-4", children: [
1878
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1879
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: "Sort Column" }),
1880
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2123
+ activeTab === "sorting" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2124
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: "Set the default column sorting when opening the spreadsheet." }),
2125
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-4", children: [
2126
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2127
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: "Sort Column" }),
2128
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1881
2129
  "select",
1882
2130
  {
1883
2131
  value: localSettings.defaultSort?.columnId || "",
@@ -1887,15 +2135,15 @@ var SpreadsheetSettingsModal = ({
1887
2135
  ),
1888
2136
  className: "w-full p-3 text-sm bg-white border border-gray-300 rounded-lg text-gray-900 cursor-pointer focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
1889
2137
  children: [
1890
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "No default sorting" }),
1891
- columns.filter((col) => col.sortable !== false).map((column) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: column.id, children: column.label }, column.id))
2138
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", children: "No default sorting" }),
2139
+ columns.filter((col) => col.sortable !== false).map((column) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: column.id, children: column.label }, column.id))
1892
2140
  ]
1893
2141
  }
1894
2142
  )
1895
2143
  ] }),
1896
- localSettings.defaultSort && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1897
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: "Sort Direction" }),
1898
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2144
+ localSettings.defaultSort && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2145
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: "Sort Direction" }),
2146
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1899
2147
  "select",
1900
2148
  {
1901
2149
  value: localSettings.defaultSort.direction,
@@ -1905,19 +2153,19 @@ var SpreadsheetSettingsModal = ({
1905
2153
  ),
1906
2154
  className: "w-full p-3 text-sm bg-white border border-gray-300 rounded-lg text-gray-900 cursor-pointer focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
1907
2155
  children: [
1908
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "asc", children: "Ascending (A \u2192 Z, 0 \u2192 9)" }),
1909
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "desc", children: "Descending (Z \u2192 A, 9 \u2192 0)" })
2156
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "asc", children: "Ascending (A \u2192 Z, 0 \u2192 9)" }),
2157
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "desc", children: "Descending (Z \u2192 A, 9 \u2192 0)" })
1910
2158
  ]
1911
2159
  }
1912
2160
  )
1913
2161
  ] })
1914
2162
  ] })
1915
2163
  ] }),
1916
- activeTab === "display" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-5", children: [
1917
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600", children: "Customize the display and behavior of the spreadsheet." }),
1918
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1919
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: "Default Page Size" }),
1920
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2164
+ activeTab === "display" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-5", children: [
2165
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-gray-600", children: "Customize the display and behavior of the spreadsheet." }),
2166
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2167
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: "Default Page Size" }),
2168
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1921
2169
  "select",
1922
2170
  {
1923
2171
  value: localSettings.defaultPageSize,
@@ -1926,20 +2174,20 @@ var SpreadsheetSettingsModal = ({
1926
2174
  defaultPageSize: parseInt(e.target.value, 10)
1927
2175
  }),
1928
2176
  className: "w-full p-3 text-sm bg-white border border-gray-300 rounded-lg text-gray-900 cursor-pointer focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
1929
- children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("option", { value: size, children: [
2177
+ children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("option", { value: size, children: [
1930
2178
  size,
1931
2179
  " rows"
1932
2180
  ] }, size))
1933
2181
  }
1934
2182
  )
1935
2183
  ] }),
1936
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1937
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: [
2184
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2185
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "block text-sm font-medium text-gray-900 mb-2", children: [
1938
2186
  "Default Zoom Level: ",
1939
2187
  localSettings.defaultZoom,
1940
2188
  "%"
1941
2189
  ] }),
1942
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2190
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1943
2191
  "input",
1944
2192
  {
1945
2193
  type: "range",
@@ -1954,14 +2202,14 @@ var SpreadsheetSettingsModal = ({
1954
2202
  className: "w-full cursor-pointer"
1955
2203
  }
1956
2204
  ),
1957
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex justify-between mt-1 text-xs text-gray-500", children: [
1958
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "50%" }),
1959
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "150%" })
2205
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-between mt-1 text-xs text-gray-500", children: [
2206
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "50%" }),
2207
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "150%" })
1960
2208
  ] })
1961
2209
  ] }),
1962
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-3", children: [
1963
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-3 p-4 bg-gray-50 border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors", children: [
1964
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2210
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-3", children: [
2211
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-3 p-4 bg-gray-50 border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors", children: [
2212
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1965
2213
  "input",
1966
2214
  {
1967
2215
  type: "checkbox",
@@ -1970,13 +2218,13 @@ var SpreadsheetSettingsModal = ({
1970
2218
  className: "w-5 h-5 cursor-pointer rounded border-gray-300 text-blue-600 focus:ring-blue-500"
1971
2219
  }
1972
2220
  ),
1973
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex-1", children: [
1974
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm font-medium text-gray-900", children: "Auto-save changes" }),
1975
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm text-gray-500 mt-0.5", children: "Automatically save changes without confirmation" })
2221
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1", children: [
2222
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-sm font-medium text-gray-900", children: "Auto-save changes" }),
2223
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-sm text-gray-500 mt-0.5", children: "Automatically save changes without confirmation" })
1976
2224
  ] })
1977
2225
  ] }),
1978
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-3 p-4 bg-gray-50 border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors", children: [
1979
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2226
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-3 p-4 bg-gray-50 border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors", children: [
2227
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1980
2228
  "input",
1981
2229
  {
1982
2230
  type: "checkbox",
@@ -1988,16 +2236,16 @@ var SpreadsheetSettingsModal = ({
1988
2236
  className: "w-5 h-5 cursor-pointer rounded border-gray-300 text-blue-600 focus:ring-blue-500"
1989
2237
  }
1990
2238
  ),
1991
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex-1", children: [
1992
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm font-medium text-gray-900", children: "Compact view" }),
1993
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm text-gray-500 mt-0.5", children: "Reduce padding and spacing to show more rows on screen" })
2239
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1", children: [
2240
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-sm font-medium text-gray-900", children: "Compact view" }),
2241
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-sm text-gray-500 mt-0.5", children: "Reduce padding and spacing to show more rows on screen" })
1994
2242
  ] })
1995
2243
  ] })
1996
2244
  ] })
1997
2245
  ] })
1998
2246
  ] }),
1999
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "px-6 py-4 border-t border-gray-200 flex justify-between items-center gap-3", children: [
2000
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2247
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "px-6 py-4 border-t border-gray-200 flex justify-between items-center gap-3", children: [
2248
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2001
2249
  "button",
2002
2250
  {
2003
2251
  type: "button",
@@ -2006,8 +2254,8 @@ var SpreadsheetSettingsModal = ({
2006
2254
  children: "Reset to Defaults"
2007
2255
  }
2008
2256
  ),
2009
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex gap-2", children: [
2010
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2257
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-2", children: [
2258
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2011
2259
  "button",
2012
2260
  {
2013
2261
  type: "button",
@@ -2016,7 +2264,7 @@ var SpreadsheetSettingsModal = ({
2016
2264
  children: "Cancel"
2017
2265
  }
2018
2266
  ),
2019
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2267
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2020
2268
  "button",
2021
2269
  {
2022
2270
  type: "button",
@@ -2036,7 +2284,7 @@ SpreadsheetSettingsModal.displayName = "SpreadsheetSettingsModal";
2036
2284
 
2037
2285
  // src/components/CommentModals.tsx
2038
2286
  var import_react9 = require("react");
2039
- var import_jsx_runtime9 = require("react/jsx-runtime");
2287
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2040
2288
  function AddCommentModal({ isOpen, columnLabel, onAdd, onClose }) {
2041
2289
  const [commentText, setCommentText] = (0, import_react9.useState)("");
2042
2290
  (0, import_react9.useEffect)(() => {
@@ -2055,12 +2303,12 @@ function AddCommentModal({ isOpen, columnLabel, onAdd, onClose }) {
2055
2303
  setCommentText("");
2056
2304
  onClose();
2057
2305
  };
2058
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-96 max-w-full mx-4", children: [
2059
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("h3", { className: "text-lg font-semibold mb-4", children: [
2306
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-96 max-w-full mx-4", children: [
2307
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("h3", { className: "text-lg font-semibold mb-4", children: [
2060
2308
  "Add Comment",
2061
2309
  columnLabel ? ` - ${columnLabel}` : ""
2062
2310
  ] }),
2063
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2311
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2064
2312
  "textarea",
2065
2313
  {
2066
2314
  value: commentText,
@@ -2074,8 +2322,8 @@ function AddCommentModal({ isOpen, columnLabel, onAdd, onClose }) {
2074
2322
  autoFocus: true
2075
2323
  }
2076
2324
  ),
2077
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-end gap-2 mt-4", children: [
2078
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2325
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-end gap-2 mt-4", children: [
2326
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2079
2327
  "button",
2080
2328
  {
2081
2329
  type: "button",
@@ -2084,7 +2332,7 @@ function AddCommentModal({ isOpen, columnLabel, onAdd, onClose }) {
2084
2332
  children: "Cancel"
2085
2333
  }
2086
2334
  ),
2087
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2335
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2088
2336
  "button",
2089
2337
  {
2090
2338
  type: "button",
@@ -2107,13 +2355,13 @@ function ViewCommentsModal({
2107
2355
  onClose
2108
2356
  }) {
2109
2357
  if (!isOpen) return null;
2110
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-[480px] max-w-full mx-4 max-h-[80vh] flex flex-col", children: [
2111
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
2112
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("h3", { className: "text-lg font-semibold", children: [
2358
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-[480px] max-w-full mx-4 max-h-[80vh] flex flex-col", children: [
2359
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
2360
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("h3", { className: "text-lg font-semibold", children: [
2113
2361
  "Comments",
2114
2362
  columnLabel ? ` - ${columnLabel}` : ""
2115
2363
  ] }),
2116
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2364
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2117
2365
  "button",
2118
2366
  {
2119
2367
  type: "button",
@@ -2123,8 +2371,8 @@ function ViewCommentsModal({
2123
2371
  }
2124
2372
  )
2125
2373
  ] }),
2126
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1 overflow-y-auto space-y-3", children: [
2127
- comments.map((comment) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2374
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 overflow-y-auto space-y-3", children: [
2375
+ comments.map((comment) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2128
2376
  "div",
2129
2377
  {
2130
2378
  className: cn(
@@ -2132,9 +2380,9 @@ function ViewCommentsModal({
2132
2380
  comment.resolved ? "bg-gray-50 border-gray-200" : "bg-yellow-50 border-yellow-200"
2133
2381
  ),
2134
2382
  children: [
2135
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
2136
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-gray-700", children: comment.text }),
2137
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2383
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
2384
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-gray-700", children: comment.text }),
2385
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2138
2386
  "button",
2139
2387
  {
2140
2388
  type: "button",
@@ -2147,23 +2395,23 @@ function ViewCommentsModal({
2147
2395
  }
2148
2396
  )
2149
2397
  ] }),
2150
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2 mt-2 text-xs text-gray-500", children: [
2151
- comment.author && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: comment.author }),
2152
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: new Date(comment.timestamp).toLocaleString() })
2398
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 mt-2 text-xs text-gray-500", children: [
2399
+ comment.author && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: comment.author }),
2400
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: new Date(comment.timestamp).toLocaleString() })
2153
2401
  ] })
2154
2402
  ]
2155
2403
  },
2156
2404
  comment.id
2157
2405
  )),
2158
- comments.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-center text-gray-500 py-8", children: "No comments for this cell." })
2406
+ comments.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-center text-gray-500 py-8", children: "No comments for this cell." })
2159
2407
  ] }),
2160
- onAddComment && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-4 pt-4 border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2408
+ onAddComment && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4 pt-4 border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2161
2409
  "button",
2162
2410
  {
2163
2411
  type: "button",
2164
2412
  onClick: onAddComment,
2165
2413
  className: "w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center justify-center gap-2",
2166
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "+ Add Comment" })
2414
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "+ Add Comment" })
2167
2415
  }
2168
2416
  ) })
2169
2417
  ] }) });
@@ -2178,11 +2426,11 @@ function DeleteConfirmationModal({
2178
2426
  onClose
2179
2427
  }) {
2180
2428
  if (!isOpen) return null;
2181
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-96 max-w-full mx-4", children: [
2182
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "text-lg font-semibold mb-2", children: title }),
2183
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-gray-600 mb-6", children: message }),
2184
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-end gap-2", children: [
2185
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2429
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-96 max-w-full mx-4", children: [
2430
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-lg font-semibold mb-2", children: title }),
2431
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-gray-600 mb-6", children: message }),
2432
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-end gap-2", children: [
2433
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2186
2434
  "button",
2187
2435
  {
2188
2436
  type: "button",
@@ -2191,7 +2439,7 @@ function DeleteConfirmationModal({
2191
2439
  children: "Cancel"
2192
2440
  }
2193
2441
  ),
2194
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2442
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2195
2443
  "button",
2196
2444
  {
2197
2445
  type: "button",
@@ -2210,50 +2458,50 @@ DeleteConfirmationModal.displayName = "DeleteConfirmationModal";
2210
2458
 
2211
2459
  // src/components/KeyboardShortcutsModal.tsx
2212
2460
  var import_react10 = __toESM(require("react"));
2213
- var import_jsx_runtime10 = require("react/jsx-runtime");
2461
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2214
2462
  function KeyboardShortcutsModal({
2215
2463
  isOpen,
2216
2464
  onClose,
2217
2465
  shortcuts
2218
2466
  }) {
2219
2467
  if (!isOpen) return null;
2220
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto mx-4", children: [
2221
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
2222
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-xl font-bold text-gray-900", children: "Keyboard Shortcuts" }),
2223
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2468
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "bg-white rounded-lg shadow-xl p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto mx-4", children: [
2469
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
2470
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "text-xl font-bold text-gray-900", children: "Keyboard Shortcuts" }),
2471
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2224
2472
  "button",
2225
2473
  {
2226
2474
  type: "button",
2227
2475
  onClick: onClose,
2228
2476
  className: "p-1 hover:bg-gray-100 rounded",
2229
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-500 text-xl", children: "\u2715" })
2477
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-gray-500 text-xl", children: "\u2715" })
2230
2478
  }
2231
2479
  )
2232
2480
  ] }),
2233
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-6", children: [
2234
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "General", children: shortcuts.general.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2235
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Row Selection", children: shortcuts.rowSelection.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2236
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Editing", children: shortcuts.editing.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2237
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Cell Navigation", children: shortcuts.navigation.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2238
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Row Actions (hover over row #)", children: shortcuts.rowActions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2239
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-600 text-sm", children: action.label }),
2240
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-500 text-xs", children: action.description })
2481
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-6", children: [
2482
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutSection, { title: "General", children: shortcuts.general.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2483
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutSection, { title: "Row Selection", children: shortcuts.rowSelection.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2484
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutSection, { title: "Editing", children: shortcuts.editing.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2485
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutSection, { title: "Cell Navigation", children: shortcuts.navigation.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
2486
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShortcutSection, { title: "Row Actions (hover over row #)", children: shortcuts.rowActions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
2487
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-gray-600 text-sm", children: action.label }),
2488
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-gray-500 text-xs", children: action.description })
2241
2489
  ] }, index)) })
2242
2490
  ] })
2243
2491
  ] }) });
2244
2492
  }
2245
2493
  function ShortcutSection({ title, children }) {
2246
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2247
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { className: "text-gray-900 font-semibold mb-3", children: title }),
2248
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "space-y-2", children })
2494
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2495
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h4", { className: "text-gray-900 font-semibold mb-3", children: title }),
2496
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-2", children })
2249
2497
  ] });
2250
2498
  }
2251
2499
  function ShortcutRow({ label, keys }) {
2252
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2253
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-600 text-sm", children: label }),
2254
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center gap-1", children: keys.map((key, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react10.default.Fragment, { children: [
2255
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-400", children: "+" }),
2256
- key.includes("Click") ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-500 text-xs", children: key }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("kbd", { className: "px-2 py-1 bg-gray-100 text-gray-800 rounded text-xs border border-gray-200", children: key })
2500
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
2501
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-gray-600 text-sm", children: label }),
2502
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex items-center gap-1", children: keys.map((key, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react10.default.Fragment, { children: [
2503
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-gray-400", children: "+" }),
2504
+ key.includes("Click") ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-gray-500 text-xs", children: key }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("kbd", { className: "px-2 py-1 bg-gray-100 text-gray-800 rounded text-xs border border-gray-200", children: key })
2257
2505
  ] }, index)) })
2258
2506
  ] });
2259
2507
  }
@@ -2262,7 +2510,7 @@ KeyboardShortcutsModal.displayName = "KeyboardShortcutsModal";
2262
2510
  // src/components/RowContextMenu.tsx
2263
2511
  var import_react11 = require("react");
2264
2512
  var import_design_system = require("@xcelsior/design-system");
2265
- var import_jsx_runtime11 = require("react/jsx-runtime");
2513
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2266
2514
  function RowContextMenu({
2267
2515
  row,
2268
2516
  rowId,
@@ -2276,10 +2524,10 @@ function RowContextMenu({
2276
2524
  if (visibleItems.length === 0) {
2277
2525
  return null;
2278
2526
  }
2279
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2527
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2280
2528
  import_design_system.ContextMenu,
2281
2529
  {
2282
- trigger: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2530
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2283
2531
  "button",
2284
2532
  {
2285
2533
  type: "button",
@@ -2288,7 +2536,7 @@ function RowContextMenu({
2288
2536
  className
2289
2537
  ),
2290
2538
  title: "More actions",
2291
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2539
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2292
2540
  HiDotsVertical,
2293
2541
  {
2294
2542
  className: cn("text-gray-500", compactMode ? "h-2.5 w-2.5" : "h-3 w-3")
@@ -2300,7 +2548,7 @@ function RowContextMenu({
2300
2548
  children: visibleItems.map((item) => {
2301
2549
  const isDisabled = item.disabled?.(row);
2302
2550
  const variantClass = item.variant === "destructive" ? "text-red-600 hover:bg-red-50" : "";
2303
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2551
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2304
2552
  import_design_system.ContextMenuItem,
2305
2553
  {
2306
2554
  onClick: (e) => {
@@ -2310,7 +2558,7 @@ function RowContextMenu({
2310
2558
  disabled: isDisabled,
2311
2559
  className: `${variantClass} ${item.className || ""}`,
2312
2560
  children: [
2313
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "mr-2", children: item.icon }),
2561
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "mr-2", children: item.icon }),
2314
2562
  item.label
2315
2563
  ]
2316
2564
  },
@@ -2327,7 +2575,7 @@ var import_design_system2 = require("@xcelsior/design-system");
2327
2575
 
2328
2576
  // src/hooks/useSpreadsheetFiltering.ts
2329
2577
  var import_react12 = require("react");
2330
- var import_utils10 = require("@xcelsior/utils");
2578
+ var import_utils11 = require("@xcelsior/utils");
2331
2579
  function useSpreadsheetFiltering({
2332
2580
  data,
2333
2581
  columns,
@@ -2525,13 +2773,13 @@ function useSpreadsheetFiltering({
2525
2773
  [sortConfig?.columnId]
2526
2774
  );
2527
2775
  const filteredData = (0, import_react12.useMemo)(() => {
2528
- if (!data || !Array.isArray(data)) return import_utils10.LazyArray.empty();
2776
+ if (!data || !Array.isArray(data)) return import_utils11.LazyArray.empty();
2529
2777
  if (serverSide) {
2530
- return import_utils10.LazyArray.from(data);
2778
+ return import_utils11.LazyArray.from(data);
2531
2779
  }
2532
- if (!columns || !Array.isArray(columns)) return import_utils10.LazyArray.from(data);
2533
- let lazyResult = import_utils10.LazyArray.from(data);
2534
- const filterChain = new import_utils10.FilterChain();
2780
+ if (!columns || !Array.isArray(columns)) return import_utils11.LazyArray.from(data);
2781
+ let lazyResult = import_utils11.LazyArray.from(data);
2782
+ const filterChain = new import_utils11.FilterChain();
2535
2783
  for (const [columnId, filter] of Object.entries(filters)) {
2536
2784
  if (!filter) continue;
2537
2785
  const column = columns.find((c) => c.id === columnId);
@@ -3409,7 +3657,7 @@ function useSpreadsheetSelection({
3409
3657
  }
3410
3658
 
3411
3659
  // src/components/Spreadsheet.tsx
3412
- var import_jsx_runtime12 = require("react/jsx-runtime");
3660
+ var import_jsx_runtime13 = require("react/jsx-runtime");
3413
3661
  function Spreadsheet({
3414
3662
  data,
3415
3663
  columns,
@@ -3540,6 +3788,7 @@ function Spreadsheet({
3540
3788
  onToggleCommentResolved
3541
3789
  });
3542
3790
  const [showSettingsModal, setShowSettingsModal] = (0, import_react17.useState)(false);
3791
+ const [showFiltersPanel, setShowFiltersPanel] = (0, import_react17.useState)(false);
3543
3792
  const {
3544
3793
  canUndo,
3545
3794
  canRedo,
@@ -3984,8 +4233,8 @@ function Spreadsheet({
3984
4233
  );
3985
4234
  return [...leftPinned, ...groups, ...rightPinned];
3986
4235
  }, [columnGroups, collapsedGroups, columns, pinnedColumns]);
3987
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cn("flex flex-col h-full bg-white", className), children: [
3988
- showToolbar && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4236
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("flex flex-col h-full bg-white", className), children: [
4237
+ showToolbar && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3989
4238
  SpreadsheetToolbar,
3990
4239
  {
3991
4240
  zoom,
@@ -3999,6 +4248,11 @@ function Spreadsheet({
3999
4248
  autoSave: spreadsheetSettings.autoSave,
4000
4249
  hasActiveFilters,
4001
4250
  onClearFilters: clearAllFilters,
4251
+ filters,
4252
+ columns,
4253
+ onClearFilter: (columnId) => handleFilterChange(columnId, void 0),
4254
+ showFiltersPanel,
4255
+ onToggleFiltersPanel: () => setShowFiltersPanel(!showFiltersPanel),
4002
4256
  onZoomIn: () => setZoom((z) => Math.min(z + 10, 200)),
4003
4257
  onZoomOut: () => setZoom((z) => Math.max(z - 10, 50)),
4004
4258
  onZoomReset: () => setZoom(100),
@@ -4015,16 +4269,16 @@ function Spreadsheet({
4015
4269
  menuItems: toolbarMenuItems
4016
4270
  }
4017
4271
  ),
4018
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: tableRef, className: "flex-1 overflow-auto border border-gray-200 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4272
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: tableRef, className: "flex-1 overflow-auto border border-gray-200 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4019
4273
  "div",
4020
4274
  {
4021
4275
  style: {
4022
4276
  zoom: zoom / 100
4023
4277
  },
4024
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("table", { className: "border-separate border-spacing-0 text-xs select-none", children: [
4025
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("thead", { children: [
4026
- columnGroups && groupHeaderItems && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("tr", { children: [
4027
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4278
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("table", { className: "border-separate border-spacing-0 text-xs select-none", children: [
4279
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("thead", { children: [
4280
+ columnGroups && groupHeaderItems && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("tr", { children: [
4281
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4028
4282
  RowIndexColumnHeader,
4029
4283
  {
4030
4284
  enableHighlighting,
@@ -4040,7 +4294,11 @@ function Spreadsheet({
4040
4294
  if (item.type === "pinned-column") {
4041
4295
  const col = columns.find((c) => c.id === item.columnId);
4042
4296
  const isPinnedLeft = item.pinSide === "left";
4043
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4297
+ const pinnedWidth = Math.max(
4298
+ col?.minWidth || col?.width || MIN_PINNED_COLUMN_WIDTH,
4299
+ MIN_PINNED_COLUMN_WIDTH
4300
+ );
4301
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4044
4302
  "th",
4045
4303
  {
4046
4304
  className: cn(
@@ -4052,14 +4310,14 @@ function Spreadsheet({
4052
4310
  position: "sticky",
4053
4311
  left: isPinnedLeft ? `${getColumnLeftOffset(item.columnId)}px` : void 0,
4054
4312
  right: !isPinnedLeft ? `${getColumnRightOffset(item.columnId)}px` : void 0,
4055
- minWidth: col?.minWidth || col?.width
4313
+ minWidth: pinnedWidth
4056
4314
  }
4057
4315
  },
4058
4316
  `pinned-group-${item.columnId}`
4059
4317
  );
4060
4318
  }
4061
4319
  const { group, colSpan, isCollapsed } = item;
4062
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4320
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4063
4321
  "th",
4064
4322
  {
4065
4323
  colSpan,
@@ -4071,17 +4329,17 @@ function Spreadsheet({
4071
4329
  backgroundColor: group.headerColor || "rgb(243 244 246)"
4072
4330
  },
4073
4331
  onClick: () => group.collapsible && handleToggleGroupCollapse(group.id),
4074
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
4075
- group.collapsible && (isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(HiChevronRight, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(HiChevronDown, { className: "h-3 w-3" })),
4076
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: group.label })
4332
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
4333
+ group.collapsible && (isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(HiChevronRight, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(HiChevronDown, { className: "h-3 w-3" })),
4334
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: group.label })
4077
4335
  ] })
4078
4336
  },
4079
4337
  group.id
4080
4338
  );
4081
4339
  })
4082
4340
  ] }),
4083
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("tr", { children: [
4084
- !columnGroups && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4341
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("tr", { children: [
4342
+ !columnGroups && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4085
4343
  RowIndexColumnHeader,
4086
4344
  {
4087
4345
  enableHighlighting,
@@ -4095,7 +4353,7 @@ function Spreadsheet({
4095
4353
  ),
4096
4354
  columnRenderItems.map((item) => {
4097
4355
  if (item.type === "collapsed-placeholder") {
4098
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4356
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4099
4357
  "th",
4100
4358
  {
4101
4359
  className: "border border-gray-200 px-2 py-1 text-center text-gray-400",
@@ -4111,7 +4369,7 @@ function Spreadsheet({
4111
4369
  const column = item.column;
4112
4370
  const isPinnedLeft = isColumnPinned(column.id) && getColumnPinSide(column.id) === "left";
4113
4371
  const isPinnedRight = isColumnPinned(column.id) && getColumnPinSide(column.id) === "right";
4114
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4372
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4115
4373
  SpreadsheetHeader,
4116
4374
  {
4117
4375
  column,
@@ -4129,7 +4387,7 @@ function Spreadsheet({
4129
4387
  ),
4130
4388
  onPinClick: () => handleTogglePin(column.id),
4131
4389
  onHighlightClick: enableHighlighting ? () => setHighlightPickerColumn(column.id) : void 0,
4132
- children: activeFilterColumn === column.id && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4390
+ children: activeFilterColumn === column.id && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4133
4391
  SpreadsheetFilterDropdown,
4134
4392
  {
4135
4393
  column,
@@ -4144,17 +4402,17 @@ function Spreadsheet({
4144
4402
  })
4145
4403
  ] })
4146
4404
  ] }),
4147
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("tbody", { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4405
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("tbody", { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4148
4406
  "td",
4149
4407
  {
4150
4408
  colSpan: columnRenderItems.length + 1,
4151
4409
  className: "text-center py-8 text-gray-500",
4152
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [
4153
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" }),
4410
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [
4411
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" }),
4154
4412
  "Loading..."
4155
4413
  ] })
4156
4414
  }
4157
- ) }) : paginatedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4415
+ ) }) : paginatedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4158
4416
  "td",
4159
4417
  {
4160
4418
  colSpan: columnRenderItems.length + 1,
@@ -4167,7 +4425,7 @@ function Spreadsheet({
4167
4425
  const isRowHovered = hoveredRow === rowId;
4168
4426
  const rowHighlight = getRowHighlight(rowId);
4169
4427
  const displayIndex = rowIndex + 1 + (currentPage - 1) * pageSize;
4170
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4428
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4171
4429
  "tr",
4172
4430
  {
4173
4431
  onMouseEnter: () => setHoveredRow(rowId),
@@ -4177,7 +4435,7 @@ function Spreadsheet({
4177
4435
  },
4178
4436
  onDoubleClick: () => onRowDoubleClick?.(row, rowIndex),
4179
4437
  children: [
4180
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4438
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4181
4439
  "td",
4182
4440
  {
4183
4441
  onClick: (e) => handleRowSelect(rowId, e),
@@ -4198,10 +4456,10 @@ function Spreadsheet({
4198
4456
  left: 0
4199
4457
  }
4200
4458
  },
4201
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative flex items-center justify-center w-full h-full", children: [
4202
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: displayIndex }),
4203
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "absolute inset-0 flex items-center justify-evenly", children: [
4204
- rowContextMenuItems && rowContextMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4459
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative flex items-center justify-center w-full h-full", children: [
4460
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: displayIndex }),
4461
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "absolute inset-0 flex items-center justify-evenly", children: [
4462
+ rowContextMenuItems && rowContextMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4205
4463
  RowContextMenu,
4206
4464
  {
4207
4465
  row,
@@ -4210,7 +4468,7 @@ function Spreadsheet({
4210
4468
  compactMode: effectiveCompactMode
4211
4469
  }
4212
4470
  ),
4213
- enableHighlighting && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4471
+ enableHighlighting && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4214
4472
  "button",
4215
4473
  {
4216
4474
  type: "button",
@@ -4220,7 +4478,7 @@ function Spreadsheet({
4220
4478
  },
4221
4479
  className: "opacity-0 group-hover:opacity-100 transition-opacity p-0.5 bg-gray-100 hover:bg-gray-200 rounded",
4222
4480
  title: "Highlight row",
4223
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4481
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4224
4482
  AiFillHighlight,
4225
4483
  {
4226
4484
  className: cn(
@@ -4234,7 +4492,7 @@ function Spreadsheet({
4234
4492
  enableComments && (cellHasComments(
4235
4493
  rowId,
4236
4494
  ROW_INDEX_COLUMN_ID
4237
- ) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4495
+ ) ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4238
4496
  "button",
4239
4497
  {
4240
4498
  type: "button",
@@ -4248,11 +4506,11 @@ function Spreadsheet({
4248
4506
  className: "p-0.5 bg-amber-100 hover:bg-amber-200 rounded transition-colors flex items-center gap-0.5",
4249
4507
  title: `${getCellUnresolvedCommentCount(rowId, ROW_INDEX_COLUMN_ID)} comment(s) - click to view`,
4250
4508
  children: [
4251
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FaComment, { className: "h-2.5 w-2.5 text-amber-500" }),
4509
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FaComment, { className: "h-2.5 w-2.5 text-amber-500" }),
4252
4510
  getCellUnresolvedCommentCount(
4253
4511
  rowId,
4254
4512
  ROW_INDEX_COLUMN_ID
4255
- ) > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-[9px] font-medium text-amber-600", children: getCellUnresolvedCommentCount(
4513
+ ) > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-[9px] font-medium text-amber-600", children: getCellUnresolvedCommentCount(
4256
4514
  rowId,
4257
4515
  ROW_INDEX_COLUMN_ID
4258
4516
  ) > 99 ? "99+" : getCellUnresolvedCommentCount(
@@ -4261,7 +4519,7 @@ function Spreadsheet({
4261
4519
  ) })
4262
4520
  ]
4263
4521
  }
4264
- ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4522
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4265
4523
  "button",
4266
4524
  {
4267
4525
  type: "button",
@@ -4274,13 +4532,13 @@ function Spreadsheet({
4274
4532
  },
4275
4533
  className: "opacity-0 group-hover:opacity-100 transition-opacity p-0.5 bg-gray-100 hover:bg-gray-200 rounded",
4276
4534
  title: "Add comment",
4277
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FaRegComment, { className: "h-2.5 w-2.5 text-gray-500" })
4535
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FaRegComment, { className: "h-2.5 w-2.5 text-gray-500" })
4278
4536
  }
4279
4537
  )),
4280
4538
  rowActions?.map((action) => {
4281
4539
  if (action.visible && !action.visible(row))
4282
4540
  return null;
4283
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4541
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4284
4542
  "button",
4285
4543
  {
4286
4544
  type: "button",
@@ -4304,7 +4562,7 @@ function Spreadsheet({
4304
4562
  ),
4305
4563
  columnRenderItems.map((item) => {
4306
4564
  if (item.type === "collapsed-placeholder") {
4307
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4565
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4308
4566
  "td",
4309
4567
  {
4310
4568
  className: "border border-gray-200 px-2 py-1 text-center text-gray-300",
@@ -4330,7 +4588,7 @@ function Spreadsheet({
4330
4588
  const cellOrRowOrColumnHighlight = getCellHighlight(rowId, column.id) || rowHighlight?.color || getColumnHighlight(column.id);
4331
4589
  const isColPinned = isColumnPinned(column.id);
4332
4590
  const colPinSide = getColumnPinSide(column.id);
4333
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4591
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4334
4592
  MemoizedSpreadsheetCell,
4335
4593
  {
4336
4594
  value,
@@ -4390,7 +4648,7 @@ function Spreadsheet({
4390
4648
  ] })
4391
4649
  }
4392
4650
  ) }),
4393
- showPagination && effectiveTotalItems > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4651
+ showPagination && effectiveTotalItems > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4394
4652
  import_design_system2.Pagination,
4395
4653
  {
4396
4654
  currentPage,
@@ -4405,7 +4663,7 @@ function Spreadsheet({
4405
4663
  onPageSizeChange: handlePageSizeChange
4406
4664
  }
4407
4665
  ),
4408
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4666
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4409
4667
  AddCommentModal,
4410
4668
  {
4411
4669
  isOpen: commentModalCell !== null,
@@ -4416,7 +4674,7 @@ function Spreadsheet({
4416
4674
  }
4417
4675
  }
4418
4676
  ),
4419
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4677
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4420
4678
  ViewCommentsModal,
4421
4679
  {
4422
4680
  isOpen: viewCommentsCell !== null,
@@ -4431,7 +4689,7 @@ function Spreadsheet({
4431
4689
  onClose: () => setViewCommentsCell(null)
4432
4690
  }
4433
4691
  ),
4434
- highlightPickerRow !== null && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4692
+ highlightPickerRow !== null && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4435
4693
  ColorPickerPopover,
4436
4694
  {
4437
4695
  title: "Highlight Row",
@@ -4440,7 +4698,7 @@ function Spreadsheet({
4440
4698
  onClose: () => setHighlightPickerRow(null)
4441
4699
  }
4442
4700
  ),
4443
- highlightPickerColumn !== null && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4701
+ highlightPickerColumn !== null && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4444
4702
  ColorPickerPopover,
4445
4703
  {
4446
4704
  title: highlightPickerColumn === ROW_INDEX_COLUMN_ID ? "Highlight Row Index Column" : `Highlight Column: ${columns.find((c) => c.id === highlightPickerColumn)?.label || ""}`,
@@ -4449,7 +4707,7 @@ function Spreadsheet({
4449
4707
  onClose: () => setHighlightPickerColumn(null)
4450
4708
  }
4451
4709
  ),
4452
- highlightPickerCell !== null && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4710
+ highlightPickerCell !== null && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4453
4711
  ColorPickerPopover,
4454
4712
  {
4455
4713
  title: "Highlight Cell",
@@ -4462,7 +4720,7 @@ function Spreadsheet({
4462
4720
  onClose: () => setHighlightPickerCell(null)
4463
4721
  }
4464
4722
  ),
4465
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4723
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4466
4724
  KeyboardShortcutsModal,
4467
4725
  {
4468
4726
  isOpen: showKeyboardShortcuts,
@@ -4470,7 +4728,7 @@ function Spreadsheet({
4470
4728
  shortcuts
4471
4729
  }
4472
4730
  ),
4473
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4731
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4474
4732
  SpreadsheetSettingsModal,
4475
4733
  {
4476
4734
  isOpen: showSettingsModal,
@@ -4498,6 +4756,7 @@ function Spreadsheet({
4498
4756
  Spreadsheet.displayName = "Spreadsheet";
4499
4757
  // Annotate the CommonJS export names for ESM import in node:
4500
4758
  0 && (module.exports = {
4759
+ ActiveFiltersDisplay,
4501
4760
  RowContextMenu,
4502
4761
  Spreadsheet,
4503
4762
  SpreadsheetCell,