@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.d.mts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +824 -565
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +805 -547
- package/dist/index.mjs.map +1 -1
- package/dist/styles/globals.css +58 -0
- package/dist/styles/globals.css.map +1 -1
- package/package.json +1 -1
- package/src/components/ActiveFiltersDisplay.tsx +257 -0
- package/src/components/Spreadsheet.tsx +16 -1
- package/src/components/SpreadsheetCell.tsx +13 -0
- package/src/components/SpreadsheetHeader.tsx +13 -0
- package/src/components/SpreadsheetToolbar.tsx +62 -19
- package/src/hooks/useSpreadsheetPinning.ts +8 -3
- package/src/index.ts +2 -0
- package/src/types.ts +10 -0
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,
|
|
228
|
-
const inputRef = (0,
|
|
229
|
-
const selectRef = (0,
|
|
230
|
-
(0,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
720
|
+
const [textOperator, setTextOperator] = (0, import_react5.useState)(
|
|
553
721
|
filter?.textCondition?.operator || "contains"
|
|
554
722
|
);
|
|
555
|
-
const [textValue, setTextValue] = (0,
|
|
556
|
-
const [numberOperator, setNumberOperator] = (0,
|
|
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,
|
|
727
|
+
const [numberValue, setNumberValue] = (0, import_react5.useState)(
|
|
560
728
|
filter?.numberCondition?.value?.toString() || ""
|
|
561
729
|
);
|
|
562
|
-
const [numberValueTo, setNumberValueTo] = (0,
|
|
730
|
+
const [numberValueTo, setNumberValueTo] = (0, import_react5.useState)(
|
|
563
731
|
filter?.numberCondition?.valueTo?.toString() || ""
|
|
564
732
|
);
|
|
565
|
-
const [dateOperator, setDateOperator] = (0,
|
|
733
|
+
const [dateOperator, setDateOperator] = (0, import_react5.useState)(
|
|
566
734
|
filter?.dateCondition?.operator || "equals"
|
|
567
735
|
);
|
|
568
|
-
const [dateValue, setDateValue] = (0,
|
|
569
|
-
const [dateValueTo, setDateValueTo] = (0,
|
|
570
|
-
const dropdownRef = (0,
|
|
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,
|
|
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
|
|
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] =
|
|
839
|
-
const menuRef =
|
|
840
|
-
|
|
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
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
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:
|
|
918
|
-
disabled: !canRedo,
|
|
1356
|
+
onClick: onToggleFiltersPanel,
|
|
919
1357
|
className: cn(
|
|
920
|
-
|
|
921
|
-
|
|
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:
|
|
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
|
-
|
|
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,
|
|
954
|
-
"
|
|
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
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
children:
|
|
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
|
-
|
|
985
|
-
/* @__PURE__ */ (0,
|
|
986
|
-
|
|
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
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
children:
|
|
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:
|
|
1048
|
-
|
|
1049
|
-
|
|
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,
|
|
1052
|
-
|
|
1413
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HiCheck, { className: "h-3.5 w-3.5" }),
|
|
1414
|
+
"Save"
|
|
1053
1415
|
]
|
|
1054
1416
|
}
|
|
1055
1417
|
),
|
|
1056
|
-
|
|
1057
|
-
|
|
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
|
-
|
|
1078
|
-
|
|
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,
|
|
1083
|
-
/* @__PURE__ */ (0,
|
|
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
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
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
|
|
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,
|
|
1144
|
-
enableFiltering && onFilterClick && /* @__PURE__ */ (0,
|
|
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,
|
|
1543
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HiFilter, { className: "h-3 w-3" })
|
|
1158
1544
|
}
|
|
1159
1545
|
),
|
|
1160
|
-
enableHighlighting && onHighlightClick && /* @__PURE__ */ (0,
|
|
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,
|
|
1559
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AiFillHighlight, { className: "h-3 w-3" })
|
|
1174
1560
|
}
|
|
1175
1561
|
),
|
|
1176
|
-
enablePinning && onPinClick && /* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
1253
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
1464
|
-
/* @__PURE__ */ (0,
|
|
1465
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
1679
|
-
/* @__PURE__ */ (0,
|
|
1680
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
1804
|
-
/* @__PURE__ */ (0,
|
|
1805
|
-
/* @__PURE__ */ (0,
|
|
1806
|
-
/* @__PURE__ */ (0,
|
|
1807
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2063
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HiX, { className: "h-5 w-5" })
|
|
1816
2064
|
}
|
|
1817
2065
|
)
|
|
1818
2066
|
] }),
|
|
1819
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
1833
|
-
activeTab === "columns" && /* @__PURE__ */ (0,
|
|
1834
|
-
/* @__PURE__ */ (0,
|
|
1835
|
-
/* @__PURE__ */ (0,
|
|
1836
|
-
/* @__PURE__ */ (0,
|
|
1837
|
-
/* @__PURE__ */ (0,
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1842
|
-
/* @__PURE__ */ (0,
|
|
1843
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1851
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1876
|
-
/* @__PURE__ */ (0,
|
|
1877
|
-
/* @__PURE__ */ (0,
|
|
1878
|
-
/* @__PURE__ */ (0,
|
|
1879
|
-
/* @__PURE__ */ (0,
|
|
1880
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1891
|
-
columns.filter((col) => col.sortable !== false).map((column) => /* @__PURE__ */ (0,
|
|
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,
|
|
1897
|
-
/* @__PURE__ */ (0,
|
|
1898
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1909
|
-
/* @__PURE__ */ (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,
|
|
1917
|
-
/* @__PURE__ */ (0,
|
|
1918
|
-
/* @__PURE__ */ (0,
|
|
1919
|
-
/* @__PURE__ */ (0,
|
|
1920
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
1937
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
1958
|
-
/* @__PURE__ */ (0,
|
|
1959
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1963
|
-
/* @__PURE__ */ (0,
|
|
1964
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1974
|
-
/* @__PURE__ */ (0,
|
|
1975
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1979
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1992
|
-
/* @__PURE__ */ (0,
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2000
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2010
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2078
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2111
|
-
/* @__PURE__ */ (0,
|
|
2112
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2127
|
-
comments.map((comment) => /* @__PURE__ */ (0,
|
|
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,
|
|
2136
|
-
/* @__PURE__ */ (0,
|
|
2137
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2151
|
-
comment.author && /* @__PURE__ */ (0,
|
|
2152
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
2182
|
-
/* @__PURE__ */ (0,
|
|
2183
|
-
/* @__PURE__ */ (0,
|
|
2184
|
-
/* @__PURE__ */ (0,
|
|
2185
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
2221
|
-
/* @__PURE__ */ (0,
|
|
2222
|
-
/* @__PURE__ */ (0,
|
|
2223
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2234
|
-
/* @__PURE__ */ (0,
|
|
2235
|
-
/* @__PURE__ */ (0,
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2237
|
-
/* @__PURE__ */ (0,
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
2240
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2247
|
-
/* @__PURE__ */ (0,
|
|
2248
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2253
|
-
/* @__PURE__ */ (0,
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2255
|
-
index > 0 && /* @__PURE__ */ (0,
|
|
2256
|
-
key.includes("Click") ? /* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
2527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2280
2528
|
import_design_system.ContextMenu,
|
|
2281
2529
|
{
|
|
2282
|
-
trigger: /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
2776
|
+
if (!data || !Array.isArray(data)) return import_utils11.LazyArray.empty();
|
|
2529
2777
|
if (serverSide) {
|
|
2530
|
-
return
|
|
2778
|
+
return import_utils11.LazyArray.from(data);
|
|
2531
2779
|
}
|
|
2532
|
-
if (!columns || !Array.isArray(columns)) return
|
|
2533
|
-
let lazyResult =
|
|
2534
|
-
const filterChain = new
|
|
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
|
|
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,
|
|
3988
|
-
showToolbar && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4025
|
-
/* @__PURE__ */ (0,
|
|
4026
|
-
columnGroups && groupHeaderItems && /* @__PURE__ */ (0,
|
|
4027
|
-
/* @__PURE__ */ (0,
|
|
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
|
-
|
|
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:
|
|
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,
|
|
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,
|
|
4075
|
-
group.collapsible && (isCollapsed ? /* @__PURE__ */ (0,
|
|
4076
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4084
|
-
!columnGroups && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
4202
|
-
/* @__PURE__ */ (0,
|
|
4203
|
-
/* @__PURE__ */ (0,
|
|
4204
|
-
rowContextMenuItems && rowContextMenuItems.length > 0 && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|