@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.cjs CHANGED
@@ -45,8 +45,8 @@ __export(index_exports, {
45
45
  module.exports = __toCommonJS(index_exports);
46
46
 
47
47
  // src/components/DataGrid.tsx
48
- var import_react8 = require("react");
49
- var import_react_dom = require("react-dom");
48
+ var import_react9 = require("react");
49
+ var import_react_dom2 = require("react-dom");
50
50
 
51
51
  // src/hooks/useExcelGrid.ts
52
52
  var import_react = require("react");
@@ -312,6 +312,7 @@ function usePivotTable(data) {
312
312
  const [valueFields, setValueFields] = (0, import_react3.useState)([]);
313
313
  const [showRowTotals, setShowRowTotals] = (0, import_react3.useState)(true);
314
314
  const [showColumnTotals, setShowColumnTotals] = (0, import_react3.useState)(true);
315
+ const [calculatedFields, setCalculatedFields] = (0, import_react3.useState)(() => (0, import_tinypivot_core3.loadCalculatedFields)());
315
316
  const [currentStorageKey, setCurrentStorageKey] = (0, import_react3.useState)(null);
316
317
  const availableFields = (0, import_react3.useMemo)(() => {
317
318
  return (0, import_tinypivot_core3.computeAvailableFields)(data);
@@ -336,9 +337,10 @@ function usePivotTable(data) {
336
337
  columnFields,
337
338
  valueFields,
338
339
  showRowTotals,
339
- showColumnTotals
340
+ showColumnTotals,
341
+ calculatedFields
340
342
  });
341
- }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
343
+ }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
342
344
  (0, import_react3.useEffect)(() => {
343
345
  if (data.length === 0) return;
344
346
  const newKeys = Object.keys(data[0]);
@@ -352,6 +354,9 @@ function usePivotTable(data) {
352
354
  setValueFields(savedConfig.valueFields);
353
355
  setShowRowTotals(savedConfig.showRowTotals);
354
356
  setShowColumnTotals(savedConfig.showColumnTotals);
357
+ if (savedConfig.calculatedFields) {
358
+ setCalculatedFields(savedConfig.calculatedFields);
359
+ }
355
360
  } else {
356
361
  const currentConfig = {
357
362
  rowFields,
@@ -375,10 +380,11 @@ function usePivotTable(data) {
375
380
  columnFields,
376
381
  valueFields,
377
382
  showRowTotals,
378
- showColumnTotals
383
+ showColumnTotals,
384
+ calculatedFields
379
385
  };
380
386
  (0, import_tinypivot_core3.savePivotConfig)(currentStorageKey, config);
381
- }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
387
+ }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
382
388
  const addRowField = (0, import_react3.useCallback)(
383
389
  (field) => {
384
390
  if (!requirePro("Pivot Table - Row Fields")) return;
@@ -457,6 +463,27 @@ function usePivotTable(data) {
457
463
  setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
458
464
  }
459
465
  }, [availableFields, requirePro]);
466
+ const addCalculatedField = (0, import_react3.useCallback)((field) => {
467
+ setCalculatedFields((prev) => {
468
+ const existing = prev.findIndex((f) => f.id === field.id);
469
+ let updated;
470
+ if (existing >= 0) {
471
+ updated = [...prev.slice(0, existing), field, ...prev.slice(existing + 1)];
472
+ } else {
473
+ updated = [...prev, field];
474
+ }
475
+ (0, import_tinypivot_core3.saveCalculatedFields)(updated);
476
+ return updated;
477
+ });
478
+ }, []);
479
+ const removeCalculatedField = (0, import_react3.useCallback)((id) => {
480
+ setCalculatedFields((prev) => {
481
+ const updated = prev.filter((f) => f.id !== id);
482
+ (0, import_tinypivot_core3.saveCalculatedFields)(updated);
483
+ return updated;
484
+ });
485
+ setValueFields((prev) => prev.filter((v) => v.field !== `calc:${id}`));
486
+ }, []);
460
487
  return {
461
488
  // State
462
489
  rowFields,
@@ -464,6 +491,7 @@ function usePivotTable(data) {
464
491
  valueFields,
465
492
  showRowTotals,
466
493
  showColumnTotals,
494
+ calculatedFields,
467
495
  // Computed
468
496
  availableFields,
469
497
  unassignedFields,
@@ -482,7 +510,9 @@ function usePivotTable(data) {
482
510
  setShowColumnTotals,
483
511
  autoSuggestConfig,
484
512
  setRowFields,
485
- setColumnFields
513
+ setColumnFields,
514
+ addCalculatedField,
515
+ removeCalculatedField
486
516
  };
487
517
  }
488
518
 
@@ -954,10 +984,197 @@ function ColumnFilter({
954
984
  }
955
985
 
956
986
  // src/components/PivotConfig.tsx
987
+ var import_react7 = require("react");
988
+ var import_tinypivot_core6 = require("@smallwebco/tinypivot-core");
989
+
990
+ // src/components/CalculatedFieldModal.tsx
957
991
  var import_react6 = require("react");
992
+ var import_react_dom = require("react-dom");
958
993
  var import_tinypivot_core5 = require("@smallwebco/tinypivot-core");
959
994
  var import_jsx_runtime2 = require("react/jsx-runtime");
960
- function getFieldIcon(type) {
995
+ function CalculatedFieldModal({
996
+ show,
997
+ availableFields,
998
+ existingField,
999
+ onClose,
1000
+ onSave
1001
+ }) {
1002
+ const [name, setName] = (0, import_react6.useState)("");
1003
+ const [formula, setFormula] = (0, import_react6.useState)("");
1004
+ const [formatAs, setFormatAs] = (0, import_react6.useState)("number");
1005
+ const [decimals, setDecimals] = (0, import_react6.useState)(2);
1006
+ const [error, setError] = (0, import_react6.useState)(null);
1007
+ (0, import_react6.useEffect)(() => {
1008
+ if (show) {
1009
+ if (existingField) {
1010
+ setName(existingField.name);
1011
+ setFormula(existingField.formula);
1012
+ setFormatAs(existingField.formatAs || "number");
1013
+ setDecimals(existingField.decimals ?? 2);
1014
+ } else {
1015
+ setName("");
1016
+ setFormula("");
1017
+ setFormatAs("number");
1018
+ setDecimals(2);
1019
+ }
1020
+ setError(null);
1021
+ }
1022
+ }, [show, existingField]);
1023
+ const validationError = (0, import_react6.useMemo)(() => {
1024
+ if (!formula.trim()) return null;
1025
+ return (0, import_tinypivot_core5.validateSimpleFormula)(formula, availableFields);
1026
+ }, [formula, availableFields]);
1027
+ const insertField = (0, import_react6.useCallback)((field) => {
1028
+ setFormula((prev) => {
1029
+ if (prev.trim() && !prev.endsWith(" ")) {
1030
+ return prev + " " + field;
1031
+ }
1032
+ return prev + field;
1033
+ });
1034
+ }, []);
1035
+ const insertOperator = (0, import_react6.useCallback)((op) => {
1036
+ setFormula((prev) => {
1037
+ if (prev.trim() && !prev.endsWith(" ")) {
1038
+ return prev + " " + op + " ";
1039
+ }
1040
+ return prev + op + " ";
1041
+ });
1042
+ }, []);
1043
+ const handleSave = (0, import_react6.useCallback)(() => {
1044
+ if (!name.trim()) {
1045
+ setError("Name is required");
1046
+ return;
1047
+ }
1048
+ const validationResult = (0, import_tinypivot_core5.validateSimpleFormula)(formula, availableFields);
1049
+ if (validationResult) {
1050
+ setError(validationResult);
1051
+ return;
1052
+ }
1053
+ const field = {
1054
+ id: existingField?.id || `calc_${Date.now()}`,
1055
+ name: name.trim(),
1056
+ formula: formula.trim(),
1057
+ formatAs,
1058
+ decimals
1059
+ };
1060
+ onSave(field);
1061
+ onClose();
1062
+ }, [name, formula, formatAs, decimals, existingField, availableFields, onSave, onClose]);
1063
+ const handleOverlayClick = (0, import_react6.useCallback)((e) => {
1064
+ if (e.target === e.currentTarget) {
1065
+ onClose();
1066
+ }
1067
+ }, [onClose]);
1068
+ if (!show) return null;
1069
+ const modalContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-modal-overlay", onClick: handleOverlayClick, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal", children: [
1070
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal-header", children: [
1071
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h3", { children: [
1072
+ existingField ? "Edit" : "Create",
1073
+ " Calculated Field"
1074
+ ] }),
1075
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-modal-close", onClick: onClose, children: "\xD7" })
1076
+ ] }),
1077
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal-body", children: [
1078
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
1079
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Name" }),
1080
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1081
+ "input",
1082
+ {
1083
+ type: "text",
1084
+ className: "vpg-input",
1085
+ placeholder: "e.g., Profit Margin %",
1086
+ value: name,
1087
+ onChange: (e) => setName(e.target.value)
1088
+ }
1089
+ )
1090
+ ] }),
1091
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
1092
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Formula" }),
1093
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1094
+ "textarea",
1095
+ {
1096
+ className: "vpg-textarea",
1097
+ placeholder: "e.g., revenue / units",
1098
+ rows: 2,
1099
+ value: formula,
1100
+ onChange: (e) => setFormula(e.target.value)
1101
+ }
1102
+ ),
1103
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-formula-hint", children: "Use field names with math operators: + - * / ( )" }),
1104
+ validationError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-error", children: validationError })
1105
+ ] }),
1106
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
1107
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label-small", children: "Operators" }),
1108
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-button-group", children: [
1109
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("+"), children: "+" }),
1110
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("-"), children: "\u2212" }),
1111
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("*"), children: "\xD7" }),
1112
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("/"), children: "\xF7" }),
1113
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("("), children: "(" }),
1114
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator(")"), children: ")" })
1115
+ ] })
1116
+ ] }),
1117
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
1118
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label-small", children: "Insert Field" }),
1119
+ availableFields.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-button-group vpg-field-buttons", children: availableFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1120
+ "button",
1121
+ {
1122
+ className: "vpg-insert-btn vpg-field-btn",
1123
+ onClick: () => insertField(field),
1124
+ children: field
1125
+ },
1126
+ field
1127
+ )) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-no-fields", children: "No numeric fields available" })
1128
+ ] }),
1129
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-row", children: [
1130
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group vpg-form-group-half", children: [
1131
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Format As" }),
1132
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1133
+ "select",
1134
+ {
1135
+ className: "vpg-select",
1136
+ value: formatAs,
1137
+ onChange: (e) => setFormatAs(e.target.value),
1138
+ children: [
1139
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "number", children: "Number" }),
1140
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "percent", children: "Percentage" }),
1141
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "currency", children: "Currency ($)" })
1142
+ ]
1143
+ }
1144
+ )
1145
+ ] }),
1146
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group vpg-form-group-half", children: [
1147
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Decimals" }),
1148
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1149
+ "input",
1150
+ {
1151
+ type: "number",
1152
+ className: "vpg-input",
1153
+ min: 0,
1154
+ max: 6,
1155
+ value: decimals,
1156
+ onChange: (e) => setDecimals(Number(e.target.value))
1157
+ }
1158
+ )
1159
+ ] })
1160
+ ] }),
1161
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-error vpg-error-box", children: error })
1162
+ ] }),
1163
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal-footer", children: [
1164
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-btn vpg-btn-secondary", onClick: onClose, children: "Cancel" }),
1165
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { className: "vpg-btn vpg-btn-primary", onClick: handleSave, children: [
1166
+ existingField ? "Update" : "Add",
1167
+ " Field"
1168
+ ] })
1169
+ ] })
1170
+ ] }) });
1171
+ return (0, import_react_dom.createPortal)(modalContent, document.body);
1172
+ }
1173
+
1174
+ // src/components/PivotConfig.tsx
1175
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1176
+ function getFieldIcon(type, isCalculated) {
1177
+ if (isCalculated) return "\u0192";
961
1178
  switch (type) {
962
1179
  case "number":
963
1180
  return "#";
@@ -975,7 +1192,9 @@ function PivotConfig({
975
1192
  columnFields,
976
1193
  valueFields,
977
1194
  showRowTotals,
1195
+ calculatedFields,
978
1196
  onShowRowTotalsChange,
1197
+ onShowColumnTotalsChange,
979
1198
  onClearConfig,
980
1199
  onAutoSuggest,
981
1200
  onDragStart,
@@ -985,35 +1204,71 @@ function PivotConfig({
985
1204
  onRemoveColumnField,
986
1205
  onRemoveValueField,
987
1206
  onAddRowField,
988
- onAddColumnField
1207
+ onAddColumnField,
1208
+ onAddCalculatedField,
1209
+ onRemoveCalculatedField,
1210
+ onUpdateCalculatedField
989
1211
  }) {
990
1212
  const { showWatermark } = useLicense();
991
- const [fieldSearch, setFieldSearch] = (0, import_react6.useState)("");
992
- const assignedFields = (0, import_react6.useMemo)(() => {
1213
+ const [fieldSearch, setFieldSearch] = (0, import_react7.useState)("");
1214
+ const [showCalcModal, setShowCalcModal] = (0, import_react7.useState)(false);
1215
+ const [editingCalcField, setEditingCalcField] = (0, import_react7.useState)(null);
1216
+ const numericFieldNames = (0, import_react7.useMemo)(
1217
+ () => availableFields.filter((f) => f.isNumeric).map((f) => f.field),
1218
+ [availableFields]
1219
+ );
1220
+ const calculatedFieldsAsStats = (0, import_react7.useMemo)(() => {
1221
+ if (!calculatedFields) return [];
1222
+ return calculatedFields.map((calc) => ({
1223
+ field: `calc:${calc.id}`,
1224
+ type: "number",
1225
+ uniqueCount: 0,
1226
+ isNumeric: true,
1227
+ isCalculated: true,
1228
+ calcId: calc.id,
1229
+ calcName: calc.name,
1230
+ calcFormula: calc.formula
1231
+ }));
1232
+ }, [calculatedFields]);
1233
+ const allAvailableFields = (0, import_react7.useMemo)(() => [
1234
+ ...availableFields.map((f) => ({ ...f, isCalculated: false })),
1235
+ ...calculatedFieldsAsStats
1236
+ ], [availableFields, calculatedFieldsAsStats]);
1237
+ const assignedFields = (0, import_react7.useMemo)(() => {
993
1238
  const rowSet = new Set(rowFields);
994
1239
  const colSet = new Set(columnFields);
995
1240
  const valueMap = new Map(valueFields.map((v) => [v.field, v]));
996
- return availableFields.filter((f) => rowSet.has(f.field) || colSet.has(f.field) || valueMap.has(f.field)).map((f) => ({
1241
+ return allAvailableFields.filter((f) => rowSet.has(f.field) || colSet.has(f.field) || valueMap.has(f.field)).map((f) => ({
997
1242
  ...f,
998
1243
  assignedTo: rowSet.has(f.field) ? "row" : colSet.has(f.field) ? "column" : "value",
999
1244
  valueConfig: valueMap.get(f.field)
1000
1245
  }));
1001
- }, [availableFields, rowFields, columnFields, valueFields]);
1002
- const unassignedFields = (0, import_react6.useMemo)(() => {
1246
+ }, [allAvailableFields, rowFields, columnFields, valueFields]);
1247
+ const unassignedFields = (0, import_react7.useMemo)(() => {
1003
1248
  const rowSet = new Set(rowFields);
1004
1249
  const colSet = new Set(columnFields);
1005
1250
  const valSet = new Set(valueFields.map((v) => v.field));
1006
- return availableFields.filter(
1251
+ return allAvailableFields.filter(
1007
1252
  (f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
1008
1253
  );
1009
- }, [availableFields, rowFields, columnFields, valueFields]);
1010
- const filteredUnassignedFields = (0, import_react6.useMemo)(() => {
1254
+ }, [allAvailableFields, rowFields, columnFields, valueFields]);
1255
+ const filteredUnassignedFields = (0, import_react7.useMemo)(() => {
1011
1256
  if (!fieldSearch.trim()) return unassignedFields;
1012
1257
  const search = fieldSearch.toLowerCase().trim();
1013
- return unassignedFields.filter((f) => f.field.toLowerCase().includes(search));
1258
+ return unassignedFields.filter((f) => {
1259
+ const fieldName = f.field.toLowerCase();
1260
+ const displayName = f.isCalculated && f.calcName ? f.calcName.toLowerCase() : "";
1261
+ return fieldName.includes(search) || displayName.includes(search);
1262
+ });
1014
1263
  }, [unassignedFields, fieldSearch]);
1015
1264
  const assignedCount = assignedFields.length;
1016
- const handleDragStart = (0, import_react6.useCallback)(
1265
+ const getFieldDisplayName = (0, import_react7.useCallback)((field) => {
1266
+ if (field.isCalculated && field.calcName) {
1267
+ return field.calcName;
1268
+ }
1269
+ return field.field;
1270
+ }, []);
1271
+ const handleDragStart = (0, import_react7.useCallback)(
1017
1272
  (field, event) => {
1018
1273
  event.dataTransfer?.setData("text/plain", field);
1019
1274
  event.dataTransfer.effectAllowed = "move";
@@ -1021,13 +1276,13 @@ function PivotConfig({
1021
1276
  },
1022
1277
  [onDragStart]
1023
1278
  );
1024
- const handleAggregationChange = (0, import_react6.useCallback)(
1279
+ const handleAggregationChange = (0, import_react7.useCallback)(
1025
1280
  (field, currentAgg, newAgg) => {
1026
1281
  onUpdateAggregation(field, currentAgg, newAgg);
1027
1282
  },
1028
1283
  [onUpdateAggregation]
1029
1284
  );
1030
- const toggleRowColumn = (0, import_react6.useCallback)(
1285
+ const toggleRowColumn = (0, import_react7.useCallback)(
1031
1286
  (field, currentAssignment) => {
1032
1287
  if (currentAssignment === "row") {
1033
1288
  onRemoveRowField(field);
@@ -1039,7 +1294,7 @@ function PivotConfig({
1039
1294
  },
1040
1295
  [onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
1041
1296
  );
1042
- const removeField = (0, import_react6.useCallback)(
1297
+ const removeField = (0, import_react7.useCallback)(
1043
1298
  (field, assignedTo, valueConfig) => {
1044
1299
  if (assignedTo === "row") {
1045
1300
  onRemoveRowField(field);
@@ -1051,10 +1306,31 @@ function PivotConfig({
1051
1306
  },
1052
1307
  [onRemoveRowField, onRemoveColumnField, onRemoveValueField]
1053
1308
  );
1054
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-pivot-config", children: [
1055
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-config-header", children: [
1056
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h3", { className: "vpg-config-title", children: [
1057
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1309
+ const handleTotalsToggle = (0, import_react7.useCallback)((checked) => {
1310
+ onShowRowTotalsChange(checked);
1311
+ onShowColumnTotalsChange(checked);
1312
+ }, [onShowRowTotalsChange, onShowColumnTotalsChange]);
1313
+ const openCalcModal = (0, import_react7.useCallback)((field) => {
1314
+ setEditingCalcField(field || null);
1315
+ setShowCalcModal(true);
1316
+ }, []);
1317
+ const handleSaveCalcField = (0, import_react7.useCallback)((field) => {
1318
+ if (editingCalcField && onUpdateCalculatedField) {
1319
+ onUpdateCalculatedField(field);
1320
+ } else if (onAddCalculatedField) {
1321
+ onAddCalculatedField(field);
1322
+ }
1323
+ setShowCalcModal(false);
1324
+ setEditingCalcField(null);
1325
+ }, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
1326
+ const handleCloseCalcModal = (0, import_react7.useCallback)(() => {
1327
+ setShowCalcModal(false);
1328
+ setEditingCalcField(null);
1329
+ }, []);
1330
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-pivot-config", children: [
1331
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-config-header", children: [
1332
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h3", { className: "vpg-config-title", children: [
1333
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1058
1334
  "path",
1059
1335
  {
1060
1336
  strokeLinecap: "round",
@@ -1065,13 +1341,13 @@ function PivotConfig({
1065
1341
  ) }),
1066
1342
  "Fields"
1067
1343
  ] }),
1068
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1344
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1069
1345
  "button",
1070
1346
  {
1071
1347
  className: "vpg-action-btn vpg-clear-btn",
1072
1348
  title: "Clear all",
1073
1349
  onClick: onClearConfig,
1074
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1350
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1075
1351
  "path",
1076
1352
  {
1077
1353
  strokeLinecap: "round",
@@ -1083,23 +1359,23 @@ function PivotConfig({
1083
1359
  }
1084
1360
  ) })
1085
1361
  ] }),
1086
- assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-assigned-section", children: [
1087
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-section-label", children: "Active" }),
1088
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1362
+ assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-assigned-section", children: [
1363
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-section-label", children: "Active" }),
1364
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1089
1365
  "div",
1090
1366
  {
1091
- className: `vpg-assigned-item vpg-type-${field.assignedTo}`,
1092
- title: field.field,
1367
+ className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
1368
+ title: field.isCalculated ? field.calcFormula : field.field,
1093
1369
  draggable: true,
1094
1370
  onDragStart: (e) => handleDragStart(field.field, e),
1095
1371
  onDragEnd,
1096
1372
  children: [
1097
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-item-main", children: [
1098
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `vpg-item-badge ${field.assignedTo}`, children: field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : (0, import_tinypivot_core5.getAggregationSymbol)(field.valueConfig?.aggregation || "sum") }),
1099
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-item-name", children: field.field })
1373
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-item-main", children: [
1374
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : (0, import_tinypivot_core6.getAggregationSymbol)(field.valueConfig?.aggregation || "sum") }),
1375
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
1100
1376
  ] }),
1101
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-item-actions", children: [
1102
- (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1377
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-item-actions", children: [
1378
+ (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1103
1379
  "button",
1104
1380
  {
1105
1381
  className: "vpg-toggle-btn",
@@ -1108,14 +1384,14 @@ function PivotConfig({
1108
1384
  e.stopPropagation();
1109
1385
  toggleRowColumn(field.field, field.assignedTo);
1110
1386
  },
1111
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1387
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1112
1388
  "svg",
1113
1389
  {
1114
1390
  className: "vpg-icon-xs",
1115
1391
  fill: "none",
1116
1392
  stroke: "currentColor",
1117
1393
  viewBox: "0 0 24 24",
1118
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1394
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1119
1395
  "path",
1120
1396
  {
1121
1397
  strokeLinecap: "round",
@@ -1128,7 +1404,7 @@ function PivotConfig({
1128
1404
  )
1129
1405
  }
1130
1406
  ),
1131
- field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1407
+ field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1132
1408
  "select",
1133
1409
  {
1134
1410
  className: "vpg-agg-select",
@@ -1142,14 +1418,14 @@ function PivotConfig({
1142
1418
  );
1143
1419
  },
1144
1420
  onClick: (e) => e.stopPropagation(),
1145
- children: import_tinypivot_core5.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("option", { value: agg.value, children: [
1421
+ children: import_tinypivot_core6.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: agg.value, children: [
1146
1422
  agg.symbol,
1147
1423
  " ",
1148
1424
  agg.label
1149
1425
  ] }, agg.value))
1150
1426
  }
1151
1427
  ),
1152
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1428
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1153
1429
  "button",
1154
1430
  {
1155
1431
  className: "vpg-remove-btn",
@@ -1167,13 +1443,13 @@ function PivotConfig({
1167
1443
  field.field
1168
1444
  )) })
1169
1445
  ] }),
1170
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-unassigned-section", children: [
1171
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-section-header", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-section-label", children: [
1446
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-unassigned-section", children: [
1447
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-section-header", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-section-label", children: [
1172
1448
  "Available ",
1173
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-count", children: unassignedFields.length })
1449
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-count", children: unassignedFields.length })
1174
1450
  ] }) }),
1175
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-field-search", children: [
1176
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1451
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-field-search", children: [
1452
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1177
1453
  "path",
1178
1454
  {
1179
1455
  strokeLinecap: "round",
@@ -1182,7 +1458,7 @@ function PivotConfig({
1182
1458
  d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
1183
1459
  }
1184
1460
  ) }),
1185
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1461
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1186
1462
  "input",
1187
1463
  {
1188
1464
  type: "text",
@@ -1192,7 +1468,7 @@ function PivotConfig({
1192
1468
  className: "vpg-search-input"
1193
1469
  }
1194
1470
  ),
1195
- fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1471
+ fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1196
1472
  "path",
1197
1473
  {
1198
1474
  strokeLinecap: "round",
@@ -1202,64 +1478,94 @@ function PivotConfig({
1202
1478
  }
1203
1479
  ) }) })
1204
1480
  ] }),
1205
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-field-list", children: [
1206
- filteredUnassignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1481
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-field-list", children: [
1482
+ filteredUnassignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1207
1483
  "div",
1208
1484
  {
1209
- className: `vpg-field-item ${field.isNumeric ? "vpg-is-numeric" : ""}`,
1210
- title: field.field,
1485
+ className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
1486
+ title: field.isCalculated ? field.calcFormula : field.field,
1211
1487
  draggable: true,
1212
1488
  onDragStart: (e) => handleDragStart(field.field, e),
1213
1489
  onDragEnd,
1214
1490
  children: [
1215
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-field-type-icon", title: field.type, children: getFieldIcon(field.type) }),
1216
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-field-name", children: field.field }),
1217
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-unique-count", children: field.uniqueCount })
1491
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
1492
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
1493
+ field.isCalculated ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1494
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1495
+ "button",
1496
+ {
1497
+ className: "vpg-field-edit",
1498
+ title: "Edit calculated field",
1499
+ onClick: (e) => {
1500
+ e.stopPropagation();
1501
+ const calcField = calculatedFields?.find((c) => c.id === field.calcId);
1502
+ if (calcField) openCalcModal(calcField);
1503
+ },
1504
+ children: "\u270E"
1505
+ }
1506
+ ),
1507
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1508
+ "button",
1509
+ {
1510
+ className: "vpg-field-delete",
1511
+ title: "Delete calculated field",
1512
+ onClick: (e) => {
1513
+ e.stopPropagation();
1514
+ if (field.calcId && onRemoveCalculatedField) {
1515
+ onRemoveCalculatedField(field.calcId);
1516
+ }
1517
+ },
1518
+ children: "\xD7"
1519
+ }
1520
+ )
1521
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-unique-count", children: field.uniqueCount })
1218
1522
  ]
1219
1523
  },
1220
1524
  field.field
1221
1525
  )),
1222
- filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-empty-hint", children: [
1526
+ filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-empty-hint", children: [
1223
1527
  'No fields match "',
1224
1528
  fieldSearch,
1225
1529
  '"'
1226
1530
  ] }),
