@smallwebco/tinypivot-react 1.0.51 → 1.0.52

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
@@ -188,21 +188,530 @@ function CalculatedFieldModal({
188
188
  return createPortal(modalContent, document.body);
189
189
  }
190
190
 
191
+ // src/components/ChartBuilder.tsx
192
+ import {
193
+ analyzeFieldsForChart,
194
+ CHART_AGGREGATIONS,
195
+ CHART_COLORS,
196
+ CHART_TYPES,
197
+ createDefaultChartConfig,
198
+ getChartGuidance,
199
+ isChartConfigValid,
200
+ processChartData,
201
+ processChartDataForPie,
202
+ processChartDataForScatter
203
+ } from "@smallwebco/tinypivot-core";
204
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
205
+ import Chart from "react-apexcharts";
206
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
207
+ function ChartBuilder({
208
+ data,
209
+ theme = "light",
210
+ onConfigChange
211
+ }) {
212
+ const [chartConfig, setChartConfig] = useState2(createDefaultChartConfig());
213
+ const [draggingField, setDraggingField] = useState2(null);
214
+ const [dragOverZone, setDragOverZone] = useState2(null);
215
+ const fieldInfos = useMemo2(() => analyzeFieldsForChart(data), [data]);
216
+ const dimensions = useMemo2(
217
+ () => fieldInfos.filter((f) => f.role === "dimension" || f.role === "temporal"),
218
+ [fieldInfos]
219
+ );
220
+ const measures = useMemo2(
221
+ () => fieldInfos.filter((f) => f.role === "measure"),
222
+ [fieldInfos]
223
+ );
224
+ const guidance = useMemo2(() => getChartGuidance(chartConfig), [chartConfig]);
225
+ const chartIsValid = useMemo2(() => isChartConfigValid(chartConfig), [chartConfig]);
226
+ const selectedChartType = useMemo2(
227
+ () => CHART_TYPES.find((ct) => ct.type === chartConfig.type),
228
+ [chartConfig.type]
229
+ );
230
+ const handleDragStart = useCallback2((field, event) => {
231
+ setDraggingField(field);
232
+ event.dataTransfer?.setData("text/plain", field.field);
233
+ }, []);
234
+ const handleDragEnd = useCallback2(() => {
235
+ setDraggingField(null);
236
+ setDragOverZone(null);
237
+ }, []);
238
+ const handleDragOver = useCallback2((zone, event) => {
239
+ event.preventDefault();
240
+ setDragOverZone(zone);
241
+ }, []);
242
+ const handleDragLeave = useCallback2(() => {
243
+ setDragOverZone(null);
244
+ }, []);
245
+ const handleDrop = useCallback2((zone, event) => {
246
+ event.preventDefault();
247
+ setDragOverZone(null);
248
+ if (!draggingField)
249
+ return;
250
+ const field = draggingField;
251
+ const chartField = {
252
+ field: field.field,
253
+ label: field.label,
254
+ role: field.role,
255
+ aggregation: field.role === "measure" ? "sum" : void 0
256
+ };
257
+ let newConfig = { ...chartConfig };
258
+ switch (zone) {
259
+ case "xAxis":
260
+ newConfig = { ...newConfig, xAxis: chartField };
261
+ break;
262
+ case "yAxis":
263
+ newConfig = { ...newConfig, yAxis: chartField };
264
+ break;
265
+ case "series":
266
+ newConfig = { ...newConfig, seriesField: chartField };
267
+ break;
268
+ case "size":
269
+ newConfig = { ...newConfig, sizeField: chartField };
270
+ break;
271
+ case "color":
272
+ newConfig = { ...newConfig, colorField: chartField };
273
+ break;
274
+ }
275
+ setChartConfig(newConfig);
276
+ onConfigChange?.(newConfig);
277
+ }, [chartConfig, draggingField, onConfigChange]);
278
+ const removeField = useCallback2((zone) => {
279
+ let newConfig = { ...chartConfig };
280
+ switch (zone) {
281
+ case "xAxis":
282
+ newConfig = { ...newConfig, xAxis: void 0 };
283
+ break;
284
+ case "yAxis":
285
+ newConfig = { ...newConfig, yAxis: void 0 };
286
+ break;
287
+ case "series":
288
+ newConfig = { ...newConfig, seriesField: void 0 };
289
+ break;
290
+ case "size":
291
+ newConfig = { ...newConfig, sizeField: void 0 };
292
+ break;
293
+ case "color":
294
+ newConfig = { ...newConfig, colorField: void 0 };
295
+ break;
296
+ }
297
+ setChartConfig(newConfig);
298
+ onConfigChange?.(newConfig);
299
+ }, [chartConfig, onConfigChange]);
300
+ const selectChartType = useCallback2((type) => {
301
+ const newConfig = { ...chartConfig, type };
302
+ setChartConfig(newConfig);
303
+ onConfigChange?.(newConfig);
304
+ }, [chartConfig, onConfigChange]);
305
+ const updateAggregation = useCallback2((zone, aggregation) => {
306
+ const field = zone === "yAxis" ? chartConfig.yAxis : chartConfig.sizeField;
307
+ if (!field)
308
+ return;
309
+ const updated = { ...field, aggregation };
310
+ let newConfig = { ...chartConfig };
311
+ if (zone === "yAxis") {
312
+ newConfig = { ...newConfig, yAxis: updated };
313
+ } else if (zone === "size") {
314
+ newConfig = { ...newConfig, sizeField: updated };
315
+ }
316
+ setChartConfig(newConfig);
317
+ onConfigChange?.(newConfig);
318
+ }, [chartConfig, onConfigChange]);
319
+ const getApexChartType = useCallback2((type) => {
320
+ const mapping = {
321
+ bar: "bar",
322
+ line: "line",
323
+ area: "area",
324
+ pie: "pie",
325
+ donut: "donut",
326
+ scatter: "scatter",
327
+ bubble: "bubble",
328
+ heatmap: "heatmap",
329
+ treemap: "bar",
330
+ // Treemap rendered as bar (compatibility)
331
+ radar: "radar"
332
+ };
333
+ return mapping[type] || "bar";
334
+ }, []);
335
+ const formatValue = useCallback2((val, format, decimals) => {
336
+ const dec = decimals ?? 0;
337
+ if (format === "percent") {
338
+ return `${val.toFixed(dec)}%`;
339
+ }
340
+ if (format === "currency") {
341
+ return `$${val.toLocaleString(void 0, { minimumFractionDigits: dec, maximumFractionDigits: dec })}`;
342
+ }
343
+ if (Math.abs(val) >= 1e3) {
344
+ return val.toLocaleString(void 0, { maximumFractionDigits: dec });
345
+ }
346
+ return val.toFixed(dec);
347
+ }, []);
348
+ const chartOptions = useMemo2(() => {
349
+ const isDark = theme === "dark";
350
+ const config = chartConfig;
351
+ const options = config.options || {};
352
+ const baseOptions = {
353
+ chart: {
354
+ type: getApexChartType(config.type),
355
+ background: "transparent",
356
+ foreColor: isDark ? "#e2e8f0" : "#334155",
357
+ toolbar: {
358
+ show: true,
359
+ tools: {
360
+ download: true,
361
+ selection: false,
362
+ zoom: options.enableZoom ?? false,
363
+ zoomin: options.enableZoom ?? false,
364
+ zoomout: options.enableZoom ?? false,
365
+ pan: false,
366
+ reset: options.enableZoom ?? false
367
+ },
368
+ export: {
369
+ csv: { filename: "chart-data" },
370
+ svg: { filename: "chart" },
371
+ png: { filename: "chart" }
372
+ }
373
+ },
374
+ animations: {
375
+ enabled: options.animated ?? true,
376
+ speed: 400,
377
+ dynamicAnimation: { enabled: true, speed: 300 }
378
+ },
379
+ fontFamily: "system-ui, -apple-system, sans-serif"
380
+ },
381
+ colors: options.colors || CHART_COLORS,
382
+ theme: {
383
+ mode: isDark ? "dark" : "light"
384
+ },
385
+ grid: {
386
+ show: options.showGrid ?? true,
387
+ borderColor: isDark ? "#334155" : "#e2e8f0"
388
+ },
389
+ legend: {
390
+ show: options.showLegend ?? true,
391
+ position: options.legendPosition || "top"
392
+ },
393
+ dataLabels: {
394
+ enabled: options.showDataLabels ?? false
395
+ },
396
+ tooltip: {
397
+ theme: isDark ? "dark" : "light"
398
+ },
399
+ stroke: {
400
+ curve: "smooth",
401
+ width: config.type === "line" ? 3 : config.type === "area" ? 2 : 0
402
+ },
403
+ fill: {
404
+ opacity: config.type === "area" ? 0.4 : 1
405
+ }
406
+ };
407
+ if (config.xAxis) {
408
+ baseOptions.xaxis = {
409
+ ...baseOptions.xaxis,
410
+ title: { text: options.xAxisTitle || config.xAxis.label },
411
+ labels: {
412
+ style: { colors: isDark ? "#94a3b8" : "#64748b" }
413
+ }
414
+ };
415
+ }
416
+ if (config.yAxis && !["pie", "donut", "radar", "treemap"].includes(config.type)) {
417
+ baseOptions.yaxis = {
418
+ title: { text: options.yAxisTitle || config.yAxis.label },
419
+ labels: {
420
+ style: { colors: isDark ? "#94a3b8" : "#64748b" },
421
+ formatter: (val) => formatValue(val, options.valueFormat, options.decimals)
422
+ }
423
+ };
424
+ }
425
+ if (options.title) {
426
+ baseOptions.title = {
427
+ text: options.title,
428
+ style: {
429
+ fontSize: "16px",
430
+ fontWeight: "600",
431
+ color: isDark ? "#e2e8f0" : "#334155"
432
+ }
433
+ };
434
+ }
435
+ if (options.stacked && ["bar", "area"].includes(config.type)) {
436
+ baseOptions.chart.stacked = true;
437
+ }
438
+ if (config.type === "pie" || config.type === "donut") {
439
+ baseOptions.plotOptions = {
440
+ pie: {
441
+ donut: {
442
+ size: config.type === "donut" ? "55%" : "0%",
443
+ labels: {
444
+ show: config.type === "donut",
445
+ total: {
446
+ show: true,
447
+ label: "Total",
448
+ formatter: (w) => {
449
+ const total = w.globals.seriesTotals.reduce((a, b) => a + b, 0);
450
+ return formatValue(total, options.valueFormat, options.decimals);
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+ };
457
+ }
458
+ if (config.type === "radar") {
459
+ baseOptions.plotOptions = {
460
+ radar: {
461
+ polygons: {
462
+ strokeColors: isDark ? "#334155" : "#e2e8f0",
463
+ fill: { colors: isDark ? ["#1e293b", "#0f172a"] : ["#f8fafc", "#f1f5f9"] }
464
+ }
465
+ }
466
+ };
467
+ }
468
+ return baseOptions;
469
+ }, [chartConfig, theme, getApexChartType, formatValue]);
470
+ const chartSeries = useMemo2(() => {
471
+ const config = chartConfig;
472
+ if (!chartIsValid)
473
+ return [];
474
+ if (config.type === "pie" || config.type === "donut") {
475
+ const chartData2 = processChartDataForPie(data, config);
476
+ return chartData2.series[0]?.data || [];
477
+ }
478
+ if (config.type === "scatter" || config.type === "bubble") {
479
+ const points = processChartDataForScatter(data, config);
480
+ return [{
481
+ name: config.yAxis?.label || "Data",
482
+ data: points
483
+ }];
484
+ }
485
+ const chartData = processChartData(data, config);
486
+ return chartData.series;
487
+ }, [data, chartConfig, chartIsValid]);
488
+ const chartLabels = useMemo2(() => {
489
+ const config = chartConfig;
490
+ if (!chartIsValid)
491
+ return [];
492
+ if (config.type === "pie" || config.type === "donut") {
493
+ const chartData2 = processChartDataForPie(data, config);
494
+ return chartData2.categories;
495
+ }
496
+ const chartData = processChartData(data, config);
497
+ return chartData.categories;
498
+ }, [data, chartConfig, chartIsValid]);
499
+ const chartOptionsWithCategories = useMemo2(() => {
500
+ const options = { ...chartOptions };
501
+ const config = chartConfig;
502
+ if (!["pie", "donut", "scatter", "bubble"].includes(config.type)) {
503
+ options.xaxis = {
504
+ ...options.xaxis,
505
+ categories: chartLabels
506
+ };
507
+ }
508
+ if (config.type === "pie" || config.type === "donut") {
509
+ options.labels = chartLabels;
510
+ }
511
+ return options;
512
+ }, [chartOptions, chartConfig, chartLabels]);
513
+ const getChartIcon = useCallback2((type) => {
514
+ const icons = {
515
+ bar: "M3 3v18h18V3H3zm4 14H5v-6h2v6zm4 0H9V7h2v10zm4 0h-2V9h2v8zm4 0h-2v-4h2v4z",
516
+ line: "M3.5 18.5l6-6 4 4 8-8M14.5 8.5h6v6",
517
+ area: "M3 17l6-6 4 4 8-8v10H3z",
518
+ pie: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8v8l5.66 5.66C14.28 19.04 13.18 20 12 20z",
519
+ donut: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z",
520
+ scatter: "M7 14c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm4 7c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z",
521
+ bubble: "M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-6 3c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 2c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z",
522
+ heatmap: "M3 3h4v4H3V3zm6 0h4v4H9V3zm6 0h4v4h-4V3zM3 9h4v4H3V9zm6 0h4v4H9V9zm6 0h4v4h-4V9zM3 15h4v4H3v-4zm6 0h4v4H9v-4zm6 0h4v4h-4v-4z",
523
+ treemap: "M3 3h8v10H3V3zm10 0h8v6h-8V3zM3 15h8v6H3v-6zm10-4h8v10h-8V11z",
524
+ radar: "M12 2L4 6v6c0 5.55 3.84 10.74 8 12 4.16-1.26 8-6.45 8-12V6l-8-4zm0 3.18l6 3v5.09c0 4.08-2.76 7.91-6 9.14V5.18z"
525
+ };
526
+ return icons[type] || icons.bar;
527
+ }, []);
528
+ useEffect2(() => {
529
+ onConfigChange?.(chartConfig);
530
+ }, []);
531
+ return /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-builder", children: [
532
+ /* @__PURE__ */ jsx2("div", { className: "vpg-chart-type-bar", children: CHART_TYPES.map((ct) => /* @__PURE__ */ jsxs2(
533
+ "button",
534
+ {
535
+ className: `vpg-chart-type-btn ${chartConfig.type === ct.type ? "active" : ""}`,
536
+ title: ct.description,
537
+ onClick: () => selectChartType(ct.type),
538
+ children: [
539
+ /* @__PURE__ */ jsx2("svg", { className: "vpg-icon", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d: getChartIcon(ct.type) }) }),
540
+ /* @__PURE__ */ jsx2("span", { className: "vpg-chart-type-label", children: ct.label.replace(" Chart", "") })
541
+ ]
542
+ },
543
+ ct.type
544
+ )) }),
545
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-builder-content", children: [
546
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-panel", children: [
547
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-section", children: [
548
+ /* @__PURE__ */ jsxs2("h4", { className: "vpg-chart-fields-title", children: [
549
+ /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M4 6h16M4 12h10M4 18h6" }) }),
550
+ "Dimensions"
551
+ ] }),
552
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-list", children: [
553
+ dimensions.map((field) => /* @__PURE__ */ jsxs2(
554
+ "div",
555
+ {
556
+ className: "vpg-chart-field-chip vpg-field-dimension",
557
+ draggable: true,
558
+ onDragStart: (e) => handleDragStart(field, e),
559
+ onDragEnd: handleDragEnd,
560
+ children: [
561
+ /* @__PURE__ */ jsx2("span", { className: "vpg-field-name", children: field.label }),
562
+ /* @__PURE__ */ jsx2("span", { className: "vpg-field-type", children: field.role === "temporal" ? "date" : "text" })
563
+ ]
564
+ },
565
+ field.field
566
+ )),
567
+ dimensions.length === 0 && /* @__PURE__ */ jsx2("div", { className: "vpg-chart-fields-empty", children: "No dimension fields detected" })
568
+ ] })
569
+ ] }),
570
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-section", children: [
571
+ /* @__PURE__ */ jsxs2("h4", { className: "vpg-chart-fields-title", children: [
572
+ /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M16 8v8M12 11v5M8 14v2M4 4v16h16" }) }),
573
+ "Measures"
574
+ ] }),
575
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-list", children: [
576
+ measures.map((field) => /* @__PURE__ */ jsxs2(
577
+ "div",
578
+ {
579
+ className: "vpg-chart-field-chip vpg-field-measure",
580
+ draggable: true,
581
+ onDragStart: (e) => handleDragStart(field, e),
582
+ onDragEnd: handleDragEnd,
583
+ children: [
584
+ /* @__PURE__ */ jsx2("span", { className: "vpg-field-name", children: field.label }),
585
+ /* @__PURE__ */ jsx2("span", { className: "vpg-field-type", children: "#" })
586
+ ]
587
+ },
588
+ field.field
589
+ )),
590
+ measures.length === 0 && /* @__PURE__ */ jsx2("div", { className: "vpg-chart-fields-empty", children: "No numeric fields detected" })
591
+ ] })
592
+ ] })
593
+ ] }),
594
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-config-panel", children: [
595
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
596
+ /* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "X-Axis / Category" }),
597
+ /* @__PURE__ */ jsx2(
598
+ "div",
599
+ {
600
+ className: `vpg-chart-drop-zone ${dragOverZone === "xAxis" ? "drag-over" : ""} ${chartConfig.xAxis ? "has-field" : ""}`,
601
+ onDragOver: (e) => handleDragOver("xAxis", e),
602
+ onDragLeave: handleDragLeave,
603
+ onDrop: (e) => handleDrop("xAxis", e),
604
+ children: chartConfig.xAxis ? /* @__PURE__ */ jsxs2(Fragment, { children: [
605
+ /* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.xAxis.label }),
606
+ /* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("xAxis"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
607
+ ] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Drop dimension here" })
608
+ }
609
+ )
610
+ ] }),
611
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
612
+ /* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "Y-Axis / Value" }),
613
+ /* @__PURE__ */ jsx2(
614
+ "div",
615
+ {
616
+ className: `vpg-chart-drop-zone ${dragOverZone === "yAxis" ? "drag-over" : ""} ${chartConfig.yAxis ? "has-field" : ""}`,
617
+ onDragOver: (e) => handleDragOver("yAxis", e),
618
+ onDragLeave: handleDragLeave,
619
+ onDrop: (e) => handleDrop("yAxis", e),
620
+ children: chartConfig.yAxis ? /* @__PURE__ */ jsxs2(Fragment, { children: [
621
+ /* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.yAxis.label }),
622
+ chartConfig.yAxis.role === "measure" && /* @__PURE__ */ jsx2(
623
+ "select",
624
+ {
625
+ className: "vpg-zone-aggregation",
626
+ value: chartConfig.yAxis.aggregation || "sum",
627
+ onChange: (e) => updateAggregation("yAxis", e.target.value),
628
+ children: CHART_AGGREGATIONS.map((agg) => /* @__PURE__ */ jsx2("option", { value: agg.value, children: agg.symbol }, agg.value))
629
+ }
630
+ ),
631
+ /* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("yAxis"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
632
+ ] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Drop measure here" })
633
+ }
634
+ )
635
+ ] }),
636
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
637
+ /* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "Color / Series (optional)" }),
638
+ /* @__PURE__ */ jsx2(
639
+ "div",
640
+ {
641
+ className: `vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === "series" ? "drag-over" : ""} ${chartConfig.seriesField ? "has-field" : ""}`,
642
+ onDragOver: (e) => handleDragOver("series", e),
643
+ onDragLeave: handleDragLeave,
644
+ onDrop: (e) => handleDrop("series", e),
645
+ children: chartConfig.seriesField ? /* @__PURE__ */ jsxs2(Fragment, { children: [
646
+ /* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.seriesField.label }),
647
+ /* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("series"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
648
+ ] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Group by dimension" })
649
+ }
650
+ )
651
+ ] }),
652
+ (chartConfig.type === "scatter" || chartConfig.type === "bubble") && /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
653
+ /* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "Size (bubble)" }),
654
+ /* @__PURE__ */ jsx2(
655
+ "div",
656
+ {
657
+ className: `vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === "size" ? "drag-over" : ""} ${chartConfig.sizeField ? "has-field" : ""}`,
658
+ onDragOver: (e) => handleDragOver("size", e),
659
+ onDragLeave: handleDragLeave,
660
+ onDrop: (e) => handleDrop("size", e),
661
+ children: chartConfig.sizeField ? /* @__PURE__ */ jsxs2(Fragment, { children: [
662
+ /* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.sizeField.label }),
663
+ /* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("size"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
664
+ ] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Drop measure for size" })
665
+ }
666
+ )
667
+ ] }),
668
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-guidance", children: [
669
+ /* @__PURE__ */ jsxs2("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
670
+ /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10" }),
671
+ /* @__PURE__ */ jsx2("path", { d: "M12 16v-4M12 8h.01" })
672
+ ] }),
673
+ /* @__PURE__ */ jsx2("span", { children: guidance })
674
+ ] })
675
+ ] }),
676
+ /* @__PURE__ */ jsx2("div", { className: "vpg-chart-preview-panel", children: chartIsValid ? /* @__PURE__ */ jsx2("div", { className: "vpg-chart-container", children: /* @__PURE__ */ jsx2(
677
+ Chart,
678
+ {
679
+ type: getApexChartType(chartConfig.type),
680
+ options: chartOptionsWithCategories,
681
+ series: chartSeries,
682
+ height: "100%"
683
+ },
684
+ `${chartConfig.type}-${JSON.stringify(chartConfig.xAxis)}-${JSON.stringify(chartConfig.yAxis)}`
685
+ ) }) : /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-empty-state", children: [
686
+ /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-lg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ jsx2("path", { d: getChartIcon(chartConfig.type) }) }),
687
+ /* @__PURE__ */ jsx2("h3", { children: "Build your chart" }),
688
+ /* @__PURE__ */ jsx2("p", { children: "Drag fields from the left panel to configure your visualization" }),
689
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-hint", children: [
690
+ /* @__PURE__ */ jsx2("strong", { children: selectedChartType?.label }),
691
+ ":",
692
+ " ",
693
+ selectedChartType?.description
694
+ ] })
695
+ ] }) })
696
+ ] })
697
+ ] });
698
+ }
699
+
191
700
  // src/components/ColumnFilter.tsx
