@xcelsior/ui-spreadsheets 1.1.6 → 1.1.8
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 +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles/globals.css +3 -0
- package/dist/styles/globals.css.map +1 -1
- package/package.json +2 -2
- package/src/components/RowContextMenu.tsx +1 -1
- package/src/components/Spreadsheet.stories.tsx +148 -0
- package/src/components/Spreadsheet.tsx +9 -0
- package/src/components/SpreadsheetCell.tsx +28 -0
- package/src/hooks/useSpreadsheetPinning.ts +30 -0
- package/src/types.ts +5 -2
package/dist/index.d.mts
CHANGED
|
@@ -24,7 +24,7 @@ interface SpreadsheetColumn<T = any> {
|
|
|
24
24
|
/** Whether the column can be pinned */
|
|
25
25
|
pinnable?: boolean;
|
|
26
26
|
/** Type of data in the column (for filtering/formatting) */
|
|
27
|
-
type?: 'text' | 'number' | 'date' | 'select' | 'boolean';
|
|
27
|
+
type?: 'text' | 'number' | 'date' | 'select' | 'boolean' | 'checkbox';
|
|
28
28
|
/** Options for select type columns */
|
|
29
29
|
options?: string[];
|
|
30
30
|
/** Custom render function for cell content */
|
|
@@ -323,8 +323,10 @@ interface SpreadsheetProps<T = any> {
|
|
|
323
323
|
onSave?: () => void | Promise<void>;
|
|
324
324
|
/** Initial settings (optional). All settings can be changed by user in the settings modal. */
|
|
325
325
|
settings?: {
|
|
326
|
-
/** Default pinned column IDs */
|
|
326
|
+
/** Default pinned column IDs (pinned to left) */
|
|
327
327
|
defaultPinnedColumns?: string[];
|
|
328
|
+
/** Default pinned column IDs (pinned to right) */
|
|
329
|
+
defaultPinnedRightColumns?: string[];
|
|
328
330
|
/** Default sort configuration */
|
|
329
331
|
defaultSort?: SpreadsheetSortConfig | null;
|
|
330
332
|
/** Default page size */
|
|
@@ -343,6 +345,7 @@ interface SpreadsheetProps<T = any> {
|
|
|
343
345
|
defaultPageSize?: number;
|
|
344
346
|
defaultZoom?: number;
|
|
345
347
|
defaultPinnedColumns?: string[];
|
|
348
|
+
defaultPinnedRightColumns?: string[];
|
|
346
349
|
defaultSort?: SpreadsheetSortConfig | null;
|
|
347
350
|
}) => void;
|
|
348
351
|
/** Loading state */
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ interface SpreadsheetColumn<T = any> {
|
|
|
24
24
|
/** Whether the column can be pinned */
|
|
25
25
|
pinnable?: boolean;
|
|
26
26
|
/** Type of data in the column (for filtering/formatting) */
|
|
27
|
-
type?: 'text' | 'number' | 'date' | 'select' | 'boolean';
|
|
27
|
+
type?: 'text' | 'number' | 'date' | 'select' | 'boolean' | 'checkbox';
|
|
28
28
|
/** Options for select type columns */
|
|
29
29
|
options?: string[];
|
|
30
30
|
/** Custom render function for cell content */
|
|
@@ -323,8 +323,10 @@ interface SpreadsheetProps<T = any> {
|
|
|
323
323
|
onSave?: () => void | Promise<void>;
|
|
324
324
|
/** Initial settings (optional). All settings can be changed by user in the settings modal. */
|
|
325
325
|
settings?: {
|
|
326
|
-
/** Default pinned column IDs */
|
|
326
|
+
/** Default pinned column IDs (pinned to left) */
|
|
327
327
|
defaultPinnedColumns?: string[];
|
|
328
|
+
/** Default pinned column IDs (pinned to right) */
|
|
329
|
+
defaultPinnedRightColumns?: string[];
|
|
328
330
|
/** Default sort configuration */
|
|
329
331
|
defaultSort?: SpreadsheetSortConfig | null;
|
|
330
332
|
/** Default page size */
|
|
@@ -343,6 +345,7 @@ interface SpreadsheetProps<T = any> {
|
|
|
343
345
|
defaultPageSize?: number;
|
|
344
346
|
defaultZoom?: number;
|
|
345
347
|
defaultPinnedColumns?: string[];
|
|
348
|
+
defaultPinnedRightColumns?: string[];
|
|
346
349
|
defaultSort?: SpreadsheetSortConfig | null;
|
|
347
350
|
}) => void;
|
|
348
351
|
/** Loading state */
|
package/dist/index.js
CHANGED
|
@@ -257,10 +257,31 @@ var SpreadsheetCell = ({
|
|
|
257
257
|
if (isRowHovered) return "rgb(243 244 246)";
|
|
258
258
|
return "white";
|
|
259
259
|
};
|
|
260
|
+
const handleCheckboxChange = (e) => {
|
|
261
|
+
e.stopPropagation();
|
|
262
|
+
const newValue = e.target.checked;
|
|
263
|
+
onConfirm?.(newValue);
|
|
264
|
+
};
|
|
260
265
|
const renderContent = () => {
|
|
261
266
|
if (column.render) {
|
|
262
267
|
return column.render(value, row, rowIndex);
|
|
263
268
|
}
|
|
269
|
+
if (column.type === "checkbox") {
|
|
270
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
271
|
+
"input",
|
|
272
|
+
{
|
|
273
|
+
type: "checkbox",
|
|
274
|
+
checked: Boolean(value),
|
|
275
|
+
onChange: handleCheckboxChange,
|
|
276
|
+
onClick: (e) => e.stopPropagation(),
|
|
277
|
+
disabled: !isEditable,
|
|
278
|
+
className: cn(
|
|
279
|
+
"h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 cursor-pointer",
|
|
280
|
+
!isEditable && "cursor-not-allowed opacity-60"
|
|
281
|
+
)
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
}
|
|
264
285
|
if (value === null || value === void 0 || value === "") {
|
|
265
286
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-gray-400", children: "-" });
|
|
266
287
|
}
|
|
@@ -273,6 +294,9 @@ var SpreadsheetCell = ({
|
|
|
273
294
|
return String(value);
|
|
274
295
|
};
|
|
275
296
|
const renderEditInput = () => {
|
|
297
|
+
if (column.type === "checkbox") {
|
|
298
|
+
return renderContent();
|
|
299
|
+
}
|
|
276
300
|
if (column.type === "select" && column.options) {
|
|
277
301
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
278
302
|
"select",
|
|
@@ -1260,13 +1284,17 @@ function useSpreadsheetPinning({
|
|
|
1260
1284
|
columns,
|
|
1261
1285
|
columnGroups,
|
|
1262
1286
|
showRowIndex = true,
|
|
1263
|
-
defaultPinnedColumns = []
|
|
1287
|
+
defaultPinnedColumns = [],
|
|
1288
|
+
defaultPinnedRightColumns = []
|
|
1264
1289
|
}) {
|
|
1265
1290
|
const [pinnedColumns, setPinnedColumns] = (0, import_react6.useState)(() => {
|
|
1266
1291
|
const map = /* @__PURE__ */ new Map();
|
|
1267
1292
|
defaultPinnedColumns.forEach((col) => {
|
|
1268
1293
|
map.set(col, "left");
|
|
1269
1294
|
});
|
|
1295
|
+
defaultPinnedRightColumns.forEach((col) => {
|
|
1296
|
+
map.set(col, "right");
|
|
1297
|
+
});
|
|
1270
1298
|
return map;
|
|
1271
1299
|
});
|
|
1272
1300
|
const [collapsedGroups, setCollapsedGroups] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
@@ -1369,6 +1397,20 @@ function useSpreadsheetPinning({
|
|
|
1369
1397
|
},
|
|
1370
1398
|
[pinnedColumns]
|
|
1371
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
|
+
);
|
|
1372
1414
|
return {
|
|
1373
1415
|
pinnedColumns,
|
|
1374
1416
|
isRowIndexPinned,
|
|
@@ -1378,6 +1420,7 @@ function useSpreadsheetPinning({
|
|
|
1378
1420
|
handleToggleGroupCollapse,
|
|
1379
1421
|
setPinnedColumnsFromIds,
|
|
1380
1422
|
getColumnLeftOffset,
|
|
1423
|
+
getColumnRightOffset,
|
|
1381
1424
|
isColumnPinned,
|
|
1382
1425
|
getColumnPinSide
|
|
1383
1426
|
};
|
|
@@ -3472,12 +3515,14 @@ function Spreadsheet({
|
|
|
3472
3515
|
handleToggleGroupCollapse,
|
|
3473
3516
|
setPinnedColumnsFromIds,
|
|
3474
3517
|
getColumnLeftOffset,
|
|
3518
|
+
getColumnRightOffset,
|
|
3475
3519
|
isColumnPinned,
|
|
3476
3520
|
getColumnPinSide
|
|
3477
3521
|
} = useSpreadsheetPinning({
|
|
3478
3522
|
columns,
|
|
3479
3523
|
columnGroups,
|
|
3480
|
-
defaultPinnedColumns: initialSettings?.defaultPinnedColumns
|
|
3524
|
+
defaultPinnedColumns: initialSettings?.defaultPinnedColumns,
|
|
3525
|
+
defaultPinnedRightColumns: initialSettings?.defaultPinnedRightColumns
|
|
3481
3526
|
});
|
|
3482
3527
|
const {
|
|
3483
3528
|
getCellComments,
|
|
@@ -3929,6 +3974,7 @@ function Spreadsheet({
|
|
|
3929
3974
|
),
|
|
3930
3975
|
visibleColumns.map((column) => {
|
|
3931
3976
|
const isPinnedLeft = isColumnPinned(column.id) && getColumnPinSide(column.id) === "left";
|
|
3977
|
+
const isPinnedRight = isColumnPinned(column.id) && getColumnPinSide(column.id) === "right";
|
|
3932
3978
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3933
3979
|
SpreadsheetHeader,
|
|
3934
3980
|
{
|
|
@@ -3938,6 +3984,7 @@ function Spreadsheet({
|
|
|
3938
3984
|
isPinned: isColumnPinned(column.id),
|
|
3939
3985
|
pinSide: getColumnPinSide(column.id),
|
|
3940
3986
|
leftOffset: isPinnedLeft ? getColumnLeftOffset(column.id) : 0,
|
|
3987
|
+
rightOffset: isPinnedRight ? getColumnRightOffset(column.id) : 0,
|
|
3941
3988
|
highlightColor: getColumnHighlight(column.id),
|
|
3942
3989
|
compactMode: effectiveCompactMode,
|
|
3943
3990
|
onClick: () => handleSort(column.id),
|
|
@@ -4154,6 +4201,7 @@ function Spreadsheet({
|
|
|
4154
4201
|
isPinned: isColPinned,
|
|
4155
4202
|
pinSide: colPinSide,
|
|
4156
4203
|
leftOffset: getColumnLeftOffset(column.id),
|
|
4204
|
+
rightOffset: getColumnRightOffset(column.id),
|
|
4157
4205
|
onClick: (e) => handleCellClick(rowId, column.id, e),
|
|
4158
4206
|
onConfirm: handleConfirmEdit,
|
|
4159
4207
|
onCancel: handleCancelEdit,
|