1227
- unassignedFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-empty-hint", children: "All fields assigned" })
1531
+ unassignedFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-empty-hint", children: "All fields assigned" })
1228
1532
  ] })
1229
1533
  ] }),
1230
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-options-section", children: [
1231
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "vpg-option-toggle", children: [
1232
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1534
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-options-section", children: [
1535
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "vpg-option-toggle", children: [
1536
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1233
1537
  "input",
1234
1538
  {
1235
1539
  type: "checkbox",
1236
1540
  checked: showRowTotals,
1237
- onChange: (e) => onShowRowTotalsChange(e.target.checked)
1541
+ onChange: (e) => handleTotalsToggle(e.target.checked)
1238
1542
  }
1239
1543
  ),
1240
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Totals" })
1544
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Totals" })
1241
1545
  ] }),
1242
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { className: "vpg-auto-btn", onClick: onAutoSuggest, children: [
1243
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1244
- "path",
1245
- {
1246
- strokeLinecap: "round",
1247
- strokeLinejoin: "round",
1248
- strokeWidth: 2,
1249
- d: "M13 10V3L4 14h7v7l9-11h-7z"
1250
- }
1251
- ) }),
1252
- "Auto"
1546
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
1547
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-calc-icon", children: "\u0192" }),
1548
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "+ Calc" })
1253
1549
  ] })