192
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useRef, useState as useState3 } from "react";
701
+ import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo4, useRef, useState as useState4 } from "react";
193
702
 
194
703
  // src/components/NumericRangeFilter.tsx
195
- import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
196
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
704
+ import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
705
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
197
706
  function NumericRangeFilter({
198
707
  dataMin,
199
708
  dataMax,
200
709
  currentRange,
201
710
  onChange
202
711
  }) {
203
- const [localMin, setLocalMin] = useState2(currentRange?.min ?? null);
204
- const [localMax, setLocalMax] = useState2(currentRange?.max ?? null);
205
- const step = useMemo2(() => {
712
+ const [localMin, setLocalMin] = useState3(currentRange?.min ?? null);
713
+ const [localMax, setLocalMax] = useState3(currentRange?.max ?? null);
714
+ const step = useMemo3(() => {
206
715
  const range = dataMax - dataMin;
207
716
  if (range === 0)
208
717
  return 1;
@@ -216,7 +725,7 @@ function NumericRangeFilter({
216
725
  return 10;
217
726
  return 10 ** (Math.floor(Math.log10(range)) - 2);
218
727
  }, [dataMin, dataMax]);
219
- const formatValue = useCallback2((val) => {
728
+ const formatValue = useCallback3((val) => {
220
729
  if (val === null)
221
730
  return "";
222
731
  if (Number.isInteger(val))
@@ -224,17 +733,17 @@ function NumericRangeFilter({
224
733
  return val.toLocaleString(void 0, { maximumFractionDigits: 2 });
225
734
  }, []);
226
735
  const isFilterActive = localMin !== null || localMax !== null;
227
- const minPercent = useMemo2(() => {
736
+ const minPercent = useMemo3(() => {
228
737
  if (localMin === null || dataMax === dataMin)
229
738
  return 0;
230
739
  return (localMin - dataMin) / (dataMax - dataMin) * 100;
231
740
  }, [localMin, dataMin, dataMax]);
232
- const maxPercent = useMemo2(() => {
741
+ const maxPercent = useMemo3(() => {
233
742
  if (localMax === null || dataMax === dataMin)
234
743
  return 100;
235
744
  return (localMax - dataMin) / (dataMax - dataMin) * 100;
236
745
  }, [localMax, dataMin, dataMax]);
237
- const handleMinSlider = useCallback2((event) => {
746
+ const handleMinSlider = useCallback3((event) => {
238
747
  const value = Number.parseFloat(event.target.value);
239
748
  setLocalMin(() => {
240
749
  if (localMax !== null && value > localMax) {
@@ -243,7 +752,7 @@ function NumericRangeFilter({
243
752
  return value;
244
753
  });
245
754
  }, [localMax]);
246
- const handleMaxSlider = useCallback2((event) => {
755
+ const handleMaxSlider = useCallback3((event) => {
247
756
  const value = Number.parseFloat(event.target.value);
248
757
  setLocalMax(() => {
249
758
  if (localMin !== null && value < localMin) {
@@ -252,14 +761,14 @@ function NumericRangeFilter({
252
761
  return value;
253
762
  });
254
763
  }, [localMin]);
255
- const handleSliderChange = useCallback2(() => {
764
+ const handleSliderChange = useCallback3(() => {
256
765
  if (localMin === null && localMax === null) {
257
766
  onChange(null);
258
767
  } else {
259
768
  onChange({ min: localMin, max: localMax });
260
769
  }
261
770
  }, [localMin, localMax, onChange]);
262
- const handleMinInput = useCallback2((event) => {
771
+ const handleMinInput = useCallback3((event) => {
263
772
  const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
264
773
  if (value !== null && !Number.isNaN(value)) {
265
774
  setLocalMin(Math.max(dataMin, Math.min(value, localMax ?? dataMax)));
@@ -267,7 +776,7 @@ function NumericRangeFilter({
267
776
  setLocalMin(null);
268
777
  }
269
778
  }, [dataMin, dataMax, localMax]);
270
- const handleMaxInput = useCallback2((event) => {
779
+ const handleMaxInput = useCallback3((event) => {
271
780
  const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
272
781
  if (value !== null && !Number.isNaN(value)) {
273
782
  setLocalMax(Math.min(dataMax, Math.max(value, localMin ?? dataMin)));
@@ -275,39 +784,39 @@ function NumericRangeFilter({
275
784
  setLocalMax(null);
276
785
  }
277
786
  }, [dataMin, dataMax, localMin]);
278
- const handleInputBlur = useCallback2(() => {
787
+ const handleInputBlur = useCallback3(() => {
279
788
  if (localMin === null && localMax === null) {
280
789
  onChange(null);
281
790
  } else {
282
791
  onChange({ min: localMin, max: localMax });
283
792
  }
284
793
  }, [localMin, localMax, onChange]);
285
- const clearFilter = useCallback2(() => {
794
+ const clearFilter = useCallback3(() => {
286
795
  setLocalMin(null);
287
796
  setLocalMax(null);
288
797
  onChange(null);
289
798
  }, [onChange]);
290
- const setFullRange = useCallback2(() => {
799
+ const setFullRange = useCallback3(() => {
291
800
  setLocalMin(dataMin);
292
801
  setLocalMax(dataMax);
293
802
  onChange({ min: dataMin, max: dataMax });
294
803
  }, [dataMin, dataMax, onChange]);
295
- useEffect2(() => {
804
+ useEffect3(() => {
296
805
  setLocalMin(currentRange?.min ?? null);
297
806
  setLocalMax(currentRange?.max ?? null);
298
807
  }, [currentRange]);
299
- return /* @__PURE__ */ jsxs2("div", { className: "vpg-range-filter", children: [
300
- /* @__PURE__ */ jsxs2("div", { className: "vpg-range-info", children: [
301
- /* @__PURE__ */ jsx2("span", { className: "vpg-range-label", children: "Data range:" }),
302
- /* @__PURE__ */ jsxs2("span", { className: "vpg-range-bounds", children: [
808
+ return /* @__PURE__ */ jsxs3("div", { className: "vpg-range-filter", children: [
809
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-range-info", children: [
810
+ /* @__PURE__ */ jsx3("span", { className: "vpg-range-label", children: "Data range:" }),
811
+ /* @__PURE__ */ jsxs3("span", { className: "vpg-range-bounds", children: [
303
812
  formatValue(dataMin),
304
813
  " ",
305
814
  "\u2013",
306
815
  formatValue(dataMax)
307
816
  ] })
308
817
  ] }),
309
- /* @__PURE__ */ jsxs2("div", { className: "vpg-slider-container", children: [
310
- /* @__PURE__ */ jsx2("div", { className: "vpg-slider-track", children: /* @__PURE__ */ jsx2(
818
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-slider-container", children: [
819
+ /* @__PURE__ */ jsx3("div", { className: "vpg-slider-track", children: /* @__PURE__ */ jsx3(
311
820
  "div",
312
821
  {
313
822
  className: "vpg-slider-fill",
@@ -317,7 +826,7 @@ function NumericRangeFilter({
317
826
  }
318
827
  }
319
828
  ) }),
320
- /* @__PURE__ */ jsx2(
829
+ /* @__PURE__ */ jsx3(
321
830
  "input",
322
831
  {
323
832
  type: "range",
@@ -331,7 +840,7 @@ function NumericRangeFilter({
331
840
  onTouchEnd: handleSliderChange
332
841
  }
333
842
  ),
334
- /* @__PURE__ */ jsx2(
843
+ /* @__PURE__ */ jsx3(
335
844
  "input",
336
845
  {
337
846
  type: "range",
@@ -346,10 +855,10 @@ function NumericRangeFilter({
346
855
  }
347
856
  )
348
857
  ] }),
349
- /* @__PURE__ */ jsxs2("div", { className: "vpg-range-inputs", children: [
350
- /* @__PURE__ */ jsxs2("div", { className: "vpg-input-group", children: [
351
- /* @__PURE__ */ jsx2("label", { className: "vpg-input-label", children: "Min" }),
352
- /* @__PURE__ */ jsx2(
858
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-range-inputs", children: [
859
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-input-group", children: [
860
+ /* @__PURE__ */ jsx3("label", { className: "vpg-input-label", children: "Min" }),
861
+ /* @__PURE__ */ jsx3(
353
862
  "input",
354
863
  {
355
864
  type: "number",
@@ -362,10 +871,10 @@ function NumericRangeFilter({
362
871
  }
363
872
  )
364
873
  ] }),
365
- /* @__PURE__ */ jsx2("span", { className: "vpg-input-separator", children: "to" }),
366
- /* @__PURE__ */ jsxs2("div", { className: "vpg-input-group", children: [
367
- /* @__PURE__ */ jsx2("label", { className: "vpg-input-label", children: "Max" }),
368
- /* @__PURE__ */ jsx2(
874
+ /* @__PURE__ */ jsx3("span", { className: "vpg-input-separator", children: "to" }),
875
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-input-group", children: [
876
+ /* @__PURE__ */ jsx3("label", { className: "vpg-input-label", children: "Max" }),
877
+ /* @__PURE__ */ jsx3(
369
878
  "input",
370
879
  {
371
880
  type: "number",
@@ -379,15 +888,15 @@ function NumericRangeFilter({
379
888
  )
380
889
  ] })
381
890
  ] }),
382
- /* @__PURE__ */ jsxs2("div", { className: "vpg-range-actions", children: [
383
- /* @__PURE__ */ jsxs2(
891
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-range-actions", children: [
892
+ /* @__PURE__ */ jsxs3(
384
893
  "button",
385
894
  {
386
895
  className: "vpg-range-btn",
387
896
  disabled: !isFilterActive,
388
897
  onClick: clearFilter,
389
898
  children: [
390
- /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
899
+ /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
391
900
  "path",
392
901
  {
393
902
  strokeLinecap: "round",
@@ -400,8 +909,8 @@ function NumericRangeFilter({
400
909
  ]
401
910
  }
402
911
  ),
403
- /* @__PURE__ */ jsxs2("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
404
- /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
912
+ /* @__PURE__ */ jsxs3("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
913
+ /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
405
914
  "path",
406
915
  {
407
916
  strokeLinecap: "round",
@@ -413,8 +922,8 @@ function NumericRangeFilter({
413
922
  "Full Range"
414
923
  ] })
415
924
  ] }),
416
- isFilterActive && /* @__PURE__ */ jsxs2("div", { className: "vpg-filter-summary", children: [
417
- /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
925
+ isFilterActive && /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-summary", children: [
926
+ /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
418
927
  "path",
419
928
  {
420
929
  strokeLinecap: "round",
@@ -423,15 +932,15 @@ function NumericRangeFilter({
423
932
  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"
424
933
  }
425
934
  ) }),
426
- /* @__PURE__ */ jsxs2("span", { children: [
935
+ /* @__PURE__ */ jsxs3("span", { children: [
427
936
  "Showing values",
428
937
  " ",
429
- localMin !== null && /* @__PURE__ */ jsxs2("strong", { children: [
938
+ localMin !== null && /* @__PURE__ */ jsxs3("strong", { children: [
430
939
  "\u2265",
431
940
  formatValue(localMin)
432
941
  ] }),
433
942
  localMin !== null && localMax !== null && " and ",
434
- localMax !== null && /* @__PURE__ */ jsxs2("strong", { children: [
943
+ localMax !== null && /* @__PURE__ */ jsxs3("strong", { children: [
435
944
  "\u2264",
436
945
  formatValue(localMax)
437
946
  ] })
@@ -441,7 +950,7 @@ function NumericRangeFilter({
441
950
  }
442
951
 
443
952
  // src/components/ColumnFilter.tsx
444
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
953
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
445
954
  function ColumnFilter({
446
955
  columnName,
447
956
  stats,
@@ -453,33 +962,33 @@ function ColumnFilter({
453
962
  onClose,
454
963
  onRangeFilter
455
964
  }) {
456
- const [searchQuery, setSearchQuery] = useState3("");
457
- const [localSelected, setLocalSelected] = useState3(new Set(selectedValues));
965
+ const [searchQuery, setSearchQuery] = useState4("");
966
+ const [localSelected, setLocalSelected] = useState4(new Set(selectedValues));
458
967
  const dropdownRef = useRef(null);
459
968
  const searchInputRef = useRef(null);
460
969
  const isNumericColumn = stats.type === "number" && stats.numericMin !== void 0 && stats.numericMax !== void 0;
461
- const [filterMode, setFilterMode] = useState3(numericRange ? "range" : "values");
462
- const [localRange, setLocalRange] = useState3(numericRange ?? null);
970
+ const [filterMode, setFilterMode] = useState4(numericRange ? "range" : "values");
971
+ const [localRange, setLocalRange] = useState4(numericRange ?? null);
463
972
  const hasBlankValues = stats.nullCount > 0;
464
- const filteredValues = useMemo3(() => {
973
+ const filteredValues = useMemo4(() => {
465
974
  const values = stats.uniqueValues;
466
975
  if (!searchQuery)
467
976
  return values;
468
977
  const query = searchQuery.toLowerCase();
469
978
  return values.filter((v) => v.toLowerCase().includes(query));
470
979
  }, [stats.uniqueValues, searchQuery]);
471
- const allValues = useMemo3(() => {
980
+ const allValues = useMemo4(() => {
472
981
  const values = [...filteredValues];
473
982
  if (hasBlankValues && (!searchQuery || "(blank)".includes(searchQuery.toLowerCase()))) {
474
983
  values.unshift("(blank)");
475
984
  }
476
985
  return values;
477
986
  }, [filteredValues, hasBlankValues, searchQuery]);
478
- const _isAllSelected = useMemo3(
987
+ const _isAllSelected = useMemo4(
479
988
  () => allValues.every((v) => localSelected.has(v)),
480
989
  [allValues, localSelected]
481
990
  );
482
- const toggleValue = useCallback3((value) => {
991
+ const toggleValue = useCallback4((value) => {
483
992
  setLocalSelected((prev) => {
484
993
  const next = new Set(prev);
485
994
  if (next.has(value)) {
@@ -490,7 +999,7 @@ function ColumnFilter({
490
999
  return next;
491
1000
  });
492
1001
  }, []);
493
- const selectAll = useCallback3(() => {
1002
+ const selectAll = useCallback4(() => {
494
1003
  setLocalSelected((prev) => {
495
1004
  const next = new Set(prev);
496
1005
  for (const value of allValues) {
@@ -499,10 +1008,10 @@ function ColumnFilter({
499
1008
  return next;
500
1009
  });
501
1010
  }, [allValues]);
502
- const clearAll = useCallback3(() => {
1011
+ const clearAll = useCallback4(() => {
503
1012
  setLocalSelected(/* @__PURE__ */ new Set());
504
1013
  }, []);
505
- const applyFilter = useCallback3(() => {
1014
+ const applyFilter = useCallback4(() => {
506
1015
  if (localSelected.size === 0) {
507
1016
  onFilter([]);
508
1017
  } else {
@@ -510,30 +1019,30 @@ function ColumnFilter({
510
1019
  }
511
1020
  onClose();
512
1021
  }, [localSelected, onFilter, onClose]);
513
- const sortAscending = useCallback3(() => {
1022
+ const sortAscending = useCallback4(() => {
514
1023
  onSort(sortDirection === "asc" ? null : "asc");
515
1024
  }, [sortDirection, onSort]);
516
- const sortDescending = useCallback3(() => {
1025
+ const sortDescending = useCallback4(() => {
517
1026
  onSort(sortDirection === "desc" ? null : "desc");
518
1027
  }, [sortDirection, onSort]);
519
- const clearFilter = useCallback3(() => {
1028
+ const clearFilter = useCallback4(() => {
520
1029
  setLocalSelected(/* @__PURE__ */ new Set());
521
1030
  onFilter([]);
522
1031
  onClose();
523
1032
  }, [onFilter, onClose]);
524
- const handleRangeChange = useCallback3((range) => {
1033
+ const handleRangeChange = useCallback4((range) => {
525
1034
  setLocalRange(range);
526
1035
  }, []);
527
- const applyRangeFilter = useCallback3(() => {
1036
+ const applyRangeFilter = useCallback4(() => {
528
1037
  onRangeFilter?.(localRange);
529
1038
  onClose();
530
1039
  }, [localRange, onRangeFilter, onClose]);
531
- const clearRangeFilter = useCallback3(() => {
1040
+ const clearRangeFilter = useCallback4(() => {
532
1041
  setLocalRange(null);
533
1042
  onRangeFilter?.(null);
534
1043
  onClose();
535
1044
  }, [onRangeFilter, onClose]);
536
- useEffect3(() => {
1045
+ useEffect4(() => {
537
1046
  const handleClickOutside = (event) => {
538
1047
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
539
1048
  onClose();
@@ -542,7 +1051,7 @@ function ColumnFilter({
542
1051
  document.addEventListener("mousedown", handleClickOutside);
543
1052
  return () => document.removeEventListener("mousedown", handleClickOutside);
544
1053
  }, [onClose]);
545
- useEffect3(() => {
1054
+ useEffect4(() => {
546
1055
  const handleKeydown = (event) => {
547
1056
  if (event.key === "Escape") {
548
1057
  onClose();
@@ -553,36 +1062,36 @@ function ColumnFilter({
553
1062
  document.addEventListener("keydown", handleKeydown);
554
1063
  return () => document.removeEventListener("keydown", handleKeydown);
555
1064
  }, [onClose, applyFilter]);
556
- useEffect3(() => {
1065
+ useEffect4(() => {
557
1066
  searchInputRef.current?.focus();
558
1067
  }, []);
559
- useEffect3(() => {
1068
+ useEffect4(() => {
560
1069
  setLocalSelected(new Set(selectedValues));
561
1070
  }, [selectedValues]);
562
- useEffect3(() => {
1071
+ useEffect4(() => {
563
1072
  setLocalRange(numericRange ?? null);
564
1073
  if (numericRange) {
565
1074
  setFilterMode("range");
566
1075
  }
567
1076
  }, [numericRange]);
568
- return /* @__PURE__ */ jsxs3("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
569
- /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-header", children: [
570
- /* @__PURE__ */ jsx3("span", { className: "vpg-filter-title", children: columnName }),
571
- /* @__PURE__ */ jsxs3("span", { className: "vpg-filter-count", children: [
1077
+ return /* @__PURE__ */ jsxs4("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
1078
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-header", children: [
1079
+ /* @__PURE__ */ jsx4("span", { className: "vpg-filter-title", children: columnName }),
1080
+ /* @__PURE__ */ jsxs4("span", { className: "vpg-filter-count", children: [
572
1081
  stats.uniqueValues.length.toLocaleString(),
573
1082
  " ",
574
1083
  "unique"
575
1084
  ] })
576
1085
  ] }),
577
- /* @__PURE__ */ jsxs3("div", { className: "vpg-sort-controls", children: [
578
- /* @__PURE__ */ jsxs3(
1086
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-sort-controls", children: [
1087
+ /* @__PURE__ */ jsxs4(
579
1088
  "button",
580
1089
  {
581
1090
  className: `vpg-sort-btn ${sortDirection === "asc" ? "active" : ""}`,
582
1091
  title: isNumericColumn ? "Sort Low to High" : "Sort A to Z",
583
1092
  onClick: sortAscending,
584
1093
  children: [
585
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1094
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
586
1095
  "path",
587
1096
  {
588
1097
  strokeLinecap: "round",
@@ -591,18 +1100,18 @@ function ColumnFilter({
591
1100
  d: "M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"
592
1101
  }
593
1102
  ) }),
594
- /* @__PURE__ */ jsx3("span", { children: isNumericColumn ? "1\u21929" : "A\u2192Z" })
1103
+ /* @__PURE__ */ jsx4("span", { children: isNumericColumn ? "1\u21929" : "A\u2192Z" })
595
1104
  ]
596
1105
  }
597
1106
  ),
598
- /* @__PURE__ */ jsxs3(
1107
+ /* @__PURE__ */ jsxs4(
599
1108
  "button",
600
1109
  {
601
1110
  className: `vpg-sort-btn ${sortDirection === "desc" ? "active" : ""}`,
602
1111
  title: isNumericColumn ? "Sort High to Low" : "Sort Z to A",
603
1112
  onClick: sortDescending,
604
1113
  children: [
605
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1114
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
606
1115
  "path",
607
1116
  {
608
1117
  strokeLinecap: "round",
@@ -611,20 +1120,20 @@ function ColumnFilter({
611
1120
  d: "M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"
612
1121
  }
613
1122
  ) }),
614
- /* @__PURE__ */ jsx3("span", { children: isNumericColumn ? "9\u21921" : "Z\u2192A" })
1123
+ /* @__PURE__ */ jsx4("span", { children: isNumericColumn ? "9\u21921" : "Z\u2192A" })
615
1124
  ]
616
1125
  }
617
1126
  )
618
1127
  ] }),
619
- /* @__PURE__ */ jsx3("div", { className: "vpg-divider" }),
620
- isNumericColumn && /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-tabs", children: [
621
- /* @__PURE__ */ jsxs3(
1128
+ /* @__PURE__ */ jsx4("div", { className: "vpg-divider" }),
1129
+ isNumericColumn && /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-tabs", children: [
1130
+ /* @__PURE__ */ jsxs4(
622
1131
  "button",
623
1132
  {
624
1133
  className: `vpg-tab-btn ${filterMode === "values" ? "active" : ""}`,
625
1134
  onClick: () => setFilterMode("values"),
626
1135
  children: [
627
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1136
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
628
1137
  "path",
629
1138
  {
630
1139
  strokeLinecap: "round",
@@ -637,13 +1146,13 @@ function ColumnFilter({
637
1146
  ]
638
1147
  }
639
1148
  ),
640
- /* @__PURE__ */ jsxs3(
1149
+ /* @__PURE__ */ jsxs4(
641
1150
  "button",
642
1151
  {
643
1152
  className: `vpg-tab-btn ${filterMode === "range" ? "active" : ""}`,
644
1153
  onClick: () => setFilterMode("range"),
645
1154
  children: [
646
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1155
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
647
1156
  "path",
648
1157
  {
649
1158
  strokeLinecap: "round",
@@ -657,9 +1166,9 @@ function ColumnFilter({
657
1166
  }
658
1167
  )
659
1168
  ] }),
660
- (!isNumericColumn || filterMode === "values") && /* @__PURE__ */ jsxs3(Fragment, { children: [
661
- /* @__PURE__ */ jsxs3("div", { className: "vpg-search-container", children: [
662
- /* @__PURE__ */ jsx3("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1169
+ (!isNumericColumn || filterMode === "values") && /* @__PURE__ */ jsxs4(Fragment2, { children: [
1170
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-search-container", children: [
1171
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
663
1172
  "path",
664
1173
  {
665
1174
  strokeLinecap: "round",
@@ -668,7 +1177,7 @@ function ColumnFilter({
668
1177
  d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
669
1178
  }
670
1179
  ) }),
671
- /* @__PURE__ */ jsx3(
1180
+ /* @__PURE__ */ jsx4(
672
1181
  "input",
673
1182
  {
674
1183
  ref: searchInputRef,
@@ -679,11 +1188,11 @@ function ColumnFilter({
679
1188
  className: "vpg-search-input"
680
1189
  }
681
1190
  ),
682
- searchQuery && /* @__PURE__ */ jsx3("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
1191
+ searchQuery && /* @__PURE__ */ jsx4("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
683
1192
  ] }),
684
- /* @__PURE__ */ jsxs3("div", { className: "vpg-bulk-actions", children: [
685
- /* @__PURE__ */ jsxs3("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
686
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1193
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-bulk-actions", children: [
1194
+ /* @__PURE__ */ jsxs4("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
1195
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
687
1196
  "path",
688
1197
  {
689
1198
  strokeLinecap: "round",
@@ -694,8 +1203,8 @@ function ColumnFilter({
694
1203
  ) }),
695
1204
  "Select All"
696
1205
  ] }),
697
- /* @__PURE__ */ jsxs3("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
698
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1206
+ /* @__PURE__ */ jsxs4("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
1207
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
699
1208
  "path",
700
1209
  {
701
1210
  strokeLinecap: "round",
@@ -707,13 +1216,13 @@ function ColumnFilter({
707
1216
  "Clear All"
708
1217
  ] })
709
1218
  ] }),
710
- /* @__PURE__ */ jsxs3("div", { className: "vpg-values-list", children: [
711
- allValues.map((value) => /* @__PURE__ */ jsxs3(
1219
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-values-list", children: [
1220
+ allValues.map((value) => /* @__PURE__ */ jsxs4(
712
1221
  "label",
713
1222
  {
714
1223
  className: `vpg-value-item ${localSelected.has(value) ? "selected" : ""}`,
715
1224
  children: [
716
- /* @__PURE__ */ jsx3(
1225
+ /* @__PURE__ */ jsx4(
717
1226
  "input",
718
1227
  {
719
1228
  type: "checkbox",
@@ -722,20 +1231,20 @@ function ColumnFilter({
722
1231
  className: "vpg-value-checkbox"
723
1232
  }
724
1233
  ),
725
- /* @__PURE__ */ jsx3("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
1234
+ /* @__PURE__ */ jsx4("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
726
1235
  ]
727
1236
  },
728
1237
  value
729
1238
  )),
730
- allValues.length === 0 && /* @__PURE__ */ jsx3("div", { className: "vpg-no-results", children: "No matching values" })
1239
+ allValues.length === 0 && /* @__PURE__ */ jsx4("div", { className: "vpg-no-results", children: "No matching values" })
731
1240
  ] }),
732
- /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-footer", children: [
733
- /* @__PURE__ */ jsx3("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
734
- /* @__PURE__ */ jsx3("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
1241
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-footer", children: [
1242
+ /* @__PURE__ */ jsx4("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
1243
+ /* @__PURE__ */ jsx4("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
735
1244
  ] })
736
1245
  ] }),
737
- isNumericColumn && filterMode === "range" && /* @__PURE__ */ jsxs3(Fragment, { children: [
738
- /* @__PURE__ */ jsx3(
1246
+ isNumericColumn && filterMode === "range" && /* @__PURE__ */ jsxs4(Fragment2, { children: [
1247
+ /* @__PURE__ */ jsx4(
739
1248
  NumericRangeFilter,
740
1249
  {
741
1250
  dataMin: stats.numericMin,
@@ -744,16 +1253,16 @@ function ColumnFilter({
744
1253
  onChange: handleRangeChange
745
1254
  }
746
1255
  ),
747
- /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-footer", children: [
748
- /* @__PURE__ */ jsx3("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
749
- /* @__PURE__ */ jsx3("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
1256
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-footer", children: [
1257
+ /* @__PURE__ */ jsx4("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
1258
+ /* @__PURE__ */ jsx4("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
750
1259
  ] })
751
1260
  ] })
752
1261
  ] });
753
1262
  }
754
1263
 
755
1264
  // src/components/DataGrid.tsx
756
- import { useCallback as useCallback10, useEffect as useEffect7, useMemo as useMemo10, useRef as useRef2, useState as useState10 } from "react";
1265
+ import { useCallback as useCallback11, useEffect as useEffect8, useMemo as useMemo11, useRef as useRef2, useState as useState11 } from "react";
757
1266
  import { createPortal as createPortal2 } from "react-dom";
758
1267
 
759
1268
  // src/hooks/useExcelGrid.ts
@@ -764,7 +1273,7 @@ import {
764
1273
  getSortedRowModel,
765
1274
  useReactTable
766
1275
  } from "@tanstack/react-table";
767
- import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo4, useState as useState4 } from "react";
1276
+ import { useCallback as useCallback5, useEffect as useEffect5, useMemo as useMemo5, useState as useState5 } from "react";
768
1277
  var multiSelectFilter = (row, columnId, filterValue) => {
769
1278
  if (!filterValue)
770
1279
  return true;
@@ -792,21 +1301,21 @@ var multiSelectFilter = (row, columnId, filterValue) => {
792
1301
  };
793
1302
  function useExcelGrid(options) {
794
1303
  const { data, enableSorting = true, enableFiltering = true } = options;
795
- const [sorting, setSorting] = useState4([]);
796
- const [columnFilters, setColumnFilters] = useState4([]);
797
- const [columnVisibility, setColumnVisibility] = useState4({});
798
- const [globalFilter, setGlobalFilter] = useState4("");
799
- const [columnStatsCache, setColumnStatsCache] = useState4({});
800
- const dataSignature = useMemo4(
1304
+ const [sorting, setSorting] = useState5([]);
1305
+ const [columnFilters, setColumnFilters] = useState5([]);
1306
+ const [columnVisibility, setColumnVisibility] = useState5({});
1307
+ const [globalFilter, setGlobalFilter] = useState5("");
1308
+ const [columnStatsCache, setColumnStatsCache] = useState5({});
1309
+ const dataSignature = useMemo5(
801
1310
  () => `${Date.now()}-${Math.random().toString(36).slice(2)}`,
802
1311
  [data]
803
1312
  );
804
- const columnKeys = useMemo4(() => {
1313
+ const columnKeys = useMemo5(() => {
805
1314
  if (data.length === 0)
806
1315
  return [];
807
1316
  return Object.keys(data[0]);
808
1317
  }, [data]);
809
- const getColumnStats = useCallback4(
1318
+ const getColumnStats = useCallback5(
810
1319
  (columnKey) => {
811
1320
  const cacheKey = `${columnKey}-${dataSignature}`;
812
1321
  if (!columnStatsCache[cacheKey]) {
@@ -818,13 +1327,13 @@ function useExcelGrid(options) {
818
1327
  },
819
1328
  [data, columnStatsCache, dataSignature]
820
1329
  );
821
- const clearStatsCache = useCallback4(() => {
1330
+ const clearStatsCache = useCallback5(() => {
822
1331
  setColumnStatsCache({});
823
1332
  }, []);
824
- useEffect4(() => {
1333
+ useEffect5(() => {
825
1334
  clearStatsCache();
826
1335
  }, [dataSignature, clearStatsCache]);
827
- const columnDefs = useMemo4(() => {
1336
+ const columnDefs = useMemo5(() => {
828
1337
  return columnKeys.map((key) => {
829
1338
  const stats = getColumnStats(key);
830
1339
  return {
@@ -864,7 +1373,7 @@ function useExcelGrid(options) {
864
1373
  });
865
1374
  const filteredRowCount = table.getFilteredRowModel().rows.length;
866
1375
  const totalRowCount = data.length;
867
- const activeFilters = useMemo4(() => {
1376
+ const activeFilters = useMemo5(() => {
868
1377
  return columnFilters.map((f) => {
869
1378
  const filterValue = f.value;
870
1379
  if (filterValue && isNumericRange(filterValue)) {
@@ -883,7 +1392,7 @@ function useExcelGrid(options) {
883
1392
  };
884
1393
  });
885
1394
  }, [columnFilters]);
886
- const hasActiveFilter = useCallback4(
1395
+ const hasActiveFilter = useCallback5(
887
1396
  (columnId) => {
888
1397
  const column = table.getColumn(columnId);
889
1398
  if (!column)
@@ -898,7 +1407,7 @@ function useExcelGrid(options) {
898
1407
  },
899
1408
  [table]
900
1409
  );
901
- const setColumnFilter = useCallback4(
1410
+ const setColumnFilter = useCallback5(
902
1411
  (columnId, values) => {
903
1412
  const column = table.getColumn(columnId);
904
1413
  if (column) {
@@ -907,7 +1416,7 @@ function useExcelGrid(options) {
907
1416
  },
908
1417
  [table]
909
1418
  );
910
- const setNumericRangeFilter = useCallback4(
1419
+ const setNumericRangeFilter = useCallback5(
911
1420
  (columnId, range) => {
912
1421
  const column = table.getColumn(columnId);
913
1422
  if (column) {
@@ -920,7 +1429,7 @@ function useExcelGrid(options) {
920
1429
  },
921
1430
  [table]
922
1431
  );
923
- const getNumericRangeFilter = useCallback4(
1432
+ const getNumericRangeFilter = useCallback5(
924
1433
  (columnId) => {
925
1434
  const column = table.getColumn(columnId);
926
1435
  if (!column)
@@ -933,12 +1442,12 @@ function useExcelGrid(options) {
933
1442
  },
934
1443
  [table]
935
1444
  );
936
- const clearAllFilters = useCallback4(() => {
1445
+ const clearAllFilters = useCallback5(() => {
937
1446
  table.resetColumnFilters();
938
1447
  setGlobalFilter("");
939
1448
  setColumnFilters([]);
940
1449
  }, [table]);
941
- const getColumnFilterValues = useCallback4(
1450
+ const getColumnFilterValues = useCallback5(
942
1451
  (columnId) => {
943
1452
  const column = table.getColumn(columnId);
944
1453
  if (!column)
@@ -948,7 +1457,7 @@ function useExcelGrid(options) {
948
1457
  },
949
1458
  [table]
950
1459
  );
951
- const toggleSort = useCallback4((columnId) => {
1460
+ const toggleSort = useCallback5((columnId) => {
952
1461
  setSorting((prev) => {
953
1462
  const current = prev.find((s) => s.id === columnId);
954
1463
  if (!current) {
@@ -960,7 +1469,7 @@ function useExcelGrid(options) {
960
1469
  }
961
1470
  });
962
1471
  }, []);
963
- const getSortDirection = useCallback4(
1472
+ const getSortDirection = useCallback5(
964
1473
  (columnId) => {
965
1474
  const sort = sorting.find((s) => s.id === columnId);
966
1475
  if (!sort)
@@ -1007,7 +1516,7 @@ import {
1007
1516
  exportToCSV as coreExportToCSV,
1008
1517
  formatSelectionForClipboard as coreFormatSelection
1009
1518
  } from "@smallwebco/tinypivot-core";
1010
- import { useCallback as useCallback5, useMemo as useMemo5, useState as useState5 } from "react";
1519
+ import { useCallback as useCallback6, useMemo as useMemo6, useState as useState6 } from "react";
1011
1520
  function exportToCSV(data, columns, options) {
1012
1521
  coreExportToCSV(data, columns, options);
1013
1522
  }
@@ -1021,45 +1530,45 @@ function formatSelectionForClipboard(rows, columns, selectionBounds) {
1021
1530
  return coreFormatSelection(rows, columns, selectionBounds);
1022
1531
  }
1023
1532
  function usePagination(data, options = {}) {
1024
- const [pageSize, setPageSize] = useState5(options.pageSize ?? 50);
1025
- const [currentPage, setCurrentPage] = useState5(options.currentPage ?? 1);
1026
- const totalPages = useMemo5(
1533
+ const [pageSize, setPageSize] = useState6(options.pageSize ?? 50);
1534
+ const [currentPage, setCurrentPage] = useState6(options.currentPage ?? 1);
1535
+ const totalPages = useMemo6(
1027
1536
  () => Math.max(1, Math.ceil(data.length / pageSize)),
1028
1537
  [data.length, pageSize]
1029
1538
  );
1030
- const paginatedData = useMemo5(() => {
1539
+ const paginatedData = useMemo6(() => {
1031
1540
  const start = (currentPage - 1) * pageSize;
1032
1541
  const end = start + pageSize;
1033
1542
  return data.slice(start, end);
1034
1543
  }, [data, currentPage, pageSize]);
1035
- const startIndex = useMemo5(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
1036
- const endIndex = useMemo5(
1544
+ const startIndex = useMemo6(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
1545
+ const endIndex = useMemo6(
1037
1546
  () => Math.min(currentPage * pageSize, data.length),
1038
1547
  [currentPage, pageSize, data.length]
1039
1548
  );
1040
- const goToPage = useCallback5(
1549
+ const goToPage = useCallback6(
1041
1550
  (page) => {
1042
1551
  setCurrentPage(Math.max(1, Math.min(page, totalPages)));
1043
1552
  },
1044
1553
  [totalPages]
1045
1554
  );
1046
- const nextPage = useCallback5(() => {
1555
+ const nextPage = useCallback6(() => {
1047
1556
  if (currentPage < totalPages) {
1048
1557
  setCurrentPage((prev) => prev + 1);
1049
1558
  }
1050
1559
  }, [currentPage, totalPages]);
1051
- const prevPage = useCallback5(() => {
1560
+ const prevPage = useCallback6(() => {
1052
1561
  if (currentPage > 1) {
1053
1562
  setCurrentPage((prev) => prev - 1);
1054
1563
  }
1055
1564
  }, [currentPage]);
1056
- const firstPage = useCallback5(() => {
1565
+ const firstPage = useCallback6(() => {
1057
1566
  setCurrentPage(1);
1058
1567
  }, []);
1059
- const lastPage = useCallback5(() => {
1568
+ const lastPage = useCallback6(() => {
1060
1569
  setCurrentPage(totalPages);
1061
1570
  }, [totalPages]);
1062
- const updatePageSize = useCallback5((size) => {
1571
+ const updatePageSize = useCallback6((size) => {
1063
1572
  setPageSize(size);
1064
1573
  setCurrentPage(1);
1065
1574
  }, []);
@@ -1079,9 +1588,9 @@ function usePagination(data, options = {}) {
1079
1588
  };
1080
1589
  }
1081
1590
  function useGlobalSearch(data, columns) {
1082
- const [searchTerm, setSearchTerm] = useState5("");
1083
- const [caseSensitive, setCaseSensitive] = useState5(false);
1084
- const filteredData = useMemo5(() => {
1591
+ const [searchTerm, setSearchTerm] = useState6("");
1592
+ const [caseSensitive, setCaseSensitive] = useState6(false);
1593
+ const filteredData = useMemo6(() => {
1085
1594
  if (!searchTerm.trim()) {
1086
1595
  return data;
1087
1596
  }
@@ -1099,7 +1608,7 @@ function useGlobalSearch(data, columns) {
1099
1608
  return false;
1100
1609
  });
1101
1610
  }, [data, columns, searchTerm, caseSensitive]);
1102
- const clearSearch = useCallback5(() => {
1611
+ const clearSearch = useCallback6(() => {
1103
1612
  setSearchTerm("");
1104
1613
  }, []);
1105
1614
  return {
@@ -1112,17 +1621,17 @@ function useGlobalSearch(data, columns) {
1112
1621
  };
1113
1622
  }
1114
1623
  function useRowSelection(data) {
1115
- const [selectedRowIndices, setSelectedRowIndices] = useState5(/* @__PURE__ */ new Set());
1116
- const selectedRows = useMemo5(() => {
1624
+ const [selectedRowIndices, setSelectedRowIndices] = useState6(/* @__PURE__ */ new Set());
1625
+ const selectedRows = useMemo6(() => {
1117
1626
  return Array.from(selectedRowIndices).sort((a, b) => a - b).map((idx) => data[idx]).filter(Boolean);
1118
1627
  }, [data, selectedRowIndices]);
1119
- const allSelected = useMemo5(() => {
1628
+ const allSelected = useMemo6(() => {
1120
1629
  return data.length > 0 && selectedRowIndices.size === data.length;
1121
1630
  }, [data.length, selectedRowIndices.size]);
1122
- const someSelected = useMemo5(() => {
1631
+ const someSelected = useMemo6(() => {
1123
1632
  return selectedRowIndices.size > 0 && selectedRowIndices.size < data.length;
1124
1633
  }, [data.length, selectedRowIndices.size]);
1125
- const toggleRow = useCallback5((index) => {
1634
+ const toggleRow = useCallback6((index) => {
1126
1635
  setSelectedRowIndices((prev) => {
1127
1636
  const next = new Set(prev);
1128
1637
  if (next.has(index)) {
@@ -1133,36 +1642,36 @@ function useRowSelection(data) {
1133
1642
  return next;
1134
1643
  });
1135
1644
  }, []);
1136
- const selectRow = useCallback5((index) => {
1645
+ const selectRow = useCallback6((index) => {
1137
1646
  setSelectedRowIndices((prev) => /* @__PURE__ */ new Set([...prev, index]));
1138
1647
  }, []);
1139
- const deselectRow = useCallback5((index) => {
1648
+ const deselectRow = useCallback6((index) => {
1140
1649
  setSelectedRowIndices((prev) => {
1141
1650
  const next = new Set(prev);
1142
1651
  next.delete(index);
1143
1652
  return next;
1144
1653
  });
1145
1654
  }, []);
1146
- const selectAll = useCallback5(() => {
1655
+ const selectAll = useCallback6(() => {
1147
1656
  setSelectedRowIndices(new Set(data.map((_, idx) => idx)));
1148
1657
  }, [data]);
1149
- const deselectAll = useCallback5(() => {
1658
+ const deselectAll = useCallback6(() => {
1150
1659
  setSelectedRowIndices(/* @__PURE__ */ new Set());
1151
1660
  }, []);
1152
- const toggleAll = useCallback5(() => {
1661
+ const toggleAll = useCallback6(() => {
1153
1662
  if (allSelected) {
1154
1663
  deselectAll();
1155
1664
  } else {
1156
1665
  selectAll();
1157
1666
  }
1158
1667
  }, [allSelected, selectAll, deselectAll]);
1159
- const isSelected = useCallback5(
1668
+ const isSelected = useCallback6(
1160
1669
  (index) => {
1161
1670
  return selectedRowIndices.has(index);
1162
1671
  },
1163
1672
  [selectedRowIndices]
1164
1673
  );
1165
- const selectRange = useCallback5((startIndex, endIndex) => {
1674
+ const selectRange = useCallback6((startIndex, endIndex) => {
1166
1675
  const min = Math.min(startIndex, endIndex);
1167
1676
  const max = Math.max(startIndex, endIndex);
1168
1677
  setSelectedRowIndices((prev) => {
@@ -1189,10 +1698,10 @@ function useRowSelection(data) {
1189
1698
  };
1190
1699
  }
1191
1700
  function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
1192
- const [columnWidths, setColumnWidths] = useState5({ ...initialWidths });
1193
- const [isResizing, setIsResizing] = useState5(false);
1194
- const [resizingColumn, setResizingColumn] = useState5(null);
1195
- const startResize = useCallback5(
1701
+ const [columnWidths, setColumnWidths] = useState6({ ...initialWidths });
1702
+ const [isResizing, setIsResizing] = useState6(false);
1703
+ const [resizingColumn, setResizingColumn] = useState6(null);
1704
+ const startResize = useCallback6(
1196
1705
  (columnId, event) => {
1197
1706
  setIsResizing(true);
1198
1707
  setResizingColumn(columnId);
@@ -1217,7 +1726,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
1217
1726
  },
1218
1727
  [columnWidths, minWidth, maxWidth]
1219
1728
  );
1220
- const resetColumnWidth = useCallback5(
1729
+ const resetColumnWidth = useCallback6(
1221
1730
  (columnId) => {
1222
1731
  if (initialWidths[columnId]) {
1223
1732
  setColumnWidths((prev) => ({
@@ -1228,7 +1737,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
1228
1737
  },
1229
1738
  [initialWidths]
1230
1739
  );
1231
- const resetAllWidths = useCallback5(() => {
1740
+ const resetAllWidths = useCallback6(() => {
1232
1741
  setColumnWidths({ ...initialWidths });
1233
1742
  }, [initialWidths]);
1234
1743
  return {
@@ -1244,6 +1753,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
1244
1753
 
1245
1754
  // src/hooks/useLicense.ts
1246
1755
  import {
1756
+ canUseCharts as coreCanUseCharts,
1247
1757
  canUsePivot as coreCanUsePivot,
1248
1758
  configureLicenseSecret as coreConfigureLicenseSecret,
1249
1759
  isPro as coreIsPro,
@@ -1253,7 +1763,7 @@ import {
1253
1763
  logProRequired,
1254
1764
  validateLicenseKey
1255
1765
  } from "@smallwebco/tinypivot-core";
1256
- import { useCallback as useCallback6, useMemo as useMemo6, useState as useState6 } from "react";
1766
+ import { useCallback as useCallback7, useMemo as useMemo7, useState as useState7 } from "react";
1257
1767
  var globalLicenseInfo = getFreeLicenseInfo();
1258
1768
  var globalDemoMode = false;
1259
1769
  var listeners = /* @__PURE__ */ new Set();
@@ -1285,35 +1795,39 @@ function configureLicenseSecret(secret) {
1285
1795
  coreConfigureLicenseSecret(secret);
1286
1796
  }
1287
1797
  function useLicense() {
1288
- const [, forceUpdate] = useState6({});
1289
- useState6(() => {
1798
+ const [, forceUpdate] = useState7({});
1799
+ useState7(() => {
1290
1800
  const update = () => forceUpdate({});
1291
1801
  listeners.add(update);
1292
1802
  return () => listeners.delete(update);
1293
1803
  });
1294
1804
  const isDemo = globalDemoMode;
1295
1805
  const licenseInfo = globalLicenseInfo;
1296
- const isPro = useMemo6(
1806
+ const isPro = useMemo7(
1297
1807
  () => globalDemoMode || coreIsPro(licenseInfo),
1298
1808
  [licenseInfo]
1299
1809
  );
1300
- const canUsePivot = useMemo6(
1810
+ const canUsePivot = useMemo7(
1301
1811
  () => globalDemoMode || coreCanUsePivot(licenseInfo),
1302
1812
  [licenseInfo]
1303
1813
  );
1304
- const canUseAdvancedAggregations = useMemo6(
1814
+ const canUseAdvancedAggregations = useMemo7(
1305
1815
  () => globalDemoMode || licenseInfo.features.advancedAggregations,
1306
1816
  [licenseInfo]
1307
1817
  );
1308
- const canUsePercentageMode = useMemo6(
1818
+ const canUsePercentageMode = useMemo7(
1309
1819
  () => globalDemoMode || licenseInfo.features.percentageMode,
1310
1820
  [licenseInfo]
1311
1821
  );
1312
- const showWatermark = useMemo6(
1822
+ const canUseCharts = useMemo7(
1823
+ () => globalDemoMode || coreCanUseCharts(licenseInfo),
1824
+ [licenseInfo]
1825
+ );
1826
+ const showWatermark = useMemo7(
1313
1827
  () => coreShouldShowWatermark(licenseInfo, globalDemoMode),
1314
1828
  [licenseInfo]
1315
1829
  );
1316
- const requirePro = useCallback6((feature) => {
1830
+ const requirePro = useCallback7((feature) => {
1317
1831
  if (!isPro) {
1318
1832
  logProRequired(feature);
1319
1833
  return false;
@@ -1327,6 +1841,7 @@ function useLicense() {
1327
1841
  canUsePivot,
1328
1842
  canUseAdvancedAggregations,
1329
1843
  canUsePercentageMode,
1844
+ canUseCharts,
1330
1845
  showWatermark,
1331
1846
  requirePro
1332
1847
  };
@@ -1346,23 +1861,23 @@ import {
1346
1861
  saveCalculatedFields,
1347
1862
  savePivotConfig
1348
1863
  } from "@smallwebco/tinypivot-core";
1349
- import { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo7, useState as useState7 } from "react";
1864
+ import { useCallback as useCallback8, useEffect as useEffect6, useMemo as useMemo8, useState as useState8 } from "react";
1350
1865
  function usePivotTable(data) {
1351
1866
  const { canUsePivot, requirePro } = useLicense();
1352
- const [rowFields, setRowFieldsState] = useState7([]);
1353
- const [columnFields, setColumnFieldsState] = useState7([]);
1354
- const [valueFields, setValueFields] = useState7([]);
1355
- const [showRowTotals, setShowRowTotals] = useState7(true);
1356
- const [showColumnTotals, setShowColumnTotals] = useState7(true);
1357
- const [calculatedFields, setCalculatedFields] = useState7(() => loadCalculatedFields());
1358
- const [currentStorageKey, setCurrentStorageKey] = useState7(null);
1359
- const availableFields = useMemo7(() => {
1867
+ const [rowFields, setRowFieldsState] = useState8([]);
1868
+ const [columnFields, setColumnFieldsState] = useState8([]);
1869
+ const [valueFields, setValueFields] = useState8([]);
1870
+ const [showRowTotals, setShowRowTotals] = useState8(true);
1871
+ const [showColumnTotals, setShowColumnTotals] = useState8(true);
1872
+ const [calculatedFields, setCalculatedFields] = useState8(() => loadCalculatedFields());
1873
+ const [currentStorageKey, setCurrentStorageKey] = useState8(null);
1874
+ const availableFields = useMemo8(() => {
1360
1875
  return computeAvailableFields(data);
1361
1876
  }, [data]);
1362
- const unassignedFields = useMemo7(() => {
1877
+ const unassignedFields = useMemo8(() => {
1363
1878
  return getUnassignedFields(availableFields, rowFields, columnFields, valueFields);
1364
1879
  }, [availableFields, rowFields, columnFields, valueFields]);
1365
- const isConfigured = useMemo7(() => {
1880
+ const isConfigured = useMemo8(() => {
1366
1881
  return isPivotConfigured({
1367
1882
  rowFields,
1368
1883
  columnFields,
@@ -1371,7 +1886,7 @@ function usePivotTable(data) {
1371
1886
  showColumnTotals
1372
1887
  });
1373
1888
  }, [rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
1374
- const pivotResult = useMemo7(() => {
1889
+ const pivotResult = useMemo8(() => {
1375
1890
  if (!isConfigured)
1376
1891
  return null;
1377
1892
  if (!canUsePivot)
@@ -1385,7 +1900,7 @@ function usePivotTable(data) {
1385
1900
  calculatedFields
1386
1901
  });
1387
1902
  }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
1388
- useEffect5(() => {
1903
+ useEffect6(() => {
1389
1904
  if (data.length === 0)
1390
1905
  return;
1391
1906
  const newKeys = Object.keys(data[0]);
@@ -1418,7 +1933,7 @@ function usePivotTable(data) {
1418
1933
  }
1419
1934
  }
1420
1935
  }, [data]);
1421
- useEffect5(() => {
1936
+ useEffect6(() => {
1422
1937
  if (!currentStorageKey)
1423
1938
  return;
1424
1939
  const config = {
@@ -1431,7 +1946,7 @@ function usePivotTable(data) {
1431
1946
  };
1432
1947
  savePivotConfig(currentStorageKey, config);
1433
1948
  }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
1434
- const addRowField = useCallback7(
1949
+ const addRowField = useCallback8(
1435
1950
  (field) => {
1436
1951
  if (!rowFields.includes(field)) {
1437
1952
  setRowFieldsState((prev) => [...prev, field]);
@@ -1439,13 +1954,13 @@ function usePivotTable(data) {
1439
1954
  },
1440
1955
  [rowFields]
1441
1956
  );
1442
- const removeRowField = useCallback7((field) => {
1957
+ const removeRowField = useCallback8((field) => {
1443
1958
  setRowFieldsState((prev) => prev.filter((f) => f !== field));
1444
1959
  }, []);
1445
- const setRowFields = useCallback7((fields) => {
1960
+ const setRowFields = useCallback8((fields) => {
1446
1961
  setRowFieldsState(fields);
1447
1962
  }, []);
1448
- const addColumnField = useCallback7(
1963
+ const addColumnField = useCallback8(
1449
1964
  (field) => {
1450
1965
  if (!columnFields.includes(field)) {
1451
1966
  setColumnFieldsState((prev) => [...prev, field]);
@@ -1453,13 +1968,13 @@ function usePivotTable(data) {
1453
1968
  },
1454
1969
  [columnFields]
1455
1970
  );
1456
- const removeColumnField = useCallback7((field) => {
1971
+ const removeColumnField = useCallback8((field) => {
1457
1972
  setColumnFieldsState((prev) => prev.filter((f) => f !== field));
1458
1973
  }, []);
1459
- const setColumnFields = useCallback7((fields) => {
1974
+ const setColumnFields = useCallback8((fields) => {
1460
1975
  setColumnFieldsState(fields);
1461
1976
  }, []);
1462
- const addValueField = useCallback7(
1977
+ const addValueField = useCallback8(
1463
1978
  (field, aggregation = "sum") => {
1464
1979
  if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
1465
1980
  return;
@@ -1473,7 +1988,7 @@ function usePivotTable(data) {
1473
1988
  },
1474
1989
  [requirePro]
1475
1990
  );
1476
- const removeValueField = useCallback7((field, aggregation) => {
1991
+ const removeValueField = useCallback8((field, aggregation) => {
1477
1992
  setValueFields((prev) => {
1478
1993
  if (aggregation) {
1479
1994
  return prev.filter((v) => !(v.field === field && v.aggregation === aggregation));
@@ -1481,7 +1996,7 @@ function usePivotTable(data) {
1481
1996
  return prev.filter((v) => v.field !== field);
1482
1997
  });
1483
1998
  }, []);
1484
- const updateValueFieldAggregation = useCallback7(
1999
+ const updateValueFieldAggregation = useCallback8(
1485
2000
  (field, oldAgg, newAgg) => {
1486
2001
  setValueFields(
1487
2002
  (prev) => prev.map((v) => {
@@ -1494,12 +2009,12 @@ function usePivotTable(data) {
1494
2009
  },
1495
2010
  []
1496
2011
  );
1497
- const clearConfig = useCallback7(() => {
2012
+ const clearConfig = useCallback8(() => {
1498
2013
  setRowFieldsState([]);
1499
2014
  setColumnFieldsState([]);
1500
2015
  setValueFields([]);
1501
2016
  }, []);
1502
- const autoSuggestConfig = useCallback7(() => {
2017
+ const autoSuggestConfig = useCallback8(() => {
1503
2018
  if (!requirePro("Pivot Table - Auto Suggest"))
1504
2019
  return;
1505
2020
  if (availableFields.length === 0)
@@ -1511,7 +2026,7 @@ function usePivotTable(data) {
1511
2026
  setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
1512
2027
  }
1513
2028
  }, [availableFields, requirePro]);
1514
- const addCalculatedField = useCallback7((field) => {
2029
+ const addCalculatedField = useCallback8((field) => {
1515
2030
  setCalculatedFields((prev) => {
1516
2031
  const existing = prev.findIndex((f) => f.id === field.id);
1517
2032
  let updated;
@@ -1524,7 +2039,7 @@ function usePivotTable(data) {
1524
2039
  return updated;
1525
2040
  });
1526
2041
  }, []);
1527
- const removeCalculatedField = useCallback7((id) => {
2042
+ const removeCalculatedField = useCallback8((id) => {
1528
2043
  setCalculatedFields((prev) => {
1529
2044
  const updated = prev.filter((f) => f.id !== id);
1530
2045
  saveCalculatedFields(updated);
@@ -1566,8 +2081,8 @@ function usePivotTable(data) {
1566
2081
 
1567
2082
  // src/components/PivotConfig.tsx
1568
2083
  import { AGGREGATION_OPTIONS, getAggregationSymbol } from "@smallwebco/tinypivot-core";
1569
- import { useCallback as useCallback8, useMemo as useMemo8, useState as useState8 } from "react";
1570
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2084
+ import { useCallback as useCallback9, useMemo as useMemo9, useState as useState9 } from "react";
2085
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1571
2086
  function aggregationRequiresPro(agg) {
1572
2087
  return agg !== "sum";
1573
2088
  }
@@ -1608,15 +2123,15 @@ function PivotConfig({
1608
2123
  onRemoveCalculatedField,
1609
2124
  onUpdateCalculatedField
1610
2125
  }) {
1611
- const [fieldSearch, setFieldSearch] = useState8("");
1612
- const [showCalcModal, setShowCalcModal] = useState8(false);
1613
- const [editingCalcField, setEditingCalcField] = useState8(null);
2126
+ const [fieldSearch, setFieldSearch] = useState9("");
2127
+ const [showCalcModal, setShowCalcModal] = useState9(false);
2128
+ const [editingCalcField, setEditingCalcField] = useState9(null);
1614
2129
  const { canUseAdvancedAggregations } = useLicense();
1615
- const isAggregationAvailable = useCallback8((agg) => {
2130
+ const isAggregationAvailable = useCallback9((agg) => {
1616
2131
  return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
1617
2132
  }, [canUseAdvancedAggregations]);
1618
- const numericFieldNames = useMemo8(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
1619
- const calculatedFieldsAsStats = useMemo8(() => {
2133
+ const numericFieldNames = useMemo9(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
2134
+ const calculatedFieldsAsStats = useMemo9(() => {
1620
2135
  if (!calculatedFields)
1621
2136
  return [];
1622
2137
  return calculatedFields.map((calc) => ({
@@ -1630,11 +2145,11 @@ function PivotConfig({
1630
2145
  calcFormula: calc.formula
1631
2146
  }));
1632
2147
  }, [calculatedFields]);
1633
- const allAvailableFields = useMemo8(() => [
2148
+ const allAvailableFields = useMemo9(() => [
1634
2149
  ...availableFields.map((f) => ({ ...f, isCalculated: false })),
1635
2150
  ...calculatedFieldsAsStats
1636
2151
  ], [availableFields, calculatedFieldsAsStats]);
1637
- const assignedFields = useMemo8(() => {
2152
+ const assignedFields = useMemo9(() => {
1638
2153
  const rowSet = new Set(rowFields);
1639
2154
  const colSet = new Set(columnFields);
1640
2155
  const valueMap = new Map(valueFields.map((v) => [v.field, v]));
@@ -1644,7 +2159,7 @@ function PivotConfig({
1644
2159
  valueConfig: valueMap.get(f.field)
1645
2160
  }));
1646
2161
  }, [allAvailableFields, rowFields, columnFields, valueFields]);
1647
- const unassignedFields = useMemo8(() => {
2162
+ const unassignedFields = useMemo9(() => {
1648
2163
  const rowSet = new Set(rowFields);
1649
2164
  const colSet = new Set(columnFields);
1650
2165
  const valSet = new Set(valueFields.map((v) => v.field));
@@ -1652,7 +2167,7 @@ function PivotConfig({
1652
2167
  (f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
1653
2168
  );
1654
2169
  }, [allAvailableFields, rowFields, columnFields, valueFields]);
1655
- const filteredUnassignedFields = useMemo8(() => {
2170
+ const filteredUnassignedFields = useMemo9(() => {
1656
2171
  if (!fieldSearch.trim())
1657
2172
  return unassignedFields;
1658
2173
  const search = fieldSearch.toLowerCase().trim();
@@ -1663,13 +2178,13 @@ function PivotConfig({
1663
2178
  });
1664
2179
  }, [unassignedFields, fieldSearch]);
1665
2180
  const assignedCount = assignedFields.length;
1666
- const getFieldDisplayName = useCallback8((field) => {
2181
+ const getFieldDisplayName = useCallback9((field) => {
1667
2182
  if (field.isCalculated && field.calcName) {
1668
2183
  return field.calcName;
1669
2184
  }
1670
2185
  return field.field;
1671
2186
  }, []);
1672
- const handleDragStart = useCallback8(
2187
+ const handleDragStart = useCallback9(
1673
2188
  (field, event) => {
1674
2189
  event.dataTransfer?.setData("text/plain", field);
1675
2190
  event.dataTransfer.effectAllowed = "move";
@@ -1677,7 +2192,7 @@ function PivotConfig({
1677
2192
  },
1678
2193
  [onDragStart]
1679
2194
  );
1680
- const handleAggregationChange = useCallback8(
2195
+ const handleAggregationChange = useCallback9(
1681
2196
  (field, currentAgg, newAgg) => {
1682
2197
  if (!isAggregationAvailable(newAgg)) {
1683
2198
  console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
@@ -1687,7 +2202,7 @@ function PivotConfig({
1687
2202
  },
1688
2203
  [onUpdateAggregation, isAggregationAvailable]
1689
2204
  );
1690
- const toggleRowColumn = useCallback8(
2205
+ const toggleRowColumn = useCallback9(
1691
2206
  (field, currentAssignment) => {
1692
2207
  if (currentAssignment === "row") {
1693
2208
  onRemoveRowField(field);
@@ -1699,7 +2214,7 @@ function PivotConfig({
1699
2214
  },
1700
2215
  [onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
1701
2216
  );
1702
- const removeField = useCallback8(
2217
+ const removeField = useCallback9(
1703
2218
  (field, assignedTo, valueConfig) => {
1704
2219
  if (assignedTo === "row") {
1705
2220
  onRemoveRowField(field);
@@ -1711,15 +2226,15 @@ function PivotConfig({
1711
2226
  },
1712
2227
  [onRemoveRowField, onRemoveColumnField, onRemoveValueField]
1713
2228
  );
1714
- const handleTotalsToggle = useCallback8((checked) => {
2229
+ const handleTotalsToggle = useCallback9((checked) => {
1715
2230
  onShowRowTotalsChange(checked);
1716
2231
  onShowColumnTotalsChange(checked);
1717
2232
  }, [onShowRowTotalsChange, onShowColumnTotalsChange]);
1718
- const openCalcModal = useCallback8((field) => {
2233
+ const openCalcModal = useCallback9((field) => {
1719
2234
  setEditingCalcField(field || null);
1720
2235
  setShowCalcModal(true);
1721
2236
  }, []);
1722
- const handleSaveCalcField = useCallback8((field) => {
2237
+ const handleSaveCalcField = useCallback9((field) => {
1723
2238
  if (editingCalcField && onUpdateCalculatedField) {
1724
2239
  onUpdateCalculatedField(field);
1725
2240
  } else if (onAddCalculatedField) {
@@ -1728,14 +2243,14 @@ function PivotConfig({
1728
2243
  setShowCalcModal(false);
1729
2244
  setEditingCalcField(null);
1730
2245
  }, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
1731
- const handleCloseCalcModal = useCallback8(() => {
2246
+ const handleCloseCalcModal = useCallback9(() => {
1732
2247
  setShowCalcModal(false);
1733
2248
  setEditingCalcField(null);
1734
2249
  }, []);
1735
- return /* @__PURE__ */ jsxs4("div", { className: "vpg-pivot-config", children: [
1736
- /* @__PURE__ */ jsxs4("div", { className: "vpg-config-header", children: [
1737
- /* @__PURE__ */ jsxs4("h3", { className: "vpg-config-title", children: [
1738
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2250
+ return /* @__PURE__ */ jsxs5("div", { className: "vpg-pivot-config", children: [
2251
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-config-header", children: [
2252
+ /* @__PURE__ */ jsxs5("h3", { className: "vpg-config-title", children: [
2253
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
1739
2254
  "path",
1740
2255
  {
1741
2256
  strokeLinecap: "round",
@@ -1746,13 +2261,13 @@ function PivotConfig({
1746
2261
  ) }),
1747
2262
  "Fields"
1748
2263
  ] }),
1749
- /* @__PURE__ */ jsx4("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx4(
2264
+ /* @__PURE__ */ jsx5("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx5(
1750
2265
  "button",
1751
2266
  {
1752
2267
  className: "vpg-action-btn vpg-clear-btn",
1753
2268
  title: "Clear all",
1754
2269
  onClick: onClearConfig,
1755
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2270
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
1756
2271
  "path",
1757
2272
  {
1758
2273
  strokeLinecap: "round",
@@ -1764,9 +2279,9 @@ function PivotConfig({
1764
2279
  }
1765
2280
  ) })
1766
2281
  ] }),
1767
- assignedCount > 0 && /* @__PURE__ */ jsxs4("div", { className: "vpg-assigned-section", children: [
1768
- /* @__PURE__ */ jsx4("div", { className: "vpg-section-label", children: "Active" }),
1769
- /* @__PURE__ */ jsx4("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs4(
2282
+ assignedCount > 0 && /* @__PURE__ */ jsxs5("div", { className: "vpg-assigned-section", children: [
2283
+ /* @__PURE__ */ jsx5("div", { className: "vpg-section-label", children: "Active" }),
2284
+ /* @__PURE__ */ jsx5("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs5(
1770
2285
  "div",
1771
2286
  {
1772
2287
  className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
@@ -1775,12 +2290,12 @@ function PivotConfig({
1775
2290
  onDragStart: (e) => handleDragStart(field.field, e),
1776
2291
  onDragEnd,
1777
2292
  children: [
1778
- /* @__PURE__ */ jsxs4("div", { className: "vpg-item-main", children: [
1779
- /* @__PURE__ */ jsx4("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : getAggregationSymbol(field.valueConfig?.aggregation || "sum") }),
1780
- /* @__PURE__ */ jsx4("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
2293
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-item-main", children: [
2294
+ /* @__PURE__ */ jsx5("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : getAggregationSymbol(field.valueConfig?.aggregation || "sum") }),
2295
+ /* @__PURE__ */ jsx5("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
1781
2296
  ] }),
1782
- /* @__PURE__ */ jsxs4("div", { className: "vpg-item-actions", children: [
1783
- (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx4(
2297
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-item-actions", children: [
2298
+ (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx5(
1784
2299
  "button",
1785
2300
  {
1786
2301
  className: "vpg-toggle-btn",
@@ -1789,14 +2304,14 @@ function PivotConfig({
1789
2304
  e.stopPropagation();
1790
2305
  toggleRowColumn(field.field, field.assignedTo);
1791
2306
  },
1792
- children: /* @__PURE__ */ jsx4(
2307
+ children: /* @__PURE__ */ jsx5(
1793
2308
  "svg",
1794
2309
  {
1795
2310
  className: "vpg-icon-xs",
1796
2311
  fill: "none",
1797
2312
  stroke: "currentColor",
1798
2313
  viewBox: "0 0 24 24",
1799
- children: /* @__PURE__ */ jsx4(
2314
+ children: /* @__PURE__ */ jsx5(
1800
2315
  "path",
1801
2316
  {
1802
2317
  strokeLinecap: "round",
@@ -1809,7 +2324,7 @@ function PivotConfig({
1809
2324
  )
1810
2325
  }
1811
2326
  ),
1812
- field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx4(
2327
+ field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx5(
1813
2328
  "select",
1814
2329
  {
1815
2330
  className: "vpg-agg-select",
@@ -1823,7 +2338,7 @@ function PivotConfig({
1823
2338
  );
1824
2339
  },
1825
2340
  onClick: (e) => e.stopPropagation(),
1826
- children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs4(
2341
+ children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs5(
1827
2342
  "option",
1828
2343
  {
1829
2344
  value: agg.value,
@@ -1839,7 +2354,7 @@ function PivotConfig({
1839
2354
  ))
1840
2355
  }
1841
2356
  ),
1842
- /* @__PURE__ */ jsx4(
2357
+ /* @__PURE__ */ jsx5(
1843
2358
  "button",
1844
2359
  {
1845
2360
  className: "vpg-remove-btn",
@@ -1857,14 +2372,14 @@ function PivotConfig({
1857
2372
  field.field
1858
2373
  )) })
1859
2374
  ] }),
1860
- /* @__PURE__ */ jsxs4("div", { className: "vpg-unassigned-section", children: [
1861
- /* @__PURE__ */ jsx4("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs4("div", { className: "vpg-section-label", children: [
2375
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-unassigned-section", children: [
2376
+ /* @__PURE__ */ jsx5("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs5("div", { className: "vpg-section-label", children: [
1862
2377
  "Available",
1863
2378
  " ",
1864
- /* @__PURE__ */ jsx4("span", { className: "vpg-count", children: unassignedFields.length })
2379
+ /* @__PURE__ */ jsx5("span", { className: "vpg-count", children: unassignedFields.length })
1865
2380
  ] }) }),
1866
- /* @__PURE__ */ jsxs4("div", { className: "vpg-field-search", children: [
1867
- /* @__PURE__ */ jsx4("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2381
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-field-search", children: [
2382
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
1868
2383
  "path",
1869
2384
  {
1870
2385
  strokeLinecap: "round",
@@ -1873,7 +2388,7 @@ function PivotConfig({
1873
2388
  d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
1874
2389
  }
1875
2390
  ) }),
1876
- /* @__PURE__ */ jsx4(
2391
+ /* @__PURE__ */ jsx5(
1877
2392
  "input",
1878
2393
  {
1879
2394
  type: "text",
@@ -1883,7 +2398,7 @@ function PivotConfig({
1883
2398
  className: "vpg-search-input"
1884
2399
  }
1885
2400
  ),
1886
- fieldSearch && /* @__PURE__ */ jsx4("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2401
+ fieldSearch && /* @__PURE__ */ jsx5("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
1887
2402
  "path",
1888
2403
  {
1889
2404
  strokeLinecap: "round",
@@ -1893,8 +2408,8 @@ function PivotConfig({
1893
2408
  }
1894
2409
  ) }) })
1895
2410
  ] }),
1896
- /* @__PURE__ */ jsxs4("div", { className: "vpg-field-list", children: [
1897
- filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs4(
2411
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-field-list", children: [
2412
+ filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs5(
1898
2413
  "div",
1899
2414
  {
1900
2415
  className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
@@ -1903,10 +2418,10 @@ function PivotConfig({
1903
2418
  onDragStart: (e) => handleDragStart(field.field, e),
1904
2419
  onDragEnd,
1905
2420
  children: [
1906
- /* @__PURE__ */ jsx4("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
1907
- /* @__PURE__ */ jsx4("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
1908
- field.isCalculated ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1909
- /* @__PURE__ */ jsx4(
2421
+ /* @__PURE__ */ jsx5("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
2422
+ /* @__PURE__ */ jsx5("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
2423
+ field.isCalculated ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
2424
+ /* @__PURE__ */ jsx5(
1910
2425
  "button",
1911
2426
  {
1912
2427
  className: "vpg-field-edit",
@@ -1920,7 +2435,7 @@ function PivotConfig({
1920
2435
  children: "\u270E"
1921
2436
  }
1922
2437
  ),
1923
- /* @__PURE__ */ jsx4(
2438
+ /* @__PURE__ */ jsx5(
1924
2439
  "button",
1925
2440
  {
1926
2441
  className: "vpg-field-delete",
@@ -1934,22 +2449,22 @@ function PivotConfig({
1934
2449
  children: "\xD7"
1935
2450
  }
1936
2451
  )
1937
- ] }) : /* @__PURE__ */ jsx4("span", { className: "vpg-unique-count", children: field.uniqueCount })
2452
+ ] }) : /* @__PURE__ */ jsx5("span", { className: "vpg-unique-count", children: field.uniqueCount })
1938
2453
  ]
1939
2454
  },
1940
2455
  field.field
1941
2456
  )),
1942
- filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs4("div", { className: "vpg-empty-hint", children: [
2457
+ filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs5("div", { className: "vpg-empty-hint", children: [
1943
2458
  'No fields match "',
1944
2459
  fieldSearch,
1945
2460
  '"'
1946
2461
  ] }),
1947
- unassignedFields.length === 0 && /* @__PURE__ */ jsx4("div", { className: "vpg-empty-hint", children: "All fields assigned" })
2462
+ unassignedFields.length === 0 && /* @__PURE__ */ jsx5("div", { className: "vpg-empty-hint", children: "All fields assigned" })
1948
2463
  ] })
1949
2464
  ] }),
1950
- /* @__PURE__ */ jsxs4("div", { className: "vpg-options-section", children: [
1951
- /* @__PURE__ */ jsxs4("label", { className: "vpg-option-toggle", children: [
1952
- /* @__PURE__ */ jsx4(
2465
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-options-section", children: [
2466
+ /* @__PURE__ */ jsxs5("label", { className: "vpg-option-toggle", children: [
2467
+ /* @__PURE__ */ jsx5(
1953
2468
  "input",
1954
2469
  {
1955
2470
  type: "checkbox",
@@ -1957,14 +2472,14 @@ function PivotConfig({
1957
2472
  onChange: (e) => handleTotalsToggle(e.target.checked)
1958
2473
  }
1959
2474
  ),
1960
- /* @__PURE__ */ jsx4("span", { children: "Totals" })
2475
+ /* @__PURE__ */ jsx5("span", { children: "Totals" })
1961
2476
  ] }),
1962
- /* @__PURE__ */ jsxs4("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
1963
- /* @__PURE__ */ jsx4("span", { className: "vpg-calc-icon", children: "\u0192" }),
1964
- /* @__PURE__ */ jsx4("span", { children: "+ Calc" })
2477
+ /* @__PURE__ */ jsxs5("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
2478
+ /* @__PURE__ */ jsx5("span", { className: "vpg-calc-icon", children: "\u0192" }),
2479
+ /* @__PURE__ */ jsx5("span", { children: "+ Calc" })
1965
2480
  ] })
1966
2481
  ] }),
1967
- /* @__PURE__ */ jsx4(
2482
+ /* @__PURE__ */ jsx5(
1968
2483
  CalculatedFieldModal,
1969
2484
  {
1970
2485
  show: showCalcModal,
@@ -1979,8 +2494,8 @@ function PivotConfig({
1979
2494
 
1980
2495
  // src/components/PivotSkeleton.tsx
1981
2496
  import { getAggregationLabel as getAggregationLabel2, getAggregationSymbol as getAggregationSymbol2 } from "@smallwebco/tinypivot-core";
1982
- import { useCallback as useCallback9, useEffect as useEffect6, useMemo as useMemo9, useState as useState9 } from "react";
1983
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2497
+ import { useCallback as useCallback10, useEffect as useEffect7, useMemo as useMemo10, useState as useState10 } from "react";
2498
+ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1984
2499
  function PivotSkeleton({
1985
2500
  rowFields,
1986
2501
  columnFields,
@@ -2003,7 +2518,7 @@ function PivotSkeleton({
2003
2518
  onReorderColumnFields
2004
2519
  }) {
2005
2520
  const { showWatermark, canUsePivot, isDemo } = useLicense();
2006
- const getValueFieldDisplayName = useCallback9((field) => {
2521
+ const getValueFieldDisplayName = useCallback10((field) => {
2007
2522
  if (field.startsWith("calc:")) {
2008
2523
  const calcId = field.replace("calc:", "");
2009
2524
  const calcField = calculatedFields?.find((c) => c.id === calcId);
@@ -2011,15 +2526,15 @@ function PivotSkeleton({
2011
2526
  }
2012
2527
  return field;
2013
2528
  }, [calculatedFields]);
2014
- const isCalculatedField = useCallback9((field) => {
2529
+ const isCalculatedField = useCallback10((field) => {
2015
2530
  return field.startsWith("calc:");
2016
2531
  }, []);
2017
- const [dragOverArea, setDragOverArea] = useState9(null);
2018
- const [reorderDragSource, setReorderDragSource] = useState9(null);
2019
- const [reorderDropTarget, setReorderDropTarget] = useState9(null);
2020
- const [sortDirection, setSortDirection] = useState9("asc");
2021
- const [sortTarget, setSortTarget] = useState9("row");
2022
- const toggleSort = useCallback9((target = "row") => {
2532
+ const [dragOverArea, setDragOverArea] = useState10(null);
2533
+ const [reorderDragSource, setReorderDragSource] = useState10(null);
2534
+ const [reorderDropTarget, setReorderDropTarget] = useState10(null);
2535
+ const [sortDirection, setSortDirection] = useState10("asc");
2536
+ const [sortTarget, setSortTarget] = useState10("row");
2537
+ const toggleSort = useCallback10((target = "row") => {
2023
2538
  if (sortTarget === target) {
2024
2539
  setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
2025
2540
  } else {
@@ -2027,13 +2542,13 @@ function PivotSkeleton({
2027
2542
  setSortDirection("asc");
2028
2543
  }
2029
2544
  }, [sortTarget]);
2030
- const [selectedCell, setSelectedCell] = useState9(null);
2031
- const [selectionStart, setSelectionStart] = useState9(null);
2032
- const [selectionEnd, setSelectionEnd] = useState9(null);
2033
- const [isSelecting, setIsSelecting] = useState9(false);
2034
- const [showCopyToast, setShowCopyToast] = useState9(false);
2035
- const [copyToastMessage, setCopyToastMessage] = useState9("");
2036
- const selectionBounds = useMemo9(() => {
2545
+ const [selectedCell, setSelectedCell] = useState10(null);
2546
+ const [selectionStart, setSelectionStart] = useState10(null);
2547
+ const [selectionEnd, setSelectionEnd] = useState10(null);
2548
+ const [isSelecting, setIsSelecting] = useState10(false);
2549
+ const [showCopyToast, setShowCopyToast] = useState10(false);
2550
+ const [copyToastMessage, setCopyToastMessage] = useState10("");
2551
+ const selectionBounds = useMemo10(() => {
2037
2552
  if (!selectionStart || !selectionEnd)
2038
2553
  return null;
2039
2554
  return {
@@ -2043,7 +2558,7 @@ function PivotSkeleton({
2043
2558
  maxCol: Math.max(selectionStart.col, selectionEnd.col)
2044
2559
  };
2045
2560
  }, [selectionStart, selectionEnd]);
2046
- const handleCellMouseDown = useCallback9(
2561
+ const handleCellMouseDown = useCallback10(
2047
2562
  (rowIndex, colIndex, event) => {
2048
2563
  event.preventDefault();
2049
2564
  if (event.shiftKey && selectedCell) {
@@ -2057,7 +2572,7 @@ function PivotSkeleton({
2057
2572
  },
2058
2573
  [selectedCell]
2059
2574
  );
2060
- const handleCellMouseEnter = useCallback9(
2575
+ const handleCellMouseEnter = useCallback10(
2061
2576
  (rowIndex, colIndex) => {
2062
2577
  if (isSelecting) {
2063
2578
  setSelectionEnd({ row: rowIndex, col: colIndex });
@@ -2065,7 +2580,7 @@ function PivotSkeleton({
2065
2580
  },
2066
2581
  [isSelecting]
2067
2582
  );
2068
- const isCellSelected = useCallback9(
2583
+ const isCellSelected = useCallback10(
2069
2584
  (rowIndex, colIndex) => {
2070
2585
  if (!selectionBounds) {
2071
2586
  return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
@@ -2075,12 +2590,12 @@ function PivotSkeleton({
2075
2590
  },
2076
2591
  [selectionBounds, selectedCell]
2077
2592
  );
2078
- useEffect6(() => {
2593
+ useEffect7(() => {
2079
2594
  const handleMouseUp = () => setIsSelecting(false);
2080
2595
  document.addEventListener("mouseup", handleMouseUp);
2081
2596
  return () => document.removeEventListener("mouseup", handleMouseUp);
2082
2597
  }, []);
2083
- const sortedRowIndices = useMemo9(() => {
2598
+ const sortedRowIndices = useMemo10(() => {
2084
2599
  if (!pivotResult)
2085
2600
  return [];
2086
2601
  const indices = pivotResult.rowHeaders.map((_, i) => i);
@@ -2108,7 +2623,7 @@ function PivotSkeleton({
2108
2623
  });
2109
2624
  return indices;
2110
2625
  }, [pivotResult, sortTarget, sortDirection]);
2111
- const copySelectionToClipboard = useCallback9(() => {
2626
+ const copySelectionToClipboard = useCallback10(() => {
2112
2627
  if (!selectionBounds || !pivotResult)
2113
2628
  return;
2114
2629
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
@@ -2134,7 +2649,7 @@ function PivotSkeleton({
2134
2649
  console.error("Copy failed:", err);
2135
2650
  });
2136
2651
  }, [selectionBounds, pivotResult, sortedRowIndices]);
2137
- useEffect6(() => {
2652
+ useEffect7(() => {
2138
2653
  const handleKeydown = (event) => {
2139
2654
  if (!selectionBounds)
2140
2655
  return;
@@ -2152,7 +2667,7 @@ function PivotSkeleton({
2152
2667
  document.addEventListener("keydown", handleKeydown);
2153
2668
  return () => document.removeEventListener("keydown", handleKeydown);
2154
2669
  }, [selectionBounds, copySelectionToClipboard]);
2155
- const selectionStats = useMemo9(() => {
2670
+ const selectionStats = useMemo10(() => {
2156
2671
  if (!selectionBounds || !pivotResult)
2157
2672
  return null;
2158
2673
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
@@ -2181,14 +2696,14 @@ function PivotSkeleton({
2181
2696
  avg
2182
2697
  };
2183
2698
  }, [selectionBounds, pivotResult, sortedRowIndices]);
2184
- const formatStatValue = useCallback9((val) => {
2699
+ const formatStatValue = useCallback10((val) => {
2185
2700
  if (Math.abs(val) >= 1e6)
2186
2701
  return `${(val / 1e6).toFixed(2)}M`;
2187
2702
  if (Math.abs(val) >= 1e3)
2188
2703
  return `${(val / 1e3).toFixed(2)}K`;
2189
2704
  return val.toFixed(2);
2190
2705
  }, []);
2191
- const columnHeaderCells = useMemo9(() => {
2706
+ const columnHeaderCells = useMemo10(() => {
2192
2707
  if (!pivotResult || pivotResult.headers.length === 0) {
2193
2708
  return [
2194
2709
  valueFields.map((vf) => ({
@@ -2216,13 +2731,13 @@ function PivotSkeleton({
2216
2731
  return result;
2217
2732
  }, [pivotResult, valueFields]);
2218
2733
  const hasActiveFilters = activeFilters && activeFilters.length > 0;
2219
- const filterSummary = useMemo9(() => {
2734
+ const filterSummary = useMemo10(() => {
2220
2735
  if (!activeFilters || activeFilters.length === 0)
2221
2736
  return "";
2222
2737
  return activeFilters.map((f) => f.column).join(", ");
2223
2738
  }, [activeFilters]);
2224
- const [showFilterTooltip, setShowFilterTooltip] = useState9(false);
2225
- const filterTooltipDetails = useMemo9(() => {
2739
+ const [showFilterTooltip, setShowFilterTooltip] = useState10(false);
2740
+ const filterTooltipDetails = useMemo10(() => {
2226
2741
  if (!activeFilters || activeFilters.length === 0)
2227
2742
  return [];
2228
2743
  return activeFilters.map((f) => {
@@ -2247,7 +2762,7 @@ function PivotSkeleton({
2247
2762
  };
2248
2763
  });
2249
2764
  }, [activeFilters]);
2250
- const handleDragOver = useCallback9(
2765
+ const handleDragOver = useCallback10(
2251
2766
  (area, event) => {
2252
2767
  event.preventDefault();
2253
2768
  event.dataTransfer.dropEffect = "move";
@@ -2255,10 +2770,10 @@ function PivotSkeleton({
2255
2770
  },
2256
2771
  []
2257
2772
  );
2258
- const handleDragLeave = useCallback9(() => {
2773
+ const handleDragLeave = useCallback10(() => {
2259
2774
  setDragOverArea(null);
2260
2775
  }, []);
2261
- const handleDrop = useCallback9(
2776
+ const handleDrop = useCallback10(
2262
2777
  (area, event) => {
2263
2778
  event.preventDefault();
2264
2779
  const field = event.dataTransfer?.getData("text/plain");
@@ -2288,7 +2803,7 @@ function PivotSkeleton({
2288
2803
  },
2289
2804
  [rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
2290
2805
  );
2291
- const handleChipDragStart = useCallback9(
2806
+ const handleChipDragStart = useCallback10(
2292
2807
  (zone, index, event) => {
2293
2808
  setReorderDragSource({ zone, index });
2294
2809
  event.dataTransfer.effectAllowed = "move";
@@ -2299,11 +2814,11 @@ function PivotSkeleton({
2299
2814
  },
2300
2815
  []
2301
2816
  );
2302
- const handleChipDragEnd = useCallback9(() => {
2817
+ const handleChipDragEnd = useCallback10(() => {
2303
2818
  setReorderDragSource(null);
2304
2819
  setReorderDropTarget(null);
2305
2820
  }, []);
2306
- const handleChipDragOver = useCallback9(
2821
+ const handleChipDragOver = useCallback10(
2307
2822
  (zone, index, event) => {
2308
2823
  event.preventDefault();
2309
2824
  if (reorderDragSource && reorderDragSource.zone === zone) {
@@ -2313,10 +2828,10 @@ function PivotSkeleton({
2313
2828
  },
2314
2829
  [reorderDragSource]
2315
2830
  );
2316
- const handleChipDragLeave = useCallback9(() => {
2831
+ const handleChipDragLeave = useCallback10(() => {
2317
2832
  setReorderDropTarget(null);
2318
2833
  }, []);
2319
- const handleChipDrop = useCallback9(
2834
+ const handleChipDrop = useCallback10(
2320
2835
  (zone, targetIndex, event) => {
2321
2836
  event.preventDefault();
2322
2837
  event.stopPropagation();
@@ -2342,13 +2857,13 @@ function PivotSkeleton({
2342
2857
  },
2343
2858
  [reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
2344
2859
  );
2345
- const isChipDragSource = useCallback9(
2860
+ const isChipDragSource = useCallback10(
2346
2861
  (zone, index) => {
2347
2862
  return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
2348
2863
  },
2349
2864
  [reorderDragSource]
2350
2865
  );
2351
- const isChipDropTarget = useCallback9(
2866
+ const isChipDropTarget = useCallback10(
2352
2867
  (zone, index) => {
2353
2868
  return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
2354
2869
  },
@@ -2356,25 +2871,25 @@ function PivotSkeleton({
2356
2871
  );
2357
2872
  const currentFontSize = fontSize;
2358
2873
  const rowHeaderWidth = 180;
2359
- const rowHeaderColWidth = useMemo9(() => {
2874
+ const rowHeaderColWidth = useMemo10(() => {
2360
2875
  const numCols = Math.max(rowFields.length, 1);
2361
2876
  return Math.max(rowHeaderWidth / numCols, 80);
2362
2877
  }, [rowFields.length]);
2363
- const getRowHeaderLeftOffset = useCallback9((fieldIdx) => {
2878
+ const getRowHeaderLeftOffset = useCallback10((fieldIdx) => {
2364
2879
  return fieldIdx * rowHeaderColWidth;
2365
2880
  }, [rowHeaderColWidth]);
2366
- return /* @__PURE__ */ jsxs5(
2881
+ return /* @__PURE__ */ jsxs6(
2367
2882
  "div",
2368
2883
  {
2369
2884
  className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
2370
2885
  children: [
2371
- showCopyToast && /* @__PURE__ */ jsxs5("div", { className: "vpg-toast", children: [
2372
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
2886
+ showCopyToast && /* @__PURE__ */ jsxs6("div", { className: "vpg-toast", children: [
2887
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
2373
2888
  copyToastMessage
2374
2889
  ] }),
2375
- /* @__PURE__ */ jsxs5("div", { className: "vpg-skeleton-header", children: [
2376
- /* @__PURE__ */ jsxs5("div", { className: "vpg-skeleton-title", children: [
2377
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2890
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-skeleton-header", children: [
2891
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-skeleton-title", children: [
2892
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2378
2893
  "path",
2379
2894
  {
2380
2895
  strokeLinecap: "round",
@@ -2383,24 +2898,24 @@ function PivotSkeleton({
2383
2898
  d: "M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"
2384
2899
  }
2385
2900
  ) }),
2386
- /* @__PURE__ */ jsx5("span", { children: "Pivot Table" })
2901
+ /* @__PURE__ */ jsx6("span", { children: "Pivot Table" })
2387
2902
  ] }),
2388
- /* @__PURE__ */ jsxs5("div", { className: "vpg-header-right", children: [
2389
- hasActiveFilters && /* @__PURE__ */ jsxs5(
2903
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-header-right", children: [
2904
+ hasActiveFilters && /* @__PURE__ */ jsxs6(
2390
2905
  "div",
2391
2906
  {
2392
2907
  className: "vpg-filter-indicator",
2393
2908
  onMouseEnter: () => setShowFilterTooltip(true),
2394
2909
  onMouseLeave: () => setShowFilterTooltip(false),
2395
2910
  children: [
2396
- /* @__PURE__ */ jsx5(
2911
+ /* @__PURE__ */ jsx6(
2397
2912
  "svg",
2398
2913
  {
2399
2914
  className: "vpg-filter-icon",
2400
2915
  fill: "none",
2401
2916
  stroke: "currentColor",
2402
2917
  viewBox: "0 0 24 24",
2403
- children: /* @__PURE__ */ jsx5(
2918
+ children: /* @__PURE__ */ jsx6(
2404
2919
  "path",
2405
2920
  {
2406
2921
  strokeLinecap: "round",
@@ -2411,11 +2926,11 @@ function PivotSkeleton({
2411
2926
  )
2412
2927
  }
2413
2928
  ),
2414
- /* @__PURE__ */ jsxs5("span", { className: "vpg-filter-text", children: [
2929
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-filter-text", children: [
2415
2930
  "Filtered:",
2416
2931
  " ",
2417
- /* @__PURE__ */ jsx5("strong", { children: filterSummary }),
2418
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs5("span", { className: "vpg-filter-count", children: [
2932
+ /* @__PURE__ */ jsx6("strong", { children: filterSummary }),
2933
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs6("span", { className: "vpg-filter-count", children: [
2419
2934
  "(",
2420
2935
  filteredRowCount.toLocaleString(),
2421
2936
  " ",
@@ -2426,13 +2941,13 @@ function PivotSkeleton({
2426
2941
  "rows)"
2427
2942
  ] })
2428
2943
  ] }),
2429
- showFilterTooltip && /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-tooltip", children: [
2430
- /* @__PURE__ */ jsx5("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
2431
- filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs5("div", { className: "vpg-tooltip-filter", children: [
2432
- /* @__PURE__ */ jsx5("div", { className: "vpg-tooltip-column", children: filter.column }),
2433
- /* @__PURE__ */ jsx5("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ jsx5("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
2434
- filter.values.map((val, idx) => /* @__PURE__ */ jsx5("span", { className: "vpg-tooltip-value", children: val }, idx)),
2435
- filter.remaining > 0 && /* @__PURE__ */ jsxs5("span", { className: "vpg-tooltip-more", children: [
2944
+ showFilterTooltip && /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-tooltip", children: [
2945
+ /* @__PURE__ */ jsx6("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
2946
+ filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs6("div", { className: "vpg-tooltip-filter", children: [
2947
+ /* @__PURE__ */ jsx6("div", { className: "vpg-tooltip-column", children: filter.column }),
2948
+ /* @__PURE__ */ jsx6("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ jsx6("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
2949
+ filter.values.map((val, idx) => /* @__PURE__ */ jsx6("span", { className: "vpg-tooltip-value", children: val }, idx)),
2950
+ filter.remaining > 0 && /* @__PURE__ */ jsxs6("span", { className: "vpg-tooltip-more", children: [
2436
2951
  "+",
2437
2952
  filter.remaining,
2438
2953
  " ",
@@ -2440,7 +2955,7 @@ function PivotSkeleton({
2440
2955
  ] })
2441
2956
  ] }) })
2442
2957
  ] }, filter.column)),
2443
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs5("div", { className: "vpg-tooltip-summary", children: [
2958
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs6("div", { className: "vpg-tooltip-summary", children: [
2444
2959
  "Showing",
2445
2960
  " ",
2446
2961
  filteredRowCount.toLocaleString(),
@@ -2455,20 +2970,20 @@ function PivotSkeleton({
2455
2970
  ]
2456
2971
  }
2457
2972
  ),
2458
- isConfigured && /* @__PURE__ */ jsxs5("div", { className: "vpg-config-summary", children: [
2459
- /* @__PURE__ */ jsxs5("span", { className: "vpg-summary-badge vpg-rows", children: [
2973
+ isConfigured && /* @__PURE__ */ jsxs6("div", { className: "vpg-config-summary", children: [
2974
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-summary-badge vpg-rows", children: [
2460
2975
  rowFields.length,
2461
2976
  " ",
2462
2977
  "row",
2463
2978
  rowFields.length !== 1 ? "s" : ""
2464
2979
  ] }),
2465
- /* @__PURE__ */ jsxs5("span", { className: "vpg-summary-badge vpg-cols", children: [
2980
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-summary-badge vpg-cols", children: [
2466
2981
  columnFields.length,
2467
2982
  " ",
2468
2983
  "col",
2469
2984
  columnFields.length !== 1 ? "s" : ""
2470
2985
  ] }),
2471
- /* @__PURE__ */ jsxs5("span", { className: "vpg-summary-badge vpg-vals", children: [
2986
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-summary-badge vpg-vals", children: [
2472
2987
  valueFields.length,
2473
2988
  " ",
2474
2989
  "val",
@@ -2477,8 +2992,8 @@ function PivotSkeleton({
2477
2992
  ] })
2478
2993
  ] })
2479
2994
  ] }),
2480
- !canUsePivot ? /* @__PURE__ */ jsx5("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs5("div", { className: "vpg-pro-content", children: [
2481
- /* @__PURE__ */ jsx5("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5(
2995
+ !canUsePivot ? /* @__PURE__ */ jsx6("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs6("div", { className: "vpg-pro-content", children: [
2996
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6(
2482
2997
  "path",
2483
2998
  {
2484
2999
  strokeLinecap: "round",
@@ -2487,12 +3002,12 @@ function PivotSkeleton({
2487
3002
  d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
2488
3003
  }
2489
3004
  ) }),
2490
- /* @__PURE__ */ jsx5("h3", { children: "Pro Feature" }),
2491
- /* @__PURE__ */ jsx5("p", { children: "Pivot Table functionality requires a Pro license." }),
2492
- /* @__PURE__ */ jsx5("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
2493
- ] }) }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
2494
- /* @__PURE__ */ jsxs5("div", { className: "vpg-config-bar", children: [
2495
- /* @__PURE__ */ jsxs5(
3005
+ /* @__PURE__ */ jsx6("h3", { children: "Pro Feature" }),
3006
+ /* @__PURE__ */ jsx6("p", { children: "Pivot Table functionality requires a Pro license." }),
3007
+ /* @__PURE__ */ jsx6("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
3008
+ ] }) }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
3009
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-config-bar", children: [
3010
+ /* @__PURE__ */ jsxs6(
2496
3011
  "div",
2497
3012
  {
2498
3013
  className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
@@ -2500,12 +3015,12 @@ function PivotSkeleton({
2500
3015
  onDragLeave: handleDragLeave,
2501
3016
  onDrop: (e) => handleDrop("row", e),
2502
3017
  children: [
2503
- /* @__PURE__ */ jsxs5("div", { className: "vpg-zone-header", children: [
2504
- /* @__PURE__ */ jsx5("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
2505
- /* @__PURE__ */ jsx5("span", { className: "vpg-zone-label", children: "Rows" })
3018
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-zone-header", children: [
3019
+ /* @__PURE__ */ jsx6("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
3020
+ /* @__PURE__ */ jsx6("span", { className: "vpg-zone-label", children: "Rows" })
2506
3021
  ] }),
2507
- /* @__PURE__ */ jsxs5("div", { className: "vpg-zone-chips", children: [
2508
- rowFields.map((field, idx) => /* @__PURE__ */ jsxs5(
3022
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-zone-chips", children: [
3023
+ rowFields.map((field, idx) => /* @__PURE__ */ jsxs6(
2509
3024
  "div",
2510
3025
  {
2511
3026
  className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -2516,9 +3031,9 @@ function PivotSkeleton({
2516
3031
  onDragLeave: handleChipDragLeave,
2517
3032
  onDrop: (e) => handleChipDrop("row", idx, e),
2518
3033
  children: [
2519
- /* @__PURE__ */ jsx5("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
2520
- /* @__PURE__ */ jsx5("span", { className: "vpg-mini-name", children: field }),
2521
- /* @__PURE__ */ jsx5(
3034
+ /* @__PURE__ */ jsx6("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
3035
+ /* @__PURE__ */ jsx6("span", { className: "vpg-mini-name", children: field }),
3036
+ /* @__PURE__ */ jsx6(
2522
3037
  "button",
2523
3038
  {
2524
3039
  className: "vpg-mini-remove",
@@ -2533,12 +3048,12 @@ function PivotSkeleton({
2533
3048
  },
2534
3049
  field
2535
3050
  )),
2536
- rowFields.length === 0 && /* @__PURE__ */ jsx5("span", { className: "vpg-zone-hint", children: "Drop here" })
3051
+ rowFields.length === 0 && /* @__PURE__ */ jsx6("span", { className: "vpg-zone-hint", children: "Drop here" })
2537
3052
  ] })
2538
3053
  ]
2539
3054
  }
2540
3055
  ),
2541
- /* @__PURE__ */ jsxs5(
3056
+ /* @__PURE__ */ jsxs6(
2542
3057
  "div",
2543
3058
  {
2544
3059
  className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
@@ -2546,12 +3061,12 @@ function PivotSkeleton({
2546
3061
  onDragLeave: handleDragLeave,
2547
3062
  onDrop: (e) => handleDrop("column", e),
2548
3063
  children: [
2549
- /* @__PURE__ */ jsxs5("div", { className: "vpg-zone-header", children: [
2550
- /* @__PURE__ */ jsx5("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
2551
- /* @__PURE__ */ jsx5("span", { className: "vpg-zone-label", children: "Columns" })
3064
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-zone-header", children: [
3065
+ /* @__PURE__ */ jsx6("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
3066
+ /* @__PURE__ */ jsx6("span", { className: "vpg-zone-label", children: "Columns" })
2552
3067
  ] }),
2553
- /* @__PURE__ */ jsxs5("div", { className: "vpg-zone-chips", children: [
2554
- columnFields.map((field, idx) => /* @__PURE__ */ jsxs5(
3068
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-zone-chips", children: [
3069
+ columnFields.map((field, idx) => /* @__PURE__ */ jsxs6(
2555
3070
  "div",
2556
3071
  {
2557
3072
  className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -2562,9 +3077,9 @@ function PivotSkeleton({
2562
3077
  onDragLeave: handleChipDragLeave,
2563
3078
  onDrop: (e) => handleChipDrop("column", idx, e),
2564
3079
  children: [
2565
- /* @__PURE__ */ jsx5("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
2566
- /* @__PURE__ */ jsx5("span", { className: "vpg-mini-name", children: field }),
2567
- /* @__PURE__ */ jsx5(
3080
+ /* @__PURE__ */ jsx6("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
3081
+ /* @__PURE__ */ jsx6("span", { className: "vpg-mini-name", children: field }),
3082
+ /* @__PURE__ */ jsx6(
2568
3083
  "button",
2569
3084
  {
2570
3085
  className: "vpg-mini-remove",
@@ -2579,12 +3094,12 @@ function PivotSkeleton({
2579
3094
  },
2580
3095
  field
2581
3096
  )),
2582
- columnFields.length === 0 && /* @__PURE__ */ jsx5("span", { className: "vpg-zone-hint", children: "Drop here" })
3097
+ columnFields.length === 0 && /* @__PURE__ */ jsx6("span", { className: "vpg-zone-hint", children: "Drop here" })
2583
3098
  ] })
2584
3099
  ]
2585
3100
  }
2586
3101
  ),
2587
- /* @__PURE__ */ jsxs5(
3102
+ /* @__PURE__ */ jsxs6(
2588
3103
  "div",
2589
3104
  {
2590
3105
  className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
@@ -2592,19 +3107,19 @@ function PivotSkeleton({
2592
3107
  onDragLeave: handleDragLeave,
2593
3108
  onDrop: (e) => handleDrop("value", e),
2594
3109
  children: [
2595
- /* @__PURE__ */ jsxs5("div", { className: "vpg-zone-header", children: [
2596
- /* @__PURE__ */ jsx5("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
2597
- /* @__PURE__ */ jsx5("span", { className: "vpg-zone-label", children: "Values" })
3110
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-zone-header", children: [
3111
+ /* @__PURE__ */ jsx6("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
3112
+ /* @__PURE__ */ jsx6("span", { className: "vpg-zone-label", children: "Values" })
2598
3113
  ] }),
2599
- /* @__PURE__ */ jsxs5("div", { className: "vpg-zone-chips", children: [
2600
- valueFields.map((vf) => /* @__PURE__ */ jsxs5(
3114
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-zone-chips", children: [
3115
+ valueFields.map((vf) => /* @__PURE__ */ jsxs6(
2601
3116
  "div",
2602
3117
  {
2603
3118
  className: `vpg-mini-chip vpg-value-chip${isCalculatedField(vf.field) ? " vpg-calc-chip" : ""}`,
2604
3119
  children: [
2605
- /* @__PURE__ */ jsx5("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : getAggregationSymbol2(vf.aggregation) }),
2606
- /* @__PURE__ */ jsx5("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
2607
- /* @__PURE__ */ jsx5(
3120
+ /* @__PURE__ */ jsx6("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : getAggregationSymbol2(vf.aggregation) }),
3121
+ /* @__PURE__ */ jsx6("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
3122
+ /* @__PURE__ */ jsx6(
2608
3123
  "button",
2609
3124
  {
2610
3125
  className: "vpg-mini-remove",
@@ -2616,21 +3131,21 @@ function PivotSkeleton({
2616
3131
  },
2617
3132
  `${vf.field}-${vf.aggregation}`
2618
3133
  )),
2619
- valueFields.length === 0 && /* @__PURE__ */ jsx5("span", { className: "vpg-zone-hint", children: "Drop numeric" })
3134
+ valueFields.length === 0 && /* @__PURE__ */ jsx6("span", { className: "vpg-zone-hint", children: "Drop numeric" })
2620
3135
  ] })
2621
3136
  ]
2622
3137
  }
2623
3138
  )
2624
3139
  ] }),
2625
- (!isConfigured || !pivotResult) && /* @__PURE__ */ jsx5("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs5("div", { className: "vpg-placeholder-content", children: [
2626
- /* @__PURE__ */ jsx5(
3140
+ (!isConfigured || !pivotResult) && /* @__PURE__ */ jsx6("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs6("div", { className: "vpg-placeholder-content", children: [
3141
+ /* @__PURE__ */ jsx6(
2627
3142
  "svg",
2628
3143
  {
2629
3144
  className: "vpg-placeholder-icon",
2630
3145
  fill: "none",
2631
3146
  viewBox: "0 0 24 24",
2632
3147
  stroke: "currentColor",
2633
- children: /* @__PURE__ */ jsx5(
3148
+ children: /* @__PURE__ */ jsx6(
2634
3149
  "path",
2635
3150
  {
2636
3151
  strokeLinecap: "round",
@@ -2641,58 +3156,58 @@ function PivotSkeleton({
2641
3156
  )
2642
3157
  }
2643
3158
  ),
2644
- /* @__PURE__ */ jsx5("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3159
+ /* @__PURE__ */ jsx6("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
2645
3160
  "Add a",
2646
3161
  " ",
2647
- /* @__PURE__ */ jsx5("strong", { children: "Values" }),
3162
+ /* @__PURE__ */ jsx6("strong", { children: "Values" }),
2648
3163
  " ",
2649
3164
  "field to see your pivot table"
2650
- ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3165
+ ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
2651
3166
  "Add",
2652
3167
  " ",
2653
- /* @__PURE__ */ jsx5("strong", { children: "Row" }),
3168
+ /* @__PURE__ */ jsx6("strong", { children: "Row" }),
2654
3169
  " ",
2655
3170
  "or",
2656
3171
  " ",
2657
- /* @__PURE__ */ jsx5("strong", { children: "Column" }),
3172
+ /* @__PURE__ */ jsx6("strong", { children: "Column" }),
2658
3173
  " ",
2659
3174
  "fields to group your data"
2660
3175
  ] }) : "Your pivot table will appear here" })
2661
3176
  ] }) }),
2662
- isConfigured && pivotResult && /* @__PURE__ */ jsx5("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs5("table", { className: "vpg-pivot-table", children: [
2663
- /* @__PURE__ */ jsx5("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs5("tr", { className: "vpg-column-header-row", children: [
2664
- levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ jsx5(
3177
+ isConfigured && pivotResult && /* @__PURE__ */ jsx6("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs6("table", { className: "vpg-pivot-table", children: [
3178
+ /* @__PURE__ */ jsx6("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs6("tr", { className: "vpg-column-header-row", children: [
3179
+ levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ jsx6(
2665
3180
  "th",
2666
3181
  {
2667
3182
  className: "vpg-row-header-label",
2668
3183
  rowSpan: columnHeaderCells.length,
2669
3184
  style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(fieldIdx)}px` },
2670
3185
  onClick: () => toggleSort("row"),
2671
- children: /* @__PURE__ */ jsxs5("div", { className: "vpg-header-content", children: [
2672
- /* @__PURE__ */ jsx5("span", { children: field }),
2673
- (fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ jsx5("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
3186
+ children: /* @__PURE__ */ jsxs6("div", { className: "vpg-header-content", children: [
3187
+ /* @__PURE__ */ jsx6("span", { children: field }),
3188
+ (fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ jsx6("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
2674
3189
  ] })
2675
3190
  },
2676
3191
  `row-header-${fieldIdx}`
2677
3192
  )),
2678
- headerRow.map((cell, idx) => /* @__PURE__ */ jsx5(
3193
+ headerRow.map((cell, idx) => /* @__PURE__ */ jsx6(
2679
3194
  "th",
2680
3195
  {
2681
3196
  className: "vpg-column-header-cell",
2682
3197
  colSpan: cell.colspan,
2683
3198
  onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
2684
- children: /* @__PURE__ */ jsxs5("div", { className: "vpg-header-content", children: [
2685
- /* @__PURE__ */ jsx5("span", { children: cell.label }),
2686
- levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx5("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
3199
+ children: /* @__PURE__ */ jsxs6("div", { className: "vpg-header-content", children: [
3200
+ /* @__PURE__ */ jsx6("span", { children: cell.label }),
3201
+ levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx6("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
2687
3202
  ] })
2688
3203
  },
2689
3204
  idx
2690
3205
  )),
2691
- pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx5("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
3206
+ pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx6("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
2692
3207
  ] }, `header-${levelIdx}`)) }),
2693
- /* @__PURE__ */ jsxs5("tbody", { children: [
2694
- sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs5("tr", { className: "vpg-data-row", children: [
2695
- pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx5(
3208
+ /* @__PURE__ */ jsxs6("tbody", { children: [
3209
+ sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs6("tr", { className: "vpg-data-row", children: [
3210
+ pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx6(
2696
3211
  "th",
2697
3212
  {
2698
3213
  className: "vpg-row-header-cell",
@@ -2703,7 +3218,7 @@ function PivotSkeleton({
2703
3218
  )),
2704
3219
  pivotResult.data[sortedIdx].map((cell, colIdx) => {
2705
3220
  const displayRowIdx = sortedRowIndices.indexOf(sortedIdx);
2706
- return /* @__PURE__ */ jsx5(
3221
+ return /* @__PURE__ */ jsx6(
2707
3222
  "td",
2708
3223
  {
2709
3224
  className: `vpg-data-cell ${isCellSelected(displayRowIdx, colIdx) ? "selected" : ""} ${cell.value === null ? "vpg-is-null" : ""}`,
@@ -2714,10 +3229,10 @@ function PivotSkeleton({
2714
3229
  colIdx
2715
3230
  );
2716
3231
  }),
2717
- pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx5("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
3232
+ pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx6("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
2718
3233
  ] }, sortedIdx)),
2719
- pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs5("tr", { className: "vpg-totals-row", children: [
2720
- /* @__PURE__ */ jsx5(
3234
+ pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs6("tr", { className: "vpg-totals-row", children: [
3235
+ /* @__PURE__ */ jsx6(
2721
3236
  "th",
2722
3237
  {
2723
3238
  className: "vpg-row-header-cell vpg-total-label",
@@ -2726,13 +3241,13 @@ function PivotSkeleton({
2726
3241
  children: "Total"
2727
3242
  }
2728
3243
  ),
2729
- pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx5("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
2730
- pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx5("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
3244
+ pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx6("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
3245
+ pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx6("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
2731
3246
  ] })
2732
3247
  ] })
2733
3248
  ] }) }),
2734
- isConfigured && pivotResult && /* @__PURE__ */ jsxs5("div", { className: "vpg-skeleton-footer", children: [
2735
- /* @__PURE__ */ jsxs5("span", { className: "vpg-footer-info", children: [
3249
+ isConfigured && pivotResult && /* @__PURE__ */ jsxs6("div", { className: "vpg-skeleton-footer", children: [
3250
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-footer-info", children: [
2736
3251
  pivotResult.rowHeaders.length,
2737
3252
  " ",
2738
3253
  "rows \xD7",
@@ -2740,30 +3255,30 @@ function PivotSkeleton({
2740
3255
  " ",
2741
3256
  "columns"
2742
3257
  ] }),
2743
- selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs5("div", { className: "vpg-selection-stats", children: [
2744
- /* @__PURE__ */ jsxs5("span", { className: "vpg-stat", children: [
2745
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-label", children: "Count:" }),
2746
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-value", children: selectionStats.count })
3258
+ selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs6("div", { className: "vpg-selection-stats", children: [
3259
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
3260
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Count:" }),
3261
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: selectionStats.count })
2747
3262
  ] }),
2748
- selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs5(Fragment3, { children: [
2749
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-divider", children: "|" }),
2750
- /* @__PURE__ */ jsxs5("span", { className: "vpg-stat", children: [
2751
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-label", children: "Sum:" }),
2752
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
3263
+ selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs6(Fragment4, { children: [
3264
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-divider", children: "|" }),
3265
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
3266
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Sum:" }),
3267
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
2753
3268
  ] }),
2754
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-divider", children: "|" }),
2755
- /* @__PURE__ */ jsxs5("span", { className: "vpg-stat", children: [
2756
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-label", children: "Avg:" }),
2757
- /* @__PURE__ */ jsx5("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
3269
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-divider", children: "|" }),
3270
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
3271
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Avg:" }),
3272
+ /* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
2758
3273
  ] })
2759
3274
  ] })
2760
3275
  ] })
2761
3276
  ] })
2762
3277
  ] }),
2763
- showWatermark && canUsePivot && /* @__PURE__ */ jsx5("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
2764
- /* @__PURE__ */ jsx5("span", { className: "vpg-demo-badge", children: "DEMO" }),
2765
- /* @__PURE__ */ jsx5("span", { children: "Pro features unlocked for evaluation" }),
2766
- /* @__PURE__ */ jsx5(
3278
+ showWatermark && canUsePivot && /* @__PURE__ */ jsx6("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
3279
+ /* @__PURE__ */ jsx6("span", { className: "vpg-demo-badge", children: "DEMO" }),
3280
+ /* @__PURE__ */ jsx6("span", { children: "Pro features unlocked for evaluation" }),
3281
+ /* @__PURE__ */ jsx6(
2767
3282
  "a",
2768
3283
  {
2769
3284
  href: "https://tiny-pivot.com/#pricing",
@@ -2773,14 +3288,14 @@ function PivotSkeleton({
2773
3288
  children: "Get Pro License \u2192"
2774
3289
  }
2775
3290
  )
2776
- ] }) : /* @__PURE__ */ jsx5("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
3291
+ ] }) : /* @__PURE__ */ jsx6("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
2777
3292
  ]
2778
3293
  }
2779
3294
  );
2780
3295
  }
2781
3296
 
2782
3297
  // src/components/DataGrid.tsx
2783
- import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
3298
+ import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2784
3299
  var MIN_COL_WIDTH = 120;
2785
3300
  var MAX_COL_WIDTH = 350;
2786
3301
  function DataGrid({
@@ -2805,36 +3320,40 @@ function DataGrid({
2805
3320
  onExport,
2806
3321
  onCopy
2807
3322
  }) {
2808
- const { showWatermark, canUsePivot, isDemo, isPro } = useLicense();
2809
- const currentTheme = useMemo10(() => {
3323
+ const { showWatermark, canUsePivot, canUseCharts, isDemo, isPro } = useLicense();
3324
+ const currentTheme = useMemo11(() => {
2810
3325
  if (theme === "auto") {
2811
3326
  return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2812
3327
  }
2813
3328
  return theme;
2814
3329
  }, [theme]);
2815
- const [currentFontSize, setCurrentFontSize] = useState10(initialFontSize);
2816
- const [globalSearchTerm, setGlobalSearchTerm] = useState10("");
2817
- const [showSearchInput, setShowSearchInput] = useState10(false);
2818
- const [currentPage, setCurrentPage] = useState10(1);
2819
- const [columnWidths, setColumnWidths] = useState10({});
2820
- const [resizingColumnId, setResizingColumnId] = useState10(null);
2821
- const [resizeStartX, setResizeStartX] = useState10(0);
2822
- const [resizeStartWidth, setResizeStartWidth] = useState10(0);
2823
- const [gridHeight, setGridHeight] = useState10(initialHeight);
2824
- const [isResizingVertically, setIsResizingVertically] = useState10(false);
2825
- const [verticalResizeStartY, setVerticalResizeStartY] = useState10(0);
2826
- const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState10(0);
2827
- const [showCopyToast, setShowCopyToast] = useState10(false);
2828
- const [copyToastMessage, setCopyToastMessage] = useState10("");
2829
- const [viewMode, setViewMode] = useState10("grid");
2830
- const [showPivotConfig, setShowPivotConfig] = useState10(true);
2831
- const [draggingField, setDraggingField] = useState10(null);
2832
- const [activeFilterColumn, setActiveFilterColumn] = useState10(null);
2833
- const [filterDropdownPosition, setFilterDropdownPosition] = useState10({ top: 0, left: 0, maxHeight: 400 });
2834
- const [selectedCell, setSelectedCell] = useState10(null);
2835
- const [selectionStart, setSelectionStart] = useState10(null);
2836
- const [selectionEnd, setSelectionEnd] = useState10(null);
2837
- const [isSelecting, setIsSelecting] = useState10(false);
3330
+ const [currentFontSize, setCurrentFontSize] = useState11(initialFontSize);
3331
+ const [globalSearchTerm, setGlobalSearchTerm] = useState11("");
3332
+ const [showSearchInput, setShowSearchInput] = useState11(false);
3333
+ const [currentPage, setCurrentPage] = useState11(1);
3334
+ const [columnWidths, setColumnWidths] = useState11({});
3335
+ const [resizingColumnId, setResizingColumnId] = useState11(null);
3336
+ const [resizeStartX, setResizeStartX] = useState11(0);
3337
+ const [resizeStartWidth, setResizeStartWidth] = useState11(0);
3338
+ const [gridHeight, setGridHeight] = useState11(initialHeight);
3339
+ const [isResizingVertically, setIsResizingVertically] = useState11(false);
3340
+ const [verticalResizeStartY, setVerticalResizeStartY] = useState11(0);
3341
+ const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState11(0);
3342
+ const [showCopyToast, setShowCopyToast] = useState11(false);
3343
+ const [copyToastMessage, setCopyToastMessage] = useState11("");
3344
+ const [viewMode, setViewMode] = useState11("grid");
3345
+ const [_chartConfig, setChartConfig] = useState11(null);
3346
+ const handleChartConfigChange = useCallback11((config) => {
3347
+ setChartConfig(config);
3348
+ }, []);
3349
+ const [showPivotConfig, setShowPivotConfig] = useState11(true);
3350
+ const [draggingField, setDraggingField] = useState11(null);
3351
+ const [activeFilterColumn, setActiveFilterColumn] = useState11(null);
3352
+ const [filterDropdownPosition, setFilterDropdownPosition] = useState11({ top: 0, left: 0, maxHeight: 400 });
3353
+ const [selectedCell, setSelectedCell] = useState11(null);
3354
+ const [selectionStart, setSelectionStart] = useState11(null);
3355
+ const [selectionEnd, setSelectionEnd] = useState11(null);
3356
+ const [isSelecting, setIsSelecting] = useState11(false);
2838
3357
  const tableContainerRef = useRef2(null);
2839
3358
  const tableBodyRef = useRef2(null);
2840
3359
  const fontSizeOptions = [
@@ -2860,7 +3379,7 @@ function DataGrid({
2860
3379
  setNumericRangeFilter,
2861
3380
  getNumericRangeFilter
2862
3381
  } = useExcelGrid({ data, enableSorting: true, enableFiltering: true });
2863
- const filteredDataForPivot = useMemo10(() => {
3382
+ const filteredDataForPivot = useMemo11(() => {
2864
3383
  const filteredRows = table.getFilteredRowModel().rows;
2865
3384
  return filteredRows.map((row) => row.original);
2866
3385
  }, [table, columnFilters]);
@@ -2890,7 +3409,7 @@ function DataGrid({
2890
3409
  addCalculatedField,
2891
3410
  removeCalculatedField
2892
3411
  } = usePivotTable(filteredDataForPivot);
2893
- const activeFilterInfo = useMemo10(() => {
3412
+ const activeFilterInfo = useMemo11(() => {
2894
3413
  if (activeFilters.length === 0)
2895
3414
  return null;
2896
3415
  return activeFilters.map((f) => {
@@ -2915,8 +3434,8 @@ function DataGrid({
2915
3434
  };
2916
3435
  });
2917
3436
  }, [activeFilters]);
2918
- const rows = useMemo10(() => table.getFilteredRowModel().rows, [table, columnFilters]);
2919
- const searchFilteredData = useMemo10(() => {
3437
+ const rows = useMemo11(() => table.getFilteredRowModel().rows, [table, columnFilters]);
3438
+ const searchFilteredData = useMemo11(() => {
2920
3439
  if (!globalSearchTerm.trim() || !enableSearch) {
2921
3440
  return rows;
2922
3441
  }
@@ -2934,22 +3453,22 @@ function DataGrid({
2934
3453
  });
2935
3454
  }, [rows, globalSearchTerm, enableSearch, columnKeys]);
2936
3455
  const totalSearchedRows = searchFilteredData.length;
2937
- const totalPages = useMemo10(() => {
3456
+ const totalPages = useMemo11(() => {
2938
3457
  if (!enablePagination)
2939
3458
  return 1;
2940
3459
  return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
2941
3460
  }, [enablePagination, totalSearchedRows, pageSize]);
2942
- const paginatedRows = useMemo10(() => {
3461
+ const paginatedRows = useMemo11(() => {
2943
3462
  if (!enablePagination)
2944
3463
  return searchFilteredData;
2945
3464
  const start = (currentPage - 1) * pageSize;
2946
3465
  const end = start + pageSize;
2947
3466
  return searchFilteredData.slice(start, end);
2948
3467
  }, [enablePagination, searchFilteredData, currentPage, pageSize]);
2949
- useEffect7(() => {
3468
+ useEffect8(() => {
2950
3469
  setCurrentPage(1);
2951
3470
  }, [columnFilters, globalSearchTerm]);
2952
- const selectionBounds = useMemo10(() => {
3471
+ const selectionBounds = useMemo11(() => {
2953
3472
  if (!selectionStart || !selectionEnd)
2954
3473
  return null;
2955
3474
  return {
@@ -2959,7 +3478,7 @@ function DataGrid({
2959
3478
  maxCol: Math.max(selectionStart.col, selectionEnd.col)
2960
3479
  };
2961
3480
  }, [selectionStart, selectionEnd]);
2962
- const selectionStats = useMemo10(() => {
3481
+ const selectionStats = useMemo11(() => {
2963
3482
  if (!selectionBounds)
2964
3483
  return null;
2965
3484
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
@@ -2989,7 +3508,7 @@ function DataGrid({
2989
3508
  const avg = sum / values.length;
2990
3509
  return { count, sum, avg, numericCount: values.length };
2991
3510
  }, [selectionBounds, rows, columnKeys]);
2992
- useEffect7(() => {
3511
+ useEffect8(() => {
2993
3512
  if (typeof document === "undefined")
2994
3513
  return;
2995
3514
  if (data.length === 0)
@@ -3013,7 +3532,7 @@ function DataGrid({
3013
3532
  }
3014
3533
  setColumnWidths(widths);
3015
3534
  }, [data, columnKeys]);
3016
- const startColumnResize = useCallback10(
3535
+ const startColumnResize = useCallback11(
3017
3536
  (columnId, event) => {
3018
3537
  if (!enableColumnResize)
3019
3538
  return;
@@ -3025,7 +3544,7 @@ function DataGrid({
3025
3544
  },
3026
3545
  [enableColumnResize, columnWidths]
3027
3546
  );
3028
- useEffect7(() => {
3547
+ useEffect8(() => {
3029
3548
  if (!resizingColumnId)
3030
3549
  return;
3031
3550
  const handleResizeMove = (event) => {
@@ -3046,7 +3565,7 @@ function DataGrid({
3046
3565
  document.removeEventListener("mouseup", handleResizeEnd);
3047
3566
  };
3048
3567
  }, [resizingColumnId, resizeStartX, resizeStartWidth]);
3049
- const startVerticalResize = useCallback10(
3568
+ const startVerticalResize = useCallback11(
3050
3569
  (event) => {
3051
3570
  if (!enableVerticalResize)
3052
3571
  return;
@@ -3057,7 +3576,7 @@ function DataGrid({
3057
3576
  },
3058
3577
  [enableVerticalResize, gridHeight]
3059
3578
  );
3060
- useEffect7(() => {
3579
+ useEffect8(() => {
3061
3580
  if (!isResizingVertically)
3062
3581
  return;
3063
3582
  const handleVerticalResizeMove = (event) => {
@@ -3075,7 +3594,7 @@ function DataGrid({
3075
3594
  document.removeEventListener("mouseup", handleVerticalResizeEnd);
3076
3595
  };
3077
3596
  }, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
3078
- const handleExport = useCallback10(() => {
3597
+ const handleExport = useCallback11(() => {
3079
3598
  if (viewMode === "pivot") {
3080
3599
  if (!pivotResult)
3081
3600
  return;
@@ -3121,7 +3640,7 @@ function DataGrid({
3121
3640
  columnKeys,
3122
3641
  onExport
3123
3642
  ]);
3124
- const copySelectionToClipboard = useCallback10(() => {
3643
+ const copySelectionToClipboard = useCallback11(() => {
3125
3644
  if (!selectionBounds || !enableClipboard)
3126
3645
  return;
3127
3646
  const text = formatSelectionForClipboard(
@@ -3146,7 +3665,7 @@ function DataGrid({
3146
3665
  }
3147
3666
  );
3148
3667
  }, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
3149
- const handleMouseDown = useCallback10(
3668
+ const handleMouseDown = useCallback11(
3150
3669
  (rowIndex, colIndex, event) => {
3151
3670
  event.preventDefault();
3152
3671
  if (event.shiftKey && selectedCell) {
@@ -3170,7 +3689,7 @@ function DataGrid({
3170
3689
  },
3171
3690
  [selectedCell, rows, columnKeys, onCellClick]
3172
3691
  );
3173
- const handleMouseEnter = useCallback10(
3692
+ const handleMouseEnter = useCallback11(
3174
3693
  (rowIndex, colIndex) => {
3175
3694
  if (isSelecting) {
3176
3695
  setSelectionEnd({ row: rowIndex, col: colIndex });
@@ -3178,12 +3697,12 @@ function DataGrid({
3178
3697
  },
3179
3698
  [isSelecting]
3180
3699
  );
3181
- useEffect7(() => {
3700
+ useEffect8(() => {
3182
3701
  const handleMouseUp = () => setIsSelecting(false);
3183
3702
  document.addEventListener("mouseup", handleMouseUp);
3184
3703
  return () => document.removeEventListener("mouseup", handleMouseUp);
3185
3704
  }, []);
3186
- useEffect7(() => {
3705
+ useEffect8(() => {
3187
3706
  const handleKeydown = (event) => {
3188
3707
  if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
3189
3708
  event.preventDefault();
@@ -3201,7 +3720,7 @@ function DataGrid({
3201
3720
  document.addEventListener("keydown", handleKeydown);
3202
3721
  return () => document.removeEventListener("keydown", handleKeydown);
3203
3722
  }, [selectionBounds, copySelectionToClipboard]);
3204
- const openFilterDropdown = useCallback10(
3723
+ const openFilterDropdown = useCallback11(
3205
3724
  (columnId, event) => {
3206
3725
  event.stopPropagation();
3207
3726
  const target = event.currentTarget;
@@ -3230,22 +3749,22 @@ function DataGrid({
3230
3749
  },
3231
3750
  []
3232
3751
  );
3233
- const closeFilterDropdown = useCallback10(() => {
3752
+ const closeFilterDropdown = useCallback11(() => {
3234
3753
  setActiveFilterColumn(null);
3235
3754
  }, []);
3236
- const handleFilter = useCallback10(
3755
+ const handleFilter = useCallback11(
3237
3756
  (columnId, values) => {
3238
3757
  setColumnFilter(columnId, values);
3239
3758
  },
3240
3759
  [setColumnFilter]
3241
3760
  );
3242
- const handleRangeFilter = useCallback10(
3761
+ const handleRangeFilter = useCallback11(
3243
3762
  (columnId, range) => {
3244
3763
  setNumericRangeFilter(columnId, range);
3245
3764
  },
3246
3765
  [setNumericRangeFilter]
3247
3766
  );
3248
- const handleSort = useCallback10(
3767
+ const handleSort = useCallback11(
3249
3768
  (columnId, direction) => {
3250
3769
  if (direction === null) {
3251
3770
  const current = getSortDirection(columnId);
@@ -3269,7 +3788,7 @@ function DataGrid({
3269
3788
  },
3270
3789
  [getSortDirection, toggleSort]
3271
3790
  );
3272
- const isCellSelected = useCallback10(
3791
+ const isCellSelected = useCallback11(
3273
3792
  (rowIndex, colIndex) => {
3274
3793
  if (!selectionBounds) {
3275
3794
  return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
@@ -3311,30 +3830,30 @@ function DataGrid({
3311
3830
  }
3312
3831
  return String(value);
3313
3832
  };
3314
- const totalTableWidth = useMemo10(() => {
3833
+ const totalTableWidth = useMemo11(() => {
3315
3834
  return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
3316
3835
  }, [columnKeys, columnWidths]);
3317
3836
  const activeFilterCount = columnFilters.length;
3318
- return /* @__PURE__ */ jsxs6(
3837
+ return /* @__PURE__ */ jsxs7(
3319
3838
  "div",
3320
3839
  {
3321
3840
  className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
3322
3841
  style: { height: `${gridHeight}px` },
3323
3842
  children: [
3324
- showCopyToast && /* @__PURE__ */ jsxs6("div", { className: "vpg-toast", children: [
3325
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
3843
+ showCopyToast && /* @__PURE__ */ jsxs7("div", { className: "vpg-toast", children: [
3844
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
3326
3845
  copyToastMessage
3327
3846
  ] }),
3328
- /* @__PURE__ */ jsxs6("div", { className: "vpg-toolbar", children: [
3329
- /* @__PURE__ */ jsxs6("div", { className: "vpg-toolbar-left", children: [
3330
- showPivot && /* @__PURE__ */ jsxs6("div", { className: "vpg-view-toggle", children: [
3331
- /* @__PURE__ */ jsxs6(
3847
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-toolbar", children: [
3848
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-toolbar-left", children: [
3849
+ showPivot && /* @__PURE__ */ jsxs7("div", { className: "vpg-view-toggle", children: [
3850
+ /* @__PURE__ */ jsxs7(
3332
3851
  "button",
3333
3852
  {
3334
3853
  className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
3335
3854
  onClick: () => setViewMode("grid"),
3336
3855
  children: [
3337
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
3856
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3338
3857
  "path",
3339
3858
  {
3340
3859
  strokeLinecap: "round",
@@ -3347,13 +3866,13 @@ function DataGrid({
3347
3866
  ]
3348
3867
  }
3349
3868
  ),
3350
- /* @__PURE__ */ jsxs6(
3869
+ /* @__PURE__ */ jsxs7(
3351
3870
  "button",
3352
3871
  {
3353
3872
  className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
3354
3873
  onClick: () => setViewMode("pivot"),
3355
3874
  children: [
3356
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
3875
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3357
3876
  "path",
3358
3877
  {
3359
3878
  strokeLinecap: "round",
@@ -3365,16 +3884,37 @@ function DataGrid({
3365
3884
  "Pivot"
3366
3885
  ]
3367
3886
  }
3887
+ ),
3888
+ /* @__PURE__ */ jsxs7(
3889
+ "button",
3890
+ {
3891
+ className: `vpg-view-btn vpg-chart-btn ${viewMode === "chart" ? "active" : ""} ${!canUseCharts ? "vpg-pro-feature" : ""}`,
3892
+ title: canUseCharts ? "Chart Builder" : "Chart Builder (Pro feature)",
3893
+ onClick: () => canUseCharts && setViewMode("chart"),
3894
+ children: [
3895
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3896
+ "path",
3897
+ {
3898
+ strokeLinecap: "round",
3899
+ strokeLinejoin: "round",
3900
+ strokeWidth: 2,
3901
+ d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
3902
+ }
3903
+ ) }),
3904
+ "Chart",
3905
+ !canUseCharts && /* @__PURE__ */ jsx7("span", { className: "vpg-pro-badge", children: "Pro" })
3906
+ ]
3907
+ }
3368
3908
  )
3369
3909
  ] }),
3370
- viewMode === "grid" && /* @__PURE__ */ jsxs6(Fragment4, { children: [
3371
- enableSearch && /* @__PURE__ */ jsx6("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx6(
3910
+ viewMode === "grid" && /* @__PURE__ */ jsxs7(Fragment5, { children: [
3911
+ enableSearch && /* @__PURE__ */ jsx7("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx7(
3372
3912
  "button",
3373
3913
  {
3374
3914
  className: "vpg-icon-btn",
3375
3915
  title: "Search (Ctrl+F)",
3376
3916
  onClick: () => setShowSearchInput(true),
3377
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
3917
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3378
3918
  "path",
3379
3919
  {
3380
3920
  strokeLinecap: "round",
@@ -3384,15 +3924,15 @@ function DataGrid({
3384
3924
  }
3385
3925
  ) })
3386
3926
  }
3387
- ) : /* @__PURE__ */ jsxs6("div", { className: "vpg-search-box", children: [
3388
- /* @__PURE__ */ jsx6(
3927
+ ) : /* @__PURE__ */ jsxs7("div", { className: "vpg-search-box", children: [
3928
+ /* @__PURE__ */ jsx7(
3389
3929
  "svg",
3390
3930
  {
3391
3931
  className: "vpg-search-icon",
3392
3932
  fill: "none",
3393
3933
  stroke: "currentColor",
3394
3934
  viewBox: "0 0 24 24",
3395
- children: /* @__PURE__ */ jsx6(
3935
+ children: /* @__PURE__ */ jsx7(
3396
3936
  "path",
3397
3937
  {
3398
3938
  strokeLinecap: "round",
@@ -3403,7 +3943,7 @@ function DataGrid({
3403
3943
  )
3404
3944
  }
3405
3945
  ),
3406
- /* @__PURE__ */ jsx6(
3946
+ /* @__PURE__ */ jsx7(
3407
3947
  "input",
3408
3948
  {
3409
3949
  type: "text",
@@ -3420,14 +3960,14 @@ function DataGrid({
3420
3960
  autoFocus: true
3421
3961
  }
3422
3962
  ),
3423
- globalSearchTerm && /* @__PURE__ */ jsx6("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx6(
3963
+ globalSearchTerm && /* @__PURE__ */ jsx7("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx7(
3424
3964
  "svg",
3425
3965
  {
3426
3966
  className: "vpg-icon-xs",
3427
3967
  fill: "none",
3428
3968
  stroke: "currentColor",
3429
3969
  viewBox: "0 0 24 24",
3430
- children: /* @__PURE__ */ jsx6(
3970
+ children: /* @__PURE__ */ jsx7(
3431
3971
  "path",
3432
3972
  {
3433
3973
  strokeLinecap: "round",
@@ -3439,9 +3979,9 @@ function DataGrid({
3439
3979
  }
3440
3980
  ) })
3441
3981
  ] }) }),
3442
- /* @__PURE__ */ jsxs6("div", { className: "vpg-font-size-control", children: [
3443
- /* @__PURE__ */ jsx6("span", { className: "vpg-label", children: "Size:" }),
3444
- /* @__PURE__ */ jsx6("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx6(
3982
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-font-size-control", children: [
3983
+ /* @__PURE__ */ jsx7("span", { className: "vpg-label", children: "Size:" }),
3984
+ /* @__PURE__ */ jsx7("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx7(
3445
3985
  "button",
3446
3986
  {
3447
3987
  className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
@@ -3451,8 +3991,8 @@ function DataGrid({
3451
3991
  opt.value
3452
3992
  )) })
3453
3993
  ] }),
3454
- activeFilterCount > 0 && /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-info", children: [
3455
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6(
3994
+ activeFilterCount > 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-filter-info", children: [
3995
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7(
3456
3996
  "path",
3457
3997
  {
3458
3998
  fillRule: "evenodd",
@@ -3460,28 +4000,28 @@ function DataGrid({
3460
4000
  clipRule: "evenodd"
3461
4001
  }
3462
4002
  ) }),
3463
- /* @__PURE__ */ jsxs6("span", { children: [
4003
+ /* @__PURE__ */ jsxs7("span", { children: [
3464
4004
  activeFilterCount,
3465
4005
  " ",
3466
4006
  "filter",
3467
4007
  activeFilterCount > 1 ? "s" : ""
3468
4008
  ] })
3469
4009
  ] }),
3470
- globalSearchTerm && /* @__PURE__ */ jsx6("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs6("span", { children: [
4010
+ globalSearchTerm && /* @__PURE__ */ jsx7("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs7("span", { children: [
3471
4011
  totalSearchedRows,
3472
4012
  " ",
3473
4013
  "match",
3474
4014
  totalSearchedRows !== 1 ? "es" : ""
3475
4015
  ] }) })
3476
4016
  ] }),
3477
- viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs6(Fragment4, { children: [
3478
- /* @__PURE__ */ jsxs6(
4017
+ viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs7(Fragment5, { children: [
4018
+ /* @__PURE__ */ jsxs7(
3479
4019
  "button",
3480
4020
  {
3481
4021
  className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
3482
4022
  onClick: () => setShowPivotConfig(!showPivotConfig),
3483
4023
  children: [
3484
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4024
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3485
4025
  "path",
3486
4026
  {
3487
4027
  strokeLinecap: "round",
@@ -3496,8 +4036,8 @@ function DataGrid({
3496
4036
  ]
3497
4037
  }
3498
4038
  ),
3499
- pivotIsConfigured && /* @__PURE__ */ jsxs6("div", { className: "vpg-pivot-status", children: [
3500
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6(
4039
+ pivotIsConfigured && /* @__PURE__ */ jsxs7("div", { className: "vpg-pivot-status", children: [
4040
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7(
3501
4041
  "path",
3502
4042
  {
3503
4043
  fillRule: "evenodd",
@@ -3505,13 +4045,13 @@ function DataGrid({
3505
4045
  clipRule: "evenodd"
3506
4046
  }
3507
4047
  ) }),
3508
- /* @__PURE__ */ jsx6("span", { children: "Pivot configured" })
4048
+ /* @__PURE__ */ jsx7("span", { children: "Pivot configured" })
3509
4049
  ] })
3510
4050
  ] })
3511
4051
  ] }),
3512
- /* @__PURE__ */ jsxs6("div", { className: "vpg-toolbar-right", children: [
3513
- viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs6("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
3514
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4052
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-toolbar-right", children: [
4053
+ viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs7("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
4054
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3515
4055
  "path",
3516
4056
  {
3517
4057
  strokeLinecap: "round",
@@ -3522,13 +4062,13 @@ function DataGrid({
3522
4062
  ) }),
3523
4063
  "Clear Filters"
3524
4064
  ] }),
3525
- enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx6(
4065
+ enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx7(
3526
4066
  "button",
3527
4067
  {
3528
4068
  className: "vpg-icon-btn",
3529
4069
  title: "Copy selection (Ctrl+C)",
3530
4070
  onClick: copySelectionToClipboard,
3531
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4071
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3532
4072
  "path",
3533
4073
  {
3534
4074
  strokeLinecap: "round",
@@ -3539,14 +4079,14 @@ function DataGrid({
3539
4079
  ) })
3540
4080
  }
3541
4081
  ),
3542
- enableExport && viewMode === "grid" && /* @__PURE__ */ jsxs6(
4082
+ enableExport && viewMode === "grid" && /* @__PURE__ */ jsxs7(
3543
4083
  "button",
3544
4084
  {
3545
4085
  className: "vpg-export-btn",
3546
4086
  title: "Export to CSV",
3547
4087
  onClick: handleExport,
3548
4088
  children: [
3549
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4089
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3550
4090
  "path",
3551
4091
  {
3552
4092
  strokeLinecap: "round",
@@ -3559,7 +4099,7 @@ function DataGrid({
3559
4099
  ]
3560
4100
  }
3561
4101
  ),
3562
- enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ jsxs6(
4102
+ enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ jsxs7(
3563
4103
  "button",
3564
4104
  {
3565
4105
  className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
@@ -3567,7 +4107,7 @@ function DataGrid({
3567
4107
  title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
3568
4108
  onClick: () => isPro && handleExport(),
3569
4109
  children: [
3570
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4110
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3571
4111
  "path",
3572
4112
  {
3573
4113
  strokeLinecap: "round",
@@ -3583,13 +4123,13 @@ function DataGrid({
3583
4123
  )
3584
4124
  ] })
3585
4125
  ] }),
3586
- viewMode === "grid" && /* @__PURE__ */ jsxs6("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
3587
- loading && /* @__PURE__ */ jsxs6("div", { className: "vpg-loading", children: [
3588
- /* @__PURE__ */ jsx6("div", { className: "vpg-spinner" }),
3589
- /* @__PURE__ */ jsx6("span", { children: "Loading data..." })
4126
+ viewMode === "grid" && /* @__PURE__ */ jsxs7("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
4127
+ loading && /* @__PURE__ */ jsxs7("div", { className: "vpg-loading", children: [
4128
+ /* @__PURE__ */ jsx7("div", { className: "vpg-spinner" }),
4129
+ /* @__PURE__ */ jsx7("span", { children: "Loading data..." })
3590
4130
  ] }),
3591
- !loading && data.length === 0 && /* @__PURE__ */ jsxs6("div", { className: "vpg-empty", children: [
3592
- /* @__PURE__ */ jsx6("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4131
+ !loading && data.length === 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-empty", children: [
4132
+ /* @__PURE__ */ jsx7("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3593
4133
  "path",
3594
4134
  {
3595
4135
  strokeLinecap: "round",
@@ -3598,10 +4138,10 @@ function DataGrid({
3598
4138
  d: "M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
3599
4139
  }
3600
4140
  ) }) }),
3601
- /* @__PURE__ */ jsx6("span", { children: "No data available" })
4141
+ /* @__PURE__ */ jsx7("span", { children: "No data available" })
3602
4142
  ] }),
3603
- !loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs6("div", { className: "vpg-empty", children: [
3604
- /* @__PURE__ */ jsx6("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4143
+ !loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-empty", children: [
4144
+ /* @__PURE__ */ jsx7("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3605
4145
  "path",
3606
4146
  {
3607
4147
  strokeLinecap: "round",
@@ -3610,11 +4150,11 @@ function DataGrid({
3610
4150
  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"
3611
4151
  }
3612
4152
  ) }) }),
3613
- /* @__PURE__ */ jsx6("span", { children: "No matching records" }),
3614
- /* @__PURE__ */ jsx6("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
4153
+ /* @__PURE__ */ jsx7("span", { children: "No matching records" }),
4154
+ /* @__PURE__ */ jsx7("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
3615
4155
  ] }),
3616
- !loading && filteredRowCount > 0 && /* @__PURE__ */ jsx6("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs6("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
3617
- /* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsx6("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ jsxs6(
4156
+ !loading && filteredRowCount > 0 && /* @__PURE__ */ jsx7("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs7("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
4157
+ /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsx7("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ jsxs7(
3618
4158
  "th",
3619
4159
  {
3620
4160
  className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
@@ -3629,16 +4169,16 @@ function DataGrid({
3629
4169
  }
3630
4170
  },
3631
4171
  children: [
3632
- /* @__PURE__ */ jsxs6("div", { className: "vpg-header-content", children: [
3633
- /* @__PURE__ */ jsx6("span", { className: "vpg-header-text", children: colId }),
3634
- /* @__PURE__ */ jsxs6("div", { className: "vpg-header-icons", children: [
3635
- getSortDirection(colId) && /* @__PURE__ */ jsx6("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx6(
4172
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-header-content", children: [
4173
+ /* @__PURE__ */ jsx7("span", { className: "vpg-header-text", children: colId }),
4174
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-header-icons", children: [
4175
+ getSortDirection(colId) && /* @__PURE__ */ jsx7("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx7(
3636
4176
  "svg",
3637
4177
  {
3638
4178
  className: "vpg-icon-sm",
3639
4179
  fill: "currentColor",
3640
4180
  viewBox: "0 0 20 20",
3641
- children: /* @__PURE__ */ jsx6(
4181
+ children: /* @__PURE__ */ jsx7(
3642
4182
  "path",
3643
4183
  {
3644
4184
  fillRule: "evenodd",
@@ -3647,13 +4187,13 @@ function DataGrid({
3647
4187
  }
3648
4188
  )
3649
4189
  }
3650
- ) : /* @__PURE__ */ jsx6(
4190
+ ) : /* @__PURE__ */ jsx7(
3651
4191
  "svg",
3652
4192
  {
3653
4193
  className: "vpg-icon-sm",
3654
4194
  fill: "currentColor",
3655
4195
  viewBox: "0 0 20 20",
3656
- children: /* @__PURE__ */ jsx6(
4196
+ children: /* @__PURE__ */ jsx7(
3657
4197
  "path",
3658
4198
  {
3659
4199
  fillRule: "evenodd",
@@ -3663,13 +4203,13 @@ function DataGrid({
3663
4203
  )
3664
4204
  }
3665
4205
  ) }),
3666
- hasActiveFilter(colId) && /* @__PURE__ */ jsx6("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx6(
4206
+ hasActiveFilter(colId) && /* @__PURE__ */ jsx7("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx7(
3667
4207
  "svg",
3668
4208
  {
3669
4209
  className: "vpg-icon-xs",
3670
4210
  fill: "currentColor",
3671
4211
  viewBox: "0 0 20 20",
3672
- children: /* @__PURE__ */ jsx6(
4212
+ children: /* @__PURE__ */ jsx7(
3673
4213
  "path",
3674
4214
  {
3675
4215
  fillRule: "evenodd",
@@ -3679,14 +4219,14 @@ function DataGrid({
3679
4219
  )
3680
4220
  }
3681
4221
  ) }),
3682
- /* @__PURE__ */ jsx6("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx6(
4222
+ /* @__PURE__ */ jsx7("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx7(
3683
4223
  "svg",
3684
4224
  {
3685
4225
  className: "vpg-icon-sm",
3686
4226
  fill: "none",
3687
4227
  stroke: "currentColor",
3688
4228
  viewBox: "0 0 24 24",
3689
- children: /* @__PURE__ */ jsx6(
4229
+ children: /* @__PURE__ */ jsx7(
3690
4230
  "path",
3691
4231
  {
3692
4232
  strokeLinecap: "round",
@@ -3699,7 +4239,7 @@ function DataGrid({
3699
4239
  ) })
3700
4240
  ] })
3701
4241
  ] }),
3702
- enableColumnResize && /* @__PURE__ */ jsx6(
4242
+ enableColumnResize && /* @__PURE__ */ jsx7(
3703
4243
  "div",
3704
4244
  {
3705
4245
  className: "vpg-resize-handle",
@@ -3710,7 +4250,7 @@ function DataGrid({
3710
4250
  },
3711
4251
  colId
3712
4252
  )) }) }),
3713
- /* @__PURE__ */ jsx6("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx6("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx6(
4253
+ /* @__PURE__ */ jsx7("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx7("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx7(
3714
4254
  "td",
3715
4255
  {
3716
4256
  className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
@@ -3728,8 +4268,8 @@ function DataGrid({
3728
4268
  )) }, row.id)) })
3729
4269
  ] }) })
3730
4270
  ] }),
3731
- viewMode === "pivot" && /* @__PURE__ */ jsxs6("div", { className: "vpg-pivot-container", children: [
3732
- showPivotConfig && canUsePivot && /* @__PURE__ */ jsx6("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx6(
4271
+ viewMode === "pivot" && /* @__PURE__ */ jsxs7("div", { className: "vpg-pivot-container", children: [
4272
+ showPivotConfig && canUsePivot && /* @__PURE__ */ jsx7("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx7(
3733
4273
  PivotConfig,
3734
4274
  {
3735
4275
  availableFields: pivotAvailableFields,
@@ -3757,7 +4297,7 @@ function DataGrid({
3757
4297
  onUpdateCalculatedField: addCalculatedField
3758
4298
  }
3759
4299
  ) }),
3760
- /* @__PURE__ */ jsx6("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx6(
4300
+ /* @__PURE__ */ jsx7("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx7(
3761
4301
  PivotSkeleton,
3762
4302
  {
3763
4303
  rowFields: pivotRowFields,
@@ -3783,47 +4323,78 @@ function DataGrid({
3783
4323
  }
3784
4324
  ) })
3785
4325
  ] }),
3786
- /* @__PURE__ */ jsxs6("div", { className: "vpg-footer", children: [
3787
- /* @__PURE__ */ jsx6("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
3788
- /* @__PURE__ */ jsxs6("span", { children: [
4326
+ viewMode === "chart" && /* @__PURE__ */ jsxs7("div", { className: "vpg-chart-view", children: [
4327
+ activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-chart-filter-bar", children: [
4328
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7("path", { fillRule: "evenodd", d: "M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z", clipRule: "evenodd" }) }),
4329
+ /* @__PURE__ */ jsxs7("span", { children: [
4330
+ "Chart showing",
4331
+ filteredRowCount.toLocaleString(),
4332
+ " ",
4333
+ "of",
4334
+ totalRowCount.toLocaleString(),
4335
+ " ",
4336
+ "records"
4337
+ ] }),
4338
+ /* @__PURE__ */ jsx7("button", { className: "vpg-chart-clear-filters", onClick: clearAllFilters, children: "Clear filters" })
4339
+ ] }),
4340
+ /* @__PURE__ */ jsx7(
4341
+ ChartBuilder,
4342
+ {
4343
+ data: filteredDataForPivot,
4344
+ theme: currentTheme,
4345
+ onConfigChange: handleChartConfigChange
4346
+ }
4347
+ )
4348
+ ] }),
4349
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-footer", children: [
4350
+ /* @__PURE__ */ jsx7("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
4351
+ /* @__PURE__ */ jsxs7("span", { children: [
3789
4352
  ((currentPage - 1) * pageSize + 1).toLocaleString(),
3790
4353
  "-",
3791
4354
  Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
3792
4355
  ] }),
3793
- /* @__PURE__ */ jsx6("span", { className: "vpg-separator", children: "of" }),
3794
- /* @__PURE__ */ jsx6("span", { children: totalSearchedRows.toLocaleString() }),
3795
- totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs6("span", { className: "vpg-filtered-note", children: [
4356
+ /* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "of" }),
4357
+ /* @__PURE__ */ jsx7("span", { children: totalSearchedRows.toLocaleString() }),
4358
+ totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs7("span", { className: "vpg-filtered-note", children: [
3796
4359
  "(",
3797
4360
  totalRowCount.toLocaleString(),
3798
4361
  " ",
3799
4362
  "total)"
3800
4363
  ] })
3801
- ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs6("span", { children: [
4364
+ ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs7("span", { children: [
3802
4365
  totalRowCount.toLocaleString(),
3803
4366
  " ",
3804
4367
  "records"
3805
- ] }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
3806
- /* @__PURE__ */ jsx6("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
3807
- /* @__PURE__ */ jsx6("span", { className: "vpg-separator", children: "of" }),
3808
- /* @__PURE__ */ jsx6("span", { children: totalRowCount.toLocaleString() }),
3809
- /* @__PURE__ */ jsx6("span", { className: "vpg-separator", children: "records" })
3810
- ] }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
3811
- /* @__PURE__ */ jsx6("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
3812
- /* @__PURE__ */ jsx6("span", { className: "vpg-separator", children: "\u2022" }),
3813
- /* @__PURE__ */ jsxs6("span", { children: [
4368
+ ] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
4369
+ /* @__PURE__ */ jsx7("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
4370
+ /* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "of" }),
4371
+ /* @__PURE__ */ jsx7("span", { children: totalRowCount.toLocaleString() }),
4372
+ /* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "records" })
4373
+ ] }) : viewMode === "pivot" ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
4374
+ /* @__PURE__ */ jsx7("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
4375
+ /* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "\u2022" }),
4376
+ /* @__PURE__ */ jsxs7("span", { children: [
3814
4377
  totalRowCount.toLocaleString(),
3815
4378
  " ",
3816
4379
  "source records"
3817
4380
  ] })
4381
+ ] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
4382
+ /* @__PURE__ */ jsx7("span", { className: "vpg-chart-label", children: "Chart Builder" }),
4383
+ /* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "\u2022" }),
4384
+ /* @__PURE__ */ jsxs7("span", { children: [
4385
+ totalRowCount.toLocaleString(),
4386
+ " ",
4387
+ "records"
4388
+ ] })
3818
4389
  ] }) }),
3819
- enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs6("div", { className: "vpg-pagination", children: [
3820
- /* @__PURE__ */ jsx6(
4390
+ enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs7("div", { className: "vpg-pagination", children: [
4391
+ /* @__PURE__ */ jsx7(
3821
4392
  "button",
3822
4393
  {
3823
4394
  className: "vpg-page-btn",
3824
4395
  disabled: currentPage === 1,
3825
4396
  onClick: () => setCurrentPage(1),
3826
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4397
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3827
4398
  "path",
3828
4399
  {
3829
4400
  strokeLinecap: "round",
@@ -3834,13 +4405,13 @@ function DataGrid({
3834
4405
  ) })
3835
4406
  }
3836
4407
  ),
3837
- /* @__PURE__ */ jsx6(
4408
+ /* @__PURE__ */ jsx7(
3838
4409
  "button",
3839
4410
  {
3840
4411
  className: "vpg-page-btn",
3841
4412
  disabled: currentPage === 1,
3842
4413
  onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
3843
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4414
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3844
4415
  "path",
3845
4416
  {
3846
4417
  strokeLinecap: "round",
@@ -3851,7 +4422,7 @@ function DataGrid({
3851
4422
  ) })
3852
4423
  }
3853
4424
  ),
3854
- /* @__PURE__ */ jsxs6("span", { className: "vpg-page-info", children: [
4425
+ /* @__PURE__ */ jsxs7("span", { className: "vpg-page-info", children: [
3855
4426
  "Page",
3856
4427
  " ",
3857
4428
  currentPage,
@@ -3860,13 +4431,13 @@ function DataGrid({
3860
4431
  " ",
3861
4432
  totalPages
3862
4433
  ] }),
3863
- /* @__PURE__ */ jsx6(
4434
+ /* @__PURE__ */ jsx7(
3864
4435
  "button",
3865
4436
  {
3866
4437
  className: "vpg-page-btn",
3867
4438
  disabled: currentPage === totalPages,
3868
4439
  onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
3869
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4440
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3870
4441
  "path",
3871
4442
  {
3872
4443
  strokeLinecap: "round",
@@ -3877,13 +4448,13 @@ function DataGrid({
3877
4448
  ) })
3878
4449
  }
3879
4450
  ),
3880
- /* @__PURE__ */ jsx6(
4451
+ /* @__PURE__ */ jsx7(
3881
4452
  "button",
3882
4453
  {
3883
4454
  className: "vpg-page-btn",
3884
4455
  disabled: currentPage === totalPages,
3885
4456
  onClick: () => setCurrentPage(totalPages),
3886
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4457
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3887
4458
  "path",
3888
4459
  {
3889
4460
  strokeLinecap: "round",
@@ -3895,45 +4466,45 @@ function DataGrid({
3895
4466
  }
3896
4467
  )
3897
4468
  ] }),
3898
- viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs6("div", { className: "vpg-selection-stats", children: [
3899
- /* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
3900
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Count:" }),
3901
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: selectionStats.count })
4469
+ viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs7("div", { className: "vpg-selection-stats", children: [
4470
+ /* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
4471
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Count:" }),
4472
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: selectionStats.count })
3902
4473
  ] }),
3903
- selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs6(Fragment4, { children: [
3904
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-divider", children: "|" }),
3905
- /* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
3906
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Sum:" }),
3907
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
4474
+ selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs7(Fragment5, { children: [
4475
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-divider", children: "|" }),
4476
+ /* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
4477
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Sum:" }),
4478
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
3908
4479
  ] }),
3909
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-divider", children: "|" }),
3910
- /* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
3911
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Avg:" }),
3912
- /* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
4480
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-divider", children: "|" }),
4481
+ /* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
4482
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Avg:" }),
4483
+ /* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
3913
4484
  ] })
3914
4485
  ] })
3915
4486
  ] }),
3916
- /* @__PURE__ */ jsx6("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs6("div", { className: "vpg-demo-banner", children: [
3917
- /* @__PURE__ */ jsx6("span", { className: "vpg-demo-badge", children: "DEMO" }),
3918
- /* @__PURE__ */ jsx6("span", { children: "Pro features enabled" }),
3919
- /* @__PURE__ */ jsx6("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
3920
- ] }) : showWatermark ? /* @__PURE__ */ jsx6("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs6("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
3921
- /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3922
- /* @__PURE__ */ jsx6("rect", { x: "3", y: "3", width: "7", height: "7" }),
3923
- /* @__PURE__ */ jsx6("rect", { x: "14", y: "3", width: "7", height: "7" }),
3924
- /* @__PURE__ */ jsx6("rect", { x: "14", y: "14", width: "7", height: "7" }),
3925
- /* @__PURE__ */ jsx6("rect", { x: "3", y: "14", width: "7", height: "7" })
4487
+ /* @__PURE__ */ jsx7("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs7("div", { className: "vpg-demo-banner", children: [
4488
+ /* @__PURE__ */ jsx7("span", { className: "vpg-demo-badge", children: "DEMO" }),
4489
+ /* @__PURE__ */ jsx7("span", { children: "Pro features enabled" }),
4490
+ /* @__PURE__ */ jsx7("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
4491
+ ] }) : showWatermark ? /* @__PURE__ */ jsx7("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs7("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
4492
+ /* @__PURE__ */ jsxs7("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
4493
+ /* @__PURE__ */ jsx7("rect", { x: "3", y: "3", width: "7", height: "7" }),
4494
+ /* @__PURE__ */ jsx7("rect", { x: "14", y: "3", width: "7", height: "7" }),
4495
+ /* @__PURE__ */ jsx7("rect", { x: "14", y: "14", width: "7", height: "7" }),
4496
+ /* @__PURE__ */ jsx7("rect", { x: "3", y: "14", width: "7", height: "7" })
3926
4497
  ] }),
3927
4498
  "Powered by TinyPivot"
3928
4499
  ] }) }) : null })
3929
4500
  ] }),
3930
- enableVerticalResize && /* @__PURE__ */ jsx6("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs6("div", { className: "vpg-resize-grip", children: [
3931
- /* @__PURE__ */ jsx6("span", {}),
3932
- /* @__PURE__ */ jsx6("span", {}),
3933
- /* @__PURE__ */ jsx6("span", {})
4501
+ enableVerticalResize && /* @__PURE__ */ jsx7("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs7("div", { className: "vpg-resize-grip", children: [
4502
+ /* @__PURE__ */ jsx7("span", {}),
4503
+ /* @__PURE__ */ jsx7("span", {}),
4504
+ /* @__PURE__ */ jsx7("span", {})
3934
4505
  ] }) }),
3935
4506
  activeFilterColumn && typeof document !== "undefined" && createPortal2(
3936
- /* @__PURE__ */ jsx6(
4507
+ /* @__PURE__ */ jsx7(
3937
4508
  "div",
3938
4509
  {
3939
4510
  className: "vpg-filter-portal",
@@ -3944,7 +4515,7 @@ function DataGrid({
3944
4515
  maxHeight: `${filterDropdownPosition.maxHeight}px`,
3945
4516
  zIndex: 9999
3946
4517
  },
3947
- children: /* @__PURE__ */ jsx6(
4518
+ children: /* @__PURE__ */ jsx7(
3948
4519
  ColumnFilter,
3949
4520
  {
3950
4521
  columnId: activeFilterColumn,