@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/styles.css CHANGED
@@ -350,7 +350,7 @@
350
350
  --tw-contain-style: ;
351
351
  }
352
352
 
353
- /* ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com */
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.21",
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.0.8",
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 bg-stone-100 font-semibold text-ink-600 text-${column.align || 'left'} ${
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
- isZebra && isFrozenCol ? 'bg-paper-50' : isFrozenCol ? 'bg-white' : ''
955
- } ${isSelected ? 'ring-2 ring-inset ring-primary-500' : ''} ${
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,