1254
1550
  ] }),
1255
- showWatermark && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-watermark", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "TinyPivot" }) })
1551
+ showWatermark && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-watermark", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "TinyPivot" }) }),
1552
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1553
+ CalculatedFieldModal,
1554
+ {
1555
+ show: showCalcModal,
1556
+ availableFields: numericFieldNames,
1557
+ existingField: editingCalcField,
1558
+ onClose: handleCloseCalcModal,
1559
+ onSave: handleSaveCalcField
1560
+ }
1561
+ )
1256
1562
  ] });
1257
1563
  }
1258
1564
 
1259
1565
  // src/components/PivotSkeleton.tsx
1260
- var import_react7 = require("react");
1261
- var import_tinypivot_core6 = require("@smallwebco/tinypivot-core");
1262
- var import_jsx_runtime3 = require("react/jsx-runtime");
1566
+ var import_react8 = require("react");
1567
+ var import_tinypivot_core7 = require("@smallwebco/tinypivot-core");
1568
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1263
1569
  function PivotSkeleton({
1264
1570
  rowFields,
1265
1571
  columnFields,
@@ -1281,12 +1587,12 @@ function PivotSkeleton({
1281
1587
  onReorderColumnFields
1282
1588
  }) {
1283
1589
  const { showWatermark, canUsePivot, isDemo } = useLicense();
1284
- const [dragOverArea, setDragOverArea] = (0, import_react7.useState)(null);
1285
- const [reorderDragSource, setReorderDragSource] = (0, import_react7.useState)(null);
1286
- const [reorderDropTarget, setReorderDropTarget] = (0, import_react7.useState)(null);
1287
- const [sortDirection, setSortDirection] = (0, import_react7.useState)("asc");
1288
- const [sortTarget, setSortTarget] = (0, import_react7.useState)("row");
1289
- const toggleSort = (0, import_react7.useCallback)((target = "row") => {
1590
+ const [dragOverArea, setDragOverArea] = (0, import_react8.useState)(null);
1591
+ const [reorderDragSource, setReorderDragSource] = (0, import_react8.useState)(null);
1592
+ const [reorderDropTarget, setReorderDropTarget] = (0, import_react8.useState)(null);
1593
+ const [sortDirection, setSortDirection] = (0, import_react8.useState)("asc");
1594
+ const [sortTarget, setSortTarget] = (0, import_react8.useState)("row");
1595
+ const toggleSort = (0, import_react8.useCallback)((target = "row") => {
1290
1596
  if (sortTarget === target) {
1291
1597
  setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
1292
1598
  } else {
@@ -1294,7 +1600,7 @@ function PivotSkeleton({
1294
1600
  setSortDirection("asc");
1295
1601
  }
1296
1602
  }, [sortTarget]);
1297
- const sortedRowIndices = (0, import_react7.useMemo)(() => {
1603
+ const sortedRowIndices = (0, import_react8.useMemo)(() => {
1298
1604
  if (!pivotResult) return [];
1299
1605
  const indices = pivotResult.rowHeaders.map((_, i) => i);
1300
1606
  const headers = pivotResult.rowHeaders;
@@ -1318,11 +1624,11 @@ function PivotSkeleton({
1318
1624
  });
1319
1625
  return indices;
1320
1626
  }, [pivotResult, sortTarget, sortDirection]);
1321
- const columnHeaderCells = (0, import_react7.useMemo)(() => {
1627
+ const columnHeaderCells = (0, import_react8.useMemo)(() => {
1322
1628
  if (!pivotResult || pivotResult.headers.length === 0) {
1323
1629
  return [
1324
1630
  valueFields.map((vf) => ({
1325
- label: `${vf.field} (${(0, import_tinypivot_core6.getAggregationLabel)(vf.aggregation)})`,
1631
+ label: `${vf.field} (${(0, import_tinypivot_core7.getAggregationLabel)(vf.aggregation)})`,
1326
1632
  colspan: 1
1327
1633
  }))
1328
1634
  ];
@@ -1346,12 +1652,12 @@ function PivotSkeleton({
1346
1652
  return result;
1347
1653
  }, [pivotResult, valueFields]);
1348
1654
  const hasActiveFilters = activeFilters && activeFilters.length > 0;
1349
- const filterSummary = (0, import_react7.useMemo)(() => {
1655
+ const filterSummary = (0, import_react8.useMemo)(() => {
1350
1656
  if (!activeFilters || activeFilters.length === 0) return "";
1351
1657
  return activeFilters.map((f) => f.column).join(", ");
1352
1658
  }, [activeFilters]);
1353
- const [showFilterTooltip, setShowFilterTooltip] = (0, import_react7.useState)(false);
1354
- const filterTooltipDetails = (0, import_react7.useMemo)(() => {
1659
+ const [showFilterTooltip, setShowFilterTooltip] = (0, import_react8.useState)(false);
1660
+ const filterTooltipDetails = (0, import_react8.useMemo)(() => {
1355
1661
  if (!activeFilters || activeFilters.length === 0) return [];
1356
1662
  return activeFilters.map((f) => {
1357
1663
  const maxDisplay = 5;
@@ -1364,7 +1670,7 @@ function PivotSkeleton({
1364
1670
  };
1365
1671
  });
1366
1672
  }, [activeFilters]);
1367
- const handleDragOver = (0, import_react7.useCallback)(
1673
+ const handleDragOver = (0, import_react8.useCallback)(
1368
1674
  (area, event) => {
1369
1675
  event.preventDefault();
1370
1676
  event.dataTransfer.dropEffect = "move";
@@ -1372,10 +1678,10 @@ function PivotSkeleton({
1372
1678
  },
1373
1679
  []
1374
1680
  );
1375
- const handleDragLeave = (0, import_react7.useCallback)(() => {
1681
+ const handleDragLeave = (0, import_react8.useCallback)(() => {
1376
1682
  setDragOverArea(null);
1377
1683
  }, []);
1378
- const handleDrop = (0, import_react7.useCallback)(
1684
+ const handleDrop = (0, import_react8.useCallback)(
1379
1685
  (area, event) => {
1380
1686
  event.preventDefault();
1381
1687
  const field = event.dataTransfer?.getData("text/plain");
@@ -1402,7 +1708,7 @@ function PivotSkeleton({
1402
1708
  },
1403
1709
  [rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
1404
1710
  );
1405
- const handleChipDragStart = (0, import_react7.useCallback)(
1711
+ const handleChipDragStart = (0, import_react8.useCallback)(
1406
1712
  (zone, index, event) => {
1407
1713
  setReorderDragSource({ zone, index });
1408
1714
  event.dataTransfer.effectAllowed = "move";
@@ -1413,11 +1719,11 @@ function PivotSkeleton({
1413
1719
  },
1414
1720
  []
1415
1721
  );
1416
- const handleChipDragEnd = (0, import_react7.useCallback)(() => {
1722
+ const handleChipDragEnd = (0, import_react8.useCallback)(() => {
1417
1723
  setReorderDragSource(null);
1418
1724
  setReorderDropTarget(null);
1419
1725
  }, []);
1420
- const handleChipDragOver = (0, import_react7.useCallback)(
1726
+ const handleChipDragOver = (0, import_react8.useCallback)(
1421
1727
  (zone, index, event) => {
1422
1728
  event.preventDefault();
1423
1729
  if (reorderDragSource && reorderDragSource.zone === zone) {
@@ -1427,10 +1733,10 @@ function PivotSkeleton({
1427
1733
  },
1428
1734
  [reorderDragSource]
1429
1735
  );
1430
- const handleChipDragLeave = (0, import_react7.useCallback)(() => {
1736
+ const handleChipDragLeave = (0, import_react8.useCallback)(() => {
1431
1737
  setReorderDropTarget(null);
1432
1738
  }, []);
1433
- const handleChipDrop = (0, import_react7.useCallback)(
1739
+ const handleChipDrop = (0, import_react8.useCallback)(
1434
1740
  (zone, targetIndex, event) => {
1435
1741
  event.preventDefault();
1436
1742
  event.stopPropagation();
@@ -1456,27 +1762,27 @@ function PivotSkeleton({
1456
1762
  },
1457
1763
  [reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
1458
1764
  );
1459
- const isChipDragSource = (0, import_react7.useCallback)(
1765
+ const isChipDragSource = (0, import_react8.useCallback)(
1460
1766
  (zone, index) => {
1461
1767
  return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
1462
1768
  },
1463
1769
  [reorderDragSource]
1464
1770
  );
1465
- const isChipDropTarget = (0, import_react7.useCallback)(
1771
+ const isChipDropTarget = (0, import_react8.useCallback)(
1466
1772
  (zone, index) => {
1467
1773
  return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
1468
1774
  },
1469
1775
  [reorderDropTarget]
1470
1776
  );
1471
1777
  const currentFontSize = fontSize;
1472
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1778
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1473
1779
  "div",
1474
1780
  {
1475
1781
  className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
1476
1782
  children: [
1477
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-skeleton-header", children: [
1478
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-skeleton-title", children: [
1479
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1783
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-skeleton-header", children: [
1784
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-skeleton-title", children: [
1785
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1480
1786
  "path",
1481
1787
  {
1482
1788
  strokeLinecap: "round",
@@ -1485,24 +1791,24 @@ function PivotSkeleton({
1485
1791
  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"
1486
1792
  }
1487
1793
  ) }),
1488
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Pivot Table" })
1794
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Pivot Table" })
1489
1795
  ] }),
1490
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-header-right", children: [
1491
- hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1796
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-right", children: [
1797
+ hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1492
1798
  "div",
1493
1799
  {
1494
1800
  className: "vpg-filter-indicator",
1495
1801
  onMouseEnter: () => setShowFilterTooltip(true),
1496
1802
  onMouseLeave: () => setShowFilterTooltip(false),
1497
1803
  children: [
1498
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1804
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1499
1805
  "svg",
1500
1806
  {
1501
1807
  className: "vpg-filter-icon",
1502
1808
  fill: "none",
1503
1809
  stroke: "currentColor",
1504
1810
  viewBox: "0 0 24 24",
1505
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1811
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1506
1812
  "path",
1507
1813
  {
1508
1814
  strokeLinecap: "round",
@@ -1513,10 +1819,10 @@ function PivotSkeleton({
1513
1819
  )
1514
1820
  }
1515
1821
  ),
1516
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-filter-text", children: [
1822
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-filter-text", children: [
1517
1823
  "Filtered: ",
1518
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: filterSummary }),
1519
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-filter-count", children: [
1824
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: filterSummary }),
1825
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-filter-count", children: [
1520
1826
  "(",
1521
1827
  filteredRowCount.toLocaleString(),
1522
1828
  " of ",
@@ -1524,20 +1830,20 @@ function PivotSkeleton({
1524
1830
  " rows)"
1525
1831
  ] })
1526
1832
  ] }),
1527
- showFilterTooltip && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-filter-tooltip", children: [
1528
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
1529
- filterTooltipDetails.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-tooltip-filter", children: [
1530
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-tooltip-column", children: filter.column }),
1531
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-tooltip-values", children: [
1532
- filter.values.map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-tooltip-value", children: val }, idx)),
1533
- filter.remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-tooltip-more", children: [
1833
+ showFilterTooltip && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-tooltip", children: [
1834
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
1835
+ filterTooltipDetails.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-tooltip-filter", children: [
1836
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-tooltip-column", children: filter.column }),
1837
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-tooltip-values", children: [
1838
+ filter.values.map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-tooltip-value", children: val }, idx)),
1839
+ filter.remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-tooltip-more", children: [
1534
1840
  "+",
1535
1841
  filter.remaining,
1536
1842
  " more"
1537
1843
  ] })
1538
1844
  ] })
1539
1845
  ] }, filter.column)),
1540
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-tooltip-summary", children: [
1846
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-tooltip-summary", children: [
1541
1847
  "Showing ",
1542
1848
  filteredRowCount.toLocaleString(),
1543
1849
  " of ",
@@ -1548,18 +1854,18 @@ function PivotSkeleton({
1548
1854
  ]
1549
1855
  }
1550
1856
  ),
1551
- isConfigured && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-config-summary", children: [
1552
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-summary-badge vpg-rows", children: [
1857
+ isConfigured && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-config-summary", children: [
1858
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-summary-badge vpg-rows", children: [
1553
1859
  rowFields.length,
1554
1860
  " row",
1555
1861
  rowFields.length !== 1 ? "s" : ""
1556
1862
  ] }),
1557
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-summary-badge vpg-cols", children: [
1863
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-summary-badge vpg-cols", children: [
1558
1864
  columnFields.length,
1559
1865
  " col",
1560
1866
  columnFields.length !== 1 ? "s" : ""
1561
1867
  ] }),
1562
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-summary-badge vpg-vals", children: [
1868
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-summary-badge vpg-vals", children: [
1563
1869
  valueFields.length,
1564
1870
  " val",
1565
1871
  valueFields.length !== 1 ? "s" : ""
@@ -1567,8 +1873,8 @@ function PivotSkeleton({
1567
1873
  ] })
1568
1874
  ] })
1569
1875
  ] }),
1570
- !canUsePivot ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-pro-required", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-pro-content", children: [
1571
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1876
+ !canUsePivot ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-pro-required", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-pro-content", children: [
1877
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1572
1878
  "path",
1573
1879
  {
1574
1880
  strokeLinecap: "round",
@@ -1577,12 +1883,12 @@ function PivotSkeleton({
1577
1883
  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"
1578
1884
  }
1579
1885
  ) }),
1580
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "Pro Feature" }),
1581
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "Pivot Table functionality requires a Pro license." }),
1582
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
1583
- ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1584
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-config-bar", children: [
1585
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1886
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { children: "Pro Feature" }),
1887
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: "Pivot Table functionality requires a Pro license." }),
1888
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
1889
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1890
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-config-bar", children: [
1891
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1586
1892
  "div",
1587
1893
  {
1588
1894
  className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
@@ -1590,12 +1896,12 @@ function PivotSkeleton({
1590
1896
  onDragLeave: handleDragLeave,
1591
1897
  onDrop: (e) => handleDrop("row", e),
1592
1898
  children: [
1593
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-zone-header", children: [
1594
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
1595
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-label", children: "Rows" })
1899
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-header", children: [
1900
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
1901
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-label", children: "Rows" })
1596
1902
  ] }),
1597
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-zone-chips", children: [
1598
- rowFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1903
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-chips", children: [
1904
+ rowFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1599
1905
  "div",
1600
1906
  {
1601
1907
  className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -1606,9 +1912,9 @@ function PivotSkeleton({
1606
1912
  onDragLeave: handleChipDragLeave,
1607
1913
  onDrop: (e) => handleChipDrop("row", idx, e),
1608
1914
  children: [
1609
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-mini-name", children: field }),
1611
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1915
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1916
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-mini-name", children: field }),
1917
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1612
1918
  "button",
1613
1919
  {
1614
1920
  className: "vpg-mini-remove",
@@ -1623,12 +1929,12 @@ function PivotSkeleton({
1623
1929
  },
1624
1930
  field
1625
1931
  )),
1626
- rowFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
1932
+ rowFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
1627
1933
  ] })
1628
1934
  ]
1629
1935
  }
1630
1936
  ),
1631
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1632
1938
  "div",
1633
1939
  {
1634
1940
  className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
@@ -1636,12 +1942,12 @@ function PivotSkeleton({
1636
1942
  onDragLeave: handleDragLeave,
1637
1943
  onDrop: (e) => handleDrop("column", e),
1638
1944
  children: [
1639
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-zone-header", children: [
1640
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
1641
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-label", children: "Columns" })
1945
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-header", children: [
1946
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
1947
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-label", children: "Columns" })
1642
1948
  ] }),
1643
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-zone-chips", children: [
1644
- columnFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1949
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-chips", children: [
1950
+ columnFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1645
1951
  "div",
1646
1952
  {
1647
1953
  className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -1652,9 +1958,9 @@ function PivotSkeleton({
1652
1958
  onDragLeave: handleChipDragLeave,
1653
1959
  onDrop: (e) => handleChipDrop("column", idx, e),
1654
1960
  children: [
1655
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1656
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-mini-name", children: field }),
1657
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1961
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
1962
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-mini-name", children: field }),
1963
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1658
1964
  "button",
1659
1965
  {
1660
1966
  className: "vpg-mini-remove",
@@ -1669,12 +1975,12 @@ function PivotSkeleton({
1669
1975
  },
1670
1976
  field
1671
1977
  )),
1672
- columnFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
1978
+ columnFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
1673
1979
  ] })
1674
1980
  ]
1675
1981
  }
1676
1982
  ),
1677
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1983
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1678
1984
  "div",
1679
1985
  {
1680
1986
  className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
@@ -1682,19 +1988,19 @@ function PivotSkeleton({
1682
1988
  onDragLeave: handleDragLeave,
1683
1989
  onDrop: (e) => handleDrop("value", e),
1684
1990
  children: [
1685
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-zone-header", children: [
1686
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
1687
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-label", children: "Values" })
1991
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-header", children: [
1992
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
1993
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-label", children: "Values" })
1688
1994
  ] }),
1689
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-zone-chips", children: [
1690
- valueFields.map((vf) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1995
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-chips", children: [
1996
+ valueFields.map((vf) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1691
1997
  "div",
1692
1998
  {
1693
1999
  className: "vpg-mini-chip vpg-value-chip",
1694
2000
  children: [
1695
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-agg-symbol", children: (0, import_tinypivot_core6.getAggregationSymbol)(vf.aggregation) }),
1696
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-mini-name", children: vf.field }),
1697
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2001
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-agg-symbol", children: (0, import_tinypivot_core7.getAggregationSymbol)(vf.aggregation) }),
2002
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-mini-name", children: vf.field }),
2003
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1698
2004
  "button",
1699
2005
  {
1700
2006
  className: "vpg-mini-remove",
@@ -1706,21 +2012,21 @@ function PivotSkeleton({
1706
2012
  },
1707
2013
  `${vf.field}-${vf.aggregation}`
1708
2014
  )),
1709
- valueFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-zone-hint", children: "Drop numeric" })
2015
+ valueFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-hint", children: "Drop numeric" })
1710
2016
  ] })
1711
2017
  ]
1712
2018
  }
1713
2019
  )
1714
2020
  ] }),
1715
- (!isConfigured || !pivotResult) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-placeholder-content", children: [
1716
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2021
+ (!isConfigured || !pivotResult) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-placeholder-content", children: [
2022
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1717
2023
  "svg",
1718
2024
  {
1719
2025
  className: "vpg-placeholder-icon",
1720
2026
  fill: "none",
1721
2027
  viewBox: "0 0 24 24",
1722
2028
  stroke: "currentColor",
1723
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2029
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1724
2030
  "path",
1725
2031
  {
1726
2032
  strokeLinecap: "round",
@@ -1731,51 +2037,51 @@ function PivotSkeleton({
1731
2037
  )
1732
2038
  }
1733
2039
  ),
1734
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2040
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1735
2041
  "Add a ",
1736
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "Values" }),
2042
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Values" }),
1737
2043
  " field to see your pivot table"
1738
- ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2044
+ ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1739
2045
  "Add ",
1740
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "Row" }),
2046
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Row" }),
1741
2047
  " or ",
