@smallwebco/tinypivot-react 1.0.24 → 1.0.25

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
@@ -1,6 +1,6 @@
1
1
  // src/components/DataGrid.tsx
2
- import { useState as useState8, useMemo as useMemo8, useCallback as useCallback8, useEffect as useEffect4, useRef as useRef2 } from "react";
3
- import { createPortal } from "react-dom";
2
+ import { useState as useState9, useMemo as useMemo9, useCallback as useCallback9, useEffect as useEffect5, useRef as useRef2 } from "react";
3
+ import { createPortal as createPortal2 } from "react-dom";
4
4
 
5
5
  // src/hooks/useExcelGrid.ts
6
6
  import { useState, useMemo, useCallback, useEffect } from "react";
@@ -189,7 +189,9 @@ import {
189
189
  savePivotConfig,
190
190
  loadPivotConfig,
191
191
  isConfigValidForFields,
192
- getAggregationLabel
192
+ getAggregationLabel,
193
+ loadCalculatedFields,
194
+ saveCalculatedFields
193
195
  } from "@smallwebco/tinypivot-core";
194
196
 
195
197
  // src/hooks/useLicense.ts
@@ -290,6 +292,7 @@ function usePivotTable(data) {
290
292
  const [valueFields, setValueFields] = useState3([]);
291
293
  const [showRowTotals, setShowRowTotals] = useState3(true);
292
294
  const [showColumnTotals, setShowColumnTotals] = useState3(true);
295
+ const [calculatedFields, setCalculatedFields] = useState3(() => loadCalculatedFields());
293
296
  const [currentStorageKey, setCurrentStorageKey] = useState3(null);
294
297
  const availableFields = useMemo3(() => {
295
298
  return computeAvailableFields(data);
@@ -314,9 +317,10 @@ function usePivotTable(data) {
314
317
  columnFields,
315
318
  valueFields,
316
319
  showRowTotals,
317
- showColumnTotals
320
+ showColumnTotals,
321
+ calculatedFields
318
322
  });
319
- }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
323
+ }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
320
324
  useEffect2(() => {
321
325
  if (data.length === 0) return;
322
326
  const newKeys = Object.keys(data[0]);
@@ -330,6 +334,9 @@ function usePivotTable(data) {
330
334
  setValueFields(savedConfig.valueFields);
331
335
  setShowRowTotals(savedConfig.showRowTotals);
332
336
  setShowColumnTotals(savedConfig.showColumnTotals);
337
+ if (savedConfig.calculatedFields) {
338
+ setCalculatedFields(savedConfig.calculatedFields);
339
+ }
333
340
  } else {
334
341
  const currentConfig = {
335
342
  rowFields,
@@ -353,10 +360,11 @@ function usePivotTable(data) {
353
360
  columnFields,
354
361
  valueFields,
355
362
  showRowTotals,
356
- showColumnTotals
363
+ showColumnTotals,
364
+ calculatedFields
357
365
  };
358
366
  savePivotConfig(currentStorageKey, config);
359
- }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
367
+ }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
360
368
  const addRowField = useCallback3(
361
369
  (field) => {
362
370
  if (!requirePro("Pivot Table - Row Fields")) return;
@@ -435,6 +443,27 @@ function usePivotTable(data) {
435
443
  setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
436
444
  }
437
445
  }, [availableFields, requirePro]);
446
+ const addCalculatedField = useCallback3((field) => {
447
+ setCalculatedFields((prev) => {
448
+ const existing = prev.findIndex((f) => f.id === field.id);
449
+ let updated;
450
+ if (existing >= 0) {
451
+ updated = [...prev.slice(0, existing), field, ...prev.slice(existing + 1)];
452
+ } else {
453
+ updated = [...prev, field];
454
+ }
455
+ saveCalculatedFields(updated);
456
+ return updated;
457
+ });
458
+ }, []);
459
+ const removeCalculatedField = useCallback3((id) => {
460
+ setCalculatedFields((prev) => {
461
+ const updated = prev.filter((f) => f.id !== id);
462
+ saveCalculatedFields(updated);
463
+ return updated;
464
+ });
465
+ setValueFields((prev) => prev.filter((v) => v.field !== `calc:${id}`));
466
+ }, []);
438
467
  return {
439
468
  // State
440
469
  rowFields,
@@ -442,6 +471,7 @@ function usePivotTable(data) {
442
471
  valueFields,
443
472
  showRowTotals,
444
473
  showColumnTotals,
474
+ calculatedFields,
445
475
  // Computed
446
476
  availableFields,
447
477
  unassignedFields,
@@ -460,7 +490,9 @@ function usePivotTable(data) {
460
490
  setShowColumnTotals,
461
491
  autoSuggestConfig,
462
492
  setRowFields,
463
- setColumnFields
493
+ setColumnFields,
494
+ addCalculatedField,
495
+ removeCalculatedField
464
496
  };
465
497
  }
466
498
 
@@ -937,10 +969,197 @@ function ColumnFilter({
937
969
  }
938
970
 
939
971
  // src/components/PivotConfig.tsx
940
- import { useState as useState6, useMemo as useMemo6, useCallback as useCallback6 } from "react";
972
+ import { useState as useState7, useMemo as useMemo7, useCallback as useCallback7 } from "react";
941
973
  import { AGGREGATION_OPTIONS, getAggregationSymbol } from "@smallwebco/tinypivot-core";
974
+
975
+ // src/components/CalculatedFieldModal.tsx
976
+ import { useState as useState6, useEffect as useEffect4, useMemo as useMemo6, useCallback as useCallback6 } from "react";
977
+ import { createPortal } from "react-dom";
978
+ import { validateSimpleFormula } from "@smallwebco/tinypivot-core";
942
979
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
943
- function getFieldIcon(type) {
980
+ function CalculatedFieldModal({
981
+ show,
982
+ availableFields,
983
+ existingField,
984
+ onClose,
985
+ onSave
986
+ }) {
987
+ const [name, setName] = useState6("");
988
+ const [formula, setFormula] = useState6("");
989
+ const [formatAs, setFormatAs] = useState6("number");
990
+ const [decimals, setDecimals] = useState6(2);
991
+ const [error, setError] = useState6(null);
992
+ useEffect4(() => {
993
+ if (show) {
994
+ if (existingField) {
995
+ setName(existingField.name);
996
+ setFormula(existingField.formula);
997
+ setFormatAs(existingField.formatAs || "number");
998
+ setDecimals(existingField.decimals ?? 2);
999
+ } else {
1000
+ setName("");
1001
+ setFormula("");
1002
+ setFormatAs("number");
1003
+ setDecimals(2);
1004
+ }
1005
+ setError(null);
1006
+ }
1007
+ }, [show, existingField]);
1008
+ const validationError = useMemo6(() => {
1009
+ if (!formula.trim()) return null;
1010
+ return validateSimpleFormula(formula, availableFields);
1011
+ }, [formula, availableFields]);
1012
+ const insertField = useCallback6((field) => {
1013
+ setFormula((prev) => {
1014
+ if (prev.trim() && !prev.endsWith(" ")) {
1015
+ return prev + " " + field;
1016
+ }
1017
+ return prev + field;
1018
+ });
1019
+ }, []);
1020
+ const insertOperator = useCallback6((op) => {
1021
+ setFormula((prev) => {
1022
+ if (prev.trim() && !prev.endsWith(" ")) {
1023
+ return prev + " " + op + " ";
1024
+ }
1025
+ return prev + op + " ";
1026
+ });
1027
+ }, []);
1028
+ const handleSave = useCallback6(() => {
1029
+ if (!name.trim()) {
1030
+ setError("Name is required");
1031
+ return;
1032
+ }
1033
+ const validationResult = validateSimpleFormula(formula, availableFields);
1034
+ if (validationResult) {
1035
+ setError(validationResult);
1036
+ return;
1037
+ }
1038
+ const field = {
1039
+ id: existingField?.id || `calc_${Date.now()}`,
1040
+ name: name.trim(),
1041
+ formula: formula.trim(),
1042
+ formatAs,
1043
+ decimals
1044
+ };
1045
+ onSave(field);
1046
+ onClose();
1047
+ }, [name, formula, formatAs, decimals, existingField, availableFields, onSave, onClose]);
1048
+ const handleOverlayClick = useCallback6((e) => {
1049
+ if (e.target === e.currentTarget) {
1050
+ onClose();
1051
+ }
1052
+ }, [onClose]);
1053
+ if (!show) return null;
1054
+ const modalContent = /* @__PURE__ */ jsx2("div", { className: "vpg-modal-overlay", onClick: handleOverlayClick, children: /* @__PURE__ */ jsxs2("div", { className: "vpg-modal", children: [
1055
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-modal-header", children: [
1056
+ /* @__PURE__ */ jsxs2("h3", { children: [
1057
+ existingField ? "Edit" : "Create",
1058
+ " Calculated Field"
1059
+ ] }),
1060
+ /* @__PURE__ */ jsx2("button", { className: "vpg-modal-close", onClick: onClose, children: "\xD7" })
1061
+ ] }),
1062
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-modal-body", children: [
1063
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-group", children: [
1064
+ /* @__PURE__ */ jsx2("label", { className: "vpg-label", children: "Name" }),
1065
+ /* @__PURE__ */ jsx2(
1066
+ "input",
1067
+ {
1068
+ type: "text",
1069
+ className: "vpg-input",
1070
+ placeholder: "e.g., Profit Margin %",
1071
+ value: name,
1072
+ onChange: (e) => setName(e.target.value)
1073
+ }
1074
+ )
1075
+ ] }),
1076
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-group", children: [
1077
+ /* @__PURE__ */ jsx2("label", { className: "vpg-label", children: "Formula" }),
1078
+ /* @__PURE__ */ jsx2(
1079
+ "textarea",
1080
+ {
1081
+ className: "vpg-textarea",
1082
+ placeholder: "e.g., revenue / units",
1083
+ rows: 2,
1084
+ value: formula,
1085
+ onChange: (e) => setFormula(e.target.value)
1086
+ }
1087
+ ),
1088
+ /* @__PURE__ */ jsx2("div", { className: "vpg-formula-hint", children: "Use field names with math operators: + - * / ( )" }),
1089
+ validationError && /* @__PURE__ */ jsx2("div", { className: "vpg-error", children: validationError })
1090
+ ] }),
1091
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-group", children: [
1092
+ /* @__PURE__ */ jsx2("label", { className: "vpg-label-small", children: "Operators" }),
1093
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-button-group", children: [
1094
+ /* @__PURE__ */ jsx2("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("+"), children: "+" }),
1095
+ /* @__PURE__ */ jsx2("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("-"), children: "\u2212" }),
1096
+ /* @__PURE__ */ jsx2("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("*"), children: "\xD7" }),
1097
+ /* @__PURE__ */ jsx2("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("/"), children: "\xF7" }),
1098
+ /* @__PURE__ */ jsx2("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("("), children: "(" }),
1099
+ /* @__PURE__ */ jsx2("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator(")"), children: ")" })
1100
+ ] })
1101
+ ] }),
1102
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-group", children: [
1103
+ /* @__PURE__ */ jsx2("label", { className: "vpg-label-small", children: "Insert Field" }),
1104
+ availableFields.length > 0 ? /* @__PURE__ */ jsx2("div", { className: "vpg-button-group vpg-field-buttons", children: availableFields.map((field) => /* @__PURE__ */ jsx2(
1105
+ "button",
1106
+ {
1107
+ className: "vpg-insert-btn vpg-field-btn",
1108
+ onClick: () => insertField(field),
1109
+ children: field
1110
+ },
1111
+ field
1112
+ )) }) : /* @__PURE__ */ jsx2("div", { className: "vpg-no-fields", children: "No numeric fields available" })
1113
+ ] }),
1114
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-row", children: [
1115
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-group vpg-form-group-half", children: [
1116
+ /* @__PURE__ */ jsx2("label", { className: "vpg-label", children: "Format As" }),
1117
+ /* @__PURE__ */ jsxs2(
1118
+ "select",
1119
+ {
1120
+ className: "vpg-select",
1121
+ value: formatAs,
1122
+ onChange: (e) => setFormatAs(e.target.value),
1123
+ children: [
1124
+ /* @__PURE__ */ jsx2("option", { value: "number", children: "Number" }),
1125
+ /* @__PURE__ */ jsx2("option", { value: "percent", children: "Percentage" }),
1126
+ /* @__PURE__ */ jsx2("option", { value: "currency", children: "Currency ($)" })
1127
+ ]
1128
+ }
1129
+ )
1130
+ ] }),
1131
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-form-group vpg-form-group-half", children: [
1132
+ /* @__PURE__ */ jsx2("label", { className: "vpg-label", children: "Decimals" }),
1133
+ /* @__PURE__ */ jsx2(
1134
+ "input",
1135
+ {
1136
+ type: "number",
1137
+ className: "vpg-input",
1138
+ min: 0,
1139
+ max: 6,
1140
+ value: decimals,
1141
+ onChange: (e) => setDecimals(Number(e.target.value))
1142
+ }
1143
+ )
1144
+ ] })
1145
+ ] }),
1146
+ error && /* @__PURE__ */ jsx2("div", { className: "vpg-error vpg-error-box", children: error })
1147
+ ] }),
1148
+ /* @__PURE__ */ jsxs2("div", { className: "vpg-modal-footer", children: [
1149
+ /* @__PURE__ */ jsx2("button", { className: "vpg-btn vpg-btn-secondary", onClick: onClose, children: "Cancel" }),
1150
+ /* @__PURE__ */ jsxs2("button", { className: "vpg-btn vpg-btn-primary", onClick: handleSave, children: [
1151
+ existingField ? "Update" : "Add",
1152
+ " Field"
1153
+ ] })
1154
+ ] })
1155
+ ] }) });
1156
+ return createPortal(modalContent, document.body);
1157
+ }
1158
+
1159
+ // src/components/PivotConfig.tsx
1160
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1161
+ function getFieldIcon(type, isCalculated) {
1162
+ if (isCalculated) return "\u0192";
944
1163
  switch (type) {
945
1164
  case "number":
946
1165
  return "#";
@@ -958,7 +1177,9 @@ function PivotConfig({
958
1177
  columnFields,
959
1178
  valueFields,
960
1179
  showRowTotals,
1180
+ calculatedFields,
961
1181
  onShowRowTotalsChange,
1182
+ onShowColumnTotalsChange,
962
1183
  onClearConfig,
963
1184
  onAutoSuggest,
964
1185
  onDragStart,
@@ -968,35 +1189,71 @@ function PivotConfig({
968
1189
  onRemoveColumnField,
969
1190
  onRemoveValueField,
970
1191
  onAddRowField,
971
- onAddColumnField
1192
+ onAddColumnField,
1193
+ onAddCalculatedField,
1194
+ onRemoveCalculatedField,
1195
+ onUpdateCalculatedField
972
1196
  }) {
973
1197
  const { showWatermark } = useLicense();
974
- const [fieldSearch, setFieldSearch] = useState6("");
975
- const assignedFields = useMemo6(() => {
1198
+ const [fieldSearch, setFieldSearch] = useState7("");
1199
+ const [showCalcModal, setShowCalcModal] = useState7(false);
1200
+ const [editingCalcField, setEditingCalcField] = useState7(null);
1201
+ const numericFieldNames = useMemo7(
1202
+ () => availableFields.filter((f) => f.isNumeric).map((f) => f.field),
1203
+ [availableFields]
1204
+ );
1205
+ const calculatedFieldsAsStats = useMemo7(() => {
1206
+ if (!calculatedFields) return [];
1207
+ return calculatedFields.map((calc) => ({
1208
+ field: `calc:${calc.id}`,
1209
+ type: "number",
1210
+ uniqueCount: 0,
1211
+ isNumeric: true,
1212
+ isCalculated: true,
1213
+ calcId: calc.id,
1214
+ calcName: calc.name,
1215
+ calcFormula: calc.formula
1216
+ }));
1217
+ }, [calculatedFields]);
1218
+ const allAvailableFields = useMemo7(() => [
1219
+ ...availableFields.map((f) => ({ ...f, isCalculated: false })),
1220
+ ...calculatedFieldsAsStats
1221
+ ], [availableFields, calculatedFieldsAsStats]);
1222
+ const assignedFields = useMemo7(() => {
976
1223
  const rowSet = new Set(rowFields);
977
1224
  const colSet = new Set(columnFields);
978
1225
  const valueMap = new Map(valueFields.map((v) => [v.field, v]));
979
- return availableFields.filter((f) => rowSet.has(f.field) || colSet.has(f.field) || valueMap.has(f.field)).map((f) => ({
1226
+ return allAvailableFields.filter((f) => rowSet.has(f.field) || colSet.has(f.field) || valueMap.has(f.field)).map((f) => ({
980
1227
  ...f,
981
1228
  assignedTo: rowSet.has(f.field) ? "row" : colSet.has(f.field) ? "column" : "value",
982
1229
  valueConfig: valueMap.get(f.field)
983
1230
  }));
984
- }, [availableFields, rowFields, columnFields, valueFields]);
985
- const unassignedFields = useMemo6(() => {
1231
+ }, [allAvailableFields, rowFields, columnFields, valueFields]);
1232
+ const unassignedFields = useMemo7(() => {
986
1233
  const rowSet = new Set(rowFields);
987
1234
  const colSet = new Set(columnFields);
988
1235
  const valSet = new Set(valueFields.map((v) => v.field));
989
- return availableFields.filter(
1236
+ return allAvailableFields.filter(
990
1237
  (f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
991
1238
  );
992
- }, [availableFields, rowFields, columnFields, valueFields]);
993
- const filteredUnassignedFields = useMemo6(() => {
1239
+ }, [allAvailableFields, rowFields, columnFields, valueFields]);
1240
+ const filteredUnassignedFields = useMemo7(() => {
994
1241
  if (!fieldSearch.trim()) return unassignedFields;
995
1242
  const search = fieldSearch.toLowerCase().trim();
996
- return unassignedFields.filter((f) => f.field.toLowerCase().includes(search));
1243
+ return unassignedFields.filter((f) => {
1244
+ const fieldName = f.field.toLowerCase();
1245
+ const displayName = f.isCalculated && f.calcName ? f.calcName.toLowerCase() : "";
1246
+ return fieldName.includes(search) || displayName.includes(search);
1247
+ });
997
1248
  }, [unassignedFields, fieldSearch]);
998
1249
  const assignedCount = assignedFields.length;
999
- const handleDragStart = useCallback6(
1250
+ const getFieldDisplayName = useCallback7((field) => {
1251
+ if (field.isCalculated && field.calcName) {
1252
+ return field.calcName;
1253
+ }
1254
+ return field.field;
1255
+ }, []);
1256
+ const handleDragStart = useCallback7(
1000
1257
  (field, event) => {
1001
1258
  event.dataTransfer?.setData("text/plain", field);
1002
1259
  event.dataTransfer.effectAllowed = "move";
@@ -1004,13 +1261,13 @@ function PivotConfig({
1004
1261
  },
1005
1262
  [onDragStart]
1006
1263
  );
1007
- const handleAggregationChange = useCallback6(
1264
+ const handleAggregationChange = useCallback7(
1008
1265
  (field, currentAgg, newAgg) => {
1009
1266
  onUpdateAggregation(field, currentAgg, newAgg);
1010
1267
  },
1011
1268
  [onUpdateAggregation]
1012
1269
  );
1013
- const toggleRowColumn = useCallback6(
1270
+ const toggleRowColumn = useCallback7(
1014
1271
  (field, currentAssignment) => {
1015
1272
  if (currentAssignment === "row") {
1016
1273
  onRemoveRowField(field);
@@ -1022,7 +1279,7 @@ function PivotConfig({
1022
1279
  },
1023
1280
  [onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
1024
1281
  );
1025
- const removeField = useCallback6(
1282
+ const removeField = useCallback7(
1026
1283
  (field, assignedTo, valueConfig) => {
1027
1284
  if (assignedTo === "row") {
1028
1285
  onRemoveRowField(field);
@@ -1034,10 +1291,31 @@ function PivotConfig({
1034
1291
  },
1035
1292
  [onRemoveRowField, onRemoveColumnField, onRemoveValueField]
1036
1293
  );
1037
- return /* @__PURE__ */ jsxs2("div", { className: "vpg-pivot-config", children: [
1038
- /* @__PURE__ */ jsxs2("div", { className: "vpg-config-header", children: [
1039
- /* @__PURE__ */ jsxs2("h3", { className: "vpg-config-title", children: [
1040
- /* @__PURE__ */ jsx2("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
1294
+ const handleTotalsToggle = useCallback7((checked) => {
1295
+ onShowRowTotalsChange(checked);
1296
+ onShowColumnTotalsChange(checked);
1297
+ }, [onShowRowTotalsChange, onShowColumnTotalsChange]);
1298
+ const openCalcModal = useCallback7((field) => {
1299
+ setEditingCalcField(field || null);
1300
+ setShowCalcModal(true);
1301
+ }, []);
1302
+ const handleSaveCalcField = useCallback7((field) => {
1303
+ if (editingCalcField && onUpdateCalculatedField) {
1304
+ onUpdateCalculatedField(field);
1305
+ } else if (onAddCalculatedField) {
1306
+ onAddCalculatedField(field);
1307
+ }
1308
+ setShowCalcModal(false);
1309
+ setEditingCalcField(null);
1310
+ }, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
1311
+ const handleCloseCalcModal = useCallback7(() => {
1312
+ setShowCalcModal(false);
1313
+ setEditingCalcField(null);
1314
+ }, []);
1315
+ return /* @__PURE__ */ jsxs3("div", { className: "vpg-pivot-config", children: [
1316
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-config-header", children: [
1317
+ /* @__PURE__ */ jsxs3("h3", { className: "vpg-config-title", children: [
1318
+ /* @__PURE__ */ jsx3("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1041
1319
  "path",
1042
1320
  {
1043
1321
  strokeLinecap: "round",
@@ -1048,13 +1326,13 @@ function PivotConfig({
1048
1326
  ) }),
1049
1327
  "Fields"
1050
1328
  ] }),
1051
- /* @__PURE__ */ jsx2("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx2(
1329
+ /* @__PURE__ */ jsx3("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx3(
1052
1330
  "button",
1053
1331
  {
1054
1332
  className: "vpg-action-btn vpg-clear-btn",
1055
1333
  title: "Clear all",
1056
1334
  onClick: onClearConfig,
1057
- children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
1335
+ children: /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1058
1336
  "path",
1059
1337
  {
1060
1338
  strokeLinecap: "round",
@@ -1066,23 +1344,23 @@ function PivotConfig({
1066
1344
  }
1067
1345
  ) })
1068
1346
  ] }),
1069
- assignedCount > 0 && /* @__PURE__ */ jsxs2("div", { className: "vpg-assigned-section", children: [
1070
- /* @__PURE__ */ jsx2("div", { className: "vpg-section-label", children: "Active" }),
1071
- /* @__PURE__ */ jsx2("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs2(
1347
+ assignedCount > 0 && /* @__PURE__ */ jsxs3("div", { className: "vpg-assigned-section", children: [
1348
+ /* @__PURE__ */ jsx3("div", { className: "vpg-section-label", children: "Active" }),
1349
+ /* @__PURE__ */ jsx3("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs3(
1072
1350
  "div",
1073
1351
  {
1074
- className: `vpg-assigned-item vpg-type-${field.assignedTo}`,
1075
- title: field.field,
1352
+ className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
1353
+ title: field.isCalculated ? field.calcFormula : field.field,
1076
1354
  draggable: true,
1077
1355
  onDragStart: (e) => handleDragStart(field.field, e),
1078
1356
  onDragEnd,
1079
1357
  children: [
1080
- /* @__PURE__ */ jsxs2("div", { className: "vpg-item-main", children: [
1081
- /* @__PURE__ */ jsx2("span", { className: `vpg-item-badge ${field.assignedTo}`, children: field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : getAggregationSymbol(field.valueConfig?.aggregation || "sum") }),
1082
- /* @__PURE__ */ jsx2("span", { className: "vpg-item-name", children: field.field })
1358
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-item-main", children: [
1359
+ /* @__PURE__ */ jsx3("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") }),
1360
+ /* @__PURE__ */ jsx3("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
1083
1361
  ] }),
1084
- /* @__PURE__ */ jsxs2("div", { className: "vpg-item-actions", children: [
1085
- (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx2(
1362
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-item-actions", children: [
1363
+ (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx3(
1086
1364
  "button",
1087
1365
  {
1088
1366
  className: "vpg-toggle-btn",
@@ -1091,14 +1369,14 @@ function PivotConfig({
1091
1369
  e.stopPropagation();
1092
1370
  toggleRowColumn(field.field, field.assignedTo);
1093
1371
  },
1094
- children: /* @__PURE__ */ jsx2(
1372
+ children: /* @__PURE__ */ jsx3(
1095
1373
  "svg",
1096
1374
  {
1097
1375
  className: "vpg-icon-xs",
1098
1376
  fill: "none",
1099
1377
  stroke: "currentColor",
1100
1378
  viewBox: "0 0 24 24",
1101
- children: /* @__PURE__ */ jsx2(
1379
+ children: /* @__PURE__ */ jsx3(
1102
1380
  "path",
1103
1381
  {
1104
1382
  strokeLinecap: "round",
@@ -1111,7 +1389,7 @@ function PivotConfig({
1111
1389
  )
1112
1390
  }
1113
1391
  ),
1114
- field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx2(
1392
+ field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx3(
1115
1393
  "select",
1116
1394
  {
1117
1395
  className: "vpg-agg-select",
@@ -1125,14 +1403,14 @@ function PivotConfig({
1125
1403
  );
1126
1404
  },
1127
1405
  onClick: (e) => e.stopPropagation(),
1128
- children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs2("option", { value: agg.value, children: [
1406
+ children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs3("option", { value: agg.value, children: [
1129
1407
  agg.symbol,
1130
1408
  " ",
1131
1409
  agg.label
1132
1410
  ] }, agg.value))
1133
1411
  }
1134
1412
  ),
1135
- /* @__PURE__ */ jsx2(
1413
+ /* @__PURE__ */ jsx3(
1136
1414
  "button",
1137
1415
  {
1138
1416
  className: "vpg-remove-btn",
@@ -1150,13 +1428,13 @@ function PivotConfig({
1150
1428
  field.field
1151
1429
  )) })
1152
1430
  ] }),
1153
- /* @__PURE__ */ jsxs2("div", { className: "vpg-unassigned-section", children: [
1154
- /* @__PURE__ */ jsx2("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs2("div", { className: "vpg-section-label", children: [
1431
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-unassigned-section", children: [
1432
+ /* @__PURE__ */ jsx3("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs3("div", { className: "vpg-section-label", children: [
1155
1433
  "Available ",
1156
- /* @__PURE__ */ jsx2("span", { className: "vpg-count", children: unassignedFields.length })
1434
+ /* @__PURE__ */ jsx3("span", { className: "vpg-count", children: unassignedFields.length })
1157
1435
  ] }) }),
1158
- /* @__PURE__ */ jsxs2("div", { className: "vpg-field-search", children: [
1159
- /* @__PURE__ */ jsx2("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
1436
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-field-search", children: [
1437
+ /* @__PURE__ */ jsx3("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1160
1438
  "path",
1161
1439
  {
1162
1440
  strokeLinecap: "round",
@@ -1165,7 +1443,7 @@ function PivotConfig({
1165
1443
  d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
1166
1444
  }
1167
1445
  ) }),
1168
- /* @__PURE__ */ jsx2(
1446
+ /* @__PURE__ */ jsx3(
1169
1447
  "input",
1170
1448
  {
1171
1449
  type: "text",
@@ -1175,7 +1453,7 @@ function PivotConfig({
1175
1453
  className: "vpg-search-input"
1176
1454
  }
1177
1455
  ),
1178
- fieldSearch && /* @__PURE__ */ jsx2("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
1456
+ fieldSearch && /* @__PURE__ */ jsx3("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1179
1457
  "path",
1180
1458
  {
1181
1459
  strokeLinecap: "round",
@@ -1185,64 +1463,94 @@ function PivotConfig({
1185
1463
  }
1186
1464
  ) }) })
1187
1465
  ] }),
1188
- /* @__PURE__ */ jsxs2("div", { className: "vpg-field-list", children: [
1189
- filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs2(
1466
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-field-list", children: [
1467
+ filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs3(
1190
1468
  "div",
1191
1469
  {
1192
- className: `vpg-field-item ${field.isNumeric ? "vpg-is-numeric" : ""}`,
1193
- title: field.field,
1470
+ className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
1471
+ title: field.isCalculated ? field.calcFormula : field.field,
1194
1472
  draggable: true,
1195
1473
  onDragStart: (e) => handleDragStart(field.field, e),
1196
1474
  onDragEnd,
1197
1475
  children: [
1198
- /* @__PURE__ */ jsx2("span", { className: "vpg-field-type-icon", title: field.type, children: getFieldIcon(field.type) }),
1199
- /* @__PURE__ */ jsx2("span", { className: "vpg-field-name", children: field.field }),
1200
- /* @__PURE__ */ jsx2("span", { className: "vpg-unique-count", children: field.uniqueCount })
1476
+ /* @__PURE__ */ jsx3("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
1477
+ /* @__PURE__ */ jsx3("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
1478
+ field.isCalculated ? /* @__PURE__ */ jsxs3(Fragment, { children: [
1479
+ /* @__PURE__ */ jsx3(
1480
+ "button",
1481
+ {
1482
+ className: "vpg-field-edit",
1483
+ title: "Edit calculated field",
1484
+ onClick: (e) => {
1485
+ e.stopPropagation();
1486
+ const calcField = calculatedFields?.find((c) => c.id === field.calcId);
1487
+ if (calcField) openCalcModal(calcField);
1488
+ },
1489
+ children: "\u270E"
1490
+ }
1491
+ ),
1492
+ /* @__PURE__ */ jsx3(
1493
+ "button",
1494
+ {
1495
+ className: "vpg-field-delete",
1496
+ title: "Delete calculated field",
1497
+ onClick: (e) => {
1498
+ e.stopPropagation();
1499
+ if (field.calcId && onRemoveCalculatedField) {
1500
+ onRemoveCalculatedField(field.calcId);
1501
+ }
1502
+ },
1503
+ children: "\xD7"
1504
+ }
1505
+ )
1506
+ ] }) : /* @__PURE__ */ jsx3("span", { className: "vpg-unique-count", children: field.uniqueCount })
1201
1507
  ]
1202
1508
  },
1203
1509
  field.field
1204
1510
  )),
1205
- filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs2("div", { className: "vpg-empty-hint", children: [
1511
+ filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs3("div", { className: "vpg-empty-hint", children: [
1206
1512
  'No fields match "',
1207
1513
  fieldSearch,
1208
1514
  '"'
1209
1515
  ] }),
1210
- unassignedFields.length === 0 && /* @__PURE__ */ jsx2("div", { className: "vpg-empty-hint", children: "All fields assigned" })
1516
+ unassignedFields.length === 0 && /* @__PURE__ */ jsx3("div", { className: "vpg-empty-hint", children: "All fields assigned" })
1211
1517
  ] })
1212
1518
  ] }),
1213
- /* @__PURE__ */ jsxs2("div", { className: "vpg-options-section", children: [
1214
- /* @__PURE__ */ jsxs2("label", { className: "vpg-option-toggle", children: [
1215
- /* @__PURE__ */ jsx2(
1519
+ /* @__PURE__ */ jsxs3("div", { className: "vpg-options-section", children: [
1520
+ /* @__PURE__ */ jsxs3("label", { className: "vpg-option-toggle", children: [
1521
+ /* @__PURE__ */ jsx3(
1216
1522
  "input",
1217
1523
  {
1218
1524
  type: "checkbox",
1219
1525
  checked: showRowTotals,
1220
- onChange: (e) => onShowRowTotalsChange(e.target.checked)
1526
+ onChange: (e) => handleTotalsToggle(e.target.checked)
1221
1527
  }
1222
1528
  ),
1223
- /* @__PURE__ */ jsx2("span", { children: "Totals" })
1529
+ /* @__PURE__ */ jsx3("span", { children: "Totals" })
1224
1530
  ] }),
1225
- /* @__PURE__ */ jsxs2("button", { className: "vpg-auto-btn", onClick: onAutoSuggest, children: [
1226
- /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2(
1227
- "path",
1228
- {
1229
- strokeLinecap: "round",
1230
- strokeLinejoin: "round",
1231
- strokeWidth: 2,
1232
- d: "M13 10V3L4 14h7v7l9-11h-7z"
1233
- }
1234
- ) }),
1235
- "Auto"
1531
+ /* @__PURE__ */ jsxs3("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
1532
+ /* @__PURE__ */ jsx3("span", { className: "vpg-calc-icon", children: "\u0192" }),
1533
+ /* @__PURE__ */ jsx3("span", { children: "+ Calc" })
1236
1534
  ] })
1237
1535
  ] }),
1238
- showWatermark && /* @__PURE__ */ jsx2("div", { className: "vpg-watermark", children: /* @__PURE__ */ jsx2("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "TinyPivot" }) })
1536
+ showWatermark && /* @__PURE__ */ jsx3("div", { className: "vpg-watermark", children: /* @__PURE__ */ jsx3("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "TinyPivot" }) }),
1537
+ /* @__PURE__ */ jsx3(
1538
+ CalculatedFieldModal,
1539
+ {
1540
+ show: showCalcModal,
1541
+ availableFields: numericFieldNames,
1542
+ existingField: editingCalcField,
1543
+ onClose: handleCloseCalcModal,
1544
+ onSave: handleSaveCalcField
1545
+ }
1546
+ )
1239
1547
  ] });
1240
1548
  }
1241
1549
 
1242
1550
  // src/components/PivotSkeleton.tsx
1243
- import { useState as useState7, useMemo as useMemo7, useCallback as useCallback7 } from "react";
1551
+ import { useState as useState8, useMemo as useMemo8, useCallback as useCallback8 } from "react";
1244
1552
  import { getAggregationLabel as getAggregationLabel2, getAggregationSymbol as getAggregationSymbol2 } from "@smallwebco/tinypivot-core";
1245
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1553
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1246
1554
  function PivotSkeleton({
1247
1555
  rowFields,
1248
1556
  columnFields,
@@ -1264,12 +1572,12 @@ function PivotSkeleton({
1264
1572
  onReorderColumnFields
1265
1573
  }) {
1266
1574
  const { showWatermark, canUsePivot, isDemo } = useLicense();
1267
- const [dragOverArea, setDragOverArea] = useState7(null);
1268
- const [reorderDragSource, setReorderDragSource] = useState7(null);
1269
- const [reorderDropTarget, setReorderDropTarget] = useState7(null);
1270
- const [sortDirection, setSortDirection] = useState7("asc");
1271
- const [sortTarget, setSortTarget] = useState7("row");
1272
- const toggleSort = useCallback7((target = "row") => {
1575
+ const [dragOverArea, setDragOverArea] = useState8(null);
1576
+ const [reorderDragSource, setReorderDragSource] = useState8(null);
1577
+ const [reorderDropTarget, setReorderDropTarget] = useState8(null);
1578
+ const [sortDirection, setSortDirection] = useState8("asc");
1579
+ const [sortTarget, setSortTarget] = useState8("row");
1580
+ const toggleSort = useCallback8((target = "row") => {
1273
1581
  if (sortTarget === target) {
1274
1582
  setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
1275
1583
  } else {
@@ -1277,7 +1585,7 @@ function PivotSkeleton({
1277
1585
  setSortDirection("asc");
1278
1586
  }
1279
1587
  }, [sortTarget]);
1280
- const sortedRowIndices = useMemo7(() => {
1588
+ const sortedRowIndices = useMemo8(() => {
1281
1589
  if (!pivotResult) return [];
1282
1590
  const indices = pivotResult.rowHeaders.map((_, i) => i);
1283
1591
  const headers = pivotResult.rowHeaders;
@@ -1301,7 +1609,7 @@ function PivotSkeleton({
1301
1609
  });
1302
1610
  return indices;
1303
1611
  }, [pivotResult, sortTarget, sortDirection]);
1304
- const columnHeaderCells = useMemo7(() => {
1612
+ const columnHeaderCells = useMemo8(() => {
1305
1613
  if (!pivotResult || pivotResult.headers.length === 0) {
1306
1614
  return [
1307
1615
  valueFields.map((vf) => ({
@@ -1329,12 +1637,12 @@ function PivotSkeleton({
1329
1637
  return result;
1330
1638
  }, [pivotResult, valueFields]);
1331
1639
  const hasActiveFilters = activeFilters && activeFilters.length > 0;
1332
- const filterSummary = useMemo7(() => {
1640
+ const filterSummary = useMemo8(() => {
1333
1641
  if (!activeFilters || activeFilters.length === 0) return "";
1334
1642
  return activeFilters.map((f) => f.column).join(", ");
1335
1643
  }, [activeFilters]);
1336
- const [showFilterTooltip, setShowFilterTooltip] = useState7(false);
1337
- const filterTooltipDetails = useMemo7(() => {
1644
+ const [showFilterTooltip, setShowFilterTooltip] = useState8(false);
1645
+ const filterTooltipDetails = useMemo8(() => {
1338
1646
  if (!activeFilters || activeFilters.length === 0) return [];
1339
1647
  return activeFilters.map((f) => {
1340
1648
  const maxDisplay = 5;
@@ -1347,7 +1655,7 @@ function PivotSkeleton({
1347
1655
  };
1348
1656
  });
1349
1657
  }, [activeFilters]);
1350
- const handleDragOver = useCallback7(
1658
+ const handleDragOver = useCallback8(
1351
1659
  (area, event) => {
1352
1660
  event.preventDefault();
1353
1661
  event.dataTransfer.dropEffect = "move";
@@ -1355,10 +1663,10 @@ function PivotSkeleton({
1355
1663
  },
1356
1664
  []
1357
1665
  );
1358
- const handleDragLeave = useCallback7(() => {
1666
+ const handleDragLeave = useCallback8(() => {
1359
1667
  setDragOverArea(null);
1360
1668
  }, []);
1361
- const handleDrop = useCallback7(
1669
+ const handleDrop = useCallback8(
1362
1670
  (area, event) => {
1363
1671
  event.preventDefault();
1364
1672
  const field = event.dataTransfer?.getData("text/plain");
@@ -1385,7 +1693,7 @@ function PivotSkeleton({
1385
1693
  },
1386
1694
  [rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
1387
1695
  );
1388
- const handleChipDragStart = useCallback7(
1696
+ const handleChipDragStart = useCallback8(
1389
1697
  (zone, index, event) => {
1390
1698
  setReorderDragSource({ zone, index });
1391
1699
  event.dataTransfer.effectAllowed = "move";
@@ -1396,11 +1704,11 @@ function PivotSkeleton({
1396
1704
  },
1397
1705
  []
1398
1706
  );
1399
- const handleChipDragEnd = useCallback7(() => {
1707
+ const handleChipDragEnd = useCallback8(() => {
1400
1708
  setReorderDragSource(null);
1401
1709
  setReorderDropTarget(null);
1402
1710
  }, []);
1403
- const handleChipDragOver = useCallback7(
1711
+ const handleChipDragOver = useCallback8(
1404
1712
  (zone, index, event) => {
1405
1713
  event.preventDefault();
1406
1714
  if (reorderDragSource && reorderDragSource.zone === zone) {
@@ -1410,10 +1718,10 @@ function PivotSkeleton({
1410
1718
  },
1411
1719
  [reorderDragSource]
1412
1720
  );
1413
- const handleChipDragLeave = useCallback7(() => {
1721
+ const handleChipDragLeave = useCallback8(() => {
1414
1722
  setReorderDropTarget(null);
1415
1723
  }, []);
1416
- const handleChipDrop = useCallback7(
1724
+ const handleChipDrop = useCallback8(
1417
1725
  (zone, targetIndex, event) => {
1418
1726
  event.preventDefault();
1419
1727
  event.stopPropagation();
@@ -1439,27 +1747,27 @@ function PivotSkeleton({
1439
1747
  },
1440
1748
  [reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
1441
1749
  );
1442
- const isChipDragSource = useCallback7(
1750
+ const isChipDragSource = useCallback8(
1443
1751
  (zone, index) => {
1444
1752
  return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
1445
1753
  },
1446
1754
  [reorderDragSource]
1447
1755
  );
1448
- const isChipDropTarget = useCallback7(
1756
+ const isChipDropTarget = useCallback8(
1449
1757
  (zone, index) => {
1450
1758
  return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
1451
1759
  },
1452
1760
  [reorderDropTarget]
1453
1761
  );
1454
1762
  const currentFontSize = fontSize;
1455
- return /* @__PURE__ */ jsxs3(
1763
+ return /* @__PURE__ */ jsxs4(
1456
1764
  "div",
1457
1765
  {
1458
1766
  className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
1459
1767
  children: [
1460
- /* @__PURE__ */ jsxs3("div", { className: "vpg-skeleton-header", children: [
1461
- /* @__PURE__ */ jsxs3("div", { className: "vpg-skeleton-title", children: [
1462
- /* @__PURE__ */ jsx3("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1768
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-skeleton-header", children: [
1769
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-skeleton-title", children: [
1770
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
1463
1771
  "path",
1464
1772
  {
1465
1773
  strokeLinecap: "round",
@@ -1468,24 +1776,24 @@ function PivotSkeleton({
1468
1776
  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"
1469
1777
  }
1470
1778
  ) }),
1471
- /* @__PURE__ */ jsx3("span", { children: "Pivot Table" })
1779
+ /* @__PURE__ */ jsx4("span", { children: "Pivot Table" })
1472
1780
  ] }),
1473
- /* @__PURE__ */ jsxs3("div", { className: "vpg-header-right", children: [
1474
- hasActiveFilters && /* @__PURE__ */ jsxs3(
1781
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-header-right", children: [
1782
+ hasActiveFilters && /* @__PURE__ */ jsxs4(
1475
1783
  "div",
1476
1784
  {
1477
1785
  className: "vpg-filter-indicator",
1478
1786
  onMouseEnter: () => setShowFilterTooltip(true),
1479
1787
  onMouseLeave: () => setShowFilterTooltip(false),
1480
1788
  children: [
1481
- /* @__PURE__ */ jsx3(
1789
+ /* @__PURE__ */ jsx4(
1482
1790
  "svg",
1483
1791
  {
1484
1792
  className: "vpg-filter-icon",
1485
1793
  fill: "none",
1486
1794
  stroke: "currentColor",
1487
1795
  viewBox: "0 0 24 24",
1488
- children: /* @__PURE__ */ jsx3(
1796
+ children: /* @__PURE__ */ jsx4(
1489
1797
  "path",
1490
1798
  {
1491
1799
  strokeLinecap: "round",
@@ -1496,10 +1804,10 @@ function PivotSkeleton({
1496
1804
  )
1497
1805
  }
1498
1806
  ),
1499
- /* @__PURE__ */ jsxs3("span", { className: "vpg-filter-text", children: [
1807
+ /* @__PURE__ */ jsxs4("span", { className: "vpg-filter-text", children: [
1500
1808
  "Filtered: ",
1501
- /* @__PURE__ */ jsx3("strong", { children: filterSummary }),
1502
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs3("span", { className: "vpg-filter-count", children: [
1809
+ /* @__PURE__ */ jsx4("strong", { children: filterSummary }),
1810
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs4("span", { className: "vpg-filter-count", children: [
1503
1811
  "(",
1504
1812
  filteredRowCount.toLocaleString(),
1505
1813
  " of ",
@@ -1507,20 +1815,20 @@ function PivotSkeleton({
1507
1815
  " rows)"
1508
1816
  ] })
1509
1817
  ] }),
1510
- showFilterTooltip && /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-tooltip", children: [
1511
- /* @__PURE__ */ jsx3("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
1512
- filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs3("div", { className: "vpg-tooltip-filter", children: [
1513
- /* @__PURE__ */ jsx3("div", { className: "vpg-tooltip-column", children: filter.column }),
1514
- /* @__PURE__ */ jsxs3("div", { className: "vpg-tooltip-values", children: [
1515
- filter.values.map((val, idx) => /* @__PURE__ */ jsx3("span", { className: "vpg-tooltip-value", children: val }, idx)),
1516
- filter.remaining > 0 && /* @__PURE__ */ jsxs3("span", { className: "vpg-tooltip-more", children: [
1818
+ showFilterTooltip && /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-tooltip", children: [
1819
+ /* @__PURE__ */ jsx4("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
1820
+ filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs4("div", { className: "vpg-tooltip-filter", children: [
1821
+ /* @__PURE__ */ jsx4("div", { className: "vpg-tooltip-column", children: filter.column }),
1822
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-tooltip-values", children: [
1823
+ filter.values.map((val, idx) => /* @__PURE__ */ jsx4("span", { className: "vpg-tooltip-value", children: val }, idx)),
1824
+ filter.remaining > 0 && /* @__PURE__ */ jsxs4("span", { className: "vpg-tooltip-more", children: [
1517
1825
  "+",
1518
1826
  filter.remaining,
1519
1827
  " more"
1520
1828
  ] })
1521
1829
  ] })
1522
1830
  ] }, filter.column)),
1523
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs3("div", { className: "vpg-tooltip-summary", children: [
1831
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs4("div", { className: "vpg-tooltip-summary", children: [
1524
1832
  "Showing ",
1525
1833
  filteredRowCount.toLocaleString(),
1526
1834
  " of ",
@@ -1531,18 +1839,18 @@ function PivotSkeleton({
1531
1839
  ]
1532
1840
  }
1533
1841
  ),
1534
- isConfigured && /* @__PURE__ */ jsxs3("div", { className: "vpg-config-summary", children: [
1535
- /* @__PURE__ */ jsxs3("span", { className: "vpg-summary-badge vpg-rows", children: [
1842
+ isConfigured && /* @__PURE__ */ jsxs4("div", { className: "vpg-config-summary", children: [
1843
+ /* @__PURE__ */ jsxs4("span", { className: "vpg-summary-badge vpg-rows", children: [
1536
1844
  rowFields.length,
1537
1845
  " row",
1538
1846
  rowFields.length !== 1 ? "s" : ""
1539
1847
  ] }),
1540
- /* @__PURE__ */ jsxs3("span", { className: "vpg-summary-badge vpg-cols", children: [
1848
+ /* @__PURE__ */ jsxs4("span", { className: "vpg-summary-badge vpg-cols", children: [
1541
1849
  columnFields.length,
1542
1850
  " col",
1543
1851
  columnFields.length !== 1 ? "s" : ""
1544
1852
  ] }),
1545
- /* @__PURE__ */ jsxs3("span", { className: "vpg-summary-badge vpg-vals", children: [
1853
+ /* @__PURE__ */ jsxs4("span", { className: "vpg-summary-badge vpg-vals", children: [
1546
1854
  valueFields.length,
1547
1855
  " val",
1548
1856
  valueFields.length !== 1 ? "s" : ""
@@ -1550,8 +1858,8 @@ function PivotSkeleton({
1550
1858
  ] })
1551
1859
  ] })
1552
1860
  ] }),
1553
- !canUsePivot ? /* @__PURE__ */ jsx3("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs3("div", { className: "vpg-pro-content", children: [
1554
- /* @__PURE__ */ jsx3("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx3(
1861
+ !canUsePivot ? /* @__PURE__ */ jsx4("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs4("div", { className: "vpg-pro-content", children: [
1862
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx4(
1555
1863
  "path",
1556
1864
  {
1557
1865
  strokeLinecap: "round",
@@ -1560,12 +1868,12 @@ function PivotSkeleton({
1560
1868
  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"
1561
1869
  }
1562
1870
  ) }),
1563
- /* @__PURE__ */ jsx3("h3", { children: "Pro Feature" }),
1564
- /* @__PURE__ */ jsx3("p", { children: "Pivot Table functionality requires a Pro license." }),
1565
- /* @__PURE__ */ jsx3("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
1566
- ] }) }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
1567
- /* @__PURE__ */ jsxs3("div", { className: "vpg-config-bar", children: [
1568
- /* @__PURE__ */ jsxs3(
1871
+ /* @__PURE__ */ jsx4("h3", { children: "Pro Feature" }),
1872
+ /* @__PURE__ */ jsx4("p", { children: "Pivot Table functionality requires a Pro license." }),
1873
+ /* @__PURE__ */ jsx4("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
1874
+ ] }) }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
1875
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-config-bar", children: [
1876
+ /* @__PURE__ */ jsxs4(
1569
1877
  "div",
1570
1878
  {
1571
1879
  className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
@@ -1573,12 +1881,12 @@ function PivotSkeleton({
1573
1881
  onDragLeave: handleDragLeave,
1574
1882
  onDrop: (e) => handleDrop("row", e),
1575
1883
  children: [
1576
- /* @__PURE__ */ jsxs3("div", { className: "vpg-zone-header", children: [
1577
- /* @__PURE__ */ jsx3("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
1578
- /* @__PURE__ */ jsx3("span", { className: "vpg-zone-label", children: "Rows" })
1884
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-zone-header", children: [
1885
+ /* @__PURE__ */ jsx4("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
1886
+ /* @__PURE__ */ jsx4("span", { className: "vpg-zone-label", children: "Rows" })
1579
1887
  ] }),
1580
- /* @__PURE__ */ jsxs3("div", { className: "vpg-zone-chips", children: [
1581
- rowFields.map((field, idx) => /* @__PURE__ */ jsxs3(
1888
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-zone-chips", children: [
1889
+ rowFields.map((field, idx) => /* @__PURE__ */ jsxs4(
1582
1890
  "div",
1583
1891
  {
1584
1892
  className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -1589,9 +1897,9 @@ function PivotSkeleton({
1589
1897
  onDragLeave: handleChipDragLeave,
1590
1898
  onDrop: (e) => handleChipDrop("row", idx, e),
1591
1899
  children: [
1592
- /* @__PURE__ */ jsx3("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1593
- /* @__PURE__ */ jsx3("span", { className: "vpg-mini-name", children: field }),
1594
- /* @__PURE__ */ jsx3(
1900
+ /* @__PURE__ */ jsx4("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1901
+ /* @__PURE__ */ jsx4("span", { className: "vpg-mini-name", children: field }),
1902
+ /* @__PURE__ */ jsx4(
1595
1903
  "button",
1596
1904
  {
1597
1905
  className: "vpg-mini-remove",
@@ -1606,12 +1914,12 @@ function PivotSkeleton({
1606
1914
  },
1607
1915
  field
1608
1916
  )),
1609
- rowFields.length === 0 && /* @__PURE__ */ jsx3("span", { className: "vpg-zone-hint", children: "Drop here" })
1917
+ rowFields.length === 0 && /* @__PURE__ */ jsx4("span", { className: "vpg-zone-hint", children: "Drop here" })
1610
1918
  ] })
1611
1919
  ]
1612
1920
  }
1613
1921
  ),
1614
- /* @__PURE__ */ jsxs3(
1922
+ /* @__PURE__ */ jsxs4(
1615
1923
  "div",
1616
1924
  {
1617
1925
  className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
@@ -1619,12 +1927,12 @@ function PivotSkeleton({
1619
1927
  onDragLeave: handleDragLeave,
1620
1928
  onDrop: (e) => handleDrop("column", e),
1621
1929
  children: [
1622
- /* @__PURE__ */ jsxs3("div", { className: "vpg-zone-header", children: [
1623
- /* @__PURE__ */ jsx3("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
1624
- /* @__PURE__ */ jsx3("span", { className: "vpg-zone-label", children: "Columns" })
1930
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-zone-header", children: [
1931
+ /* @__PURE__ */ jsx4("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
1932
+ /* @__PURE__ */ jsx4("span", { className: "vpg-zone-label", children: "Columns" })
1625
1933
  ] }),
1626
- /* @__PURE__ */ jsxs3("div", { className: "vpg-zone-chips", children: [
1627
- columnFields.map((field, idx) => /* @__PURE__ */ jsxs3(
1934
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-zone-chips", children: [
1935
+ columnFields.map((field, idx) => /* @__PURE__ */ jsxs4(
1628
1936
  "div",
1629
1937
  {
1630
1938
  className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -1635,9 +1943,9 @@ function PivotSkeleton({
1635
1943
  onDragLeave: handleChipDragLeave,
1636
1944
  onDrop: (e) => handleChipDrop("column", idx, e),
1637
1945
  children: [
1638
- /* @__PURE__ */ jsx3("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1639
- /* @__PURE__ */ jsx3("span", { className: "vpg-mini-name", children: field }),
1640
- /* @__PURE__ */ jsx3(
1946
+ /* @__PURE__ */ jsx4("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1947
+ /* @__PURE__ */ jsx4("span", { className: "vpg-mini-name", children: field }),
1948
+ /* @__PURE__ */ jsx4(
1641
1949
  "button",
1642
1950
  {
1643
1951
  className: "vpg-mini-remove",
@@ -1652,12 +1960,12 @@ function PivotSkeleton({
1652
1960
  },
1653
1961
  field
1654
1962
  )),
1655
- columnFields.length === 0 && /* @__PURE__ */ jsx3("span", { className: "vpg-zone-hint", children: "Drop here" })
1963
+ columnFields.length === 0 && /* @__PURE__ */ jsx4("span", { className: "vpg-zone-hint", children: "Drop here" })
1656
1964
  ] })
1657
1965
  ]
1658
1966
  }
1659
1967
  ),
1660
- /* @__PURE__ */ jsxs3(
1968
+ /* @__PURE__ */ jsxs4(
1661
1969
  "div",
1662
1970
  {
1663
1971
  className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
@@ -1665,19 +1973,19 @@ function PivotSkeleton({
1665
1973
  onDragLeave: handleDragLeave,
1666
1974
  onDrop: (e) => handleDrop("value", e),
1667
1975
  children: [
1668
- /* @__PURE__ */ jsxs3("div", { className: "vpg-zone-header", children: [
1669
- /* @__PURE__ */ jsx3("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
1670
- /* @__PURE__ */ jsx3("span", { className: "vpg-zone-label", children: "Values" })
1976
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-zone-header", children: [
1977
+ /* @__PURE__ */ jsx4("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
1978
+ /* @__PURE__ */ jsx4("span", { className: "vpg-zone-label", children: "Values" })
1671
1979
  ] }),
1672
- /* @__PURE__ */ jsxs3("div", { className: "vpg-zone-chips", children: [
1673
- valueFields.map((vf) => /* @__PURE__ */ jsxs3(
1980
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-zone-chips", children: [
1981
+ valueFields.map((vf) => /* @__PURE__ */ jsxs4(
1674
1982
  "div",
1675
1983
  {
1676
1984
  className: "vpg-mini-chip vpg-value-chip",
1677
1985
  children: [
1678
- /* @__PURE__ */ jsx3("span", { className: "vpg-agg-symbol", children: getAggregationSymbol2(vf.aggregation) }),
1679
- /* @__PURE__ */ jsx3("span", { className: "vpg-mini-name", children: vf.field }),
1680
- /* @__PURE__ */ jsx3(
1986
+ /* @__PURE__ */ jsx4("span", { className: "vpg-agg-symbol", children: getAggregationSymbol2(vf.aggregation) }),
1987
+ /* @__PURE__ */ jsx4("span", { className: "vpg-mini-name", children: vf.field }),
1988
+ /* @__PURE__ */ jsx4(
1681
1989
  "button",
1682
1990
  {
1683
1991
  className: "vpg-mini-remove",
@@ -1689,21 +1997,21 @@ function PivotSkeleton({
1689
1997
  },
1690
1998
  `${vf.field}-${vf.aggregation}`
1691
1999
  )),
1692
- valueFields.length === 0 && /* @__PURE__ */ jsx3("span", { className: "vpg-zone-hint", children: "Drop numeric" })
2000
+ valueFields.length === 0 && /* @__PURE__ */ jsx4("span", { className: "vpg-zone-hint", children: "Drop numeric" })
1693
2001
  ] })
1694
2002
  ]
1695
2003
  }
1696
2004
  )
1697
2005
  ] }),
1698
- (!isConfigured || !pivotResult) && /* @__PURE__ */ jsx3("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs3("div", { className: "vpg-placeholder-content", children: [
1699
- /* @__PURE__ */ jsx3(
2006
+ (!isConfigured || !pivotResult) && /* @__PURE__ */ jsx4("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs4("div", { className: "vpg-placeholder-content", children: [
2007
+ /* @__PURE__ */ jsx4(
1700
2008
  "svg",
1701
2009
  {
1702
2010
  className: "vpg-placeholder-icon",
1703
2011
  fill: "none",
1704
2012
  viewBox: "0 0 24 24",
1705
2013
  stroke: "currentColor",
1706
- children: /* @__PURE__ */ jsx3(
2014
+ children: /* @__PURE__ */ jsx4(
1707
2015
  "path",
1708
2016
  {
1709
2017
  strokeLinecap: "round",
@@ -1714,51 +2022,51 @@ function PivotSkeleton({
1714
2022
  )
1715
2023
  }
1716
2024
  ),
1717
- /* @__PURE__ */ jsx3("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs3(Fragment, { children: [
2025
+ /* @__PURE__ */ jsx4("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1718
2026
  "Add a ",
1719
- /* @__PURE__ */ jsx3("strong", { children: "Values" }),
2027
+ /* @__PURE__ */ jsx4("strong", { children: "Values" }),
1720
2028
  " field to see your pivot table"
1721
- ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs3(Fragment, { children: [
2029
+ ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1722
2030
  "Add ",
1723
- /* @__PURE__ */ jsx3("strong", { children: "Row" }),
2031
+ /* @__PURE__ */ jsx4("strong", { children: "Row" }),
1724
2032
  " or ",
1725
- /* @__PURE__ */ jsx3("strong", { children: "Column" }),
2033
+ /* @__PURE__ */ jsx4("strong", { children: "Column" }),
1726
2034
  " fields to group your data"
1727
2035
  ] }) : "Your pivot table will appear here" })
1728
2036
  ] }) }),
1729
- isConfigured && pivotResult && /* @__PURE__ */ jsx3("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs3("table", { className: "vpg-pivot-table", children: [
1730
- /* @__PURE__ */ jsx3("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs3("tr", { className: "vpg-column-header-row", children: [
1731
- levelIdx === 0 && /* @__PURE__ */ jsx3(
2037
+ isConfigured && pivotResult && /* @__PURE__ */ jsx4("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs4("table", { className: "vpg-pivot-table", children: [
2038
+ /* @__PURE__ */ jsx4("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs4("tr", { className: "vpg-column-header-row", children: [
2039
+ levelIdx === 0 && /* @__PURE__ */ jsx4(
1732
2040
  "th",
1733
2041
  {
1734
2042
  className: "vpg-row-header-label",
1735
2043
  rowSpan: columnHeaderCells.length,
1736
2044
  onClick: () => toggleSort("row"),
1737
- children: /* @__PURE__ */ jsxs3("div", { className: "vpg-header-content", children: [
1738
- /* @__PURE__ */ jsx3("span", { children: rowFields.join(" / ") || "Rows" }),
1739
- /* @__PURE__ */ jsx3("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
2045
+ children: /* @__PURE__ */ jsxs4("div", { className: "vpg-header-content", children: [
2046
+ /* @__PURE__ */ jsx4("span", { children: rowFields.join(" / ") || "Rows" }),
2047
+ /* @__PURE__ */ jsx4("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
1740
2048
  ] })
1741
2049
  }
1742
2050
  ),
1743
- headerRow.map((cell, idx) => /* @__PURE__ */ jsx3(
2051
+ headerRow.map((cell, idx) => /* @__PURE__ */ jsx4(
1744
2052
  "th",
1745
2053
  {
1746
2054
  className: "vpg-column-header-cell",
1747
2055
  colSpan: cell.colspan,
1748
2056
  onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
1749
- children: /* @__PURE__ */ jsxs3("div", { className: "vpg-header-content", children: [
1750
- /* @__PURE__ */ jsx3("span", { children: cell.label }),
1751
- levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx3("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
2057
+ children: /* @__PURE__ */ jsxs4("div", { className: "vpg-header-content", children: [
2058
+ /* @__PURE__ */ jsx4("span", { children: cell.label }),
2059
+ levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx4("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
1752
2060
  ] })
1753
2061
  },
1754
2062
  idx
1755
2063
  )),
1756
- pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx3("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
2064
+ pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx4("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
1757
2065
  ] }, `header-${levelIdx}`)) }),
1758
- /* @__PURE__ */ jsxs3("tbody", { children: [
1759
- sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs3("tr", { className: "vpg-data-row", children: [
1760
- /* @__PURE__ */ jsx3("th", { className: "vpg-row-header-cell", children: pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx3("span", { className: "vpg-row-value", children: val }, idx)) }),
1761
- pivotResult.data[sortedIdx].map((cell, colIdx) => /* @__PURE__ */ jsx3(
2066
+ /* @__PURE__ */ jsxs4("tbody", { children: [
2067
+ sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs4("tr", { className: "vpg-data-row", children: [
2068
+ /* @__PURE__ */ jsx4("th", { className: "vpg-row-header-cell", children: pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx4("span", { className: "vpg-row-value", children: val }, idx)) }),
2069
+ pivotResult.data[sortedIdx].map((cell, colIdx) => /* @__PURE__ */ jsx4(
1762
2070
  "td",
1763
2071
  {
1764
2072
  className: `vpg-data-cell ${cell.value === null ? "vpg-is-null" : ""}`,
@@ -1766,26 +2074,26 @@ function PivotSkeleton({
1766
2074
  },
1767
2075
  colIdx
1768
2076
  )),
1769
- pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx3("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
2077
+ pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx4("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
1770
2078
  ] }, sortedIdx)),
1771
- pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs3("tr", { className: "vpg-totals-row", children: [
1772
- /* @__PURE__ */ jsx3("th", { className: "vpg-row-header-cell vpg-total-label", children: "Total" }),
1773
- pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx3("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
1774
- pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx3("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
2079
+ pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs4("tr", { className: "vpg-totals-row", children: [
2080
+ /* @__PURE__ */ jsx4("th", { className: "vpg-row-header-cell vpg-total-label", children: "Total" }),
2081
+ pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx4("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
2082
+ pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx4("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
1775
2083
  ] })
1776
2084
  ] })
1777
2085
  ] }) }),
1778
- isConfigured && pivotResult && /* @__PURE__ */ jsx3("div", { className: "vpg-skeleton-footer", children: /* @__PURE__ */ jsxs3("span", { children: [
2086
+ isConfigured && pivotResult && /* @__PURE__ */ jsx4("div", { className: "vpg-skeleton-footer", children: /* @__PURE__ */ jsxs4("span", { children: [
1779
2087
  pivotResult.rowHeaders.length,
1780
2088
  " rows \xD7 ",
1781
2089
  pivotResult.data[0]?.length || 0,
1782
2090
  " columns"
1783
2091
  ] }) })
1784
2092
  ] }),
1785
- showWatermark && canUsePivot && /* @__PURE__ */ jsx3("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs3(Fragment, { children: [
1786
- /* @__PURE__ */ jsx3("span", { className: "vpg-demo-badge", children: "DEMO" }),
1787
- /* @__PURE__ */ jsx3("span", { children: "Pro features unlocked for evaluation" }),
1788
- /* @__PURE__ */ jsx3(
2093
+ showWatermark && canUsePivot && /* @__PURE__ */ jsx4("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
2094
+ /* @__PURE__ */ jsx4("span", { className: "vpg-demo-badge", children: "DEMO" }),
2095
+ /* @__PURE__ */ jsx4("span", { children: "Pro features unlocked for evaluation" }),
2096
+ /* @__PURE__ */ jsx4(
1789
2097
  "a",
1790
2098
  {
1791
2099
  href: "https://tiny-pivot.com/#pricing",
@@ -1795,14 +2103,14 @@ function PivotSkeleton({
1795
2103
  children: "Get Pro License \u2192"
1796
2104
  }
1797
2105
  )
1798
- ] }) : /* @__PURE__ */ jsx3("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
2106
+ ] }) : /* @__PURE__ */ jsx4("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
1799
2107
  ]
1800
2108
  }
1801
2109
  );
1802
2110
  }
1803
2111
 
1804
2112
  // src/components/DataGrid.tsx
1805
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2113
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1806
2114
  var MIN_COL_WIDTH = 120;
1807
2115
  var MAX_COL_WIDTH = 350;
1808
2116
  function DataGrid({
@@ -1828,35 +2136,35 @@ function DataGrid({
1828
2136
  onCopy
1829
2137
  }) {
1830
2138
  const { showWatermark, canUsePivot, isDemo } = useLicense();
1831
- const currentTheme = useMemo8(() => {
2139
+ const currentTheme = useMemo9(() => {
1832
2140
  if (theme === "auto") {
1833
2141
  return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1834
2142
  }
1835
2143
  return theme;
1836
2144
  }, [theme]);
1837
- const [currentFontSize, setCurrentFontSize] = useState8(initialFontSize);
1838
- const [globalSearchTerm, setGlobalSearchTerm] = useState8("");
1839
- const [showSearchInput, setShowSearchInput] = useState8(false);
1840
- const [currentPage, setCurrentPage] = useState8(1);
1841
- const [columnWidths, setColumnWidths] = useState8({});
1842
- const [resizingColumnId, setResizingColumnId] = useState8(null);
1843
- const [resizeStartX, setResizeStartX] = useState8(0);
1844
- const [resizeStartWidth, setResizeStartWidth] = useState8(0);
1845
- const [gridHeight, setGridHeight] = useState8(initialHeight);
1846
- const [isResizingVertically, setIsResizingVertically] = useState8(false);
1847
- const [verticalResizeStartY, setVerticalResizeStartY] = useState8(0);
1848
- const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState8(0);
1849
- const [showCopyToast, setShowCopyToast] = useState8(false);
1850
- const [copyToastMessage, setCopyToastMessage] = useState8("");
1851
- const [viewMode, setViewMode] = useState8("grid");
1852
- const [showPivotConfig, setShowPivotConfig] = useState8(true);
1853
- const [draggingField, setDraggingField] = useState8(null);
1854
- const [activeFilterColumn, setActiveFilterColumn] = useState8(null);
1855
- const [filterDropdownPosition, setFilterDropdownPosition] = useState8({ top: 0, left: 0, maxHeight: 400 });
1856
- const [selectedCell, setSelectedCell] = useState8(null);
1857
- const [selectionStart, setSelectionStart] = useState8(null);
1858
- const [selectionEnd, setSelectionEnd] = useState8(null);
1859
- const [isSelecting, setIsSelecting] = useState8(false);
2145
+ const [currentFontSize, setCurrentFontSize] = useState9(initialFontSize);
2146
+ const [globalSearchTerm, setGlobalSearchTerm] = useState9("");
2147
+ const [showSearchInput, setShowSearchInput] = useState9(false);
2148
+ const [currentPage, setCurrentPage] = useState9(1);
2149
+ const [columnWidths, setColumnWidths] = useState9({});
2150
+ const [resizingColumnId, setResizingColumnId] = useState9(null);
2151
+ const [resizeStartX, setResizeStartX] = useState9(0);
2152
+ const [resizeStartWidth, setResizeStartWidth] = useState9(0);
2153
+ const [gridHeight, setGridHeight] = useState9(initialHeight);
2154
+ const [isResizingVertically, setIsResizingVertically] = useState9(false);
2155
+ const [verticalResizeStartY, setVerticalResizeStartY] = useState9(0);
2156
+ const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState9(0);
2157
+ const [showCopyToast, setShowCopyToast] = useState9(false);
2158
+ const [copyToastMessage, setCopyToastMessage] = useState9("");
2159
+ const [viewMode, setViewMode] = useState9("grid");
2160
+ const [showPivotConfig, setShowPivotConfig] = useState9(true);
2161
+ const [draggingField, setDraggingField] = useState9(null);
2162
+ const [activeFilterColumn, setActiveFilterColumn] = useState9(null);
2163
+ const [filterDropdownPosition, setFilterDropdownPosition] = useState9({ top: 0, left: 0, maxHeight: 400 });
2164
+ const [selectedCell, setSelectedCell] = useState9(null);
2165
+ const [selectionStart, setSelectionStart] = useState9(null);
2166
+ const [selectionEnd, setSelectionEnd] = useState9(null);
2167
+ const [isSelecting, setIsSelecting] = useState9(false);
1860
2168
  const tableContainerRef = useRef2(null);
1861
2169
  const tableBodyRef = useRef2(null);
1862
2170
  const fontSizeOptions = [
@@ -1879,7 +2187,7 @@ function DataGrid({
1879
2187
  columnFilters,
1880
2188
  activeFilters
1881
2189
  } = useExcelGrid({ data, enableSorting: true, enableFiltering: true });
1882
- const filteredDataForPivot = useMemo8(() => {
2190
+ const filteredDataForPivot = useMemo9(() => {
1883
2191
  const filteredRows = table.getFilteredRowModel().rows;
1884
2192
  return filteredRows.map((row) => row.original);
1885
2193
  }, [table, columnFilters]);
@@ -1906,7 +2214,7 @@ function DataGrid({
1906
2214
  setRowFields,
1907
2215
  setColumnFields
1908
2216
  } = usePivotTable(filteredDataForPivot);
1909
- const activeFilterInfo = useMemo8(() => {
2217
+ const activeFilterInfo = useMemo9(() => {
1910
2218
  if (activeFilters.length === 0) return null;
1911
2219
  return activeFilters.map((f) => ({
1912
2220
  column: f.column,
@@ -1914,8 +2222,8 @@ function DataGrid({
1914
2222
  values: f.values || []
1915
2223
  }));
1916
2224
  }, [activeFilters]);
1917
- const rows = useMemo8(() => table.getFilteredRowModel().rows, [table, columnFilters]);
1918
- const searchFilteredData = useMemo8(() => {
2225
+ const rows = useMemo9(() => table.getFilteredRowModel().rows, [table, columnFilters]);
2226
+ const searchFilteredData = useMemo9(() => {
1919
2227
  if (!globalSearchTerm.trim() || !enableSearch) {
1920
2228
  return rows;
1921
2229
  }
@@ -1932,20 +2240,20 @@ function DataGrid({
1932
2240
  });
1933
2241
  }, [rows, globalSearchTerm, enableSearch, columnKeys]);
1934
2242
  const totalSearchedRows = searchFilteredData.length;
1935
- const totalPages = useMemo8(() => {
2243
+ const totalPages = useMemo9(() => {
1936
2244
  if (!enablePagination) return 1;
1937
2245
  return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
1938
2246
  }, [enablePagination, totalSearchedRows, pageSize]);
1939
- const paginatedRows = useMemo8(() => {
2247
+ const paginatedRows = useMemo9(() => {
1940
2248
  if (!enablePagination) return searchFilteredData;
1941
2249
  const start = (currentPage - 1) * pageSize;
1942
2250
  const end = start + pageSize;
1943
2251
  return searchFilteredData.slice(start, end);
1944
2252
  }, [enablePagination, searchFilteredData, currentPage, pageSize]);
1945
- useEffect4(() => {
2253
+ useEffect5(() => {
1946
2254
  setCurrentPage(1);
1947
2255
  }, [columnFilters, globalSearchTerm]);
1948
- const selectionBounds = useMemo8(() => {
2256
+ const selectionBounds = useMemo9(() => {
1949
2257
  if (!selectionStart || !selectionEnd) return null;
1950
2258
  return {
1951
2259
  minRow: Math.min(selectionStart.row, selectionEnd.row),
@@ -1954,7 +2262,7 @@ function DataGrid({
1954
2262
  maxCol: Math.max(selectionStart.col, selectionEnd.col)
1955
2263
  };
1956
2264
  }, [selectionStart, selectionEnd]);
1957
- const selectionStats = useMemo8(() => {
2265
+ const selectionStats = useMemo9(() => {
1958
2266
  if (!selectionBounds) return null;
1959
2267
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
1960
2268
  const values = [];
@@ -1980,7 +2288,7 @@ function DataGrid({
1980
2288
  const avg = sum / values.length;
1981
2289
  return { count, sum, avg, numericCount: values.length };
1982
2290
  }, [selectionBounds, rows, columnKeys]);
1983
- useEffect4(() => {
2291
+ useEffect5(() => {
1984
2292
  if (data.length === 0) return;
1985
2293
  const widths = {};
1986
2294
  const sampleSize = Math.min(100, data.length);
@@ -2000,7 +2308,7 @@ function DataGrid({
2000
2308
  }
2001
2309
  setColumnWidths(widths);
2002
2310
  }, [data, columnKeys]);
2003
- const startColumnResize = useCallback8(
2311
+ const startColumnResize = useCallback9(
2004
2312
  (columnId, event) => {
2005
2313
  if (!enableColumnResize) return;
2006
2314
  event.preventDefault();
@@ -2011,7 +2319,7 @@ function DataGrid({
2011
2319
  },
2012
2320
  [enableColumnResize, columnWidths]
2013
2321
  );
2014
- useEffect4(() => {
2322
+ useEffect5(() => {
2015
2323
  if (!resizingColumnId) return;
2016
2324
  const handleResizeMove = (event) => {
2017
2325
  const diff = event.clientX - resizeStartX;
@@ -2031,7 +2339,7 @@ function DataGrid({
2031
2339
  document.removeEventListener("mouseup", handleResizeEnd);
2032
2340
  };
2033
2341
  }, [resizingColumnId, resizeStartX, resizeStartWidth]);
2034
- const startVerticalResize = useCallback8(
2342
+ const startVerticalResize = useCallback9(
2035
2343
  (event) => {
2036
2344
  if (!enableVerticalResize) return;
2037
2345
  event.preventDefault();
@@ -2041,7 +2349,7 @@ function DataGrid({
2041
2349
  },
2042
2350
  [enableVerticalResize, gridHeight]
2043
2351
  );
2044
- useEffect4(() => {
2352
+ useEffect5(() => {
2045
2353
  if (!isResizingVertically) return;
2046
2354
  const handleVerticalResizeMove = (event) => {
2047
2355
  const diff = event.clientY - verticalResizeStartY;
@@ -2058,7 +2366,7 @@ function DataGrid({
2058
2366
  document.removeEventListener("mouseup", handleVerticalResizeEnd);
2059
2367
  };
2060
2368
  }, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
2061
- const handleExport = useCallback8(() => {
2369
+ const handleExport = useCallback9(() => {
2062
2370
  if (viewMode === "pivot") {
2063
2371
  if (!pivotResult) return;
2064
2372
  const pivotFilename = exportFilename.replace(".csv", "-pivot.csv");
@@ -2103,7 +2411,7 @@ function DataGrid({
2103
2411
  columnKeys,
2104
2412
  onExport
2105
2413
  ]);
2106
- const copySelectionToClipboard = useCallback8(() => {
2414
+ const copySelectionToClipboard = useCallback9(() => {
2107
2415
  if (!selectionBounds || !enableClipboard) return;
2108
2416
  const text = formatSelectionForClipboard(
2109
2417
  rows.map((r) => r.original),
@@ -2127,7 +2435,7 @@ function DataGrid({
2127
2435
  }
2128
2436
  );
2129
2437
  }, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
2130
- const handleMouseDown = useCallback8(
2438
+ const handleMouseDown = useCallback9(
2131
2439
  (rowIndex, colIndex, event) => {
2132
2440
  event.preventDefault();
2133
2441
  if (event.shiftKey && selectedCell) {
@@ -2151,7 +2459,7 @@ function DataGrid({
2151
2459
  },
2152
2460
  [selectedCell, rows, columnKeys, onCellClick]
2153
2461
  );
2154
- const handleMouseEnter = useCallback8(
2462
+ const handleMouseEnter = useCallback9(
2155
2463
  (rowIndex, colIndex) => {
2156
2464
  if (isSelecting) {
2157
2465
  setSelectionEnd({ row: rowIndex, col: colIndex });
@@ -2159,12 +2467,12 @@ function DataGrid({
2159
2467
  },
2160
2468
  [isSelecting]
2161
2469
  );
2162
- useEffect4(() => {
2470
+ useEffect5(() => {
2163
2471
  const handleMouseUp = () => setIsSelecting(false);
2164
2472
  document.addEventListener("mouseup", handleMouseUp);
2165
2473
  return () => document.removeEventListener("mouseup", handleMouseUp);
2166
2474
  }, []);
2167
- useEffect4(() => {
2475
+ useEffect5(() => {
2168
2476
  const handleKeydown = (event) => {
2169
2477
  if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
2170
2478
  event.preventDefault();
@@ -2182,7 +2490,7 @@ function DataGrid({
2182
2490
  document.addEventListener("keydown", handleKeydown);
2183
2491
  return () => document.removeEventListener("keydown", handleKeydown);
2184
2492
  }, [selectionBounds, copySelectionToClipboard]);
2185
- const openFilterDropdown = useCallback8(
2493
+ const openFilterDropdown = useCallback9(
2186
2494
  (columnId, event) => {
2187
2495
  event.stopPropagation();
2188
2496
  const target = event.currentTarget;
@@ -2211,16 +2519,16 @@ function DataGrid({
2211
2519
  },
2212
2520
  []
2213
2521
  );
2214
- const closeFilterDropdown = useCallback8(() => {
2522
+ const closeFilterDropdown = useCallback9(() => {
2215
2523
  setActiveFilterColumn(null);
2216
2524
  }, []);
2217
- const handleFilter = useCallback8(
2525
+ const handleFilter = useCallback9(
2218
2526
  (columnId, values) => {
2219
2527
  setColumnFilter(columnId, values);
2220
2528
  },
2221
2529
  [setColumnFilter]
2222
2530
  );
2223
- const handleSort = useCallback8(
2531
+ const handleSort = useCallback9(
2224
2532
  (columnId, direction) => {
2225
2533
  if (direction === null) {
2226
2534
  const current = getSortDirection(columnId);
@@ -2244,7 +2552,7 @@ function DataGrid({
2244
2552
  },
2245
2553
  [getSortDirection, toggleSort]
2246
2554
  );
2247
- const isCellSelected = useCallback8(
2555
+ const isCellSelected = useCallback9(
2248
2556
  (rowIndex, colIndex) => {
2249
2557
  if (!selectionBounds) {
2250
2558
  return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
@@ -2282,30 +2590,30 @@ function DataGrid({
2282
2590
  }
2283
2591
  return String(value);
2284
2592
  };
2285
- const totalTableWidth = useMemo8(() => {
2593
+ const totalTableWidth = useMemo9(() => {
2286
2594
  return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
2287
2595
  }, [columnKeys, columnWidths]);
2288
2596
  const activeFilterCount = columnFilters.length;
2289
- return /* @__PURE__ */ jsxs4(
2597
+ return /* @__PURE__ */ jsxs5(
2290
2598
  "div",
2291
2599
  {
2292
2600
  className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
2293
2601
  style: { height: `${gridHeight}px` },
2294
2602
  children: [
2295
- showCopyToast && /* @__PURE__ */ jsxs4("div", { className: "vpg-toast", children: [
2296
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
2603
+ showCopyToast && /* @__PURE__ */ jsxs5("div", { className: "vpg-toast", children: [
2604
+ /* @__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" }) }),
2297
2605
  copyToastMessage
2298
2606
  ] }),
2299
- /* @__PURE__ */ jsxs4("div", { className: "vpg-toolbar", children: [
2300
- /* @__PURE__ */ jsxs4("div", { className: "vpg-toolbar-left", children: [
2301
- showPivot && /* @__PURE__ */ jsxs4("div", { className: "vpg-view-toggle", children: [
2302
- /* @__PURE__ */ jsxs4(
2607
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-toolbar", children: [
2608
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-toolbar-left", children: [
2609
+ showPivot && /* @__PURE__ */ jsxs5("div", { className: "vpg-view-toggle", children: [
2610
+ /* @__PURE__ */ jsxs5(
2303
2611
  "button",
2304
2612
  {
2305
2613
  className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
2306
2614
  onClick: () => setViewMode("grid"),
2307
2615
  children: [
2308
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2616
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2309
2617
  "path",
2310
2618
  {
2311
2619
  strokeLinecap: "round",
@@ -2318,13 +2626,13 @@ function DataGrid({
2318
2626
  ]
2319
2627
  }
2320
2628
  ),
2321
- /* @__PURE__ */ jsxs4(
2629
+ /* @__PURE__ */ jsxs5(
2322
2630
  "button",
2323
2631
  {
2324
2632
  className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
2325
2633
  onClick: () => setViewMode("pivot"),
2326
2634
  children: [
2327
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2635
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2328
2636
  "path",
2329
2637
  {
2330
2638
  strokeLinecap: "round",
@@ -2338,14 +2646,14 @@ function DataGrid({
2338
2646
  }
2339
2647
  )
2340
2648
  ] }),
2341
- viewMode === "grid" && /* @__PURE__ */ jsxs4(Fragment2, { children: [
2342
- enableSearch && /* @__PURE__ */ jsx4("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx4(
2649
+ viewMode === "grid" && /* @__PURE__ */ jsxs5(Fragment3, { children: [
2650
+ enableSearch && /* @__PURE__ */ jsx5("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx5(
2343
2651
  "button",
2344
2652
  {
2345
2653
  className: "vpg-icon-btn",
2346
2654
  title: "Search (Ctrl+F)",
2347
2655
  onClick: () => setShowSearchInput(true),
2348
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2656
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2349
2657
  "path",
2350
2658
  {
2351
2659
  strokeLinecap: "round",
@@ -2355,15 +2663,15 @@ function DataGrid({
2355
2663
  }
2356
2664
  ) })
2357
2665
  }
2358
- ) : /* @__PURE__ */ jsxs4("div", { className: "vpg-search-box", children: [
2359
- /* @__PURE__ */ jsx4(
2666
+ ) : /* @__PURE__ */ jsxs5("div", { className: "vpg-search-box", children: [
2667
+ /* @__PURE__ */ jsx5(
2360
2668
  "svg",
2361
2669
  {
2362
2670
  className: "vpg-search-icon",
2363
2671
  fill: "none",
2364
2672
  stroke: "currentColor",
2365
2673
  viewBox: "0 0 24 24",
2366
- children: /* @__PURE__ */ jsx4(
2674
+ children: /* @__PURE__ */ jsx5(
2367
2675
  "path",
2368
2676
  {
2369
2677
  strokeLinecap: "round",
@@ -2374,7 +2682,7 @@ function DataGrid({
2374
2682
  )
2375
2683
  }
2376
2684
  ),
2377
- /* @__PURE__ */ jsx4(
2685
+ /* @__PURE__ */ jsx5(
2378
2686
  "input",
2379
2687
  {
2380
2688
  type: "text",
@@ -2391,14 +2699,14 @@ function DataGrid({
2391
2699
  autoFocus: true
2392
2700
  }
2393
2701
  ),
2394
- globalSearchTerm && /* @__PURE__ */ jsx4("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx4(
2702
+ globalSearchTerm && /* @__PURE__ */ jsx5("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx5(
2395
2703
  "svg",
2396
2704
  {
2397
2705
  className: "vpg-icon-xs",
2398
2706
  fill: "none",
2399
2707
  stroke: "currentColor",
2400
2708
  viewBox: "0 0 24 24",
2401
- children: /* @__PURE__ */ jsx4(
2709
+ children: /* @__PURE__ */ jsx5(
2402
2710
  "path",
2403
2711
  {
2404
2712
  strokeLinecap: "round",
@@ -2410,9 +2718,9 @@ function DataGrid({
2410
2718
  }
2411
2719
  ) })
2412
2720
  ] }) }),
2413
- /* @__PURE__ */ jsxs4("div", { className: "vpg-font-size-control", children: [
2414
- /* @__PURE__ */ jsx4("span", { className: "vpg-label", children: "Size:" }),
2415
- /* @__PURE__ */ jsx4("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx4(
2721
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-font-size-control", children: [
2722
+ /* @__PURE__ */ jsx5("span", { className: "vpg-label", children: "Size:" }),
2723
+ /* @__PURE__ */ jsx5("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx5(
2416
2724
  "button",
2417
2725
  {
2418
2726
  className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
@@ -2422,8 +2730,8 @@ function DataGrid({
2422
2730
  opt.value
2423
2731
  )) })
2424
2732
  ] }),
2425
- activeFilterCount > 0 && /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-info", children: [
2426
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx4(
2733
+ activeFilterCount > 0 && /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-info", children: [
2734
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx5(
2427
2735
  "path",
2428
2736
  {
2429
2737
  fillRule: "evenodd",
@@ -2431,26 +2739,26 @@ function DataGrid({
2431
2739
  clipRule: "evenodd"
2432
2740
  }
2433
2741
  ) }),
2434
- /* @__PURE__ */ jsxs4("span", { children: [
2742
+ /* @__PURE__ */ jsxs5("span", { children: [
2435
2743
  activeFilterCount,
2436
2744
  " filter",
2437
2745
  activeFilterCount > 1 ? "s" : ""
2438
2746
  ] })
2439
2747
  ] }),
2440
- globalSearchTerm && /* @__PURE__ */ jsx4("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs4("span", { children: [
2748
+ globalSearchTerm && /* @__PURE__ */ jsx5("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs5("span", { children: [
2441
2749
  totalSearchedRows,
2442
2750
  " match",
2443
2751
  totalSearchedRows !== 1 ? "es" : ""
2444
2752
  ] }) })
2445
2753
  ] }),
2446
- viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs4(Fragment2, { children: [
2447
- /* @__PURE__ */ jsxs4(
2754
+ viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs5(Fragment3, { children: [
2755
+ /* @__PURE__ */ jsxs5(
2448
2756
  "button",
2449
2757
  {
2450
2758
  className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
2451
2759
  onClick: () => setShowPivotConfig(!showPivotConfig),
2452
2760
  children: [
2453
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2761
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2454
2762
  "path",
2455
2763
  {
2456
2764
  strokeLinecap: "round",
@@ -2464,8 +2772,8 @@ function DataGrid({
2464
2772
  ]
2465
2773
  }
2466
2774
  ),
2467
- pivotIsConfigured && /* @__PURE__ */ jsxs4("div", { className: "vpg-pivot-status", children: [
2468
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx4(
2775
+ pivotIsConfigured && /* @__PURE__ */ jsxs5("div", { className: "vpg-pivot-status", children: [
2776
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx5(
2469
2777
  "path",
2470
2778
  {
2471
2779
  fillRule: "evenodd",
@@ -2473,13 +2781,13 @@ function DataGrid({
2473
2781
  clipRule: "evenodd"
2474
2782
  }
2475
2783
  ) }),
2476
- /* @__PURE__ */ jsx4("span", { children: "Pivot configured" })
2784
+ /* @__PURE__ */ jsx5("span", { children: "Pivot configured" })
2477
2785
  ] })
2478
2786
  ] })
2479
2787
  ] }),
2480
- /* @__PURE__ */ jsxs4("div", { className: "vpg-toolbar-right", children: [
2481
- viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs4("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
2482
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2788
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-toolbar-right", children: [
2789
+ viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs5("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
2790
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2483
2791
  "path",
2484
2792
  {
2485
2793
  strokeLinecap: "round",
@@ -2490,13 +2798,13 @@ function DataGrid({
2490
2798
  ) }),
2491
2799
  "Clear Filters"
2492
2800
  ] }),
2493
- enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx4(
2801
+ enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx5(
2494
2802
  "button",
2495
2803
  {
2496
2804
  className: "vpg-icon-btn",
2497
2805
  title: "Copy selection (Ctrl+C)",
2498
2806
  onClick: copySelectionToClipboard,
2499
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2807
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2500
2808
  "path",
2501
2809
  {
2502
2810
  strokeLinecap: "round",
@@ -2507,14 +2815,14 @@ function DataGrid({
2507
2815
  ) })
2508
2816
  }
2509
2817
  ),
2510
- enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ jsxs4(
2818
+ enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ jsxs5(
2511
2819
  "button",
2512
2820
  {
2513
2821
  className: "vpg-export-btn",
2514
2822
  title: viewMode === "pivot" ? "Export Pivot to CSV" : "Export to CSV",
2515
2823
  onClick: handleExport,
2516
2824
  children: [
2517
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2825
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2518
2826
  "path",
2519
2827
  {
2520
2828
  strokeLinecap: "round",
@@ -2530,13 +2838,13 @@ function DataGrid({
2530
2838
  )
2531
2839
  ] })
2532
2840
  ] }),
2533
- viewMode === "grid" && /* @__PURE__ */ jsxs4("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
2534
- loading && /* @__PURE__ */ jsxs4("div", { className: "vpg-loading", children: [
2535
- /* @__PURE__ */ jsx4("div", { className: "vpg-spinner" }),
2536
- /* @__PURE__ */ jsx4("span", { children: "Loading data..." })
2841
+ viewMode === "grid" && /* @__PURE__ */ jsxs5("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
2842
+ loading && /* @__PURE__ */ jsxs5("div", { className: "vpg-loading", children: [
2843
+ /* @__PURE__ */ jsx5("div", { className: "vpg-spinner" }),
2844
+ /* @__PURE__ */ jsx5("span", { children: "Loading data..." })
2537
2845
  ] }),
2538
- !loading && data.length === 0 && /* @__PURE__ */ jsxs4("div", { className: "vpg-empty", children: [
2539
- /* @__PURE__ */ jsx4("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2846
+ !loading && data.length === 0 && /* @__PURE__ */ jsxs5("div", { className: "vpg-empty", children: [
2847
+ /* @__PURE__ */ jsx5("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2540
2848
  "path",
2541
2849
  {
2542
2850
  strokeLinecap: "round",
@@ -2545,10 +2853,10 @@ function DataGrid({
2545
2853
  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"
2546
2854
  }
2547
2855
  ) }) }),
2548
- /* @__PURE__ */ jsx4("span", { children: "No data available" })
2856
+ /* @__PURE__ */ jsx5("span", { children: "No data available" })
2549
2857
  ] }),
2550
- !loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs4("div", { className: "vpg-empty", children: [
2551
- /* @__PURE__ */ jsx4("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2858
+ !loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs5("div", { className: "vpg-empty", children: [
2859
+ /* @__PURE__ */ jsx5("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2552
2860
  "path",
2553
2861
  {
2554
2862
  strokeLinecap: "round",
@@ -2557,11 +2865,11 @@ function DataGrid({
2557
2865
  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"
2558
2866
  }
2559
2867
  ) }) }),
2560
- /* @__PURE__ */ jsx4("span", { children: "No matching records" }),
2561
- /* @__PURE__ */ jsx4("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
2868
+ /* @__PURE__ */ jsx5("span", { children: "No matching records" }),
2869
+ /* @__PURE__ */ jsx5("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
2562
2870
  ] }),
2563
- !loading && filteredRowCount > 0 && /* @__PURE__ */ jsx4("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs4("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
2564
- /* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsx4("tr", { children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsxs4(
2871
+ !loading && filteredRowCount > 0 && /* @__PURE__ */ jsx5("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs5("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
2872
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsx5("tr", { children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsxs5(
2565
2873
  "th",
2566
2874
  {
2567
2875
  className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
@@ -2576,16 +2884,16 @@ function DataGrid({
2576
2884
  }
2577
2885
  },
2578
2886
  children: [
2579
- /* @__PURE__ */ jsxs4("div", { className: "vpg-header-content", children: [
2580
- /* @__PURE__ */ jsx4("span", { className: "vpg-header-text", children: colId }),
2581
- /* @__PURE__ */ jsxs4("div", { className: "vpg-header-icons", children: [
2582
- getSortDirection(colId) && /* @__PURE__ */ jsx4("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx4(
2887
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-header-content", children: [
2888
+ /* @__PURE__ */ jsx5("span", { className: "vpg-header-text", children: colId }),
2889
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-header-icons", children: [
2890
+ getSortDirection(colId) && /* @__PURE__ */ jsx5("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx5(
2583
2891
  "svg",
2584
2892
  {
2585
2893
  className: "vpg-icon-sm",
2586
2894
  fill: "currentColor",
2587
2895
  viewBox: "0 0 20 20",
2588
- children: /* @__PURE__ */ jsx4(
2896
+ children: /* @__PURE__ */ jsx5(
2589
2897
  "path",
2590
2898
  {
2591
2899
  fillRule: "evenodd",
@@ -2594,13 +2902,13 @@ function DataGrid({
2594
2902
  }
2595
2903
  )
2596
2904
  }
2597
- ) : /* @__PURE__ */ jsx4(
2905
+ ) : /* @__PURE__ */ jsx5(
2598
2906
  "svg",
2599
2907
  {
2600
2908
  className: "vpg-icon-sm",
2601
2909
  fill: "currentColor",
2602
2910
  viewBox: "0 0 20 20",
2603
- children: /* @__PURE__ */ jsx4(
2911
+ children: /* @__PURE__ */ jsx5(
2604
2912
  "path",
2605
2913
  {
2606
2914
  fillRule: "evenodd",
@@ -2610,13 +2918,13 @@ function DataGrid({
2610
2918
  )
2611
2919
  }
2612
2920
  ) }),
2613
- hasActiveFilter(colId) && /* @__PURE__ */ jsx4("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx4(
2921
+ hasActiveFilter(colId) && /* @__PURE__ */ jsx5("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx5(
2614
2922
  "svg",
2615
2923
  {
2616
2924
  className: "vpg-icon-xs",
2617
2925
  fill: "currentColor",
2618
2926
  viewBox: "0 0 20 20",
2619
- children: /* @__PURE__ */ jsx4(
2927
+ children: /* @__PURE__ */ jsx5(
2620
2928
  "path",
2621
2929
  {
2622
2930
  fillRule: "evenodd",
@@ -2626,14 +2934,14 @@ function DataGrid({
2626
2934
  )
2627
2935
  }
2628
2936
  ) }),
2629
- /* @__PURE__ */ jsx4("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx4(
2937
+ /* @__PURE__ */ jsx5("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx5(
2630
2938
  "svg",
2631
2939
  {
2632
2940
  className: "vpg-icon-sm",
2633
2941
  fill: "none",
2634
2942
  stroke: "currentColor",
2635
2943
  viewBox: "0 0 24 24",
2636
- children: /* @__PURE__ */ jsx4(
2944
+ children: /* @__PURE__ */ jsx5(
2637
2945
  "path",
2638
2946
  {
2639
2947
  strokeLinecap: "round",
@@ -2646,7 +2954,7 @@ function DataGrid({
2646
2954
  ) })
2647
2955
  ] })
2648
2956
  ] }),
2649
- enableColumnResize && /* @__PURE__ */ jsx4(
2957
+ enableColumnResize && /* @__PURE__ */ jsx5(
2650
2958
  "div",
2651
2959
  {
2652
2960
  className: "vpg-resize-handle",
@@ -2657,7 +2965,7 @@ function DataGrid({
2657
2965
  },
2658
2966
  colId
2659
2967
  )) }) }),
2660
- /* @__PURE__ */ jsx4("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx4("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx4(
2968
+ /* @__PURE__ */ jsx5("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx5("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx5(
2661
2969
  "td",
2662
2970
  {
2663
2971
  className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
@@ -2675,8 +2983,8 @@ function DataGrid({
2675
2983
  )) }, row.id)) })
2676
2984
  ] }) })
2677
2985
  ] }),
2678
- viewMode === "pivot" && /* @__PURE__ */ jsxs4("div", { className: "vpg-pivot-container", children: [
2679
- showPivotConfig && canUsePivot && /* @__PURE__ */ jsx4("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx4(
2986
+ viewMode === "pivot" && /* @__PURE__ */ jsxs5("div", { className: "vpg-pivot-container", children: [
2987
+ showPivotConfig && canUsePivot && /* @__PURE__ */ jsx5("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx5(
2680
2988
  PivotConfig,
2681
2989
  {
2682
2990
  availableFields: pivotAvailableFields,
@@ -2700,7 +3008,7 @@ function DataGrid({
2700
3008
  onRemoveValueField: removeValueField
2701
3009
  }
2702
3010
  ) }),
2703
- /* @__PURE__ */ jsx4("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx4(
3011
+ /* @__PURE__ */ jsx5("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx5(
2704
3012
  PivotSkeleton,
2705
3013
  {
2706
3014
  rowFields: pivotRowFields,
@@ -2725,44 +3033,44 @@ function DataGrid({
2725
3033
  }
2726
3034
  ) })
2727
3035
  ] }),
2728
- /* @__PURE__ */ jsxs4("div", { className: "vpg-footer", children: [
2729
- /* @__PURE__ */ jsx4("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
2730
- /* @__PURE__ */ jsxs4("span", { children: [
3036
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-footer", children: [
3037
+ /* @__PURE__ */ jsx5("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3038
+ /* @__PURE__ */ jsxs5("span", { children: [
2731
3039
  ((currentPage - 1) * pageSize + 1).toLocaleString(),
2732
3040
  "-",
2733
3041
  Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
2734
3042
  ] }),
2735
- /* @__PURE__ */ jsx4("span", { className: "vpg-separator", children: "of" }),
2736
- /* @__PURE__ */ jsx4("span", { children: totalSearchedRows.toLocaleString() }),
2737
- totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs4("span", { className: "vpg-filtered-note", children: [
3043
+ /* @__PURE__ */ jsx5("span", { className: "vpg-separator", children: "of" }),
3044
+ /* @__PURE__ */ jsx5("span", { children: totalSearchedRows.toLocaleString() }),
3045
+ totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs5("span", { className: "vpg-filtered-note", children: [
2738
3046
  "(",
2739
3047
  totalRowCount.toLocaleString(),
2740
3048
  " total)"
2741
3049
  ] })
2742
- ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs4("span", { children: [
3050
+ ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs5("span", { children: [
2743
3051
  totalRowCount.toLocaleString(),
2744
3052
  " records"
2745
- ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2746
- /* @__PURE__ */ jsx4("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
2747
- /* @__PURE__ */ jsx4("span", { className: "vpg-separator", children: "of" }),
2748
- /* @__PURE__ */ jsx4("span", { children: totalRowCount.toLocaleString() }),
2749
- /* @__PURE__ */ jsx4("span", { className: "vpg-separator", children: "records" })
2750
- ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2751
- /* @__PURE__ */ jsx4("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
2752
- /* @__PURE__ */ jsx4("span", { className: "vpg-separator", children: "\u2022" }),
2753
- /* @__PURE__ */ jsxs4("span", { children: [
3053
+ ] }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
3054
+ /* @__PURE__ */ jsx5("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
3055
+ /* @__PURE__ */ jsx5("span", { className: "vpg-separator", children: "of" }),
3056
+ /* @__PURE__ */ jsx5("span", { children: totalRowCount.toLocaleString() }),
3057
+ /* @__PURE__ */ jsx5("span", { className: "vpg-separator", children: "records" })
3058
+ ] }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
3059
+ /* @__PURE__ */ jsx5("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
3060
+ /* @__PURE__ */ jsx5("span", { className: "vpg-separator", children: "\u2022" }),
3061
+ /* @__PURE__ */ jsxs5("span", { children: [
2754
3062
  totalRowCount.toLocaleString(),
2755
3063
  " source records"
2756
3064
  ] })
2757
3065
  ] }) }),
2758
- enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs4("div", { className: "vpg-pagination", children: [
2759
- /* @__PURE__ */ jsx4(
3066
+ enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs5("div", { className: "vpg-pagination", children: [
3067
+ /* @__PURE__ */ jsx5(
2760
3068
  "button",
2761
3069
  {
2762
3070
  className: "vpg-page-btn",
2763
3071
  disabled: currentPage === 1,
2764
3072
  onClick: () => setCurrentPage(1),
2765
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
3073
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2766
3074
  "path",
2767
3075
  {
2768
3076
  strokeLinecap: "round",
@@ -2773,13 +3081,13 @@ function DataGrid({
2773
3081
  ) })
2774
3082
  }
2775
3083
  ),
2776
- /* @__PURE__ */ jsx4(
3084
+ /* @__PURE__ */ jsx5(
2777
3085
  "button",
2778
3086
  {
2779
3087
  className: "vpg-page-btn",
2780
3088
  disabled: currentPage === 1,
2781
3089
  onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
2782
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
3090
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2783
3091
  "path",
2784
3092
  {
2785
3093
  strokeLinecap: "round",
@@ -2790,19 +3098,19 @@ function DataGrid({
2790
3098
  ) })
2791
3099
  }
2792
3100
  ),
2793
- /* @__PURE__ */ jsxs4("span", { className: "vpg-page-info", children: [
3101
+ /* @__PURE__ */ jsxs5("span", { className: "vpg-page-info", children: [
2794
3102
  "Page ",
2795
3103
  currentPage,
2796
3104
  " of ",
2797
3105
  totalPages
2798
3106
  ] }),
2799
- /* @__PURE__ */ jsx4(
3107
+ /* @__PURE__ */ jsx5(
2800
3108
  "button",
2801
3109
  {
2802
3110
  className: "vpg-page-btn",
2803
3111
  disabled: currentPage === totalPages,
2804
3112
  onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
2805
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
3113
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2806
3114
  "path",
2807
3115
  {
2808
3116
  strokeLinecap: "round",
@@ -2813,13 +3121,13 @@ function DataGrid({
2813
3121
  ) })
2814
3122
  }
2815
3123
  ),
2816
- /* @__PURE__ */ jsx4(
3124
+ /* @__PURE__ */ jsx5(
2817
3125
  "button",
2818
3126
  {
2819
3127
  className: "vpg-page-btn",
2820
3128
  disabled: currentPage === totalPages,
2821
3129
  onClick: () => setCurrentPage(totalPages),
2822
- children: /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
3130
+ children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2823
3131
  "path",
2824
3132
  {
2825
3133
  strokeLinecap: "round",
@@ -2831,45 +3139,45 @@ function DataGrid({
2831
3139
  }
2832
3140
  )
2833
3141
  ] }),
2834
- viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs4("div", { className: "vpg-selection-stats", children: [
2835
- /* @__PURE__ */ jsxs4("span", { className: "vpg-stat", children: [
2836
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-label", children: "Count:" }),
2837
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-value", children: selectionStats.count })
3142
+ viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs5("div", { className: "vpg-selection-stats", children: [
3143
+ /* @__PURE__ */ jsxs5("span", { className: "vpg-stat", children: [
3144
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-label", children: "Count:" }),
3145
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-value", children: selectionStats.count })
2838
3146
  ] }),
2839
- selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs4(Fragment2, { children: [
2840
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-divider", children: "|" }),
2841
- /* @__PURE__ */ jsxs4("span", { className: "vpg-stat", children: [
2842
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-label", children: "Sum:" }),
2843
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
3147
+ selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs5(Fragment3, { children: [
3148
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-divider", children: "|" }),
3149
+ /* @__PURE__ */ jsxs5("span", { className: "vpg-stat", children: [
3150
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-label", children: "Sum:" }),
3151
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
2844
3152
  ] }),
2845
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-divider", children: "|" }),
2846
- /* @__PURE__ */ jsxs4("span", { className: "vpg-stat", children: [
2847
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-label", children: "Avg:" }),
2848
- /* @__PURE__ */ jsx4("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
3153
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-divider", children: "|" }),
3154
+ /* @__PURE__ */ jsxs5("span", { className: "vpg-stat", children: [
3155
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-label", children: "Avg:" }),
3156
+ /* @__PURE__ */ jsx5("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
2849
3157
  ] })
2850
3158
  ] })
2851
3159
  ] }),
2852
- /* @__PURE__ */ jsx4("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs4("div", { className: "vpg-demo-banner", children: [
2853
- /* @__PURE__ */ jsx4("span", { className: "vpg-demo-badge", children: "DEMO" }),
2854
- /* @__PURE__ */ jsx4("span", { children: "Pro features enabled" }),
2855
- /* @__PURE__ */ jsx4("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
2856
- ] }) : showWatermark ? /* @__PURE__ */ jsx4("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs4("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
2857
- /* @__PURE__ */ jsxs4("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: [
2858
- /* @__PURE__ */ jsx4("rect", { x: "3", y: "3", width: "7", height: "7" }),
2859
- /* @__PURE__ */ jsx4("rect", { x: "14", y: "3", width: "7", height: "7" }),
2860
- /* @__PURE__ */ jsx4("rect", { x: "14", y: "14", width: "7", height: "7" }),
2861
- /* @__PURE__ */ jsx4("rect", { x: "3", y: "14", width: "7", height: "7" })
3160
+ /* @__PURE__ */ jsx5("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs5("div", { className: "vpg-demo-banner", children: [
3161
+ /* @__PURE__ */ jsx5("span", { className: "vpg-demo-badge", children: "DEMO" }),
3162
+ /* @__PURE__ */ jsx5("span", { children: "Pro features enabled" }),
3163
+ /* @__PURE__ */ jsx5("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
3164
+ ] }) : showWatermark ? /* @__PURE__ */ jsx5("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs5("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
3165
+ /* @__PURE__ */ jsxs5("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: [
3166
+ /* @__PURE__ */ jsx5("rect", { x: "3", y: "3", width: "7", height: "7" }),
3167
+ /* @__PURE__ */ jsx5("rect", { x: "14", y: "3", width: "7", height: "7" }),
3168
+ /* @__PURE__ */ jsx5("rect", { x: "14", y: "14", width: "7", height: "7" }),
3169
+ /* @__PURE__ */ jsx5("rect", { x: "3", y: "14", width: "7", height: "7" })
2862
3170
  ] }),
2863
3171
  "Powered by TinyPivot"
2864
3172
  ] }) }) : null })
2865
3173
  ] }),
2866
- enableVerticalResize && /* @__PURE__ */ jsx4("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs4("div", { className: "vpg-resize-grip", children: [
2867
- /* @__PURE__ */ jsx4("span", {}),
2868
- /* @__PURE__ */ jsx4("span", {}),
2869
- /* @__PURE__ */ jsx4("span", {})
3174
+ enableVerticalResize && /* @__PURE__ */ jsx5("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs5("div", { className: "vpg-resize-grip", children: [
3175
+ /* @__PURE__ */ jsx5("span", {}),
3176
+ /* @__PURE__ */ jsx5("span", {}),
3177
+ /* @__PURE__ */ jsx5("span", {})
2870
3178
  ] }) }),
2871
- activeFilterColumn && createPortal(
2872
- /* @__PURE__ */ jsx4(
3179
+ activeFilterColumn && createPortal2(
3180
+ /* @__PURE__ */ jsx5(
2873
3181
  "div",
2874
3182
  {
2875
3183
  className: "vpg-filter-portal",
@@ -2880,7 +3188,7 @@ function DataGrid({
2880
3188
  maxHeight: `${filterDropdownPosition.maxHeight}px`,
2881
3189
  zIndex: 9999
2882
3190
  },
2883
- children: /* @__PURE__ */ jsx4(
3191
+ children: /* @__PURE__ */ jsx5(
2884
3192
  ColumnFilter,
2885
3193
  {
2886
3194
  columnId: activeFilterColumn,