@xcelsior/ui-spreadsheets 1.1.13 → 1.1.14
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 +191 -172
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +181 -162
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Spreadsheet.tsx +5 -1
- package/src/components/SpreadsheetCell.tsx +7 -0
- package/src/components/SpreadsheetHeader.tsx +7 -0
- package/src/hooks/useSpreadsheetPinning.ts +8 -3
package/package.json
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
useSpreadsheetPinning,
|
|
22
22
|
ROW_INDEX_COLUMN_WIDTH,
|
|
23
23
|
ROW_INDEX_COLUMN_ID,
|
|
24
|
+
MIN_PINNED_COLUMN_WIDTH,
|
|
24
25
|
} from '../hooks/useSpreadsheetPinning';
|
|
25
26
|
import { useSpreadsheetComments } from '../hooks/useSpreadsheetComments';
|
|
26
27
|
import { useSpreadsheetUndoRedo } from '../hooks/useSpreadsheetUndoRedo';
|
|
@@ -868,6 +869,7 @@ export function Spreadsheet<T extends Record<string, any>>({
|
|
|
868
869
|
if (item.type === 'pinned-column') {
|
|
869
870
|
const col = columns.find((c) => c.id === item.columnId);
|
|
870
871
|
const isPinnedLeft = item.pinSide === 'left';
|
|
872
|
+
const pinnedWidth = Math.max(col?.minWidth || col?.width || MIN_PINNED_COLUMN_WIDTH, MIN_PINNED_COLUMN_WIDTH);
|
|
871
873
|
return (
|
|
872
874
|
<th
|
|
873
875
|
key={`pinned-group-${item.columnId}`}
|
|
@@ -885,7 +887,9 @@ export function Spreadsheet<T extends Record<string, any>>({
|
|
|
885
887
|
right: !isPinnedLeft
|
|
886
888
|
? `${getColumnRightOffset(item.columnId)}px`
|
|
887
889
|
: undefined,
|
|
888
|
-
minWidth:
|
|
890
|
+
minWidth: pinnedWidth,
|
|
891
|
+
width: pinnedWidth,
|
|
892
|
+
maxWidth: pinnedWidth,
|
|
889
893
|
}}
|
|
890
894
|
/>
|
|
891
895
|
);
|
|
@@ -4,6 +4,7 @@ import { AiFillHighlight } from 'react-icons/ai';
|
|
|
4
4
|
import { FaComment, FaRegComment } from 'react-icons/fa';
|
|
5
5
|
import { cn } from '../utils';
|
|
6
6
|
import type { SpreadsheetCellProps } from '../types';
|
|
7
|
+
import { MIN_PINNED_COLUMN_WIDTH } from '../hooks/useSpreadsheetPinning';
|
|
7
8
|
|
|
8
9
|
const cellPaddingCompact = 'px-1 py-px';
|
|
9
10
|
const cellPaddingNormal = 'px-2 py-1';
|
|
@@ -273,6 +274,12 @@ const SpreadsheetCell: React.FC<SpreadsheetCellProps> = ({
|
|
|
273
274
|
style={{
|
|
274
275
|
backgroundColor: isInSelection ? 'rgb(239 246 255)' : getBackgroundColor(),
|
|
275
276
|
minWidth: column.minWidth || column.width,
|
|
277
|
+
// Pinned columns must have a fixed width so sticky offsets stay correct.
|
|
278
|
+
// Enforce MIN_PINNED_COLUMN_WIDTH so header actions always fit.
|
|
279
|
+
...(isPinned && {
|
|
280
|
+
width: Math.max(column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH, MIN_PINNED_COLUMN_WIDTH),
|
|
281
|
+
maxWidth: Math.max(column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH, MIN_PINNED_COLUMN_WIDTH),
|
|
282
|
+
}),
|
|
276
283
|
...positionStyles,
|
|
277
284
|
...selectionBorderStyles,
|
|
278
285
|
}}
|
|
@@ -3,6 +3,7 @@ import { HiChevronDown, HiChevronUp } from 'react-icons/hi';
|
|
|
3
3
|
import { cn } from '../utils';
|
|
4
4
|
import type { SpreadsheetHeaderProps } from '../types';
|
|
5
5
|
import { ColumnHeaderActions } from './ColumnHeaderActions';
|
|
6
|
+
import { MIN_PINNED_COLUMN_WIDTH } from '../hooks/useSpreadsheetPinning';
|
|
6
7
|
|
|
7
8
|
const cellPaddingCompact = 'px-1 py-0.5';
|
|
8
9
|
const cellPaddingNormal = 'px-2 py-1.5';
|
|
@@ -71,6 +72,12 @@ export const SpreadsheetHeader: React.FC<
|
|
|
71
72
|
style={{
|
|
72
73
|
backgroundColor: highlightColor || 'rgb(243 244 246)', // gray-100
|
|
73
74
|
minWidth: column.minWidth || column.width,
|
|
75
|
+
// Pinned columns must have a fixed width so sticky offsets stay correct.
|
|
76
|
+
// Enforce MIN_PINNED_COLUMN_WIDTH so header actions (pin/filter/highlight) always fit.
|
|
77
|
+
...(isPinned && {
|
|
78
|
+
width: Math.max(column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH, MIN_PINNED_COLUMN_WIDTH),
|
|
79
|
+
maxWidth: Math.max(column.minWidth || column.width || MIN_PINNED_COLUMN_WIDTH, MIN_PINNED_COLUMN_WIDTH),
|
|
80
|
+
}),
|
|
74
81
|
top: 0, // For sticky header
|
|
75
82
|
...positionStyles,
|
|
76
83
|
}}
|
|
@@ -4,6 +4,8 @@ import type { SpreadsheetColumn, SpreadsheetColumnGroup } from '../types';
|
|
|
4
4
|
// Special column ID for row index
|
|
5
5
|
export const ROW_INDEX_COLUMN_ID = '__row_index__';
|
|
6
6
|
export const ROW_INDEX_COLUMN_WIDTH = 80;
|
|
7
|
+
// Minimum width for any pinned column to ensure header actions (pin, filter, highlight icons) fit
|
|
8
|
+
export const MIN_PINNED_COLUMN_WIDTH = 100;
|
|
7
9
|
|
|
8
10
|
export interface UseSpreadsheetPinningOptions<T> {
|
|
9
11
|
columns: SpreadsheetColumn<T>[];
|
|
@@ -178,8 +180,10 @@ export function useSpreadsheetPinning<T>({
|
|
|
178
180
|
let offset = baseOffset;
|
|
179
181
|
for (let i = 0; i < index; i++) {
|
|
180
182
|
const col = columns.find((c) => c.id === pinnedLeft[i]);
|
|
181
|
-
//
|
|
182
|
-
|
|
183
|
+
// Pinned columns are clamped to at least MIN_PINNED_COLUMN_WIDTH
|
|
184
|
+
// so that header actions (pin, filter, highlight icons) always fit
|
|
185
|
+
const configuredWidth = col?.minWidth || col?.width || MIN_PINNED_COLUMN_WIDTH;
|
|
186
|
+
offset += Math.max(configuredWidth, MIN_PINNED_COLUMN_WIDTH);
|
|
183
187
|
}
|
|
184
188
|
return offset;
|
|
185
189
|
},
|
|
@@ -218,7 +222,8 @@ export function useSpreadsheetPinning<T>({
|
|
|
218
222
|
let offset = 0;
|
|
219
223
|
for (let i = pinnedRight.length - 1; i > index; i--) {
|
|
220
224
|
const col = columns.find((c) => c.id === pinnedRight[i]);
|
|
221
|
-
|
|
225
|
+
const configuredWidth = col?.minWidth || col?.width || MIN_PINNED_COLUMN_WIDTH;
|
|
226
|
+
offset += Math.max(configuredWidth, MIN_PINNED_COLUMN_WIDTH);
|
|
222
227
|
}
|
|
223
228
|
return offset;
|
|
224
229
|
},
|