1742
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "Column" }),
2048
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Column" }),
1743
2049
  " fields to group your data"
1744
2050
  ] }) : "Your pivot table will appear here" })
1745
2051
  ] }) }),
1746
- isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-table-container", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { className: "vpg-pivot-table", children: [
1747
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { className: "vpg-column-header-row", children: [
1748
- levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2052
+ isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-table-container", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("table", { className: "vpg-pivot-table", children: [
2053
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { className: "vpg-column-header-row", children: [
2054
+ levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1749
2055
  "th",
1750
2056
  {
1751
2057
  className: "vpg-row-header-label",
1752
2058
  rowSpan: columnHeaderCells.length,
1753
2059
  onClick: () => toggleSort("row"),
1754
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-header-content", children: [
1755
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: rowFields.join(" / ") || "Rows" }),
1756
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
2060
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-content", children: [
2061
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: rowFields.join(" / ") || "Rows" }),
2062
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
1757
2063
  ] })
1758
2064
  }
1759
2065
  ),
1760
- headerRow.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2066
+ headerRow.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1761
2067
  "th",
1762
2068
  {
1763
2069
  className: "vpg-column-header-cell",
1764
2070
  colSpan: cell.colspan,
1765
2071
  onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
1766
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-header-content", children: [
1767
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: cell.label }),
1768
- levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
2072
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-content", children: [
2073
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: cell.label }),
2074
+ levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
1769
2075
  ] })
