@smallwebco/tinypivot-react 1.0.47 → 1.0.49
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.cjs +90 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +90 -23
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -445,12 +445,11 @@ function usePivotTable(data) {
|
|
|
445
445
|
}, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
446
446
|
const addRowField = (0, import_react3.useCallback)(
|
|
447
447
|
(field) => {
|
|
448
|
-
if (!requirePro("Pivot Table - Row Fields")) return;
|
|
449
448
|
if (!rowFields.includes(field)) {
|
|
450
449
|
setRowFieldsState((prev) => [...prev, field]);
|
|
451
450
|
}
|
|
452
451
|
},
|
|
453
|
-
[rowFields
|
|
452
|
+
[rowFields]
|
|
454
453
|
);
|
|
455
454
|
const removeRowField = (0, import_react3.useCallback)((field) => {
|
|
456
455
|
setRowFieldsState((prev) => prev.filter((f) => f !== field));
|
|
@@ -460,12 +459,11 @@ function usePivotTable(data) {
|
|
|
460
459
|
}, []);
|
|
461
460
|
const addColumnField = (0, import_react3.useCallback)(
|
|
462
461
|
(field) => {
|
|
463
|
-
if (!requirePro("Pivot Table - Column Fields")) return;
|
|
464
462
|
if (!columnFields.includes(field)) {
|
|
465
463
|
setColumnFieldsState((prev) => [...prev, field]);
|
|
466
464
|
}
|
|
467
465
|
},
|
|
468
|
-
[columnFields
|
|
466
|
+
[columnFields]
|
|
469
467
|
);
|
|
470
468
|
const removeColumnField = (0, import_react3.useCallback)((field) => {
|
|
471
469
|
setColumnFieldsState((prev) => prev.filter((f) => f !== field));
|
|
@@ -475,7 +473,9 @@ function usePivotTable(data) {
|
|
|
475
473
|
}, []);
|
|
476
474
|
const addValueField = (0, import_react3.useCallback)(
|
|
477
475
|
(field, aggregation = "sum") => {
|
|
478
|
-
if (!requirePro(
|
|
476
|
+
if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
479
|
setValueFields((prev) => {
|
|
480
480
|
if (prev.some((v) => v.field === field && v.aggregation === aggregation)) {
|
|
481
481
|
return prev;
|
|
@@ -1553,6 +1553,9 @@ function CalculatedFieldModal({
|
|
|
1553
1553
|
|
|
1554
1554
|
// src/components/PivotConfig.tsx
|
|
1555
1555
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1556
|
+
function aggregationRequiresPro(agg) {
|
|
1557
|
+
return agg !== "sum";
|
|
1558
|
+
}
|
|
1556
1559
|
function getFieldIcon(type, isCalculated) {
|
|
1557
1560
|
if (isCalculated) return "\u0192";
|
|
1558
1561
|
switch (type) {
|
|
@@ -1592,6 +1595,10 @@ function PivotConfig({
|
|
|
1592
1595
|
const [fieldSearch, setFieldSearch] = (0, import_react8.useState)("");
|
|
1593
1596
|
const [showCalcModal, setShowCalcModal] = (0, import_react8.useState)(false);
|
|
1594
1597
|
const [editingCalcField, setEditingCalcField] = (0, import_react8.useState)(null);
|
|
1598
|
+
const { canUseAdvancedAggregations } = useLicense();
|
|
1599
|
+
const isAggregationAvailable = (0, import_react8.useCallback)((agg) => {
|
|
1600
|
+
return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
|
|
1601
|
+
}, [canUseAdvancedAggregations]);
|
|
1595
1602
|
const numericFieldNames = (0, import_react8.useMemo)(
|
|
1596
1603
|
() => availableFields.filter((f) => f.isNumeric).map((f) => f.field),
|
|
1597
1604
|
[availableFields]
|
|
@@ -1657,9 +1664,13 @@ function PivotConfig({
|
|
|
1657
1664
|
);
|
|
1658
1665
|
const handleAggregationChange = (0, import_react8.useCallback)(
|
|
1659
1666
|
(field, currentAgg, newAgg) => {
|
|
1667
|
+
if (!isAggregationAvailable(newAgg)) {
|
|
1668
|
+
console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1660
1671
|
onUpdateAggregation(field, currentAgg, newAgg);
|
|
1661
1672
|
},
|
|
1662
|
-
[onUpdateAggregation]
|
|
1673
|
+
[onUpdateAggregation, isAggregationAvailable]
|
|
1663
1674
|
);
|
|
1664
1675
|
const toggleRowColumn = (0, import_react8.useCallback)(
|
|
1665
1676
|
(field, currentAssignment) => {
|
|
@@ -1797,11 +1808,20 @@ function PivotConfig({
|
|
|
1797
1808
|
);
|
|
1798
1809
|
},
|
|
1799
1810
|
onClick: (e) => e.stopPropagation(),
|
|
1800
|
-
children: import_tinypivot_core6.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1811
|
+
children: import_tinypivot_core6.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1812
|
+
"option",
|
|
1813
|
+
{
|
|
1814
|
+
value: agg.value,
|
|
1815
|
+
disabled: aggregationRequiresPro(agg.value) && !canUseAdvancedAggregations,
|
|
1816
|
+
children: [
|
|
1817
|
+
agg.symbol,
|
|
1818
|
+
" ",
|
|
1819
|
+
agg.label,
|
|
1820
|
+
aggregationRequiresPro(agg.value) && !canUseAdvancedAggregations ? " (Pro)" : ""
|
|
1821
|
+
]
|
|
1822
|
+
},
|
|
1823
|
+
agg.value
|
|
1824
|
+
))
|
|
1805
1825
|
}
|
|
1806
1826
|
),
|
|
1807
1827
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -2300,6 +2320,14 @@ function PivotSkeleton({
|
|
|
2300
2320
|
[reorderDropTarget]
|
|
2301
2321
|
);
|
|
2302
2322
|
const currentFontSize = fontSize;
|
|
2323
|
+
const rowHeaderWidth = 180;
|
|
2324
|
+
const rowHeaderColWidth = (0, import_react9.useMemo)(() => {
|
|
2325
|
+
const numCols = Math.max(rowFields.length, 1);
|
|
2326
|
+
return Math.max(rowHeaderWidth / numCols, 80);
|
|
2327
|
+
}, [rowFields.length]);
|
|
2328
|
+
const getRowHeaderLeftOffset = (0, import_react9.useCallback)((fieldIdx) => {
|
|
2329
|
+
return fieldIdx * rowHeaderColWidth;
|
|
2330
|
+
}, [rowHeaderColWidth]);
|
|
2303
2331
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2304
2332
|
"div",
|
|
2305
2333
|
{
|
|
@@ -2580,18 +2608,20 @@ function PivotSkeleton({
|
|
|
2580
2608
|
] }) }),
|
|
2581
2609
|
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-table-container", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("table", { className: "vpg-pivot-table", children: [
|
|
2582
2610
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "vpg-column-header-row", children: [
|
|
2583
|
-
levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2611
|
+
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2584
2612
|
"th",
|
|
2585
2613
|
{
|
|
2586
2614
|
className: "vpg-row-header-label",
|
|
2587
2615
|
rowSpan: columnHeaderCells.length,
|
|
2616
|
+
style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(fieldIdx)}px` },
|
|
2588
2617
|
onClick: () => toggleSort("row"),
|
|
2589
2618
|
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-header-content", children: [
|
|
2590
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children:
|
|
2591
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
2619
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: field }),
|
|
2620
|
+
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
2592
2621
|
] })
|
|
2593
|
-
}
|
|
2594
|
-
|
|
2622
|
+
},
|
|
2623
|
+
`row-header-${fieldIdx}`
|
|
2624
|
+
)),
|
|
2595
2625
|
headerRow.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2596
2626
|
"th",
|
|
2597
2627
|
{
|
|
@@ -2609,7 +2639,15 @@ function PivotSkeleton({
|
|
|
2609
2639
|
] }, `header-${levelIdx}`)) }),
|
|
2610
2640
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tbody", { children: [
|
|
2611
2641
|
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "vpg-data-row", children: [
|
|
2612
|
-
|
|
2642
|
+
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2643
|
+
"th",
|
|
2644
|
+
{
|
|
2645
|
+
className: "vpg-row-header-cell",
|
|
2646
|
+
style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(idx)}px` },
|
|
2647
|
+
children: val
|
|
2648
|
+
},
|
|
2649
|
+
`row-${sortedIdx}-${idx}`
|
|
2650
|
+
)),
|
|
2613
2651
|
pivotResult.data[sortedIdx].map((cell, colIdx) => {
|
|
2614
2652
|
const displayRowIdx = sortedRowIndices.indexOf(sortedIdx);
|
|
2615
2653
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -2626,7 +2664,15 @@ function PivotSkeleton({
|
|
|
2626
2664
|
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
|
|
2627
2665
|
] }, sortedIdx)),
|
|
2628
2666
|
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "vpg-totals-row", children: [
|
|
2629
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2667
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2668
|
+
"th",
|
|
2669
|
+
{
|
|
2670
|
+
className: "vpg-row-header-cell vpg-total-label",
|
|
2671
|
+
colSpan: Math.max(rowFields.length, 1),
|
|
2672
|
+
style: { width: `${rowHeaderWidth}px` },
|
|
2673
|
+
children: "Total"
|
|
2674
|
+
}
|
|
2675
|
+
),
|
|
2630
2676
|
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
|
|
2631
2677
|
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
|
|
2632
2678
|
] })
|
|
@@ -2704,7 +2750,7 @@ function DataGrid({
|
|
|
2704
2750
|
onExport,
|
|
2705
2751
|
onCopy
|
|
2706
2752
|
}) {
|
|
2707
|
-
const { showWatermark, canUsePivot, isDemo } = useLicense();
|
|
2753
|
+
const { showWatermark, canUsePivot, isDemo, isPro } = useLicense();
|
|
2708
2754
|
const currentTheme = (0, import_react10.useMemo)(() => {
|
|
2709
2755
|
if (theme === "auto") {
|
|
2710
2756
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
@@ -3411,11 +3457,11 @@ function DataGrid({
|
|
|
3411
3457
|
) })
|
|
3412
3458
|
}
|
|
3413
3459
|
),
|
|
3414
|
-
enableExport &&
|
|
3460
|
+
enableExport && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3415
3461
|
"button",
|
|
3416
3462
|
{
|
|
3417
3463
|
className: "vpg-export-btn",
|
|
3418
|
-
title:
|
|
3464
|
+
title: "Export to CSV",
|
|
3419
3465
|
onClick: handleExport,
|
|
3420
3466
|
children: [
|
|
3421
3467
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -3427,8 +3473,29 @@ function DataGrid({
|
|
|
3427
3473
|
d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
|
3428
3474
|
}
|
|
3429
3475
|
) }),
|
|
3430
|
-
"Export"
|
|
3431
|
-
|
|
3476
|
+
"Export"
|
|
3477
|
+
]
|
|
3478
|
+
}
|
|
3479
|
+
),
|
|
3480
|
+
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3481
|
+
"button",
|
|
3482
|
+
{
|
|
3483
|
+
className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
|
|
3484
|
+
disabled: !isPro,
|
|
3485
|
+
title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
|
|
3486
|
+
onClick: () => isPro && handleExport(),
|
|
3487
|
+
children: [
|
|
3488
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3489
|
+
"path",
|
|
3490
|
+
{
|
|
3491
|
+
strokeLinecap: "round",
|
|
3492
|
+
strokeLinejoin: "round",
|
|
3493
|
+
strokeWidth: 2,
|
|
3494
|
+
d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
|
3495
|
+
}
|
|
3496
|
+
) }),
|
|
3497
|
+
"Export Pivot",
|
|
3498
|
+
!isPro ? " (Pro)" : ""
|
|
3432
3499
|
]
|
|
3433
3500
|
}
|
|
3434
3501
|
)
|