@xcelsior/ui-spreadsheets 1.1.10 → 1.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +119 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +119 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Spreadsheet.stories.tsx +121 -0
- package/src/components/Spreadsheet.tsx +161 -27
- package/src/components/SpreadsheetCell.tsx +5 -0
- package/src/components/SpreadsheetHeader.tsx +5 -0
package/dist/index.mjs
CHANGED
|
@@ -361,6 +361,11 @@ var SpreadsheetCell = ({
|
|
|
361
361
|
style: {
|
|
362
362
|
backgroundColor: isInSelection ? "rgb(239 246 255)" : getBackgroundColor(),
|
|
363
363
|
minWidth: column.minWidth || column.width,
|
|
364
|
+
// Pinned columns need fixed width so sticky offset calculations are accurate
|
|
365
|
+
...isPinned && {
|
|
366
|
+
width: column.minWidth || column.width,
|
|
367
|
+
maxWidth: column.minWidth || column.width
|
|
368
|
+
},
|
|
364
369
|
...positionStyles,
|
|
365
370
|
...selectionBorderStyles
|
|
366
371
|
},
|
|
@@ -1202,6 +1207,11 @@ var SpreadsheetHeader = ({
|
|
|
1202
1207
|
backgroundColor: highlightColor || "rgb(243 244 246)",
|
|
1203
1208
|
// gray-100
|
|
1204
1209
|
minWidth: column.minWidth || column.width,
|
|
1210
|
+
// Pinned columns need fixed width so sticky offset calculations are accurate
|
|
1211
|
+
...isPinned && {
|
|
1212
|
+
width: column.minWidth || column.width,
|
|
1213
|
+
maxWidth: column.minWidth || column.width
|
|
1214
|
+
},
|
|
1205
1215
|
top: 0,
|
|
1206
1216
|
// For sticky header
|
|
1207
1217
|
...positionStyles
|
|
@@ -3839,11 +3849,13 @@ function Spreadsheet({
|
|
|
3839
3849
|
column: col
|
|
3840
3850
|
}));
|
|
3841
3851
|
}
|
|
3842
|
-
const
|
|
3852
|
+
const leftPinnedItems = [];
|
|
3853
|
+
const middleItems = [];
|
|
3854
|
+
const rightPinnedItems = [];
|
|
3843
3855
|
for (const group of columnGroups) {
|
|
3844
3856
|
const isCollapsed = collapsedGroups.has(group.id);
|
|
3845
3857
|
if (isCollapsed) {
|
|
3846
|
-
|
|
3858
|
+
middleItems.push({
|
|
3847
3859
|
type: "collapsed-placeholder",
|
|
3848
3860
|
groupId: group.id,
|
|
3849
3861
|
headerColor: group.headerColor
|
|
@@ -3855,7 +3867,14 @@ function Spreadsheet({
|
|
|
3855
3867
|
return true;
|
|
3856
3868
|
});
|
|
3857
3869
|
for (const col of groupVisibleCols) {
|
|
3858
|
-
|
|
3870
|
+
const pinSide = pinnedColumns.get(col.id);
|
|
3871
|
+
if (pinSide === "left") {
|
|
3872
|
+
leftPinnedItems.push({ type: "column", column: col });
|
|
3873
|
+
} else if (pinSide === "right") {
|
|
3874
|
+
rightPinnedItems.push({ type: "column", column: col });
|
|
3875
|
+
} else {
|
|
3876
|
+
middleItems.push({ type: "column", column: col });
|
|
3877
|
+
}
|
|
3859
3878
|
}
|
|
3860
3879
|
}
|
|
3861
3880
|
const allGroupedIds = new Set(
|
|
@@ -3863,11 +3882,78 @@ function Spreadsheet({
|
|
|
3863
3882
|
);
|
|
3864
3883
|
for (const col of visibleColumns) {
|
|
3865
3884
|
if (!allGroupedIds.has(col.id)) {
|
|
3866
|
-
|
|
3885
|
+
const pinSide = pinnedColumns.get(col.id);
|
|
3886
|
+
if (pinSide === "left") {
|
|
3887
|
+
leftPinnedItems.push({ type: "column", column: col });
|
|
3888
|
+
} else if (pinSide === "right") {
|
|
3889
|
+
rightPinnedItems.push({ type: "column", column: col });
|
|
3890
|
+
} else {
|
|
3891
|
+
middleItems.push({ type: "column", column: col });
|
|
3892
|
+
}
|
|
3867
3893
|
}
|
|
3868
3894
|
}
|
|
3869
|
-
|
|
3895
|
+
const pinnedLeftOrder = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "left" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
|
|
3896
|
+
const pinnedRightOrder = Array.from(pinnedColumns.entries()).filter(([, side]) => side === "right").map(([id]) => id);
|
|
3897
|
+
leftPinnedItems.sort(
|
|
3898
|
+
(a, b) => pinnedLeftOrder.indexOf(a.column.id) - pinnedLeftOrder.indexOf(b.column.id)
|
|
3899
|
+
);
|
|
3900
|
+
rightPinnedItems.sort(
|
|
3901
|
+
(a, b) => pinnedRightOrder.indexOf(a.column.id) - pinnedRightOrder.indexOf(b.column.id)
|
|
3902
|
+
);
|
|
3903
|
+
return [...leftPinnedItems, ...middleItems, ...rightPinnedItems];
|
|
3870
3904
|
}, [columnGroups, collapsedGroups, columns, pinnedColumns, visibleColumns]);
|
|
3905
|
+
const groupHeaderItems = useMemo5(() => {
|
|
3906
|
+
if (!columnGroups || columnGroups.length === 0) return null;
|
|
3907
|
+
const leftPinned = [];
|
|
3908
|
+
const groups = [];
|
|
3909
|
+
const rightPinned = [];
|
|
3910
|
+
for (const group of columnGroups) {
|
|
3911
|
+
const isCollapsed = collapsedGroups.has(group.id);
|
|
3912
|
+
const groupColumns = (columns || []).filter((c) => group.columns.includes(c.id));
|
|
3913
|
+
const visibleGroupColumns = isCollapsed ? groupColumns.filter((c) => pinnedColumns.has(c.id)) : groupColumns;
|
|
3914
|
+
let movedLeftCount = 0;
|
|
3915
|
+
let movedRightCount = 0;
|
|
3916
|
+
for (const col of visibleGroupColumns) {
|
|
3917
|
+
const pinSide = pinnedColumns.get(col.id);
|
|
3918
|
+
if (pinSide === "left") {
|
|
3919
|
+
movedLeftCount++;
|
|
3920
|
+
leftPinned.push({
|
|
3921
|
+
type: "pinned-column",
|
|
3922
|
+
columnId: col.id,
|
|
3923
|
+
headerColor: group.headerColor,
|
|
3924
|
+
pinSide: "left"
|
|
3925
|
+
});
|
|
3926
|
+
} else if (pinSide === "right") {
|
|
3927
|
+
movedRightCount++;
|
|
3928
|
+
rightPinned.push({
|
|
3929
|
+
type: "pinned-column",
|
|
3930
|
+
columnId: col.id,
|
|
3931
|
+
headerColor: group.headerColor,
|
|
3932
|
+
pinSide: "right"
|
|
3933
|
+
});
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
const remainingCols = visibleGroupColumns.length - movedLeftCount - movedRightCount;
|
|
3937
|
+
const colSpan = remainingCols + (isCollapsed ? 1 : 0);
|
|
3938
|
+
if (colSpan > 0) {
|
|
3939
|
+
groups.push({
|
|
3940
|
+
type: "group",
|
|
3941
|
+
group,
|
|
3942
|
+
colSpan,
|
|
3943
|
+
isCollapsed
|
|
3944
|
+
});
|
|
3945
|
+
}
|
|
3946
|
+
}
|
|
3947
|
+
const pinnedLeftOrder = Array.from(pinnedColumns.entries()).filter(([id, side]) => side === "left" && id !== ROW_INDEX_COLUMN_ID).map(([id]) => id);
|
|
3948
|
+
const pinnedRightOrder = Array.from(pinnedColumns.entries()).filter(([, side]) => side === "right").map(([id]) => id);
|
|
3949
|
+
leftPinned.sort(
|
|
3950
|
+
(a, b) => pinnedLeftOrder.indexOf(a.columnId) - pinnedLeftOrder.indexOf(b.columnId)
|
|
3951
|
+
);
|
|
3952
|
+
rightPinned.sort(
|
|
3953
|
+
(a, b) => pinnedRightOrder.indexOf(a.columnId) - pinnedRightOrder.indexOf(b.columnId)
|
|
3954
|
+
);
|
|
3955
|
+
return [...leftPinned, ...groups, ...rightPinned];
|
|
3956
|
+
}, [columnGroups, collapsedGroups, columns, pinnedColumns]);
|
|
3871
3957
|
return /* @__PURE__ */ jsxs12("div", { className: cn("flex flex-col h-full bg-white", className), children: [
|
|
3872
3958
|
showToolbar && /* @__PURE__ */ jsx12(
|
|
3873
3959
|
SpreadsheetToolbar,
|
|
@@ -3907,7 +3993,7 @@ function Spreadsheet({
|
|
|
3907
3993
|
},
|
|
3908
3994
|
children: /* @__PURE__ */ jsxs12("table", { className: "w-full border-separate border-spacing-0 text-xs select-none", children: [
|
|
3909
3995
|
/* @__PURE__ */ jsxs12("thead", { children: [
|
|
3910
|
-
columnGroups && /* @__PURE__ */ jsxs12("tr", { children: [
|
|
3996
|
+
columnGroups && groupHeaderItems && /* @__PURE__ */ jsxs12("tr", { children: [
|
|
3911
3997
|
/* @__PURE__ */ jsx12(
|
|
3912
3998
|
RowIndexColumnHeader,
|
|
3913
3999
|
{
|
|
@@ -3920,16 +4006,33 @@ function Spreadsheet({
|
|
|
3920
4006
|
compactMode: effectiveCompactMode
|
|
3921
4007
|
}
|
|
3922
4008
|
),
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
4009
|
+
groupHeaderItems.map((item) => {
|
|
4010
|
+
if (item.type === "pinned-column") {
|
|
4011
|
+
const col = columns.find(
|
|
4012
|
+
(c) => c.id === item.columnId
|
|
4013
|
+
);
|
|
4014
|
+
const isPinnedLeft = item.pinSide === "left";
|
|
4015
|
+
return /* @__PURE__ */ jsx12(
|
|
4016
|
+
"th",
|
|
4017
|
+
{
|
|
4018
|
+
className: cn(
|
|
4019
|
+
"border border-gray-200 px-2 py-1.5 text-center font-bold text-gray-700",
|
|
4020
|
+
"z-30"
|
|
4021
|
+
),
|
|
4022
|
+
style: {
|
|
4023
|
+
backgroundColor: item.headerColor || "rgb(243 244 246)",
|
|
4024
|
+
position: "sticky",
|
|
4025
|
+
left: isPinnedLeft ? `${getColumnLeftOffset(item.columnId)}px` : void 0,
|
|
4026
|
+
right: !isPinnedLeft ? `${getColumnRightOffset(item.columnId)}px` : void 0,
|
|
4027
|
+
minWidth: col?.minWidth || col?.width,
|
|
4028
|
+
width: col?.minWidth || col?.width,
|
|
4029
|
+
maxWidth: col?.minWidth || col?.width
|
|
4030
|
+
}
|
|
4031
|
+
},
|
|
4032
|
+
`pinned-group-${item.columnId}`
|
|
4033
|
+
);
|
|
4034
|
+
}
|
|
4035
|
+
const { group, colSpan, isCollapsed } = item;
|
|
3933
4036
|
return /* @__PURE__ */ jsx12(
|
|
3934
4037
|
"th",
|
|
3935
4038
|
{
|