@smallwebco/tinypivot-react 1.0.38 → 1.0.48

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 CHANGED
@@ -425,12 +425,11 @@ function usePivotTable(data) {
425
425
  }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
426
426
  const addRowField = useCallback3(
427
427
  (field) => {
428
- if (!requirePro("Pivot Table - Row Fields")) return;
429
428
  if (!rowFields.includes(field)) {
430
429
  setRowFieldsState((prev) => [...prev, field]);
431
430
  }
432
431
  },
433
- [rowFields, requirePro]
432
+ [rowFields]
434
433
  );
435
434
  const removeRowField = useCallback3((field) => {
436
435
  setRowFieldsState((prev) => prev.filter((f) => f !== field));
@@ -440,12 +439,11 @@ function usePivotTable(data) {
440
439
  }, []);
441
440
  const addColumnField = useCallback3(
442
441
  (field) => {
443
- if (!requirePro("Pivot Table - Column Fields")) return;
444
442
  if (!columnFields.includes(field)) {
445
443
  setColumnFieldsState((prev) => [...prev, field]);
446
444
  }
447
445
  },
448
- [columnFields, requirePro]
446
+ [columnFields]
449
447
  );
450
448
  const removeColumnField = useCallback3((field) => {
451
449
  setColumnFieldsState((prev) => prev.filter((f) => f !== field));
@@ -455,7 +453,9 @@ function usePivotTable(data) {
455
453
  }, []);
456
454
  const addValueField = useCallback3(
457
455
  (field, aggregation = "sum") => {
458
- if (!requirePro("Pivot Table - Value Fields")) return;
456
+ if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
457
+ return;
458
+ }
459
459
  setValueFields((prev) => {
460
460
  if (prev.some((v) => v.field === field && v.aggregation === aggregation)) {
461
461
  return prev;
@@ -1532,11 +1532,15 @@ function CalculatedFieldModal({
1532
1532
  ] })
1533
1533
  ] })
1534
1534
  ] }) });
1535
+ if (typeof document === "undefined") return null;
1535
1536
  return createPortal(modalContent, document.body);
1536
1537
  }
1537
1538
 
1538
1539
  // src/components/PivotConfig.tsx
