@papernote/ui 1.10.20 → 1.10.21
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/PivotTable.d.ts +47 -0
- package/dist/components/PivotTable.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +48 -2
- package/dist/index.esm.js +257 -38
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +257 -37
- package/dist/index.js.map +1 -1
- package/dist/styles.css +5 -0
- package/package.json +1 -1
- package/src/components/PivotTable.stories.tsx +188 -0
- package/src/components/PivotTable.tsx +422 -0
- package/src/components/index.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -15057,44 +15057,52 @@ function getAugmentedNamespace(n) {
|
|
|
15057
15057
|
* (A1, A1:C5, ...)
|
|
15058
15058
|
*/
|
|
15059
15059
|
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
|
|
15066
|
-
|
|
15067
|
-
|
|
15068
|
-
|
|
15069
|
-
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15060
|
+
var collection;
|
|
15061
|
+
var hasRequiredCollection;
|
|
15062
|
+
|
|
15063
|
+
function requireCollection () {
|
|
15064
|
+
if (hasRequiredCollection) return collection;
|
|
15065
|
+
hasRequiredCollection = 1;
|
|
15066
|
+
class Collection {
|
|
15067
|
+
|
|
15068
|
+
constructor(data, refs) {
|
|
15069
|
+
if (data == null && refs == null) {
|
|
15070
|
+
this._data = [];
|
|
15071
|
+
this._refs = [];
|
|
15072
|
+
} else {
|
|
15073
|
+
if (data.length !== refs.length)
|
|
15074
|
+
throw Error('Collection: data length should match references length.');
|
|
15075
|
+
this._data = data;
|
|
15076
|
+
this._refs = refs;
|
|
15077
|
+
}
|
|
15078
|
+
}
|
|
15073
15079
|
|
|
15074
|
-
|
|
15075
|
-
|
|
15076
|
-
|
|
15080
|
+
get data() {
|
|
15081
|
+
return this._data;
|
|
15082
|
+
}
|
|
15077
15083
|
|
|
15078
|
-
|
|
15079
|
-
|
|
15080
|
-
|
|
15084
|
+
get refs() {
|
|
15085
|
+
return this._refs;
|
|
15086
|
+
}
|
|
15081
15087
|
|
|
15082
|
-
|
|
15083
|
-
|
|
15084
|
-
|
|
15088
|
+
get length() {
|
|
15089
|
+
return this._data.length;
|
|
15090
|
+
}
|
|
15085
15091
|
|
|
15086
|
-
|
|
15087
|
-
|
|
15088
|
-
|
|
15089
|
-
|
|
15090
|
-
|
|
15091
|
-
|
|
15092
|
-
|
|
15093
|
-
|
|
15094
|
-
|
|
15095
|
-
}
|
|
15092
|
+
/**
|
|
15093
|
+
* Add data and references to this collection.
|
|
15094
|
+
* @param {{}} obj - data
|
|
15095
|
+
* @param {{}} ref - reference
|
|
15096
|
+
*/
|
|
15097
|
+
add(obj, ref) {
|
|
15098
|
+
this._data.push(obj);
|
|
15099
|
+
this._refs.push(ref);
|
|
15100
|
+
}
|
|
15101
|
+
}
|
|
15096
15102
|
|
|
15097
|
-
|
|
15103
|
+
collection = Collection;
|
|
15104
|
+
return collection;
|
|
15105
|
+
}
|
|
15098
15106
|
|
|
15099
15107
|
var helpers;
|
|
15100
15108
|
var hasRequiredHelpers;
|
|
@@ -15103,7 +15111,7 @@ function requireHelpers () {
|
|
|
15103
15111
|
if (hasRequiredHelpers) return helpers;
|
|
15104
15112
|
hasRequiredHelpers = 1;
|
|
15105
15113
|
const FormulaError = requireError();
|
|
15106
|
-
const Collection =
|
|
15114
|
+
const Collection = requireCollection();
|
|
15107
15115
|
|
|
15108
15116
|
const Types = {
|
|
15109
15117
|
NUMBER: 0,
|
|
@@ -24757,7 +24765,7 @@ var engineering = EngineeringFunctions;
|
|
|
24757
24765
|
|
|
24758
24766
|
const FormulaError$b = requireError();
|
|
24759
24767
|
const {FormulaHelpers: FormulaHelpers$8, Types: Types$6, WildCard, Address: Address$3} = requireHelpers();
|
|
24760
|
-
const Collection$2 =
|
|
24768
|
+
const Collection$2 = requireCollection();
|
|
24761
24769
|
const H$5 = FormulaHelpers$8;
|
|
24762
24770
|
|
|
24763
24771
|
const ReferenceFunctions$1 = {
|
|
@@ -36385,7 +36393,7 @@ var parsing = {
|
|
|
36385
36393
|
const FormulaError$4 = requireError();
|
|
36386
36394
|
const {Address: Address$1} = requireHelpers();
|
|
36387
36395
|
const {Prefix: Prefix$1, Postfix: Postfix$1, Infix: Infix$1, Operators: Operators$1} = operators;
|
|
36388
|
-
const Collection$1 =
|
|
36396
|
+
const Collection$1 = requireCollection();
|
|
36389
36397
|
const MAX_ROW$1 = 1048576, MAX_COLUMN$1 = 16384;
|
|
36390
36398
|
const {NotAllInputParsedException} = require$$4;
|
|
36391
36399
|
|
|
@@ -37147,7 +37155,7 @@ var hooks$1 = {
|
|
|
37147
37155
|
const FormulaError$2 = requireError();
|
|
37148
37156
|
const {FormulaHelpers: FormulaHelpers$1, Types, Address} = requireHelpers();
|
|
37149
37157
|
const {Prefix, Postfix, Infix, Operators} = operators;
|
|
37150
|
-
const Collection =
|
|
37158
|
+
const Collection = requireCollection();
|
|
37151
37159
|
const MAX_ROW = 1048576, MAX_COLUMN = 16384;
|
|
37152
37160
|
|
|
37153
37161
|
let Utils$1 = class Utils {
|
|
@@ -39544,6 +39552,217 @@ const DataGrid = React.forwardRef(({ data: initialData, columns, onChange, rowHe
|
|
|
39544
39552
|
});
|
|
39545
39553
|
DataGrid.displayName = 'DataGrid';
|
|
39546
39554
|
|
|
39555
|
+
/**
|
|
39556
|
+
* Default currency formatter
|
|
39557
|
+
*/
|
|
39558
|
+
const defaultFormatValue = (value) => {
|
|
39559
|
+
if (value === null || value === undefined)
|
|
39560
|
+
return '-';
|
|
39561
|
+
return new Intl.NumberFormat('en-US', {
|
|
39562
|
+
style: 'currency',
|
|
39563
|
+
currency: 'USD',
|
|
39564
|
+
minimumFractionDigits: 2,
|
|
39565
|
+
maximumFractionDigits: 2,
|
|
39566
|
+
}).format(value);
|
|
39567
|
+
};
|
|
39568
|
+
/**
|
|
39569
|
+
* Transform flat data into pivoted structure
|
|
39570
|
+
*/
|
|
39571
|
+
function pivotData(data, rowField, columnField, valueField, columnLabels, sortColumns, sortRows) {
|
|
39572
|
+
// Extract unique row and column values
|
|
39573
|
+
const rowSet = new Set();
|
|
39574
|
+
const columnSet = new Set();
|
|
39575
|
+
const valueMap = new Map();
|
|
39576
|
+
for (const row of data) {
|
|
39577
|
+
const rowValue = String(row[rowField] ?? '');
|
|
39578
|
+
const colValue = row[columnField];
|
|
39579
|
+
const val = row[valueField];
|
|
39580
|
+
if (rowValue)
|
|
39581
|
+
rowSet.add(rowValue);
|
|
39582
|
+
if (colValue !== undefined && colValue !== null)
|
|
39583
|
+
columnSet.add(colValue);
|
|
39584
|
+
// Create composite key for the cell
|
|
39585
|
+
const key = `${rowValue}|||${colValue}`;
|
|
39586
|
+
const numVal = typeof val === 'number' ? val : parseFloat(String(val)) || 0;
|
|
39587
|
+
valueMap.set(key, (valueMap.get(key) || 0) + numVal);
|
|
39588
|
+
}
|
|
39589
|
+
// Sort row labels
|
|
39590
|
+
let rowLabels = Array.from(rowSet);
|
|
39591
|
+
if (sortRows !== false) {
|
|
39592
|
+
rowLabels.sort((a, b) => a.localeCompare(b));
|
|
39593
|
+
}
|
|
39594
|
+
// Sort column keys
|
|
39595
|
+
let columnKeys = Array.from(columnSet);
|
|
39596
|
+
if (sortColumns === 'label') {
|
|
39597
|
+
columnKeys.sort((a, b) => {
|
|
39598
|
+
const labelA = columnLabels?.[a] ?? String(a);
|
|
39599
|
+
const labelB = columnLabels?.[b] ?? String(b);
|
|
39600
|
+
return labelA.localeCompare(labelB);
|
|
39601
|
+
});
|
|
39602
|
+
}
|
|
39603
|
+
else if (sortColumns !== 'none') {
|
|
39604
|
+
// Default: sort by value (numeric if possible)
|
|
39605
|
+
columnKeys.sort((a, b) => {
|
|
39606
|
+
const numA = typeof a === 'number' ? a : parseFloat(String(a));
|
|
39607
|
+
const numB = typeof b === 'number' ? b : parseFloat(String(b));
|
|
39608
|
+
if (!isNaN(numA) && !isNaN(numB))
|
|
39609
|
+
return numA - numB;
|
|
39610
|
+
return String(a).localeCompare(String(b));
|
|
39611
|
+
});
|
|
39612
|
+
}
|
|
39613
|
+
// Build column labels array
|
|
39614
|
+
const colLabels = columnKeys.map((k) => columnLabels?.[k] ?? String(k));
|
|
39615
|
+
// Build the matrix
|
|
39616
|
+
const matrix = [];
|
|
39617
|
+
const rowTotals = [];
|
|
39618
|
+
const rowAverages = [];
|
|
39619
|
+
const columnTotals = new Array(columnKeys.length).fill(0);
|
|
39620
|
+
let grandTotal = 0;
|
|
39621
|
+
for (const rowLabel of rowLabels) {
|
|
39622
|
+
const rowData = [];
|
|
39623
|
+
let rowSum = 0;
|
|
39624
|
+
let rowCount = 0;
|
|
39625
|
+
for (let colIdx = 0; colIdx < columnKeys.length; colIdx++) {
|
|
39626
|
+
const colKey = columnKeys[colIdx];
|
|
39627
|
+
const key = `${rowLabel}|||${colKey}`;
|
|
39628
|
+
const value = valueMap.get(key) ?? null;
|
|
39629
|
+
rowData.push(value);
|
|
39630
|
+
if (value !== null) {
|
|
39631
|
+
rowSum += value;
|
|
39632
|
+
rowCount++;
|
|
39633
|
+
columnTotals[colIdx] += value;
|
|
39634
|
+
grandTotal += value;
|
|
39635
|
+
}
|
|
39636
|
+
}
|
|
39637
|
+
matrix.push(rowData);
|
|
39638
|
+
rowTotals.push(rowSum);
|
|
39639
|
+
rowAverages.push(rowCount > 0 ? rowSum / rowCount : 0);
|
|
39640
|
+
}
|
|
39641
|
+
return {
|
|
39642
|
+
rowLabels,
|
|
39643
|
+
columnLabels: colLabels,
|
|
39644
|
+
columnKeys,
|
|
39645
|
+
matrix,
|
|
39646
|
+
rowTotals,
|
|
39647
|
+
rowAverages,
|
|
39648
|
+
columnTotals,
|
|
39649
|
+
grandTotal,
|
|
39650
|
+
};
|
|
39651
|
+
}
|
|
39652
|
+
/**
|
|
39653
|
+
* PivotTable Component
|
|
39654
|
+
*/
|
|
39655
|
+
function PivotTable({ data, rowField, columnField, valueField, columnLabels, rowLabel = '', formatValue = defaultFormatValue, showRowTotals = true, showRowAverages = false, showColumnTotals = true, className = '', sortColumns = 'value', sortRows = true, emptyValue = '-', }) {
|
|
39656
|
+
const pivoted = React.useMemo(() => pivotData(data, rowField, columnField, valueField, columnLabels, sortColumns, sortRows), [data, rowField, columnField, valueField, columnLabels, sortColumns, sortRows]);
|
|
39657
|
+
const formatCell = (value) => {
|
|
39658
|
+
if (value === null || value === undefined)
|
|
39659
|
+
return emptyValue;
|
|
39660
|
+
return formatValue(value);
|
|
39661
|
+
};
|
|
39662
|
+
// Calculate column totals row average
|
|
39663
|
+
const columnTotalsAverage = pivoted.columnTotals.length > 0
|
|
39664
|
+
? pivoted.columnTotals.reduce((a, b) => a + b, 0) / pivoted.columnTotals.length
|
|
39665
|
+
: 0;
|
|
39666
|
+
return (jsxRuntime.jsx("div", { className: `pivot-table-container ${className}`, style: { overflowX: 'auto' }, children: jsxRuntime.jsxs("table", { style: {
|
|
39667
|
+
width: '100%',
|
|
39668
|
+
borderCollapse: 'collapse',
|
|
39669
|
+
fontSize: '14px',
|
|
39670
|
+
fontFamily: 'inherit',
|
|
39671
|
+
}, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { style: { backgroundColor: '#f8fafc', borderBottom: '2px solid #e2e8f0' }, children: [jsxRuntime.jsx("th", { style: {
|
|
39672
|
+
padding: '12px 16px',
|
|
39673
|
+
textAlign: 'left',
|
|
39674
|
+
fontWeight: 600,
|
|
39675
|
+
color: '#334155',
|
|
39676
|
+
position: 'sticky',
|
|
39677
|
+
left: 0,
|
|
39678
|
+
backgroundColor: '#f8fafc',
|
|
39679
|
+
zIndex: 1,
|
|
39680
|
+
minWidth: '150px',
|
|
39681
|
+
}, children: rowLabel }), pivoted.columnLabels.map((label, idx) => (jsxRuntime.jsx("th", { style: {
|
|
39682
|
+
padding: '12px 16px',
|
|
39683
|
+
textAlign: 'right',
|
|
39684
|
+
fontWeight: 600,
|
|
39685
|
+
color: '#334155',
|
|
39686
|
+
minWidth: '100px',
|
|
39687
|
+
whiteSpace: 'nowrap',
|
|
39688
|
+
}, children: label }, idx))), showRowTotals && (jsxRuntime.jsx("th", { style: {
|
|
39689
|
+
padding: '12px 16px',
|
|
39690
|
+
textAlign: 'right',
|
|
39691
|
+
fontWeight: 700,
|
|
39692
|
+
color: '#1e40af',
|
|
39693
|
+
backgroundColor: '#eff6ff',
|
|
39694
|
+
minWidth: '100px',
|
|
39695
|
+
}, children: "Total" })), showRowAverages && (jsxRuntime.jsx("th", { style: {
|
|
39696
|
+
padding: '12px 16px',
|
|
39697
|
+
textAlign: 'right',
|
|
39698
|
+
fontWeight: 700,
|
|
39699
|
+
color: '#166534',
|
|
39700
|
+
backgroundColor: '#f0fdf4',
|
|
39701
|
+
minWidth: '100px',
|
|
39702
|
+
}, children: "Average" }))] }) }), jsxRuntime.jsxs("tbody", { children: [pivoted.rowLabels.map((rowLabel, rowIdx) => (jsxRuntime.jsxs("tr", { style: {
|
|
39703
|
+
borderBottom: '1px solid #e2e8f0',
|
|
39704
|
+
backgroundColor: rowIdx % 2 === 0 ? '#ffffff' : '#f8fafc',
|
|
39705
|
+
}, children: [jsxRuntime.jsx("td", { style: {
|
|
39706
|
+
padding: '10px 16px',
|
|
39707
|
+
fontWeight: 500,
|
|
39708
|
+
color: '#1e293b',
|
|
39709
|
+
position: 'sticky',
|
|
39710
|
+
left: 0,
|
|
39711
|
+
backgroundColor: rowIdx % 2 === 0 ? '#ffffff' : '#f8fafc',
|
|
39712
|
+
zIndex: 1,
|
|
39713
|
+
}, children: rowLabel }), pivoted.matrix[rowIdx].map((value, colIdx) => (jsxRuntime.jsx("td", { style: {
|
|
39714
|
+
padding: '10px 16px',
|
|
39715
|
+
textAlign: 'right',
|
|
39716
|
+
color: value === null ? '#94a3b8' : '#334155',
|
|
39717
|
+
fontVariantNumeric: 'tabular-nums',
|
|
39718
|
+
}, children: formatCell(value) }, colIdx))), showRowTotals && (jsxRuntime.jsx("td", { style: {
|
|
39719
|
+
padding: '10px 16px',
|
|
39720
|
+
textAlign: 'right',
|
|
39721
|
+
fontWeight: 600,
|
|
39722
|
+
color: '#1e40af',
|
|
39723
|
+
backgroundColor: '#eff6ff',
|
|
39724
|
+
fontVariantNumeric: 'tabular-nums',
|
|
39725
|
+
}, children: formatCell(pivoted.rowTotals[rowIdx]) })), showRowAverages && (jsxRuntime.jsx("td", { style: {
|
|
39726
|
+
padding: '10px 16px',
|
|
39727
|
+
textAlign: 'right',
|
|
39728
|
+
fontWeight: 600,
|
|
39729
|
+
color: '#166534',
|
|
39730
|
+
backgroundColor: '#f0fdf4',
|
|
39731
|
+
fontVariantNumeric: 'tabular-nums',
|
|
39732
|
+
}, children: formatCell(pivoted.rowAverages[rowIdx]) }))] }, rowIdx))), showColumnTotals && (jsxRuntime.jsxs("tr", { style: {
|
|
39733
|
+
borderTop: '2px solid #e2e8f0',
|
|
39734
|
+
backgroundColor: '#f1f5f9',
|
|
39735
|
+
fontWeight: 600,
|
|
39736
|
+
}, children: [jsxRuntime.jsx("td", { style: {
|
|
39737
|
+
padding: '12px 16px',
|
|
39738
|
+
fontWeight: 700,
|
|
39739
|
+
color: '#1e293b',
|
|
39740
|
+
position: 'sticky',
|
|
39741
|
+
left: 0,
|
|
39742
|
+
backgroundColor: '#f1f5f9',
|
|
39743
|
+
zIndex: 1,
|
|
39744
|
+
}, children: "Total" }), pivoted.columnTotals.map((total, idx) => (jsxRuntime.jsx("td", { style: {
|
|
39745
|
+
padding: '12px 16px',
|
|
39746
|
+
textAlign: 'right',
|
|
39747
|
+
color: '#1e293b',
|
|
39748
|
+
fontVariantNumeric: 'tabular-nums',
|
|
39749
|
+
}, children: formatCell(total) }, idx))), showRowTotals && (jsxRuntime.jsx("td", { style: {
|
|
39750
|
+
padding: '12px 16px',
|
|
39751
|
+
textAlign: 'right',
|
|
39752
|
+
fontWeight: 700,
|
|
39753
|
+
color: '#1e40af',
|
|
39754
|
+
backgroundColor: '#dbeafe',
|
|
39755
|
+
fontVariantNumeric: 'tabular-nums',
|
|
39756
|
+
}, children: formatCell(pivoted.grandTotal) })), showRowAverages && (jsxRuntime.jsx("td", { style: {
|
|
39757
|
+
padding: '12px 16px',
|
|
39758
|
+
textAlign: 'right',
|
|
39759
|
+
fontWeight: 700,
|
|
39760
|
+
color: '#166534',
|
|
39761
|
+
backgroundColor: '#dcfce7',
|
|
39762
|
+
fontVariantNumeric: 'tabular-nums',
|
|
39763
|
+
}, children: formatCell(columnTotalsAverage) }))] }))] })] }) }));
|
|
39764
|
+
}
|
|
39765
|
+
|
|
39547
39766
|
// Color mapping for action buttons
|
|
39548
39767
|
const colorClasses = {
|
|
39549
39768
|
primary: 'bg-accent-500 text-white',
|
|
@@ -61788,6 +62007,7 @@ exports.PageNavigation = PageNavigation;
|
|
|
61788
62007
|
exports.Pagination = Pagination;
|
|
61789
62008
|
exports.PasswordInput = PasswordInput;
|
|
61790
62009
|
exports.PermissionBadge = PermissionBadge;
|
|
62010
|
+
exports.PivotTable = PivotTable;
|
|
61791
62011
|
exports.Popover = Popover;
|
|
61792
62012
|
exports.PriorityAlertBanner = PriorityAlertBanner;
|
|
61793
62013
|
exports.Progress = Progress;
|