1770
2076
  },
1771
2077
  idx
1772
2078
  )),
1773
- pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
2079
+ pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
1774
2080
  ] }, `header-${levelIdx}`)) }),
1775
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tbody", { children: [
1776
- sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { className: "vpg-data-row", children: [
1777
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { className: "vpg-row-header-cell", children: pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-row-value", children: val }, idx)) }),
1778
- pivotResult.data[sortedIdx].map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2081
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tbody", { children: [
2082
+ sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { className: "vpg-data-row", children: [
2083
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("th", { className: "vpg-row-header-cell", children: pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-row-value", children: val }, idx)) }),
2084
+ pivotResult.data[sortedIdx].map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1779
2085
  "td",
1780
2086
  {
1781
2087
  className: `vpg-data-cell ${cell.value === null ? "vpg-is-null" : ""}`,
@@ -1783,26 +2089,26 @@ function PivotSkeleton({
1783
2089
  },
1784
2090
  colIdx
1785
2091
  )),
1786
- pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
2092
+ pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
1787
2093
  ] }, sortedIdx)),
1788
- pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { className: "vpg-totals-row", children: [
1789
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { className: "vpg-row-header-cell vpg-total-label", children: "Total" }),
1790
- pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
1791
- pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
2094
+ pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { className: "vpg-totals-row", children: [
2095
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("th", { className: "vpg-row-header-cell vpg-total-label", children: "Total" }),
2096
+ pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
2097
+ pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
1792
2098
  ] })
1793
2099
  ] })
1794
2100
  ] }) }),
1795
- isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-skeleton-footer", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
2101
+ isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-skeleton-footer", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
1796
2102
  pivotResult.rowHeaders.length,
1797
2103
  " rows \xD7 ",
1798
2104
  pivotResult.data[0]?.length || 0,
1799
2105
  " columns"
1800
2106
  ] }) })
1801
2107
  ] }),
1802
- showWatermark && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1803
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
1804
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Pro features unlocked for evaluation" }),
1805
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2108
+ showWatermark && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2109
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
2110
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Pro features unlocked for evaluation" }),
2111
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1806
2112
  "a",
1807
2113
  {
1808
2114
  href: "https://tiny-pivot.com/#pricing",
@@ -1812,14 +2118,14 @@ function PivotSkeleton({
1812
2118
  children: "Get Pro License \u2192"
1813
2119
  }
1814
2120
  )
1815
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
2121
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
1816
2122
  ]
1817
2123
  }
1818
2124
  );
1819
2125
  }
1820
2126
 
1821
2127
  // src/components/DataGrid.tsx
1822
- var import_jsx_runtime4 = require("react/jsx-runtime");
2128
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1823
2129
  var MIN_COL_WIDTH = 120;
1824
2130
  var MAX_COL_WIDTH = 350;
