@smallwebco/tinypivot-react 1.0.13 → 1.0.15
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 +89 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +105 -49
- package/dist/index.js.map +1 -1
- package/dist/style.css +119 -3
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -67,13 +67,17 @@ function useExcelGrid(options) {
|
|
|
67
67
|
const [columnVisibility, setColumnVisibility] = (0, import_react.useState)({});
|
|
68
68
|
const [globalFilter, setGlobalFilter] = (0, import_react.useState)("");
|
|
69
69
|
const [columnStatsCache, setColumnStatsCache] = (0, import_react.useState)({});
|
|
70
|
+
const dataSignature = (0, import_react.useMemo)(
|
|
71
|
+
() => `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
72
|
+
[data]
|
|
73
|
+
);
|
|
70
74
|
const columnKeys = (0, import_react.useMemo)(() => {
|
|
71
75
|
if (data.length === 0) return [];
|
|
72
76
|
return Object.keys(data[0]);
|
|
73
77
|
}, [data]);
|
|
74
78
|
const getColumnStats = (0, import_react.useCallback)(
|
|
75
79
|
(columnKey) => {
|
|
76
|
-
const cacheKey = `${columnKey}-${
|
|
80
|
+
const cacheKey = `${columnKey}-${dataSignature}`;
|
|
77
81
|
if (!columnStatsCache[cacheKey]) {
|
|
78
82
|
const stats = (0, import_tinypivot_core.getColumnUniqueValues)(data, columnKey);
|
|
79
83
|
setColumnStatsCache((prev) => ({ ...prev, [cacheKey]: stats }));
|
|
@@ -81,11 +85,14 @@ function useExcelGrid(options) {
|
|
|
81
85
|
}
|
|
82
86
|
return columnStatsCache[cacheKey];
|
|
83
87
|
},
|
|
84
|
-
[data, columnStatsCache]
|
|
88
|
+
[data, columnStatsCache, dataSignature]
|
|
85
89
|
);
|
|
86
90
|
const clearStatsCache = (0, import_react.useCallback)(() => {
|
|
87
91
|
setColumnStatsCache({});
|
|
88
92
|
}, []);
|
|
93
|
+
(0, import_react.useEffect)(() => {
|
|
94
|
+
clearStatsCache();
|
|
95
|
+
}, [dataSignature, clearStatsCache]);
|
|
89
96
|
const columnDefs = (0, import_react.useMemo)(() => {
|
|
90
97
|
return columnKeys.map((key) => {
|
|
91
98
|
const stats = getColumnStats(key);
|
|
@@ -234,11 +241,17 @@ async function setLicenseKey(key) {
|
|
|
234
241
|
}
|
|
235
242
|
notifyListeners();
|
|
236
243
|
}
|
|
237
|
-
function enableDemoMode() {
|
|
244
|
+
async function enableDemoMode(secret) {
|
|
245
|
+
const demoLicense = await (0, import_tinypivot_core2.getDemoLicenseInfo)(secret);
|
|
246
|
+
if (!demoLicense) {
|
|
247
|
+
console.warn("[TinyPivot] Demo mode activation failed - invalid secret");
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
238
250
|
globalDemoMode = true;
|
|
239
|
-
globalLicenseInfo =
|
|
251
|
+
globalLicenseInfo = demoLicense;
|
|
240
252
|
console.info("[TinyPivot] Demo mode enabled - all Pro features unlocked for evaluation");
|
|
241
253
|
notifyListeners();
|
|
254
|
+
return true;
|
|
242
255
|
}
|
|
243
256
|
function configureLicenseSecret(secret) {
|
|
244
257
|
(0, import_tinypivot_core2.configureLicenseSecret)(secret);
|
|
@@ -1337,6 +1350,20 @@ function PivotSkeleton({
|
|
|
1337
1350
|
if (!activeFilters || activeFilters.length === 0) return "";
|
|
1338
1351
|
return activeFilters.map((f) => f.column).join(", ");
|
|
1339
1352
|
}, [activeFilters]);
|
|
1353
|
+
const [showFilterTooltip, setShowFilterTooltip] = (0, import_react7.useState)(false);
|
|
1354
|
+
const filterTooltipDetails = (0, import_react7.useMemo)(() => {
|
|
1355
|
+
if (!activeFilters || activeFilters.length === 0) return [];
|
|
1356
|
+
return activeFilters.map((f) => {
|
|
1357
|
+
const maxDisplay = 5;
|
|
1358
|
+
const displayValues = f.values.slice(0, maxDisplay);
|
|
1359
|
+
const remaining = f.values.length - maxDisplay;
|
|
1360
|
+
return {
|
|
1361
|
+
column: f.column,
|
|
1362
|
+
values: displayValues,
|
|
1363
|
+
remaining: remaining > 0 ? remaining : 0
|
|
1364
|
+
};
|
|
1365
|
+
});
|
|
1366
|
+
}, [activeFilters]);
|
|
1340
1367
|
const handleDragOver = (0, import_react7.useCallback)(
|
|
1341
1368
|
(area, event) => {
|
|
1342
1369
|
event.preventDefault();
|
|
@@ -1461,37 +1488,66 @@ function PivotSkeleton({
|
|
|
1461
1488
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Pivot Table" })
|
|
1462
1489
|
] }),
|
|
1463
1490
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-header-right", children: [
|
|
1464
|
-
hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
"path",
|
|
1491
|
+
hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1492
|
+
"div",
|
|
1493
|
+
{
|
|
1494
|
+
className: "vpg-filter-indicator",
|
|
1495
|
+
onMouseEnter: () => setShowFilterTooltip(true),
|
|
1496
|
+
onMouseLeave: () => setShowFilterTooltip(false),
|
|
1497
|
+
children: [
|
|
1498
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1499
|
+
"svg",
|
|
1474
1500
|
{
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1501
|
+
className: "vpg-filter-icon",
|
|
1502
|
+
fill: "none",
|
|
1503
|
+
stroke: "currentColor",
|
|
1504
|
+
viewBox: "0 0 24 24",
|
|
1505
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1506
|
+
"path",
|
|
1507
|
+
{
|
|
1508
|
+
strokeLinecap: "round",
|
|
1509
|
+
strokeLinejoin: "round",
|
|
1510
|
+
strokeWidth: 2,
|
|
1511
|
+
d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
|
|
1512
|
+
}
|
|
1513
|
+
)
|
|
1479
1514
|
}
|
|
1480
|
-
)
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1515
|
+
),
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-filter-text", children: [
|
|
1517
|
+
"Filtered: ",
|
|
1518
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: filterSummary }),
|
|
1519
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-filter-count", children: [
|
|
1520
|
+
"(",
|
|
1521
|
+
filteredRowCount.toLocaleString(),
|
|
1522
|
+
" of ",
|
|
1523
|
+
totalRowCount.toLocaleString(),
|
|
1524
|
+
" rows)"
|
|
1525
|
+
] })
|
|
1526
|
+
] }),
|
|
1527
|
+
showFilterTooltip && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-filter-tooltip", children: [
|
|
1528
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
|
|
1529
|
+
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-tooltip-filter", children: [
|
|
1530
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-tooltip-column", children: filter.column }),
|
|
1531
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-tooltip-values", children: [
|
|
1532
|
+
filter.values.map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-tooltip-value", children: val }, idx)),
|
|
1533
|
+
filter.remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-tooltip-more", children: [
|
|
1534
|
+
"+",
|
|
1535
|
+
filter.remaining,
|
|
1536
|
+
" more"
|
|
1537
|
+
] })
|
|
1538
|
+
] })
|
|
1539
|
+
] }, filter.column)),
|
|
1540
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-tooltip-summary", children: [
|
|
1541
|
+
"Showing ",
|
|
1542
|
+
filteredRowCount.toLocaleString(),
|
|
1543
|
+
" of ",
|
|
1544
|
+
totalRowCount.toLocaleString(),
|
|
1545
|
+
" rows"
|
|
1546
|
+
] })
|
|
1547
|
+
] })
|
|
1548
|
+
]
|
|
1549
|
+
}
|
|
1550
|
+
),
|
|
1495
1551
|
isConfigured && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-config-summary", children: [
|
|
1496
1552
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-summary-badge vpg-rows", children: [
|
|
1497
1553
|
rowFields.length,
|