@papernote/ui 1.10.21 → 1.10.23
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/components/DataGrid.d.ts +4 -0
- package/dist/components/DataGrid.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +93 -47
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +93 -47
- package/dist/index.js.map +1 -1
- package/dist/styles.css +57 -1
- package/package.json +5 -2
- package/src/components/DataGrid.tsx +73 -6
package/dist/styles.css
CHANGED
|
@@ -350,7 +350,7 @@
|
|
|
350
350
|
--tw-contain-style: ;
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
-
/* ! tailwindcss v3.4.
|
|
353
|
+
/* ! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com */
|
|
354
354
|
|
|
355
355
|
/*
|
|
356
356
|
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
|
@@ -3512,6 +3512,20 @@ input:checked + .slider:before{
|
|
|
3512
3512
|
background-color: rgb(110 109 94 / var(--tw-bg-opacity, 1));
|
|
3513
3513
|
}
|
|
3514
3514
|
|
|
3515
|
+
.bg-amber-100{
|
|
3516
|
+
--tw-bg-opacity: 1;
|
|
3517
|
+
background-color: rgb(254 243 199 / var(--tw-bg-opacity, 1));
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
.bg-amber-100\/50{
|
|
3521
|
+
background-color: rgb(254 243 199 / 0.5);
|
|
3522
|
+
}
|
|
3523
|
+
|
|
3524
|
+
.bg-amber-50{
|
|
3525
|
+
--tw-bg-opacity: 1;
|
|
3526
|
+
background-color: rgb(255 251 235 / var(--tw-bg-opacity, 1));
|
|
3527
|
+
}
|
|
3528
|
+
|
|
3515
3529
|
.bg-black{
|
|
3516
3530
|
--tw-bg-opacity: 1;
|
|
3517
3531
|
background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));
|
|
@@ -3534,6 +3548,20 @@ input:checked + .slider:before{
|
|
|
3534
3548
|
background-color: currentColor;
|
|
3535
3549
|
}
|
|
3536
3550
|
|
|
3551
|
+
.bg-emerald-100{
|
|
3552
|
+
--tw-bg-opacity: 1;
|
|
3553
|
+
background-color: rgb(209 250 229 / var(--tw-bg-opacity, 1));
|
|
3554
|
+
}
|
|
3555
|
+
|
|
3556
|
+
.bg-emerald-100\/50{
|
|
3557
|
+
background-color: rgb(209 250 229 / 0.5);
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
.bg-emerald-50{
|
|
3561
|
+
--tw-bg-opacity: 1;
|
|
3562
|
+
background-color: rgb(236 253 245 / var(--tw-bg-opacity, 1));
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3537
3565
|
.bg-error-100{
|
|
3538
3566
|
--tw-bg-opacity: 1;
|
|
3539
3567
|
background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1));
|
|
@@ -3656,6 +3684,20 @@ input:checked + .slider:before{
|
|
|
3656
3684
|
background-color: rgb(250 250 249 / var(--tw-bg-opacity, 1));
|
|
3657
3685
|
}
|
|
3658
3686
|
|
|
3687
|
+
.bg-pink-100{
|
|
3688
|
+
--tw-bg-opacity: 1;
|
|
3689
|
+
background-color: rgb(252 231 243 / var(--tw-bg-opacity, 1));
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
.bg-pink-100\/50{
|
|
3693
|
+
background-color: rgb(252 231 243 / 0.5);
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
.bg-pink-50{
|
|
3697
|
+
--tw-bg-opacity: 1;
|
|
3698
|
+
background-color: rgb(253 242 248 / var(--tw-bg-opacity, 1));
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3659
3701
|
.bg-primary-100{
|
|
3660
3702
|
--tw-bg-opacity: 1;
|
|
3661
3703
|
background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1));
|
|
@@ -3689,6 +3731,20 @@ input:checked + .slider:before{
|
|
|
3689
3731
|
background-color: rgb(71 85 105 / var(--tw-bg-opacity, 1));
|
|
3690
3732
|
}
|
|
3691
3733
|
|
|
3734
|
+
.bg-sky-100{
|
|
3735
|
+
--tw-bg-opacity: 1;
|
|
3736
|
+
background-color: rgb(224 242 254 / var(--tw-bg-opacity, 1));
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3739
|
+
.bg-sky-100\/50{
|
|
3740
|
+
background-color: rgb(224 242 254 / 0.5);
|
|
3741
|
+
}
|
|
3742
|
+
|
|
3743
|
+
.bg-sky-50{
|
|
3744
|
+
--tw-bg-opacity: 1;
|
|
3745
|
+
background-color: rgb(240 249 255 / var(--tw-bg-opacity, 1));
|
|
3746
|
+
}
|
|
3747
|
+
|
|
3692
3748
|
.bg-slate-50\/80{
|
|
3693
3749
|
background-color: rgb(248 250 252 / 0.8);
|
|
3694
3750
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@papernote/ui",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A modern React component library with a paper notebook aesthetic - minimal, professional, and expressive",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"rollup-plugin-dts": "^6.0.0",
|
|
78
78
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
79
79
|
"rollup-plugin-postcss": "^4.0.0",
|
|
80
|
-
"storybook": "^10.
|
|
80
|
+
"storybook": "^10.1.11",
|
|
81
81
|
"tailwindcss": "^3.4.0",
|
|
82
82
|
"ts-jest": "^29.4.5",
|
|
83
83
|
"tslib": "^2.6.0",
|
|
@@ -111,5 +111,8 @@
|
|
|
111
111
|
"canvas-confetti": "^1.9.4",
|
|
112
112
|
"react-spreadsheet": "^0.10.1",
|
|
113
113
|
"xlsx": "^0.18.5"
|
|
114
|
+
},
|
|
115
|
+
"overrides": {
|
|
116
|
+
"esbuild": "^0.25.0"
|
|
114
117
|
}
|
|
115
118
|
}
|
|
@@ -76,6 +76,10 @@ export interface DataGridColumn {
|
|
|
76
76
|
prefix?: string;
|
|
77
77
|
suffix?: string;
|
|
78
78
|
};
|
|
79
|
+
/** Column group identifier for visual banding (e.g., "SalesAmount" groups base column with comparison variants) */
|
|
80
|
+
group?: string;
|
|
81
|
+
/** Variant type within a group: "current", "prior", "variance", "variancePct" */
|
|
82
|
+
variant?: 'current' | 'prior' | 'variance' | 'variancePct';
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
/**
|
|
@@ -195,6 +199,34 @@ const colIndexToLetter = (index: number): string => {
|
|
|
195
199
|
// Note: parseRef is available for future formula reference parsing
|
|
196
200
|
// const parseRef = (ref: string): { row: number; col: number } | null => { ... }
|
|
197
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Color banding for column groups (e.g., comparison columns)
|
|
204
|
+
* Alternates between color sets to visually distinguish groups
|
|
205
|
+
*/
|
|
206
|
+
const COLUMN_GROUP_COLORS = [
|
|
207
|
+
{ header: 'bg-sky-100', cell: 'bg-sky-50', cellAlt: 'bg-sky-100/50' },
|
|
208
|
+
{ header: 'bg-amber-100', cell: 'bg-amber-50', cellAlt: 'bg-amber-100/50' },
|
|
209
|
+
{ header: 'bg-emerald-100', cell: 'bg-emerald-50', cellAlt: 'bg-emerald-100/50' },
|
|
210
|
+
{ header: 'bg-pink-100', cell: 'bg-pink-50', cellAlt: 'bg-pink-100/50' },
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Build a map of group names to color indices for column banding
|
|
215
|
+
*/
|
|
216
|
+
const buildGroupColorMap = (columns: DataGridColumn[]): Map<string, number> => {
|
|
217
|
+
const groupColorMap = new Map<string, number>();
|
|
218
|
+
let colorIndex = 0;
|
|
219
|
+
|
|
220
|
+
for (const col of columns) {
|
|
221
|
+
if (col.group && !groupColorMap.has(col.group)) {
|
|
222
|
+
groupColorMap.set(col.group, colorIndex % COLUMN_GROUP_COLORS.length);
|
|
223
|
+
colorIndex++;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return groupColorMap;
|
|
228
|
+
};
|
|
229
|
+
|
|
198
230
|
/**
|
|
199
231
|
* DataGrid - Excel-like data grid component with formulas
|
|
200
232
|
*
|
|
@@ -291,6 +323,41 @@ export const DataGrid = forwardRef<DataGridHandle, DataGridProps>(
|
|
|
291
323
|
return 0;
|
|
292
324
|
}, [frozenRowsState, selectedCell]);
|
|
293
325
|
|
|
326
|
+
// Build group color map for column banding
|
|
327
|
+
const groupColorMap = useMemo(() => buildGroupColorMap(columns), [columns]);
|
|
328
|
+
|
|
329
|
+
// Get header background class for a column (considers group banding)
|
|
330
|
+
const getHeaderBgClass = useCallback(
|
|
331
|
+
(column: DataGridColumn): string => {
|
|
332
|
+
if (column.group) {
|
|
333
|
+
const colorIdx = groupColorMap.get(column.group);
|
|
334
|
+
if (colorIdx !== undefined) {
|
|
335
|
+
return COLUMN_GROUP_COLORS[colorIdx].header;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return 'bg-stone-100';
|
|
339
|
+
},
|
|
340
|
+
[groupColorMap]
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
// Get cell background class for a column (considers group banding and zebra)
|
|
344
|
+
const getCellBgClass = useCallback(
|
|
345
|
+
(column: DataGridColumn, isZebra: boolean, isFrozenCol: boolean): string => {
|
|
346
|
+
if (column.group) {
|
|
347
|
+
const colorIdx = groupColorMap.get(column.group);
|
|
348
|
+
if (colorIdx !== undefined) {
|
|
349
|
+
const colors = COLUMN_GROUP_COLORS[colorIdx];
|
|
350
|
+
return isZebra ? colors.cellAlt : colors.cell;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Default behavior
|
|
354
|
+
if (isZebra && isFrozenCol) return 'bg-paper-50';
|
|
355
|
+
if (isFrozenCol) return 'bg-white';
|
|
356
|
+
return '';
|
|
357
|
+
},
|
|
358
|
+
[groupColorMap]
|
|
359
|
+
);
|
|
360
|
+
|
|
294
361
|
// Check if a specific row is frozen
|
|
295
362
|
const isRowFrozen = useCallback(
|
|
296
363
|
(rowIndex: number) => {
|
|
@@ -821,11 +888,12 @@ export const DataGrid = forwardRef<DataGridHandle, DataGridProps>(
|
|
|
821
888
|
{columns.map((column, colIndex) => {
|
|
822
889
|
const isFrozen = colIndex < frozenColumns;
|
|
823
890
|
const leftOffset = rowHeaders ? 50 + columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0) : columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0);
|
|
891
|
+
const headerBgClass = getHeaderBgClass(column);
|
|
824
892
|
|
|
825
893
|
return (
|
|
826
894
|
<th
|
|
827
895
|
key={column.key}
|
|
828
|
-
className={`${cellPadding} border-b border-r border-stone-200
|
|
896
|
+
className={`${cellPadding} border-b border-r border-stone-200 ${headerBgClass} font-semibold text-ink-600 text-${column.align || 'left'} ${
|
|
829
897
|
isFrozen ? 'sticky z-30' : ''
|
|
830
898
|
}`}
|
|
831
899
|
style={{
|
|
@@ -944,17 +1012,16 @@ export const DataGrid = forwardRef<DataGridHandle, DataGridProps>(
|
|
|
944
1012
|
const leftOffset = rowHeaders
|
|
945
1013
|
? 50 + columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0)
|
|
946
1014
|
: columns.slice(0, colIndex).reduce((sum, c) => sum + (c.width || 100), 0);
|
|
1015
|
+
const cellBgClass = getCellBgClass(column, isZebra, isFrozenCol);
|
|
947
1016
|
|
|
948
1017
|
return (
|
|
949
1018
|
<td
|
|
950
1019
|
key={colIndex}
|
|
951
1020
|
className={`${cellPadding} border-b border-r border-stone-200 text-${
|
|
952
1021
|
column?.align || 'left'
|
|
953
|
-
} ${isFrozenCol ? 'sticky z-10' : ''} ${
|
|
954
|
-
|
|
955
|
-
} ${
|
|
956
|
-
hasFormula ? 'bg-blue-50' : ''
|
|
957
|
-
} ${cell?.className || ''}`}
|
|
1022
|
+
} ${isFrozenCol ? 'sticky z-10' : ''} ${cellBgClass} ${
|
|
1023
|
+
isSelected ? 'ring-2 ring-inset ring-primary-500' : ''
|
|
1024
|
+
} ${hasFormula ? 'bg-blue-50' : ''} ${cell?.className || ''}`}
|
|
958
1025
|
style={{
|
|
959
1026
|
left: isFrozenCol ? leftOffset : undefined,
|
|
960
1027
|
minWidth: column?.minWidth || 80,
|