1825
2131
  function DataGrid({
@@ -1845,37 +2151,37 @@ function DataGrid({
1845
2151
  onCopy
1846
2152
  }) {
1847
2153
  const { showWatermark, canUsePivot, isDemo } = useLicense();
1848
- const currentTheme = (0, import_react8.useMemo)(() => {
2154
+ const currentTheme = (0, import_react9.useMemo)(() => {
1849
2155
  if (theme === "auto") {
1850
2156
  return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1851
2157
  }
1852
2158
  return theme;
1853
2159
  }, [theme]);
1854
- const [currentFontSize, setCurrentFontSize] = (0, import_react8.useState)(initialFontSize);
1855
- const [globalSearchTerm, setGlobalSearchTerm] = (0, import_react8.useState)("");
1856
- const [showSearchInput, setShowSearchInput] = (0, import_react8.useState)(false);
1857
- const [currentPage, setCurrentPage] = (0, import_react8.useState)(1);
1858
- const [columnWidths, setColumnWidths] = (0, import_react8.useState)({});
1859
- const [resizingColumnId, setResizingColumnId] = (0, import_react8.useState)(null);
1860
- const [resizeStartX, setResizeStartX] = (0, import_react8.useState)(0);
1861
- const [resizeStartWidth, setResizeStartWidth] = (0, import_react8.useState)(0);
1862
- const [gridHeight, setGridHeight] = (0, import_react8.useState)(initialHeight);
1863
- const [isResizingVertically, setIsResizingVertically] = (0, import_react8.useState)(false);
1864
- const [verticalResizeStartY, setVerticalResizeStartY] = (0, import_react8.useState)(0);
1865
- const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0, import_react8.useState)(0);
1866
- const [showCopyToast, setShowCopyToast] = (0, import_react8.useState)(false);
1867
- const [copyToastMessage, setCopyToastMessage] = (0, import_react8.useState)("");
1868
- const [viewMode, setViewMode] = (0, import_react8.useState)("grid");
1869
- const [showPivotConfig, setShowPivotConfig] = (0, import_react8.useState)(true);
1870
- const [draggingField, setDraggingField] = (0, import_react8.useState)(null);
1871
- const [activeFilterColumn, setActiveFilterColumn] = (0, import_react8.useState)(null);
1872
- const [filterDropdownPosition, setFilterDropdownPosition] = (0, import_react8.useState)({ top: 0, left: 0, maxHeight: 400 });
1873
- const [selectedCell, setSelectedCell] = (0, import_react8.useState)(null);
1874
- const [selectionStart, setSelectionStart] = (0, import_react8.useState)(null);
1875
- const [selectionEnd, setSelectionEnd] = (0, import_react8.useState)(null);
1876
- const [isSelecting, setIsSelecting] = (0, import_react8.useState)(false);
1877
- const tableContainerRef = (0, import_react8.useRef)(null);
1878
- const tableBodyRef = (0, import_react8.useRef)(null);
2160
+ const [currentFontSize, setCurrentFontSize] = (0, import_react9.useState)(initialFontSize);
2161
+ const [globalSearchTerm, setGlobalSearchTerm] = (0, import_react9.useState)("");
2162
+ const [showSearchInput, setShowSearchInput] = (0, import_react9.useState)(false);
2163
+ const [currentPage, setCurrentPage] = (0, import_react9.useState)(1);
2164
+ const [columnWidths, setColumnWidths] = (0, import_react9.useState)({});
2165
+ const [resizingColumnId, setResizingColumnId] = (0, import_react9.useState)(null);
2166
+ const [resizeStartX, setResizeStartX] = (0, import_react9.useState)(0);
2167
+ const [resizeStartWidth, setResizeStartWidth] = (0, import_react9.useState)(0);
2168
+ const [gridHeight, setGridHeight] = (0, import_react9.useState)(initialHeight);
2169
+ const [isResizingVertically, setIsResizingVertically] = (0, import_react9.useState)(false);
2170
+ const [verticalResizeStartY, setVerticalResizeStartY] = (0, import_react9.useState)(0);
2171
+ const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0, import_react9.useState)(0);
2172
+ const [showCopyToast, setShowCopyToast] = (0, import_react9.useState)(false);
2173
+ const [copyToastMessage, setCopyToastMessage] = (0, import_react9.useState)("");
2174
+ const [viewMode, setViewMode] = (0, import_react9.useState)("grid");
2175
+ const [showPivotConfig, setShowPivotConfig] = (0, import_react9.useState)(true);
2176
+ const [draggingField, setDraggingField] = (0, import_react9.useState)(null);
2177
+ const [activeFilterColumn, setActiveFilterColumn] = (0, import_react9.useState)(null);
2178
+ const [filterDropdownPosition, setFilterDropdownPosition] = (0, import_react9.useState)({ top: 0, left: 0, maxHeight: 400 });
2179
+ const [selectedCell, setSelectedCell] = (0, import_react9.useState)(null);
2180
+ const [selectionStart, setSelectionStart] = (0, import_react9.useState)(null);
2181
+ const [selectionEnd, setSelectionEnd] = (0, import_react9.useState)(null);
2182
+ const [isSelecting, setIsSelecting] = (0, import_react9.useState)(false);
2183
+ const tableContainerRef = (0, import_react9.useRef)(null);
2184
+ const tableBodyRef = (0, import_react9.useRef)(null);
1879
2185
  const fontSizeOptions = [
1880
2186
  { value: "xs", label: "S" },
1881
2187
  { value: "sm", label: "M" },
@@ -1896,7 +2202,7 @@ function DataGrid({
1896
2202
  columnFilters,
1897
2203
  activeFilters
1898
2204
  } = useExcelGrid({ data, enableSorting: true, enableFiltering: true });
1899
- const filteredDataForPivot = (0, import_react8.useMemo)(() => {
2205
+ const filteredDataForPivot = (0, import_react9.useMemo)(() => {
1900
2206
  const filteredRows = table.getFilteredRowModel().rows;
1901
2207
  return filteredRows.map((row) => row.original);
1902
2208
  }, [table, columnFilters]);
@@ -1923,7 +2229,7 @@ function DataGrid({
1923
2229
  setRowFields,
1924
2230
  setColumnFields
1925
2231
  } = usePivotTable(filteredDataForPivot);
1926
- const activeFilterInfo = (0, import_react8.useMemo)(() => {
2232
+ const activeFilterInfo = (0, import_react9.useMemo)(() => {
1927
2233
  if (activeFilters.length === 0) return null;
1928
2234
  return activeFilters.map((f) => ({
1929
2235
  column: f.column,
@@ -1931,8 +2237,8 @@ function DataGrid({
1931
2237
  values: f.values || []
1932
2238
  }));
1933
2239
  }, [activeFilters]);
1934
- const rows = (0, import_react8.useMemo)(() => table.getFilteredRowModel().rows, [table, columnFilters]);
1935
- const searchFilteredData = (0, import_react8.useMemo)(() => {
2240
+ const rows = (0, import_react9.useMemo)(() => table.getFilteredRowModel().rows, [table, columnFilters]);
2241
+ const searchFilteredData = (0, import_react9.useMemo)(() => {
1936
2242
  if (!globalSearchTerm.trim() || !enableSearch) {
1937
2243
  return rows;
1938
2244
  }
@@ -1949,20 +2255,20 @@ function DataGrid({
1949
2255
  });
1950
2256
  }, [rows, globalSearchTerm, enableSearch, columnKeys]);
1951
2257
  const totalSearchedRows = searchFilteredData.length;
1952
- const totalPages = (0, import_react8.useMemo)(() => {
2258
+ const totalPages = (0, import_react9.useMemo)(() => {
1953
2259
  if (!enablePagination) return 1;
1954
2260
  return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
1955
2261
  }, [enablePagination, totalSearchedRows, pageSize]);
1956
- const paginatedRows = (0, import_react8.useMemo)(() => {
2262
+ const paginatedRows = (0, import_react9.useMemo)(() => {
1957
2263
  if (!enablePagination) return searchFilteredData;
1958
2264
  const start = (currentPage - 1) * pageSize;
1959
2265
  const end = start + pageSize;
1960
2266
  return searchFilteredData.slice(start, end);
1961
2267
  }, [enablePagination, searchFilteredData, currentPage, pageSize]);
1962
- (0, import_react8.useEffect)(() => {
2268
+ (0, import_react9.useEffect)(() => {
1963
2269
  setCurrentPage(1);
1964
2270
  }, [columnFilters, globalSearchTerm]);
1965
- const selectionBounds = (0, import_react8.useMemo)(() => {
2271
+ const selectionBounds = (0, import_react9.useMemo)(() => {
1966
2272
  if (!selectionStart || !selectionEnd) return null;
1967
2273
  return {
1968
2274
  minRow: Math.min(selectionStart.row, selectionEnd.row),
@@ -1971,7 +2277,7 @@ function DataGrid({
1971
2277
  maxCol: Math.max(selectionStart.col, selectionEnd.col)
1972
2278
  };
1973
2279
  }, [selectionStart, selectionEnd]);
1974
- const selectionStats = (0, import_react8.useMemo)(() => {
2280
+ const selectionStats = (0, import_react9.useMemo)(() => {
1975
2281
  if (!selectionBounds) return null;
1976
2282
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
1977
2283
  const values = [];
@@ -1997,7 +2303,7 @@ function DataGrid({
1997
2303
  const avg = sum / values.length;
1998
2304
  return { count, sum, avg, numericCount: values.length };
1999
2305
  }, [selectionBounds, rows, columnKeys]);
2000
- (0, import_react8.useEffect)(() => {
2306
+ (0, import_react9.useEffect)(() => {
2001
2307
  if (data.length === 0) return;
2002
2308
  const widths = {};
2003
2309
  const sampleSize = Math.min(100, data.length);
@@ -2017,7 +2323,7 @@ function DataGrid({
2017
2323
  }
2018
2324
  setColumnWidths(widths);
2019
2325
  }, [data, columnKeys]);
2020
- const startColumnResize = (0, import_react8.useCallback)(
2326
+ const startColumnResize = (0, import_react9.useCallback)(
2021
2327
  (columnId, event) => {
2022
2328
  if (!enableColumnResize) return;
2023
2329
  event.preventDefault();
@@ -2028,7 +2334,7 @@ function DataGrid({
2028
2334
  },
2029
2335
  [enableColumnResize, columnWidths]
2030
2336
  );
2031
- (0, import_react8.useEffect)(() => {
2337
+ (0, import_react9.useEffect)(() => {
2032
2338
  if (!resizingColumnId) return;
2033
2339
  const handleResizeMove = (event) => {
2034
2340
  const diff = event.clientX - resizeStartX;
@@ -2048,7 +2354,7 @@ function DataGrid({
2048
2354
  document.removeEventListener("mouseup", handleResizeEnd);
2049
2355
  };
2050
2356
  }, [resizingColumnId, resizeStartX, resizeStartWidth]);
2051
- const startVerticalResize = (0, import_react8.useCallback)(
2357
+ const startVerticalResize = (0, import_react9.useCallback)(
2052
2358
  (event) => {
2053
2359
  if (!enableVerticalResize) return;
2054
2360
  event.preventDefault();
@@ -2058,7 +2364,7 @@ function DataGrid({
2058
2364
  },
2059
2365
  [enableVerticalResize, gridHeight]
2060
2366
  );
2061
- (0, import_react8.useEffect)(() => {
2367
+ (0, import_react9.useEffect)(() => {
2062
2368
  if (!isResizingVertically) return;
2063
2369
  const handleVerticalResizeMove = (event) => {
2064
2370
  const diff = event.clientY - verticalResizeStartY;
@@ -2075,7 +2381,7 @@ function DataGrid({
2075
2381
  document.removeEventListener("mouseup", handleVerticalResizeEnd);
2076
2382
  };
2077
2383
  }, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
2078
- const handleExport = (0, import_react8.useCallback)(() => {
2384
+ const handleExport = (0, import_react9.useCallback)(() => {
2079
2385
  if (viewMode === "pivot") {
2080
2386
  if (!pivotResult) return;
2081
2387
  const pivotFilename = exportFilename.replace(".csv", "-pivot.csv");
@@ -2120,7 +2426,7 @@ function DataGrid({
2120
2426
  columnKeys,
2121
2427
  onExport
2122
2428
  ]);
2123
- const copySelectionToClipboard = (0, import_react8.useCallback)(() => {
2429
+ const copySelectionToClipboard = (0, import_react9.useCallback)(() => {
2124
2430
  if (!selectionBounds || !enableClipboard) return;
2125
2431
  const text = formatSelectionForClipboard(
2126
2432
  rows.map((r) => r.original),
@@ -2144,7 +2450,7 @@ function DataGrid({
2144
2450
  }
2145
2451
  );
2146
2452
  }, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
2147
- const handleMouseDown = (0, import_react8.useCallback)(
2453
+ const handleMouseDown = (0, import_react9.useCallback)(
2148
2454
  (rowIndex, colIndex, event) => {
2149
2455
  event.preventDefault();
2150
2456
  if (event.shiftKey && selectedCell) {
@@ -2168,7 +2474,7 @@ function DataGrid({
2168
2474
  },
2169
2475
  [selectedCell, rows, columnKeys, onCellClick]
2170
2476
  );
2171
- const handleMouseEnter = (0, import_react8.useCallback)(
2477
+ const handleMouseEnter = (0, import_react9.useCallback)(
2172
2478
  (rowIndex, colIndex) => {
2173
2479
  if (isSelecting) {
2174
2480
  setSelectionEnd({ row: rowIndex, col: colIndex });
@@ -2176,12 +2482,12 @@ function DataGrid({
2176
2482
  },
2177
2483
  [isSelecting]
2178
2484
  );
2179
- (0, import_react8.useEffect)(() => {
2485
+ (0, import_react9.useEffect)(() => {
2180
2486
  const handleMouseUp = () => setIsSelecting(false);
2181
2487
  document.addEventListener("mouseup", handleMouseUp);
2182
2488
  return () => document.removeEventListener("mouseup", handleMouseUp);
2183
2489
  }, []);
2184
- (0, import_react8.useEffect)(() => {
2490
+ (0, import_react9.useEffect)(() => {
2185
2491
  const handleKeydown = (event) => {
2186
2492
  if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
2187
2493
  event.preventDefault();
@@ -2199,7 +2505,7 @@ function DataGrid({
2199
2505
  document.addEventListener("keydown", handleKeydown);
2200
2506
  return () => document.removeEventListener("keydown", handleKeydown);
2201
2507
  }, [selectionBounds, copySelectionToClipboard]);
2202
- const openFilterDropdown = (0, import_react8.useCallback)(
2508
+ const openFilterDropdown = (0, import_react9.useCallback)(
2203
2509
  (columnId, event) => {
2204
2510
  event.stopPropagation();
2205
2511
  const target = event.currentTarget;
@@ -2228,16 +2534,16 @@ function DataGrid({
2228
2534
  },
2229
2535
  []
2230
2536
  );
2231
- const closeFilterDropdown = (0, import_react8.useCallback)(() => {
2537
+ const closeFilterDropdown = (0, import_react9.useCallback)(() => {
2232
2538
  setActiveFilterColumn(null);
2233
2539
  }, []);
2234
- const handleFilter = (0, import_react8.useCallback)(
2540
+ const handleFilter = (0, import_react9.useCallback)(
2235
2541
  (columnId, values) => {
2236
2542
  setColumnFilter(columnId, values);
2237
2543
  },
2238
2544
  [setColumnFilter]
2239
2545
  );
2240
- const handleSort = (0, import_react8.useCallback)(
2546
+ const handleSort = (0, import_react9.useCallback)(
2241
2547
  (columnId, direction) => {
2242
2548
  if (direction === null) {
2243
2549
  const current = getSortDirection(columnId);
@@ -2261,7 +2567,7 @@ function DataGrid({
2261
2567
  },
2262
2568
  [getSortDirection, toggleSort]
2263
2569
  );
2264
- const isCellSelected = (0, import_react8.useCallback)(
2570
+ const isCellSelected = (0, import_react9.useCallback)(
2265
2571
  (rowIndex, colIndex) => {
2266
2572
  if (!selectionBounds) {
2267
2573
  return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
@@ -2299,30 +2605,30 @@ function DataGrid({
2299
2605
  }
2300
2606
  return String(value);
2301
2607
  };
2302
- const totalTableWidth = (0, import_react8.useMemo)(() => {
2608
+ const totalTableWidth = (0, import_react9.useMemo)(() => {
2303
2609
  return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
2304
2610
  }, [columnKeys, columnWidths]);
2305
2611
  const activeFilterCount = columnFilters.length;
2306
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2612
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2307
2613
  "div",
2308
2614
  {
2309
2615
  className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
2310
2616
  style: { height: `${gridHeight}px` },
2311
2617
  children: [
2312
- showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-toast", children: [
2313
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
2618
+ showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toast", children: [
2619
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
2314
2620
  copyToastMessage
2315
2621
  ] }),
2316
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-toolbar", children: [
2317
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-toolbar-left", children: [
2318
- showPivot && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-view-toggle", children: [
2319
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2622
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toolbar", children: [
2623
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toolbar-left", children: [
2624
+ showPivot && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-view-toggle", children: [
2625
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2320
2626
  "button",
2321
2627
  {
2322
2628
  className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
2323
2629
  onClick: () => setViewMode("grid"),
2324
2630
  children: [
2325
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2631
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2326
2632
  "path",
2327
2633
  {
2328
2634
  strokeLinecap: "round",
@@ -2335,13 +2641,13 @@ function DataGrid({
2335
2641
  ]
2336
2642
  }
2337
2643
  ),
2338
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2644
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2339
2645
  "button",
2340
2646
  {
2341
2647
  className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
2342
2648
  onClick: () => setViewMode("pivot"),
2343
2649
  children: [
2344
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2650
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2345
2651
  "path",
2346
2652
  {
2347
2653
  strokeLinecap: "round",
@@ -2355,14 +2661,14 @@ function DataGrid({
2355
2661
  }
2356
2662
  )
2357
2663
  ] }),
2358
- viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2359
- enableSearch && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2664
+ viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2665
+ enableSearch && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2360
2666
  "button",
2361
2667
  {
2362
2668
  className: "vpg-icon-btn",
2363
2669
  title: "Search (Ctrl+F)",
2364
2670
  onClick: () => setShowSearchInput(true),
2365
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2671
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2366
2672
  "path",
2367
2673
  {
2368
2674
  strokeLinecap: "round",
@@ -2372,15 +2678,15 @@ function DataGrid({
2372
2678
  }
2373
2679
  ) })
2374
2680
  }
2375
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-search-box", children: [
2376
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2681
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-search-box", children: [
2682
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2377
2683
  "svg",
2378
2684
  {
2379
2685
  className: "vpg-search-icon",
2380
2686
  fill: "none",
2381
2687
  stroke: "currentColor",
2382
2688
  viewBox: "0 0 24 24",
2383
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2689
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2384
2690
  "path",
2385
2691
  {
2386
2692
  strokeLinecap: "round",
@@ -2391,7 +2697,7 @@ function DataGrid({
2391
2697
  )
2392
2698
  }
2393
2699
  ),
2394
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2700
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2395
2701
  "input",
2396
2702
  {
2397
2703
  type: "text",
@@ -2408,14 +2714,14 @@ function DataGrid({
2408
2714
  autoFocus: true
2409
2715
  }
2410
2716
  ),
2411
- globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2717
+ globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2412
2718
  "svg",
2413
2719
  {
2414
2720
  className: "vpg-icon-xs",
2415
2721
  fill: "none",
2416
2722
  stroke: "currentColor",
2417
2723
  viewBox: "0 0 24 24",
2418
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2724
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2419
2725
  "path",
2420
2726
  {
2421
2727
  strokeLinecap: "round",
@@ -2427,9 +2733,9 @@ function DataGrid({
2427
2733
  }
2428
2734
  ) })
2429
2735
  ] }) }),
2430
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-font-size-control", children: [
2431
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-label", children: "Size:" }),
2432
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2736
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-font-size-control", children: [
2737
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-label", children: "Size:" }),
2738
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2433
2739
  "button",
2434
2740
  {
2435
2741
  className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
@@ -2439,8 +2745,8 @@ function DataGrid({
2439
2745
  opt.value
2440
2746
  )) })
2441
2747
  ] }),
2442
- activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-info", children: [
2443
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2748
+ activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-filter-info", children: [
2749
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2444
2750
  "path",
2445
2751
  {
2446
2752
  fillRule: "evenodd",
@@ -2448,26 +2754,26 @@ function DataGrid({
2448
2754
  clipRule: "evenodd"
2449
2755
  }
2450
2756
  ) }),
2451
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
2757
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
2452
2758
  activeFilterCount,
2453
2759
  " filter",
2454
2760
  activeFilterCount > 1 ? "s" : ""
2455
2761
  ] })
2456
2762
  ] }),
2457
- globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-search-info", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
2763
+ globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-search-info", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
2458
2764
  totalSearchedRows,
2459
2765
  " match",
2460
2766
  totalSearchedRows !== 1 ? "es" : ""
2461
2767
  ] }) })
2462
2768
  ] }),
2463
- viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2464
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2769
+ viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2770
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2465
2771
  "button",
2466
2772
  {
2467
2773
  className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
2468
2774
  onClick: () => setShowPivotConfig(!showPivotConfig),
2469
2775
  children: [
2470
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2776
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2471
2777
  "path",
2472
2778
  {
2473
2779
  strokeLinecap: "round",
@@ -2481,8 +2787,8 @@ function DataGrid({
2481
2787
  ]
2482
2788
  }
2483
2789
  ),
2484
- pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-pivot-status", children: [
2485
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2790
+ pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pivot-status", children: [
2791
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2486
2792
  "path",
2487
2793
  {
2488
2794
  fillRule: "evenodd",
@@ -2490,13 +2796,13 @@ function DataGrid({
2490
2796
  clipRule: "evenodd"
2491
2797
  }
2492
2798
  ) }),
2493
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Pivot configured" })
2799
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Pivot configured" })
2494
2800
  ] })
2495
2801
  ] })
2496
2802
  ] }),
2497
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-toolbar-right", children: [
2498
- viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
2499
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2803
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toolbar-right", children: [
2804
+ viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
2805
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2500
2806
  "path",
2501
2807
  {
2502
2808
  strokeLinecap: "round",
@@ -2507,13 +2813,13 @@ function DataGrid({
2507
2813
  ) }),
2508
2814
  "Clear Filters"
2509
2815
  ] }),
2510
- enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2816
+ enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2511
2817
  "button",
2512
2818
  {
2513
2819
  className: "vpg-icon-btn",
2514
2820
  title: "Copy selection (Ctrl+C)",
2515
2821
  onClick: copySelectionToClipboard,
2516
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2822
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2517
2823
  "path",
2518
2824
  {
2519
2825
  strokeLinecap: "round",
@@ -2524,14 +2830,14 @@ function DataGrid({
2524
2830
  ) })
2525
2831
  }
2526
2832
  ),
2527
- enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2833
+ enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2528
2834
  "button",
2529
2835
  {
2530
2836
  className: "vpg-export-btn",
2531
2837
  title: viewMode === "pivot" ? "Export Pivot to CSV" : "Export to CSV",
2532
2838
  onClick: handleExport,
2533
2839
  children: [
2534
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2840
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2535
2841
  "path",
2536
2842
  {
2537
2843
  strokeLinecap: "round",
@@ -2547,13 +2853,13 @@ function DataGrid({
2547
2853
  )
2548
2854
  ] })
2549
2855
  ] }),
2550
- viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
2551
- loading && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-loading", children: [
2552
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-spinner" }),
2553
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Loading data..." })
2856
+ viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
2857
+ loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-loading", children: [
2858
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-spinner" }),
2859
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Loading data..." })
2554
2860
  ] }),
2555
- !loading && data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-empty", children: [
2556
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2861
+ !loading && data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-empty", children: [
2862
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2557
2863
  "path",
2558
2864
  {
2559
2865
  strokeLinecap: "round",
@@ -2562,10 +2868,10 @@ function DataGrid({
2562
2868
  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"
2563
2869
  }
2564
2870
  ) }) }),
2565
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "No data available" })
2871
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "No data available" })
2566
2872
  ] }),
2567
- !loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-empty", children: [
2568
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2873
+ !loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-empty", children: [
2874
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2569
2875
  "path",
2570
2876
  {
2571
2877
  strokeLinecap: "round",
@@ -2574,11 +2880,11 @@ function DataGrid({
2574
2880
  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"
2575
2881
  }
2576
2882
  ) }) }),
2577
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "No matching records" }),
2578
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
2883
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "No matching records" }),
2884
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
2579
2885
  ] }),
2580
- !loading && filteredRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
2581
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tr", { children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2886
+ !loading && filteredRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
2887
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2582
2888
  "th",
2583
2889
  {
2584
2890
  className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
@@ -2593,16 +2899,16 @@ function DataGrid({
2593
2899
  }
2594
2900
  },
2595
2901
  children: [
2596
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-content", children: [
2597
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-header-text", children: colId }),
2598
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-icons", children: [
2599
- getSortDirection(colId) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2902
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-header-content", children: [
2903
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-header-text", children: colId }),
2904
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-header-icons", children: [
2905
+ getSortDirection(colId) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2600
2906
  "svg",
2601
2907
  {
2602
2908
  className: "vpg-icon-sm",
2603
2909
  fill: "currentColor",
2604
2910
  viewBox: "0 0 20 20",
2605
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2911
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2606
2912
  "path",
2607
2913
  {
2608
2914
  fillRule: "evenodd",
@@ -2611,13 +2917,13 @@ function DataGrid({
2611
2917
  }
2612
2918
  )
2613
2919
  }
2614
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2920
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2615
2921
  "svg",
2616
2922
  {
2617
2923
  className: "vpg-icon-sm",
2618
2924
  fill: "currentColor",
2619
2925
  viewBox: "0 0 20 20",
2620
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2926
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2621
2927
  "path",
2622
2928
  {
2623
2929
  fillRule: "evenodd",
@@ -2627,13 +2933,13 @@ function DataGrid({
2627
2933
  )
2628
2934
  }
2629
2935
  ) }),
2630
- hasActiveFilter(colId) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2936
+ hasActiveFilter(colId) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2631
2937
  "svg",
2632
2938
  {
2633
2939
  className: "vpg-icon-xs",
2634
2940
  fill: "currentColor",
2635
2941
  viewBox: "0 0 20 20",
2636
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2942
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2637
2943
  "path",
2638
2944
  {
2639
2945
  fillRule: "evenodd",
@@ -2643,14 +2949,14 @@ function DataGrid({
2643
2949
  )
2644
2950
  }
2645
2951
  ) }),
2646
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2952
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2647
2953
  "svg",
2648
2954
  {
2649
2955
  className: "vpg-icon-sm",
2650
2956
  fill: "none",
2651
2957
  stroke: "currentColor",
2652
2958
  viewBox: "0 0 24 24",
2653
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2959
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2654
2960
  "path",
2655
2961
  {
2656
2962
  strokeLinecap: "round",
@@ -2663,7 +2969,7 @@ function DataGrid({
2663
2969
  ) })
2664
2970
  ] })
2665
2971
  ] }),
2666
- enableColumnResize && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2972
+ enableColumnResize && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2667
2973
  "div",
2668
2974
  {
2669
2975
  className: "vpg-resize-handle",
@@ -2674,7 +2980,7 @@ function DataGrid({
2674
2980
  },
2675
2981
  colId
2676
2982
  )) }) }),
2677
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2983
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2678
2984
  "td",
2679
2985
  {
2680
2986
  className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
@@ -2692,8 +2998,8 @@ function DataGrid({
2692
2998
  )) }, row.id)) })
2693
2999
  ] }) })
2694
3000
  ] }),
2695
- viewMode === "pivot" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-pivot-container", children: [
2696
- showPivotConfig && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3001
+ viewMode === "pivot" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pivot-container", children: [
3002
+ showPivotConfig && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2697
3003
  PivotConfig,
2698
3004
  {
2699
3005
  availableFields: pivotAvailableFields,
@@ -2717,7 +3023,7 @@ function DataGrid({
2717
3023
  onRemoveValueField: removeValueField
2718
3024
  }
2719
3025
  ) }),
2720
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3026
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2721
3027
  PivotSkeleton,
2722
3028
  {
2723
3029
  rowFields: pivotRowFields,
@@ -2742,44 +3048,44 @@ function DataGrid({
2742
3048
  }
2743
3049
  ) })
2744
3050
  ] }),
2745
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-footer", children: [
2746
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2747
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
3051
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-footer", children: [
3052
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
3053
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
2748
3054
  ((currentPage - 1) * pageSize + 1).toLocaleString(),
2749
3055
  "-",
2750
3056
  Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
2751
3057
  ] }),