1539
1540
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1541
+ function aggregationRequiresPro(agg) {
1542
+ return agg !== "sum";
1543
+ }
1540
1544
  function getFieldIcon(type, isCalculated) {
1541
1545
  if (isCalculated) return "\u0192";
1542
1546
  switch (type) {
@@ -1576,6 +1580,10 @@ function PivotConfig({
1576
1580
  const [fieldSearch, setFieldSearch] = useState8("");
1577
1581
  const [showCalcModal, setShowCalcModal] = useState8(false);
1578
1582
  const [editingCalcField, setEditingCalcField] = useState8(null);
1583
+ const { canUseAdvancedAggregations } = useLicense();
1584
+ const isAggregationAvailable = useCallback8((agg) => {
1585
+ return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
1586
+ }, [canUseAdvancedAggregations]);
1579
1587
  const numericFieldNames = useMemo8(
1580
1588
  () => availableFields.filter((f) => f.isNumeric).map((f) => f.field),
1581
1589
  [availableFields]
@@ -1641,9 +1649,13 @@ function PivotConfig({
1641
1649
  );
1642
1650
  const handleAggregationChange = useCallback8(
1643
1651
  (field, currentAgg, newAgg) => {
1652
+ if (!isAggregationAvailable(newAgg)) {
1653
+ console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
1654
+ return;
1655
+ }
1644
1656
  onUpdateAggregation(field, currentAgg, newAgg);
1645
1657
  },
1646
- [onUpdateAggregation]
1658
+ [onUpdateAggregation, isAggregationAvailable]
1647
1659
  );
1648
1660
  const toggleRowColumn = useCallback8(
1649
1661
  (field, currentAssignment) => {
@@ -1781,11 +1793,20 @@ function PivotConfig({
1781
1793
  );
1782
1794
  },
1783
1795
  onClick: (e) => e.stopPropagation(),
1784
- children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs4("option", { value: agg.value, children: [
1785
- agg.symbol,
1786
- " ",
1787
- agg.label
1788
- ] }, agg.value))
1796
+ children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs4(
1797
+ "option",
1798
+ {
1799
+ value: agg.value,
1800
+ disabled: aggregationRequiresPro(agg.value) && !canUseAdvancedAggregations,
1801
+ children: [
1802
+ agg.symbol,
1803
+ " ",
1804
+ agg.label,
1805
+ aggregationRequiresPro(agg.value) && !canUseAdvancedAggregations ? " (Pro)" : ""
1806
+ ]
1807
+ },
1808
+ agg.value
1809
+ ))
1789
1810
  }
1790
1811
  ),
1791
1812
  /* @__PURE__ */ jsx4(
@@ -2688,7 +2709,7 @@ function DataGrid({
2688
2709
  onExport,
2689
2710
  onCopy
2690
2711
  }) {
2691
- const { showWatermark, canUsePivot, isDemo } = useLicense();
2712
+ const { showWatermark, canUsePivot, isDemo, isPro } = useLicense();
2692
2713
  const currentTheme = useMemo10(() => {
2693
2714
  if (theme === "auto") {
2694
2715
  return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
@@ -2862,6 +2883,7 @@ function DataGrid({
2862
2883
  return { count, sum, avg, numericCount: values.length };
2863
2884
  }, [selectionBounds, rows, columnKeys]);
2864
2885
  useEffect7(() => {
2886
+ if (typeof document === "undefined") return;
2865
2887
  if (data.length === 0) return;
2866
2888
  const widths = {};
2867
2889
  const sampleSize = Math.min(100, data.length);
@@ -3394,11 +3416,11 @@ function DataGrid({
3394
3416
  ) })
3395
3417
  }
3396
3418
  ),
3397
- enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ jsxs6(
3419
+ enableExport && viewMode === "grid" && /* @__PURE__ */ jsxs6(
3398
3420
  "button",
3399
3421
  {
3400
3422
  className: "vpg-export-btn",
3401
- title: viewMode === "pivot" ? "Export Pivot to CSV" : "Export to CSV",
3423
+ title: "Export to CSV",
3402
3424
  onClick: handleExport,
3403
3425
  children: [
3404
3426
  /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
@@ -3410,8 +3432,29 @@ function DataGrid({
3410
3432
  d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
3411
3433
  }
3412
3434
  ) }),
3413
- "Export",
3414
- viewMode === "pivot" ? " Pivot" : ""
3435
+ "Export"
3436
+ ]
3437
+ }
3438
+ ),
3439
+ enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ jsxs6(
3440
+ "button",
3441
+ {
3442
+ className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
3443
+ disabled: !isPro,
3444
+ title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
3445
+ onClick: () => isPro && handleExport(),
3446
+ children: [
3447
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
3448
+ "path",
3449
+ {
3450
+ strokeLinecap: "round",
3451
+ strokeLinejoin: "round",
3452
+ strokeWidth: 2,
3453
+ d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
3454
+ }
3455
+ ) }),
3456
+ "Export Pivot",
3457
+ !isPro ? " (Pro)" : ""
3415
3458
  ]
3416
3459
  }
3417
3460
  )
@@ -3760,7 +3803,7 @@ function DataGrid({
3760
3803
  /* @__PURE__ */ jsx6("span", {}),
3761
3804
  /* @__PURE__ */ jsx6("span", {})
3762
3805
  ] }) }),
3763
- activeFilterColumn && createPortal2(
3806
+ activeFilterColumn && typeof document !== "undefined" && createPortal2(
3764
3807
  /* @__PURE__ */ jsx6(
3765
3808
  "div",
3766
3809
  {