2752
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-separator", children: "of" }),
2753
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: totalSearchedRows.toLocaleString() }),
2754
- totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-filtered-note", children: [
3058
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "of" }),
3059
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: totalSearchedRows.toLocaleString() }),
3060
+ totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-filtered-note", children: [
2755
3061
  "(",
2756
3062
  totalRowCount.toLocaleString(),
2757
3063
  " total)"
2758
3064
  ] })
2759
- ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
3065
+ ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
2760
3066
  totalRowCount.toLocaleString(),
2761
3067
  " records"
2762
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2763
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
2764
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-separator", children: "of" }),
2765
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: totalRowCount.toLocaleString() }),
2766
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-separator", children: "records" })
2767
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2768
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
2769
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
2770
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
3068
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
3069
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
3070
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "of" }),
3071
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: totalRowCount.toLocaleString() }),
3072
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "records" })
3073
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
3074
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
3075
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
3076
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
2771
3077
  totalRowCount.toLocaleString(),
2772
3078
  " source records"
2773
3079
  ] })
2774
3080
  ] }) }),
2775
- enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-pagination", children: [
2776
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3081
+ enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pagination", children: [
3082
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2777
3083
  "button",
2778
3084
  {
2779
3085
  className: "vpg-page-btn",
2780
3086
  disabled: currentPage === 1,
2781
3087
  onClick: () => setCurrentPage(1),
2782
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3088
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2783
3089
  "path",
2784
3090
  {
2785
3091
  strokeLinecap: "round",
@@ -2790,13 +3096,13 @@ function DataGrid({
2790
3096
  ) })
2791
3097
  }
2792
3098
  ),
2793
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3099
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2794
3100
  "button",
2795
3101
  {
2796
3102
  className: "vpg-page-btn",
2797
3103
  disabled: currentPage === 1,
2798
3104
  onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
2799
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3105
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2800
3106
  "path",
2801
3107
  {
2802
3108
  strokeLinecap: "round",
@@ -2807,19 +3113,19 @@ function DataGrid({
2807
3113
  ) })
2808
3114
  }
2809
3115
  ),
2810
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-page-info", children: [
3116
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-page-info", children: [
2811
3117
  "Page ",
2812
3118
  currentPage,
2813
3119
  " of ",
2814
3120
  totalPages
2815
3121
  ] }),
2816
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3122
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2817
3123
  "button",
2818
3124
  {
2819
3125
  className: "vpg-page-btn",
2820
3126
  disabled: currentPage === totalPages,
2821
3127
  onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
2822
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3128
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2823
3129
  "path",
2824
3130
  {
2825
3131
  strokeLinecap: "round",
@@ -2830,13 +3136,13 @@ function DataGrid({
2830
3136
  ) })
2831
3137
  }
2832
3138
  ),
2833
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3139
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2834
3140
  "button",
2835
3141
  {
2836
3142
  className: "vpg-page-btn",
2837
3143
  disabled: currentPage === totalPages,
2838
3144
  onClick: () => setCurrentPage(totalPages),
2839
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3145
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2840
3146
  "path",
2841
3147
  {
2842
3148
  strokeLinecap: "round",
@@ -2848,45 +3154,45 @@ function DataGrid({
2848
3154
  }
2849
3155
  )
2850
3156
  ] }),
2851
- viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-selection-stats", children: [
2852
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-stat", children: [
2853
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
2854
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
3157
+ viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-selection-stats", children: [
3158
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-stat", children: [
3159
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
3160
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
2855
3161
  ] }),
2856
- selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2857
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
2858
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-stat", children: [
2859
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
2860
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
3162
+ selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
3163
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
3164
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-stat", children: [
3165
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
3166
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
2861
3167
  ] }),
2862
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
2863
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-stat", children: [
2864
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
2865
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
3168
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
3169
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-stat", children: [
3170
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
3171
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
2866
3172
  ] })
2867
3173
  ] })
2868
3174
  ] }),
2869
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-demo-banner", children: [
2870
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
2871
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Pro features enabled" }),
2872
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
2873
- ] }) : showWatermark ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
2874
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("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: [
2875
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: "3", y: "3", width: "7", height: "7" }),
2876
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: "14", y: "3", width: "7", height: "7" }),
2877
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: "14", y: "14", width: "7", height: "7" }),
2878
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: "3", y: "14", width: "7", height: "7" })
3175
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-demo-banner", children: [
3176
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
3177
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Pro features enabled" }),
3178
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
3179
+ ] }) : showWatermark ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
3180
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("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: [
3181
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "3", y: "3", width: "7", height: "7" }),
3182
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "14", y: "3", width: "7", height: "7" }),
3183
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "14", y: "14", width: "7", height: "7" }),
3184
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "3", y: "14", width: "7", height: "7" })
2879
3185
  ] }),
2880
3186
  "Powered by TinyPivot"
2881
3187
  ] }) }) : null })
2882
3188
  ] }),
2883
- enableVerticalResize && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-resize-grip", children: [
2884
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", {}),
2885
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", {}),
2886
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", {})
3189
+ enableVerticalResize && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-resize-grip", children: [
3190
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
3191
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
3192
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {})
2887
3193
  ] }) }),
2888
- activeFilterColumn && (0, import_react_dom.createPortal)(
2889
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3194
+ activeFilterColumn && (0, import_react_dom2.createPortal)(
3195
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2890
3196
  "div",
2891
3197
  {
2892
3198
  className: "vpg-filter-portal",
@@ -2897,7 +3203,7 @@ function DataGrid({
2897
3203
  maxHeight: `${filterDropdownPosition.maxHeight}px`,
2898
3204
  zIndex: 9999
2899
3205
  },
2900
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3206
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2901
3207
  ColumnFilter,
2902
3208
  {
2903
3209
  columnId: activeFilterColumn,