@smallwebco/tinypivot-react 1.0.66 → 1.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2133,20 +2133,178 @@ function ChartBuilder({
2133
2133
  }
2134
2134
 
2135
2135
  // src/components/ColumnFilter.tsx
2136
- import { useCallback as useCallback6, useEffect as useEffect6, useMemo as useMemo6, useRef as useRef3, useState as useState6 } from "react";
2136
+ import { useCallback as useCallback7, useEffect as useEffect7, useMemo as useMemo7, useRef as useRef3, useState as useState7 } from "react";
2137
2137
 
2138
- // src/components/NumericRangeFilter.tsx
2138
+ // src/components/DateRangeFilter.tsx
2139
+ import { formatDate, getDatePlaceholder, parseDateInput } from "@smallwebco/tinypivot-core";
2139
2140
  import { useCallback as useCallback5, useEffect as useEffect5, useMemo as useMemo5, useState as useState5 } from "react";
2140
2141
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2142
+ function DateRangeFilter({
2143
+ dataMin,
2144
+ dataMax,
2145
+ currentRange,
2146
+ onChange,
2147
+ dateFormat = "iso"
2148
+ }) {
2149
+ const [localMinText, setLocalMinText] = useState5("");
2150
+ const [localMaxText, setLocalMaxText] = useState5("");
2151
+ const [minError, setMinError] = useState5(false);
2152
+ const [maxError, setMaxError] = useState5(false);
2153
+ const formattedMin = useMemo5(() => formatDate(dataMin, dateFormat), [dataMin, dateFormat]);
2154
+ const formattedMax = useMemo5(() => formatDate(dataMax, dateFormat), [dataMax, dateFormat]);
2155
+ const isFilterActive = localMinText !== "" || localMaxText !== "";
2156
+ const emitChange = useCallback5(() => {
2157
+ const min = localMinText ? parseDateInput(localMinText, dateFormat) : null;
2158
+ const max = localMaxText ? parseDateInput(localMaxText, dateFormat) : null;
2159
+ if (min === null && max === null) {
2160
+ onChange(null);
2161
+ } else {
2162
+ onChange({ min, max });
2163
+ }
2164
+ }, [localMinText, localMaxText, dateFormat, onChange]);
2165
+ const handleMinBlur = useCallback5(() => {
2166
+ if (localMinText === "") {
2167
+ setMinError(false);
2168
+ emitChange();
2169
+ return;
2170
+ }
2171
+ const parsed = parseDateInput(localMinText, dateFormat);
2172
+ setMinError(parsed === null);
2173
+ if (parsed !== null)
2174
+ emitChange();
2175
+ }, [localMinText, dateFormat, emitChange]);
2176
+ const handleMaxBlur = useCallback5(() => {
2177
+ if (localMaxText === "") {
2178
+ setMaxError(false);
2179
+ emitChange();
2180
+ return;
2181
+ }
2182
+ const parsed = parseDateInput(localMaxText, dateFormat);
2183
+ setMaxError(parsed === null);
2184
+ if (parsed !== null)
2185
+ emitChange();
2186
+ }, [localMaxText, dateFormat, emitChange]);
2187
+ const clearFilter = useCallback5(() => {
2188
+ setLocalMinText("");
2189
+ setLocalMaxText("");
2190
+ setMinError(false);
2191
+ setMaxError(false);
2192
+ onChange(null);
2193
+ }, [onChange]);
2194
+ const setFullRange = useCallback5(() => {
2195
+ setLocalMinText(formatDate(dataMin, dateFormat));
2196
+ setLocalMaxText(formatDate(dataMax, dateFormat));
2197
+ setMinError(false);
2198
+ setMaxError(false);
2199
+ onChange({ min: dataMin, max: dataMax });
2200
+ }, [dataMin, dataMax, dateFormat, onChange]);
2201
+ useEffect5(() => {
2202
+ if (currentRange?.min) {
2203
+ setLocalMinText(formatDate(currentRange.min, dateFormat));
2204
+ } else {
2205
+ setLocalMinText("");
2206
+ }
2207
+ if (currentRange?.max) {
2208
+ setLocalMaxText(formatDate(currentRange.max, dateFormat));
2209
+ } else {
2210
+ setLocalMaxText("");
2211
+ }
2212
+ setMinError(false);
2213
+ setMaxError(false);
2214
+ }, [currentRange, dateFormat]);
2215
+ const handleKeyDown = useCallback5((e, handler) => {
2216
+ if (e.key === "Enter")
2217
+ handler();
2218
+ }, []);
2219
+ return /* @__PURE__ */ jsxs4("div", { className: "vpg-range-filter", children: [
2220
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-range-info", children: [
2221
+ /* @__PURE__ */ jsx4("span", { className: "vpg-range-label", children: "Data range:" }),
2222
+ /* @__PURE__ */ jsxs4("span", { className: "vpg-range-bounds", children: [
2223
+ formattedMin,
2224
+ " ",
2225
+ "\u2013",
2226
+ " ",
2227
+ formattedMax
2228
+ ] })
2229
+ ] }),
2230
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-range-inputs", children: [
2231
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-input-group", children: [
2232
+ /* @__PURE__ */ jsx4("label", { className: "vpg-input-label", children: "From" }),
2233
+ /* @__PURE__ */ jsx4(
2234
+ "input",
2235
+ {
2236
+ type: "text",
2237
+ className: `vpg-range-input ${minError ? "vpg-input-error" : ""}`,
2238
+ placeholder: getDatePlaceholder(dateFormat),
2239
+ value: localMinText,
2240
+ onChange: (e) => setLocalMinText(e.target.value),
2241
+ onBlur: handleMinBlur,
2242
+ onKeyDown: (e) => handleKeyDown(e, handleMinBlur)
2243
+ }
2244
+ )
2245
+ ] }),
2246
+ /* @__PURE__ */ jsx4("span", { className: "vpg-input-separator", children: "to" }),
2247
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-input-group", children: [
2248
+ /* @__PURE__ */ jsx4("label", { className: "vpg-input-label", children: "To" }),
2249
+ /* @__PURE__ */ jsx4(
2250
+ "input",
2251
+ {
2252
+ type: "text",
2253
+ className: `vpg-range-input ${maxError ? "vpg-input-error" : ""}`,
2254
+ placeholder: getDatePlaceholder(dateFormat),
2255
+ value: localMaxText,
2256
+ onChange: (e) => setLocalMaxText(e.target.value),
2257
+ onBlur: handleMaxBlur,
2258
+ onKeyDown: (e) => handleKeyDown(e, handleMaxBlur)
2259
+ }
2260
+ )
2261
+ ] })
2262
+ ] }),
2263
+ /* @__PURE__ */ jsxs4("div", { className: "vpg-range-actions", children: [
2264
+ /* @__PURE__ */ jsxs4("button", { className: "vpg-range-btn", disabled: !isFilterActive, onClick: clearFilter, children: [
2265
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }),
2266
+ "Clear"
2267
+ ] }),
2268
+ /* @__PURE__ */ jsxs4("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
2269
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) }),
2270
+ "Full Range"
2271
+ ] })
2272
+ ] }),
2273
+ isFilterActive && !minError && !maxError && /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-summary", children: [
2274
+ /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, 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" }) }),
2275
+ /* @__PURE__ */ jsxs4("span", { children: [
2276
+ "Showing dates",
2277
+ localMinText && /* @__PURE__ */ jsxs4("strong", { children: [
2278
+ " ",
2279
+ "from",
2280
+ " ",
2281
+ localMinText
2282
+ ] }),
2283
+ localMinText && localMaxText && " ",
2284
+ localMaxText && /* @__PURE__ */ jsxs4("strong", { children: [
2285
+ "to",
2286
+ " ",
2287
+ localMaxText
2288
+ ] })
2289
+ ] })
2290
+ ] })
2291
+ ] });
2292
+ }
2293
+
2294
+ // src/components/NumericRangeFilter.tsx
2295
+ import { formatNumber } from "@smallwebco/tinypivot-core";
2296
+ import { useCallback as useCallback6, useEffect as useEffect6, useMemo as useMemo6, useState as useState6 } from "react";
2297
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2141
2298
  function NumericRangeFilter({
2142
2299
  dataMin,
2143
2300
  dataMax,
2144
2301
  currentRange,
2145
- onChange
2302
+ onChange,
2303
+ numberFormat = "us"
2146
2304
  }) {
2147
- const [localMin, setLocalMin] = useState5(currentRange?.min ?? null);
2148
- const [localMax, setLocalMax] = useState5(currentRange?.max ?? null);
2149
- const step = useMemo5(() => {
2305
+ const [localMin, setLocalMin] = useState6(currentRange?.min ?? null);
2306
+ const [localMax, setLocalMax] = useState6(currentRange?.max ?? null);
2307
+ const step = useMemo6(() => {
2150
2308
  const range = dataMax - dataMin;
2151
2309
  if (range === 0)
2152
2310
  return 1;
@@ -2160,25 +2318,23 @@ function NumericRangeFilter({
2160
2318
  return 10;
2161
2319
  return 10 ** (Math.floor(Math.log10(range)) - 2);
2162
2320
  }, [dataMin, dataMax]);
2163
- const formatValue = useCallback5((val) => {
2321
+ const formatValue = useCallback6((val) => {
2164
2322
  if (val === null)
2165
2323
  return "";
2166
- if (Number.isInteger(val))
2167
- return val.toLocaleString();
2168
- return val.toLocaleString(void 0, { maximumFractionDigits: 2 });
2169
- }, []);
2324
+ return formatNumber(val, numberFormat);
2325
+ }, [numberFormat]);
2170
2326
  const isFilterActive = localMin !== null || localMax !== null;
2171
- const minPercent = useMemo5(() => {
2327
+ const minPercent = useMemo6(() => {
2172
2328
  if (localMin === null || dataMax === dataMin)
2173
2329
  return 0;
2174
2330
  return (localMin - dataMin) / (dataMax - dataMin) * 100;
2175
2331
  }, [localMin, dataMin, dataMax]);
2176
- const maxPercent = useMemo5(() => {
2332
+ const maxPercent = useMemo6(() => {
2177
2333
  if (localMax === null || dataMax === dataMin)
2178
2334
  return 100;
2179
2335
  return (localMax - dataMin) / (dataMax - dataMin) * 100;
2180
2336
  }, [localMax, dataMin, dataMax]);
2181
- const handleMinSlider = useCallback5((event) => {
2337
+ const handleMinSlider = useCallback6((event) => {
2182
2338
  const value = Number.parseFloat(event.target.value);
2183
2339
  setLocalMin(() => {
2184
2340
  if (localMax !== null && value > localMax) {
@@ -2187,7 +2343,7 @@ function NumericRangeFilter({
2187
2343
  return value;
2188
2344
  });
2189
2345
  }, [localMax]);
2190
- const handleMaxSlider = useCallback5((event) => {
2346
+ const handleMaxSlider = useCallback6((event) => {
2191
2347
  const value = Number.parseFloat(event.target.value);
2192
2348
  setLocalMax(() => {
2193
2349
  if (localMin !== null && value < localMin) {
@@ -2196,14 +2352,14 @@ function NumericRangeFilter({
2196
2352
  return value;
2197
2353
  });
2198
2354
  }, [localMin]);
2199
- const handleSliderChange = useCallback5(() => {
2355
+ const handleSliderChange = useCallback6(() => {
2200
2356
  if (localMin === null && localMax === null) {
2201
2357
  onChange(null);
2202
2358
  } else {
2203
2359
  onChange({ min: localMin, max: localMax });
2204
2360
  }
2205
2361
  }, [localMin, localMax, onChange]);
2206
- const handleMinInput = useCallback5((event) => {
2362
+ const handleMinInput = useCallback6((event) => {
2207
2363
  const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
2208
2364
  if (value !== null && !Number.isNaN(value)) {
2209
2365
  setLocalMin(Math.max(dataMin, Math.min(value, localMax ?? dataMax)));
@@ -2211,7 +2367,7 @@ function NumericRangeFilter({
2211
2367
  setLocalMin(null);
2212
2368
  }
2213
2369
  }, [dataMin, dataMax, localMax]);
2214
- const handleMaxInput = useCallback5((event) => {
2370
+ const handleMaxInput = useCallback6((event) => {
2215
2371
  const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
2216
2372
  if (value !== null && !Number.isNaN(value)) {
2217
2373
  setLocalMax(Math.min(dataMax, Math.max(value, localMin ?? dataMin)));
@@ -2219,39 +2375,39 @@ function NumericRangeFilter({
2219
2375
  setLocalMax(null);
2220
2376
  }
2221
2377
  }, [dataMin, dataMax, localMin]);
2222
- const handleInputBlur = useCallback5(() => {
2378
+ const handleInputBlur = useCallback6(() => {
2223
2379
  if (localMin === null && localMax === null) {
2224
2380
  onChange(null);
2225
2381
  } else {
2226
2382
  onChange({ min: localMin, max: localMax });
2227
2383
  }
2228
2384
  }, [localMin, localMax, onChange]);
2229
- const clearFilter = useCallback5(() => {
2385
+ const clearFilter = useCallback6(() => {
2230
2386
  setLocalMin(null);
2231
2387
  setLocalMax(null);
2232
2388
  onChange(null);
2233
2389
  }, [onChange]);
2234
- const setFullRange = useCallback5(() => {
2390
+ const setFullRange = useCallback6(() => {
2235
2391
  setLocalMin(dataMin);
2236
2392
  setLocalMax(dataMax);
2237
2393
  onChange({ min: dataMin, max: dataMax });
2238
2394
  }, [dataMin, dataMax, onChange]);
2239
- useEffect5(() => {
2395
+ useEffect6(() => {
2240
2396
  setLocalMin(currentRange?.min ?? null);
2241
2397
  setLocalMax(currentRange?.max ?? null);
2242
2398
  }, [currentRange]);
2243
- return /* @__PURE__ */ jsxs4("div", { className: "vpg-range-filter", children: [
2244
- /* @__PURE__ */ jsxs4("div", { className: "vpg-range-info", children: [
2245
- /* @__PURE__ */ jsx4("span", { className: "vpg-range-label", children: "Data range:" }),
2246
- /* @__PURE__ */ jsxs4("span", { className: "vpg-range-bounds", children: [
2399
+ return /* @__PURE__ */ jsxs5("div", { className: "vpg-range-filter", children: [
2400
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-range-info", children: [
2401
+ /* @__PURE__ */ jsx5("span", { className: "vpg-range-label", children: "Data range:" }),
2402
+ /* @__PURE__ */ jsxs5("span", { className: "vpg-range-bounds", children: [
2247
2403
  formatValue(dataMin),
2248
2404
  " ",
2249
2405
  "\u2013",
2250
2406
  formatValue(dataMax)
2251
2407
  ] })
2252
2408
  ] }),
2253
- /* @__PURE__ */ jsxs4("div", { className: "vpg-slider-container", children: [
2254
- /* @__PURE__ */ jsx4("div", { className: "vpg-slider-track", children: /* @__PURE__ */ jsx4(
2409
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-slider-container", children: [
2410
+ /* @__PURE__ */ jsx5("div", { className: "vpg-slider-track", children: /* @__PURE__ */ jsx5(
2255
2411
  "div",
2256
2412
  {
2257
2413
  className: "vpg-slider-fill",
@@ -2261,7 +2417,7 @@ function NumericRangeFilter({
2261
2417
  }
2262
2418
  }
2263
2419
  ) }),
2264
- /* @__PURE__ */ jsx4(
2420
+ /* @__PURE__ */ jsx5(
2265
2421
  "input",
2266
2422
  {
2267
2423
  type: "range",
@@ -2275,7 +2431,7 @@ function NumericRangeFilter({
2275
2431
  onTouchEnd: handleSliderChange
2276
2432
  }
2277
2433
  ),
2278
- /* @__PURE__ */ jsx4(
2434
+ /* @__PURE__ */ jsx5(
2279
2435
  "input",
2280
2436
  {
2281
2437
  type: "range",
@@ -2290,10 +2446,10 @@ function NumericRangeFilter({
2290
2446
  }
2291
2447
  )
2292
2448
  ] }),
2293
- /* @__PURE__ */ jsxs4("div", { className: "vpg-range-inputs", children: [
2294
- /* @__PURE__ */ jsxs4("div", { className: "vpg-input-group", children: [
2295
- /* @__PURE__ */ jsx4("label", { className: "vpg-input-label", children: "Min" }),
2296
- /* @__PURE__ */ jsx4(
2449
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-range-inputs", children: [
2450
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-input-group", children: [
2451
+ /* @__PURE__ */ jsx5("label", { className: "vpg-input-label", children: "Min" }),
2452
+ /* @__PURE__ */ jsx5(
2297
2453
  "input",
2298
2454
  {
2299
2455
  type: "number",
@@ -2306,10 +2462,10 @@ function NumericRangeFilter({
2306
2462
  }
2307
2463
  )
2308
2464
  ] }),
2309
- /* @__PURE__ */ jsx4("span", { className: "vpg-input-separator", children: "to" }),
2310
- /* @__PURE__ */ jsxs4("div", { className: "vpg-input-group", children: [
2311
- /* @__PURE__ */ jsx4("label", { className: "vpg-input-label", children: "Max" }),
2312
- /* @__PURE__ */ jsx4(
2465
+ /* @__PURE__ */ jsx5("span", { className: "vpg-input-separator", children: "to" }),
2466
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-input-group", children: [
2467
+ /* @__PURE__ */ jsx5("label", { className: "vpg-input-label", children: "Max" }),
2468
+ /* @__PURE__ */ jsx5(
2313
2469
  "input",
2314
2470
  {
2315
2471
  type: "number",
@@ -2323,15 +2479,15 @@ function NumericRangeFilter({
2323
2479
  )
2324
2480
  ] })
2325
2481
  ] }),
2326
- /* @__PURE__ */ jsxs4("div", { className: "vpg-range-actions", children: [
2327
- /* @__PURE__ */ jsxs4(
2482
+ /* @__PURE__ */ jsxs5("div", { className: "vpg-range-actions", children: [
2483
+ /* @__PURE__ */ jsxs5(
2328
2484
  "button",
2329
2485
  {
2330
2486
  className: "vpg-range-btn",
2331
2487
  disabled: !isFilterActive,
2332
2488
  onClick: clearFilter,
2333
2489
  children: [
2334
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2490
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2335
2491
  "path",
2336
2492
  {
2337
2493
  strokeLinecap: "round",
@@ -2344,8 +2500,8 @@ function NumericRangeFilter({
2344
2500
  ]
2345
2501
  }
2346
2502
  ),
2347
- /* @__PURE__ */ jsxs4("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
2348
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2503
+ /* @__PURE__ */ jsxs5("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
2504
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2349
2505
  "path",
2350
2506
  {
2351
2507
  strokeLinecap: "round",
@@ -2357,8 +2513,8 @@ function NumericRangeFilter({
2357
2513
  "Full Range"
2358
2514
  ] })
2359
2515
  ] }),
2360
- isFilterActive && /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-summary", children: [
2361
- /* @__PURE__ */ jsx4("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
2516
+ isFilterActive && /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-summary", children: [
2517
+ /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2362
2518
  "path",
2363
2519
  {
2364
2520
  strokeLinecap: "round",
@@ -2367,15 +2523,15 @@ function NumericRangeFilter({
2367
2523
  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"
2368
2524
  }
2369
2525
  ) }),
2370
- /* @__PURE__ */ jsxs4("span", { children: [
2526
+ /* @__PURE__ */ jsxs5("span", { children: [
2371
2527
  "Showing values",
2372
2528
  " ",
2373
- localMin !== null && /* @__PURE__ */ jsxs4("strong", { children: [
2529
+ localMin !== null && /* @__PURE__ */ jsxs5("strong", { children: [
2374
2530
  "\u2265",
2375
2531
  formatValue(localMin)
2376
2532
  ] }),
2377
2533
  localMin !== null && localMax !== null && " and ",
2378
- localMax !== null && /* @__PURE__ */ jsxs4("strong", { children: [
2534
+ localMax !== null && /* @__PURE__ */ jsxs5("strong", { children: [
2379
2535
  "\u2264",
2380
2536
  formatValue(localMax)
2381
2537
  ] })
@@ -2385,45 +2541,53 @@ function NumericRangeFilter({
2385
2541
  }
2386
2542
 
2387
2543
  // src/components/ColumnFilter.tsx
2388
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2544
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2389
2545
  function ColumnFilter({
2390
2546
  columnName,
2391
2547
  stats,
2392
2548
  selectedValues,
2393
2549
  sortDirection,
2394
2550
  numericRange,
2551
+ dateRange,
2552
+ numberFormat,
2553
+ dateFormat,
2395
2554
  onFilter,
2396
2555
  onSort,
2397
2556
  onClose,
2398
- onRangeFilter
2557
+ onRangeFilter,
2558
+ onDateRangeFilter
2399
2559
  }) {
2400
- const [searchQuery, setSearchQuery] = useState6("");
2401
- const [localSelected, setLocalSelected] = useState6(new Set(selectedValues));
2560
+ const [searchQuery, setSearchQuery] = useState7("");
2561
+ const [localSelected, setLocalSelected] = useState7(new Set(selectedValues));
2402
2562
  const dropdownRef = useRef3(null);
2403
2563
  const searchInputRef = useRef3(null);
2404
2564
  const isNumericColumn = stats.type === "number" && stats.numericMin !== void 0 && stats.numericMax !== void 0;
2405
- const [filterMode, setFilterMode] = useState6(numericRange ? "range" : "values");
2406
- const [localRange, setLocalRange] = useState6(numericRange ?? null);
2565
+ const isDateColumn = stats.type === "date" && stats.dateMin !== void 0 && stats.dateMax !== void 0;
2566
+ const [filterMode, setFilterMode] = useState7(
2567
+ numericRange || dateRange ? "range" : "values"
2568
+ );
2569
+ const [localRange, setLocalRange] = useState7(numericRange ?? null);
2570
+ const [localDateRange, setLocalDateRange] = useState7(dateRange ?? null);
2407
2571
  const hasBlankValues = stats.nullCount > 0;
2408
- const filteredValues = useMemo6(() => {
2572
+ const filteredValues = useMemo7(() => {
2409
2573
  const values = stats.uniqueValues;
2410
2574
  if (!searchQuery)
2411
2575
  return values;
2412
2576
  const query = searchQuery.toLowerCase();
2413
2577
  return values.filter((v) => v.toLowerCase().includes(query));
2414
2578
  }, [stats.uniqueValues, searchQuery]);
2415
- const allValues = useMemo6(() => {
2579
+ const allValues = useMemo7(() => {
2416
2580
  const values = [...filteredValues];
2417
2581
  if (hasBlankValues && (!searchQuery || "(blank)".includes(searchQuery.toLowerCase()))) {
2418
2582
  values.unshift("(blank)");
2419
2583
  }
2420
2584
  return values;
2421
2585
  }, [filteredValues, hasBlankValues, searchQuery]);
2422
- const _isAllSelected = useMemo6(
2586
+ const _isAllSelected = useMemo7(
2423
2587
  () => allValues.every((v) => localSelected.has(v)),
2424
2588
  [allValues, localSelected]
2425
2589
  );
2426
- const toggleValue = useCallback6((value) => {
2590
+ const toggleValue = useCallback7((value) => {
2427
2591
  setLocalSelected((prev) => {
2428
2592
  const next = new Set(prev);
2429
2593
  if (next.has(value)) {
@@ -2434,7 +2598,7 @@ function ColumnFilter({
2434
2598
  return next;
2435
2599
  });
2436
2600
  }, []);
2437
- const selectAll = useCallback6(() => {
2601
+ const selectAll = useCallback7(() => {
2438
2602
  setLocalSelected((prev) => {
2439
2603
  const next = new Set(prev);
2440
2604
  for (const value of allValues) {
@@ -2443,10 +2607,10 @@ function ColumnFilter({
2443
2607
  return next;
2444
2608
  });
2445
2609
  }, [allValues]);
2446
- const clearAll = useCallback6(() => {
2610
+ const clearAll = useCallback7(() => {
2447
2611
  setLocalSelected(/* @__PURE__ */ new Set());
2448
2612
  }, []);
2449
- const applyFilter = useCallback6(() => {
2613
+ const applyFilter = useCallback7(() => {
2450
2614
  if (localSelected.size === 0) {
2451
2615
  onFilter([]);
2452
2616
  } else {
@@ -2454,30 +2618,42 @@ function ColumnFilter({
2454
2618
  }
2455
2619
  onClose();
2456
2620
  }, [localSelected, onFilter, onClose]);
2457
- const sortAscending = useCallback6(() => {
2621
+ const sortAscending = useCallback7(() => {
2458
2622
  onSort(sortDirection === "asc" ? null : "asc");
2459
2623
  }, [sortDirection, onSort]);
2460
- const sortDescending = useCallback6(() => {
2624
+ const sortDescending = useCallback7(() => {
2461
2625
  onSort(sortDirection === "desc" ? null : "desc");
2462
2626
  }, [sortDirection, onSort]);
2463
- const clearFilter = useCallback6(() => {
2627
+ const clearFilter = useCallback7(() => {
2464
2628
  setLocalSelected(/* @__PURE__ */ new Set());
2465
2629
  onFilter([]);
2466
2630
  onClose();
2467
2631
  }, [onFilter, onClose]);
2468
- const handleRangeChange = useCallback6((range) => {
2632
+ const handleRangeChange = useCallback7((range) => {
2469
2633
  setLocalRange(range);
2470
2634
  }, []);
2471
- const applyRangeFilter = useCallback6(() => {
2635
+ const applyRangeFilter = useCallback7(() => {
2472
2636
  onRangeFilter?.(localRange);
2473
2637
  onClose();
2474
2638
  }, [localRange, onRangeFilter, onClose]);
2475
- const clearRangeFilter = useCallback6(() => {
2639
+ const clearRangeFilter = useCallback7(() => {
2476
2640
  setLocalRange(null);
2477
2641
  onRangeFilter?.(null);
2478
2642
  onClose();
2479
2643
  }, [onRangeFilter, onClose]);
2480
- useEffect6(() => {
2644
+ const handleDateRangeChange = useCallback7((range) => {
2645
+ setLocalDateRange(range);
2646
+ }, []);
2647
+ const applyDateRangeFilter = useCallback7(() => {
2648
+ onDateRangeFilter?.(localDateRange);
2649
+ onClose();
2650
+ }, [localDateRange, onDateRangeFilter, onClose]);
2651
+ const clearDateRangeFilter = useCallback7(() => {
2652
+ setLocalDateRange(null);
2653
+ onDateRangeFilter?.(null);
2654
+ onClose();
2655
+ }, [onDateRangeFilter, onClose]);
2656
+ useEffect7(() => {
2481
2657
  const handleClickOutside = (event) => {
2482
2658
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
2483
2659
  onClose();
@@ -2486,7 +2662,7 @@ function ColumnFilter({
2486
2662
  document.addEventListener("mousedown", handleClickOutside);
2487
2663
  return () => document.removeEventListener("mousedown", handleClickOutside);
2488
2664
  }, [onClose]);
2489
- useEffect6(() => {
2665
+ useEffect7(() => {
2490
2666
  const handleKeydown = (event) => {
2491
2667
  if (event.key === "Escape") {
2492
2668
  onClose();
@@ -2497,36 +2673,42 @@ function ColumnFilter({
2497
2673
  document.addEventListener("keydown", handleKeydown);
2498
2674
  return () => document.removeEventListener("keydown", handleKeydown);
2499
2675
  }, [onClose, applyFilter]);
2500
- useEffect6(() => {
2676
+ useEffect7(() => {
2501
2677
  searchInputRef.current?.focus();
2502
2678
  }, []);
2503
- useEffect6(() => {
2679
+ useEffect7(() => {
2504
2680
  setLocalSelected(new Set(selectedValues));
2505
2681
  }, [selectedValues]);
2506
- useEffect6(() => {
2682
+ useEffect7(() => {
2507
2683
  setLocalRange(numericRange ?? null);
2508
2684
  if (numericRange) {
2509
2685
  setFilterMode("range");
2510
2686
  }
2511
2687
  }, [numericRange]);
2512
- return /* @__PURE__ */ jsxs5("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
2513
- /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-header", children: [
2514
- /* @__PURE__ */ jsx5("span", { className: "vpg-filter-title", children: columnName }),
2515
- /* @__PURE__ */ jsxs5("span", { className: "vpg-filter-count", children: [
2688
+ useEffect7(() => {
2689
+ setLocalDateRange(dateRange ?? null);
2690
+ if (dateRange) {
2691
+ setFilterMode("range");
2692
+ }
2693
+ }, [dateRange]);
2694
+ return /* @__PURE__ */ jsxs6("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
2695
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-header", children: [
2696
+ /* @__PURE__ */ jsx6("span", { className: "vpg-filter-title", children: columnName }),
2697
+ /* @__PURE__ */ jsxs6("span", { className: "vpg-filter-count", children: [
2516
2698
  stats.uniqueValues.length.toLocaleString(),
2517
2699
  " ",
2518
2700
  "unique"
2519
2701
  ] })
2520
2702
  ] }),
2521
- /* @__PURE__ */ jsxs5("div", { className: "vpg-sort-controls", children: [
2522
- /* @__PURE__ */ jsxs5(
2703
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-sort-controls", children: [
2704
+ /* @__PURE__ */ jsxs6(
2523
2705
  "button",
2524
2706
  {
2525
2707
  className: `vpg-sort-btn ${sortDirection === "asc" ? "active" : ""}`,
2526
- title: isNumericColumn ? "Sort Low to High" : "Sort A to Z",
2708
+ title: isDateColumn ? "Sort Old to New" : isNumericColumn ? "Sort Low to High" : "Sort A to Z",
2527
2709
  onClick: sortAscending,
2528
2710
  children: [
2529
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2711
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2530
2712
  "path",
2531
2713
  {
2532
2714
  strokeLinecap: "round",
@@ -2535,18 +2717,18 @@ function ColumnFilter({
2535
2717
  d: "M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"
2536
2718
  }
2537
2719
  ) }),
2538
- /* @__PURE__ */ jsx5("span", { children: isNumericColumn ? "1\u21929" : "A\u2192Z" })
2720
+ /* @__PURE__ */ jsx6("span", { children: isDateColumn ? "Old\u2192New" : isNumericColumn ? "1\u21929" : "A\u2192Z" })
2539
2721
  ]
2540
2722
  }
2541
2723
  ),
2542
- /* @__PURE__ */ jsxs5(
2724
+ /* @__PURE__ */ jsxs6(
2543
2725
  "button",
2544
2726
  {
2545
2727
  className: `vpg-sort-btn ${sortDirection === "desc" ? "active" : ""}`,
2546
- title: isNumericColumn ? "Sort High to Low" : "Sort Z to A",
2728
+ title: isDateColumn ? "Sort New to Old" : isNumericColumn ? "Sort High to Low" : "Sort Z to A",
2547
2729
  onClick: sortDescending,
2548
2730
  children: [
2549
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2731
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2550
2732
  "path",
2551
2733
  {
2552
2734
  strokeLinecap: "round",
@@ -2555,20 +2737,20 @@ function ColumnFilter({
2555
2737
  d: "M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"
2556
2738
  }
2557
2739
  ) }),
2558
- /* @__PURE__ */ jsx5("span", { children: isNumericColumn ? "9\u21921" : "Z\u2192A" })
2740
+ /* @__PURE__ */ jsx6("span", { children: isDateColumn ? "New\u2192Old" : isNumericColumn ? "9\u21921" : "Z\u2192A" })
2559
2741
  ]
2560
2742
  }
2561
2743
  )
2562
2744
  ] }),
2563
- /* @__PURE__ */ jsx5("div", { className: "vpg-divider" }),
2564
- isNumericColumn && /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-tabs", children: [
2565
- /* @__PURE__ */ jsxs5(
2745
+ /* @__PURE__ */ jsx6("div", { className: "vpg-divider" }),
2746
+ (isNumericColumn || isDateColumn) && /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-tabs", children: [
2747
+ /* @__PURE__ */ jsxs6(
2566
2748
  "button",
2567
2749
  {
2568
2750
  className: `vpg-tab-btn ${filterMode === "values" ? "active" : ""}`,
2569
2751
  onClick: () => setFilterMode("values"),
2570
2752
  children: [
2571
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2753
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2572
2754
  "path",
2573
2755
  {
2574
2756
  strokeLinecap: "round",
@@ -2581,13 +2763,13 @@ function ColumnFilter({
2581
2763
  ]
2582
2764
  }
2583
2765
  ),
2584
- /* @__PURE__ */ jsxs5(
2766
+ /* @__PURE__ */ jsxs6(
2585
2767
  "button",
2586
2768
  {
2587
2769
  className: `vpg-tab-btn ${filterMode === "range" ? "active" : ""}`,
2588
2770
  onClick: () => setFilterMode("range"),
2589
2771
  children: [
2590
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2772
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2591
2773
  "path",
2592
2774
  {
2593
2775
  strokeLinecap: "round",
@@ -2601,9 +2783,9 @@ function ColumnFilter({
2601
2783
  }
2602
2784
  )
2603
2785
  ] }),
2604
- (!isNumericColumn || filterMode === "values") && /* @__PURE__ */ jsxs5(Fragment3, { children: [
2605
- /* @__PURE__ */ jsxs5("div", { className: "vpg-search-container", children: [
2606
- /* @__PURE__ */ jsx5("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2786
+ (!isNumericColumn && !isDateColumn || filterMode === "values") && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2787
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-search-container", children: [
2788
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2607
2789
  "path",
2608
2790
  {
2609
2791
  strokeLinecap: "round",
@@ -2612,7 +2794,7 @@ function ColumnFilter({
2612
2794
  d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
2613
2795
  }
2614
2796
  ) }),
2615
- /* @__PURE__ */ jsx5(
2797
+ /* @__PURE__ */ jsx6(
2616
2798
  "input",
2617
2799
  {
2618
2800
  ref: searchInputRef,
@@ -2623,11 +2805,11 @@ function ColumnFilter({
2623
2805
  className: "vpg-search-input"
2624
2806
  }
2625
2807
  ),
2626
- searchQuery && /* @__PURE__ */ jsx5("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
2808
+ searchQuery && /* @__PURE__ */ jsx6("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
2627
2809
  ] }),
2628
- /* @__PURE__ */ jsxs5("div", { className: "vpg-bulk-actions", children: [
2629
- /* @__PURE__ */ jsxs5("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
2630
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2810
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-bulk-actions", children: [
2811
+ /* @__PURE__ */ jsxs6("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
2812
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2631
2813
  "path",
2632
2814
  {
2633
2815
  strokeLinecap: "round",
@@ -2638,8 +2820,8 @@ function ColumnFilter({
2638
2820
  ) }),
2639
2821
  "Select All"
2640
2822
  ] }),
2641
- /* @__PURE__ */ jsxs5("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
2642
- /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
2823
+ /* @__PURE__ */ jsxs6("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
2824
+ /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
2643
2825
  "path",
2644
2826
  {
2645
2827
  strokeLinecap: "round",
@@ -2651,13 +2833,13 @@ function ColumnFilter({
2651
2833
  "Clear All"
2652
2834
  ] })
2653
2835
  ] }),
2654
- /* @__PURE__ */ jsxs5("div", { className: "vpg-values-list", children: [
2655
- allValues.map((value) => /* @__PURE__ */ jsxs5(
2836
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-values-list", children: [
2837
+ allValues.map((value) => /* @__PURE__ */ jsxs6(
2656
2838
  "label",
2657
2839
  {
2658
2840
  className: `vpg-value-item ${localSelected.has(value) ? "selected" : ""}`,
2659
2841
  children: [
2660
- /* @__PURE__ */ jsx5(
2842
+ /* @__PURE__ */ jsx6(
2661
2843
  "input",
2662
2844
  {
2663
2845
  type: "checkbox",
@@ -2666,49 +2848,67 @@ function ColumnFilter({
2666
2848
  className: "vpg-value-checkbox"
2667
2849
  }
2668
2850
  ),
2669
- /* @__PURE__ */ jsx5("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
2851
+ /* @__PURE__ */ jsx6("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
2670
2852
  ]
2671
2853
  },
2672
2854
  value
2673
2855
  )),
2674
- allValues.length === 0 && /* @__PURE__ */ jsx5("div", { className: "vpg-no-results", children: "No matching values" })
2856
+ allValues.length === 0 && /* @__PURE__ */ jsx6("div", { className: "vpg-no-results", children: "No matching values" })
2675
2857
  ] }),
2676
- /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-footer", children: [
2677
- /* @__PURE__ */ jsx5("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
2678
- /* @__PURE__ */ jsx5("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
2858
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-footer", children: [
2859
+ /* @__PURE__ */ jsx6("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
2860
+ /* @__PURE__ */ jsx6("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
2679
2861
  ] })
2680
2862
  ] }),
2681
- isNumericColumn && filterMode === "range" && /* @__PURE__ */ jsxs5(Fragment3, { children: [
2682
- /* @__PURE__ */ jsx5(
2863
+ isNumericColumn && filterMode === "range" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2864
+ /* @__PURE__ */ jsx6(
2683
2865
  NumericRangeFilter,
2684
2866
  {
2685
2867
  dataMin: stats.numericMin,
2686
2868
  dataMax: stats.numericMax,
2687
2869
  currentRange: localRange,
2688
- onChange: handleRangeChange
2870
+ onChange: handleRangeChange,
2871
+ numberFormat
2689
2872
  }
2690
2873
  ),
2691
- /* @__PURE__ */ jsxs5("div", { className: "vpg-filter-footer", children: [
2692
- /* @__PURE__ */ jsx5("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
2693
- /* @__PURE__ */ jsx5("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
2874
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-footer", children: [
2875
+ /* @__PURE__ */ jsx6("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
2876
+ /* @__PURE__ */ jsx6("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
2877
+ ] })
2878
+ ] }),
2879
+ isDateColumn && filterMode === "range" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2880
+ /* @__PURE__ */ jsx6(
2881
+ DateRangeFilter,
2882
+ {
2883
+ dataMin: stats.dateMin,
2884
+ dataMax: stats.dateMax,
2885
+ currentRange: localDateRange,
2886
+ onChange: handleDateRangeChange,
2887
+ dateFormat
2888
+ }
2889
+ ),
2890
+ /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-footer", children: [
2891
+ /* @__PURE__ */ jsx6("button", { className: "vpg-btn-clear", onClick: clearDateRangeFilter, children: "Clear Filter" }),
2892
+ /* @__PURE__ */ jsx6("button", { className: "vpg-btn-apply", onClick: applyDateRangeFilter, children: "Apply" })
2694
2893
  ] })
2695
2894
  ] })
2696
2895
  ] });
2697
2896
  }
2698
2897
 
2699
2898
  // src/components/DataGrid.tsx
2700
- import { useCallback as useCallback13, useEffect as useEffect10, useMemo as useMemo13, useRef as useRef4, useState as useState13 } from "react";
2899
+ import { formatDate as coreFormatDate, formatNumber as coreFormatNumber } from "@smallwebco/tinypivot-core";
2900
+ import { useCallback as useCallback14, useEffect as useEffect11, useMemo as useMemo14, useRef as useRef4, useState as useState14 } from "react";
2701
2901
  import { createPortal as createPortal2 } from "react-dom";
2702
2902
 
2703
2903
  // src/hooks/useExcelGrid.ts
2704
- import { formatCellValue, getColumnUniqueValues, isNumericRange } from "@smallwebco/tinypivot-core";
2904
+ import { formatCellValue, getColumnUniqueValues, isDateRange, isNumericRange } from "@smallwebco/tinypivot-core";
2705
2905
  import {
2706
2906
  getCoreRowModel,
2707
2907
  getFilteredRowModel,
2708
2908
  getSortedRowModel,
2709
2909
  useReactTable
2710
2910
  } from "@tanstack/react-table";
2711
- import { useCallback as useCallback7, useEffect as useEffect7, useMemo as useMemo7, useState as useState7 } from "react";
2911
+ import { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo8, useState as useState8 } from "react";
2712
2912
  var multiSelectFilter = (row, columnId, filterValue) => {
2713
2913
  if (!filterValue)
2714
2914
  return true;
@@ -2727,6 +2927,22 @@ var multiSelectFilter = (row, columnId, filterValue) => {
2727
2927
  return false;
2728
2928
  return true;
2729
2929
  }
2930
+ if (isDateRange(filterValue)) {
2931
+ const cellValue = row.getValue(columnId);
2932
+ if (cellValue === null || cellValue === void 0 || cellValue === "") {
2933
+ return false;
2934
+ }
2935
+ const dateObj = cellValue instanceof Date ? cellValue : new Date(String(cellValue));
2936
+ if (Number.isNaN(dateObj.getTime()))
2937
+ return false;
2938
+ const dateStr = dateObj.toISOString().split("T")[0];
2939
+ const { min, max } = filterValue;
2940
+ if (min !== null && dateStr < min)
2941
+ return false;
2942
+ if (max !== null && dateStr > max)
2943
+ return false;
2944
+ return true;
2945
+ }
2730
2946
  if (Array.isArray(filterValue) && filterValue.length > 0) {
2731
2947
  const cellValue = row.getValue(columnId);
2732
2948
  const cellString = cellValue === null || cellValue === void 0 || cellValue === "" ? "(blank)" : String(cellValue);
@@ -2736,21 +2952,21 @@ var multiSelectFilter = (row, columnId, filterValue) => {
2736
2952
  };
2737
2953
  function useExcelGrid(options) {
2738
2954
  const { data, enableSorting = true, enableFiltering = true } = options;
2739
- const [sorting, setSorting] = useState7([]);
2740
- const [columnFilters, setColumnFilters] = useState7([]);
2741
- const [columnVisibility, setColumnVisibility] = useState7({});
2742
- const [globalFilter, setGlobalFilter] = useState7("");
2743
- const [columnStatsCache, setColumnStatsCache] = useState7({});
2744
- const dataSignature = useMemo7(
2955
+ const [sorting, setSorting] = useState8([]);
2956
+ const [columnFilters, setColumnFilters] = useState8([]);
2957
+ const [columnVisibility, setColumnVisibility] = useState8({});
2958
+ const [globalFilter, setGlobalFilter] = useState8("");
2959
+ const [columnStatsCache, setColumnStatsCache] = useState8({});
2960
+ const dataSignature = useMemo8(
2745
2961
  () => `${Date.now()}-${Math.random().toString(36).slice(2)}`,
2746
2962
  [data]
2747
2963
  );
2748
- const columnKeys = useMemo7(() => {
2964
+ const columnKeys = useMemo8(() => {
2749
2965
  if (data.length === 0)
2750
2966
  return [];
2751
2967
  return Object.keys(data[0]);
2752
2968
  }, [data]);
2753
- const getColumnStats = useCallback7(
2969
+ const getColumnStats = useCallback8(
2754
2970
  (columnKey) => {
2755
2971
  const cacheKey = `${columnKey}-${dataSignature}`;
2756
2972
  if (!columnStatsCache[cacheKey]) {
@@ -2762,13 +2978,13 @@ function useExcelGrid(options) {
2762
2978
  },
2763
2979
  [data, columnStatsCache, dataSignature]
2764
2980
  );
2765
- const clearStatsCache = useCallback7(() => {
2981
+ const clearStatsCache = useCallback8(() => {
2766
2982
  setColumnStatsCache({});
2767
2983
  }, []);
2768
- useEffect7(() => {
2984
+ useEffect8(() => {
2769
2985
  clearStatsCache();
2770
2986
  }, [dataSignature, clearStatsCache]);
2771
- const columnDefs = useMemo7(() => {
2987
+ const columnDefs = useMemo8(() => {
2772
2988
  return columnKeys.map((key) => {
2773
2989
  const stats = getColumnStats(key);
2774
2990
  return {
@@ -2808,7 +3024,7 @@ function useExcelGrid(options) {
2808
3024
  });
2809
3025
  const filteredRowCount = table.getFilteredRowModel().rows.length;
2810
3026
  const totalRowCount = data.length;
2811
- const activeFilters = useMemo7(() => {
3027
+ const activeFilters = useMemo8(() => {
2812
3028
  return columnFilters.map((f) => {
2813
3029
  const filterValue = f.value;
2814
3030
  if (filterValue && isNumericRange(filterValue)) {
@@ -2816,6 +3032,16 @@ function useExcelGrid(options) {
2816
3032
  column: f.id,
2817
3033
  type: "range",
2818
3034
  range: filterValue,
3035
+ dateRange: null,
3036
+ values: []
3037
+ };
3038
+ }
3039
+ if (filterValue && isDateRange(filterValue)) {
3040
+ return {
3041
+ column: f.id,
3042
+ type: "dateRange",
3043
+ range: null,
3044
+ dateRange: filterValue,
2819
3045
  values: []
2820
3046
  };
2821
3047
  }
@@ -2823,11 +3049,12 @@ function useExcelGrid(options) {
2823
3049
  column: f.id,
2824
3050
  type: "values",
2825
3051
  values: Array.isArray(filterValue) ? filterValue : [],
2826
- range: null
3052
+ range: null,
3053
+ dateRange: null
2827
3054
  };
2828
3055
  });
2829
3056
  }, [columnFilters]);
2830
- const hasActiveFilter = useCallback7(
3057
+ const hasActiveFilter = useCallback8(
2831
3058
  (columnId) => {
2832
3059
  const column = table.getColumn(columnId);
2833
3060
  if (!column)
@@ -2838,11 +3065,14 @@ function useExcelGrid(options) {
2838
3065
  if (isNumericRange(filterValue)) {
2839
3066
  return filterValue.min !== null || filterValue.max !== null;
2840
3067
  }
3068
+ if (isDateRange(filterValue)) {
3069
+ return filterValue.min !== null || filterValue.max !== null;
3070
+ }
2841
3071
  return Array.isArray(filterValue) && filterValue.length > 0;
2842
3072
  },
2843
3073
  [table]
2844
3074
  );
2845
- const setColumnFilter = useCallback7(
3075
+ const setColumnFilter = useCallback8(
2846
3076
  (columnId, values) => {
2847
3077
  const column = table.getColumn(columnId);
2848
3078
  if (column) {
@@ -2851,7 +3081,7 @@ function useExcelGrid(options) {
2851
3081
  },
2852
3082
  [table]
2853
3083
  );
2854
- const setNumericRangeFilter = useCallback7(
3084
+ const setNumericRangeFilter = useCallback8(
2855
3085
  (columnId, range) => {
2856
3086
  const column = table.getColumn(columnId);
2857
3087
  if (column) {
@@ -2864,7 +3094,7 @@ function useExcelGrid(options) {
2864
3094
  },
2865
3095
  [table]
2866
3096
  );
2867
- const getNumericRangeFilter = useCallback7(
3097
+ const getNumericRangeFilter = useCallback8(
2868
3098
  (columnId) => {
2869
3099
  const column = table.getColumn(columnId);
2870
3100
  if (!column)
@@ -2877,12 +3107,38 @@ function useExcelGrid(options) {
2877
3107
  },
2878
3108
  [table]
2879
3109
  );
2880
- const clearAllFilters = useCallback7(() => {
3110
+ const setDateRangeFilter = useCallback8(
3111
+ (columnId, range) => {
3112
+ const column = table.getColumn(columnId);
3113
+ if (column) {
3114
+ if (!range || range.min === null && range.max === null) {
3115
+ column.setFilterValue(void 0);
3116
+ } else {
3117
+ column.setFilterValue(range);
3118
+ }
3119
+ }
3120
+ },
3121
+ [table]
3122
+ );
3123
+ const getDateRangeFilter = useCallback8(
3124
+ (columnId) => {
3125
+ const column = table.getColumn(columnId);
3126
+ if (!column)
3127
+ return null;
3128
+ const filterValue = column.getFilterValue();
3129
+ if (filterValue && isDateRange(filterValue)) {
3130
+ return filterValue;
3131
+ }
3132
+ return null;
3133
+ },
3134
+ [table]
3135
+ );
3136
+ const clearAllFilters = useCallback8(() => {
2881
3137
  table.resetColumnFilters();
2882
3138
  setGlobalFilter("");
2883
3139
  setColumnFilters([]);
2884
3140
  }, [table]);
2885
- const getColumnFilterValues = useCallback7(
3141
+ const getColumnFilterValues = useCallback8(
2886
3142
  (columnId) => {
2887
3143
  const column = table.getColumn(columnId);
2888
3144
  if (!column)
@@ -2892,7 +3148,7 @@ function useExcelGrid(options) {
2892
3148
  },
2893
3149
  [table]
2894
3150
  );
2895
- const toggleSort = useCallback7((columnId) => {
3151
+ const toggleSort = useCallback8((columnId) => {
2896
3152
  setSorting((prev) => {
2897
3153
  const current = prev.find((s) => s.id === columnId);
2898
3154
  if (!current) {
@@ -2904,7 +3160,7 @@ function useExcelGrid(options) {
2904
3160
  }
2905
3161
  });
2906
3162
  }, []);
2907
- const getSortDirection = useCallback7(
3163
+ const getSortDirection = useCallback8(
2908
3164
  (columnId) => {
2909
3165
  const sort = sorting.find((s) => s.id === columnId);
2910
3166
  if (!sort)
@@ -2940,7 +3196,10 @@ function useExcelGrid(options) {
2940
3196
  getSortDirection,
2941
3197
  // Numeric range filters
2942
3198
  setNumericRangeFilter,
2943
- getNumericRangeFilter
3199
+ getNumericRangeFilter,
3200
+ // Date range filters
3201
+ setDateRangeFilter,
3202
+ getDateRangeFilter
2944
3203
  };
2945
3204
  }
2946
3205
 
@@ -2951,7 +3210,7 @@ import {
2951
3210
  exportToCSV as coreExportToCSV,
2952
3211
  formatSelectionForClipboard as coreFormatSelection
2953
3212
  } from "@smallwebco/tinypivot-core";
2954
- import { useCallback as useCallback8, useMemo as useMemo8, useState as useState8 } from "react";
3213
+ import { useCallback as useCallback9, useMemo as useMemo9, useState as useState9 } from "react";
2955
3214
  function exportToCSV(data, columns, options) {
2956
3215
  coreExportToCSV(data, columns, options);
2957
3216
  }
@@ -2965,45 +3224,45 @@ function formatSelectionForClipboard(rows, columns, selectionBounds) {
2965
3224
  return coreFormatSelection(rows, columns, selectionBounds);
2966
3225
  }
2967
3226
  function usePagination(data, options = {}) {
2968
- const [pageSize, setPageSize] = useState8(options.pageSize ?? 50);
2969
- const [currentPage, setCurrentPage] = useState8(options.currentPage ?? 1);
2970
- const totalPages = useMemo8(
3227
+ const [pageSize, setPageSize] = useState9(options.pageSize ?? 50);
3228
+ const [currentPage, setCurrentPage] = useState9(options.currentPage ?? 1);
3229
+ const totalPages = useMemo9(
2971
3230
  () => Math.max(1, Math.ceil(data.length / pageSize)),
2972
3231
  [data.length, pageSize]
2973
3232
  );
2974
- const paginatedData = useMemo8(() => {
3233
+ const paginatedData = useMemo9(() => {
2975
3234
  const start = (currentPage - 1) * pageSize;
2976
3235
  const end = start + pageSize;
2977
3236
  return data.slice(start, end);
2978
3237
  }, [data, currentPage, pageSize]);
2979
- const startIndex = useMemo8(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
2980
- const endIndex = useMemo8(
3238
+ const startIndex = useMemo9(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
3239
+ const endIndex = useMemo9(
2981
3240
  () => Math.min(currentPage * pageSize, data.length),
2982
3241
  [currentPage, pageSize, data.length]
2983
3242
  );
2984
- const goToPage = useCallback8(
3243
+ const goToPage = useCallback9(
2985
3244
  (page) => {
2986
3245
  setCurrentPage(Math.max(1, Math.min(page, totalPages)));
2987
3246
  },
2988
3247
  [totalPages]
2989
3248
  );
2990
- const nextPage = useCallback8(() => {
3249
+ const nextPage = useCallback9(() => {
2991
3250
  if (currentPage < totalPages) {
2992
3251
  setCurrentPage((prev) => prev + 1);
2993
3252
  }
2994
3253
  }, [currentPage, totalPages]);
2995
- const prevPage = useCallback8(() => {
3254
+ const prevPage = useCallback9(() => {
2996
3255
  if (currentPage > 1) {
2997
3256
  setCurrentPage((prev) => prev - 1);
2998
3257
  }
2999
3258
  }, [currentPage]);
3000
- const firstPage = useCallback8(() => {
3259
+ const firstPage = useCallback9(() => {
3001
3260
  setCurrentPage(1);
3002
3261
  }, []);
3003
- const lastPage = useCallback8(() => {
3262
+ const lastPage = useCallback9(() => {
3004
3263
  setCurrentPage(totalPages);
3005
3264
  }, [totalPages]);
3006
- const updatePageSize = useCallback8((size) => {
3265
+ const updatePageSize = useCallback9((size) => {
3007
3266
  setPageSize(size);
3008
3267
  setCurrentPage(1);
3009
3268
  }, []);
@@ -3023,9 +3282,9 @@ function usePagination(data, options = {}) {
3023
3282
  };
3024
3283
  }
3025
3284
  function useGlobalSearch(data, columns) {
3026
- const [searchTerm, setSearchTerm] = useState8("");
3027
- const [caseSensitive, setCaseSensitive] = useState8(false);
3028
- const filteredData = useMemo8(() => {
3285
+ const [searchTerm, setSearchTerm] = useState9("");
3286
+ const [caseSensitive, setCaseSensitive] = useState9(false);
3287
+ const filteredData = useMemo9(() => {
3029
3288
  if (!searchTerm.trim()) {
3030
3289
  return data;
3031
3290
  }
@@ -3043,7 +3302,7 @@ function useGlobalSearch(data, columns) {
3043
3302
  return false;
3044
3303
  });
3045
3304
  }, [data, columns, searchTerm, caseSensitive]);
3046
- const clearSearch = useCallback8(() => {
3305
+ const clearSearch = useCallback9(() => {
3047
3306
  setSearchTerm("");
3048
3307
  }, []);
3049
3308
  return {
@@ -3056,17 +3315,17 @@ function useGlobalSearch(data, columns) {
3056
3315
  };
3057
3316
  }
3058
3317
  function useRowSelection(data) {
3059
- const [selectedRowIndices, setSelectedRowIndices] = useState8(/* @__PURE__ */ new Set());
3060
- const selectedRows = useMemo8(() => {
3318
+ const [selectedRowIndices, setSelectedRowIndices] = useState9(/* @__PURE__ */ new Set());
3319
+ const selectedRows = useMemo9(() => {
3061
3320
  return Array.from(selectedRowIndices).sort((a, b) => a - b).map((idx) => data[idx]).filter(Boolean);
3062
3321
  }, [data, selectedRowIndices]);
3063
- const allSelected = useMemo8(() => {
3322
+ const allSelected = useMemo9(() => {
3064
3323
  return data.length > 0 && selectedRowIndices.size === data.length;
3065
3324
  }, [data.length, selectedRowIndices.size]);
3066
- const someSelected = useMemo8(() => {
3325
+ const someSelected = useMemo9(() => {
3067
3326
  return selectedRowIndices.size > 0 && selectedRowIndices.size < data.length;
3068
3327
  }, [data.length, selectedRowIndices.size]);
3069
- const toggleRow = useCallback8((index) => {
3328
+ const toggleRow = useCallback9((index) => {
3070
3329
  setSelectedRowIndices((prev) => {
3071
3330
  const next = new Set(prev);
3072
3331
  if (next.has(index)) {
@@ -3077,36 +3336,36 @@ function useRowSelection(data) {
3077
3336
  return next;
3078
3337
  });
3079
3338
  }, []);
3080
- const selectRow = useCallback8((index) => {
3339
+ const selectRow = useCallback9((index) => {
3081
3340
  setSelectedRowIndices((prev) => /* @__PURE__ */ new Set([...prev, index]));
3082
3341
  }, []);
3083
- const deselectRow = useCallback8((index) => {
3342
+ const deselectRow = useCallback9((index) => {
3084
3343
  setSelectedRowIndices((prev) => {
3085
3344
  const next = new Set(prev);
3086
3345
  next.delete(index);
3087
3346
  return next;
3088
3347
  });
3089
3348
  }, []);
3090
- const selectAll = useCallback8(() => {
3349
+ const selectAll = useCallback9(() => {
3091
3350
  setSelectedRowIndices(new Set(data.map((_, idx) => idx)));
3092
3351
  }, [data]);
3093
- const deselectAll = useCallback8(() => {
3352
+ const deselectAll = useCallback9(() => {
3094
3353
  setSelectedRowIndices(/* @__PURE__ */ new Set());
3095
3354
  }, []);
3096
- const toggleAll = useCallback8(() => {
3355
+ const toggleAll = useCallback9(() => {
3097
3356
  if (allSelected) {
3098
3357
  deselectAll();
3099
3358
  } else {
3100
3359
  selectAll();
3101
3360
  }
3102
3361
  }, [allSelected, selectAll, deselectAll]);
3103
- const isSelected = useCallback8(
3362
+ const isSelected = useCallback9(
3104
3363
  (index) => {
3105
3364
  return selectedRowIndices.has(index);
3106
3365
  },
3107
3366
  [selectedRowIndices]
3108
3367
  );
3109
- const selectRange = useCallback8((startIndex, endIndex) => {
3368
+ const selectRange = useCallback9((startIndex, endIndex) => {
3110
3369
  const min = Math.min(startIndex, endIndex);
3111
3370
  const max = Math.max(startIndex, endIndex);
3112
3371
  setSelectedRowIndices((prev) => {
@@ -3133,10 +3392,10 @@ function useRowSelection(data) {
3133
3392
  };
3134
3393
  }
3135
3394
  function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
3136
- const [columnWidths, setColumnWidths] = useState8({ ...initialWidths });
3137
- const [isResizing, setIsResizing] = useState8(false);
3138
- const [resizingColumn, setResizingColumn] = useState8(null);
3139
- const startResize = useCallback8(
3395
+ const [columnWidths, setColumnWidths] = useState9({ ...initialWidths });
3396
+ const [isResizing, setIsResizing] = useState9(false);
3397
+ const [resizingColumn, setResizingColumn] = useState9(null);
3398
+ const startResize = useCallback9(
3140
3399
  (columnId, event) => {
3141
3400
  setIsResizing(true);
3142
3401
  setResizingColumn(columnId);
@@ -3161,7 +3420,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
3161
3420
  },
3162
3421
  [columnWidths, minWidth, maxWidth]
3163
3422
  );
3164
- const resetColumnWidth = useCallback8(
3423
+ const resetColumnWidth = useCallback9(
3165
3424
  (columnId) => {
3166
3425
  if (initialWidths[columnId]) {
3167
3426
  setColumnWidths((prev) => ({
@@ -3172,7 +3431,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
3172
3431
  },
3173
3432
  [initialWidths]
3174
3433
  );
3175
- const resetAllWidths = useCallback8(() => {
3434
+ const resetAllWidths = useCallback9(() => {
3176
3435
  setColumnWidths({ ...initialWidths });
3177
3436
  }, [initialWidths]);
3178
3437
  return {
@@ -3199,7 +3458,7 @@ import {
3199
3458
  logProRequired,
3200
3459
  validateLicenseKey
3201
3460
  } from "@smallwebco/tinypivot-core";
3202
- import { useCallback as useCallback9, useMemo as useMemo9, useState as useState9 } from "react";
3461
+ import { useCallback as useCallback10, useMemo as useMemo10, useState as useState10 } from "react";
3203
3462
  var globalLicenseInfo = getFreeLicenseInfo();
3204
3463
  var globalDemoMode = false;
3205
3464
  var listeners = /* @__PURE__ */ new Set();
@@ -3231,43 +3490,43 @@ function configureLicenseSecret(secret) {
3231
3490
  coreConfigureLicenseSecret(secret);
3232
3491
  }
3233
3492
  function useLicense() {
3234
- const [, forceUpdate] = useState9({});
3235
- useState9(() => {
3493
+ const [, forceUpdate] = useState10({});
3494
+ useState10(() => {
3236
3495
  const update = () => forceUpdate({});
3237
3496
  listeners.add(update);
3238
3497
  return () => listeners.delete(update);
3239
3498
  });
3240
3499
  const isDemo = globalDemoMode;
3241
3500
  const licenseInfo = globalLicenseInfo;
3242
- const isPro = useMemo9(
3501
+ const isPro = useMemo10(
3243
3502
  () => globalDemoMode || coreIsPro(licenseInfo),
3244
3503
  [licenseInfo]
3245
3504
  );
3246
- const canUsePivot = useMemo9(
3505
+ const canUsePivot = useMemo10(
3247
3506
  () => globalDemoMode || coreCanUsePivot(licenseInfo),
3248
3507
  [licenseInfo]
3249
3508
  );
3250
- const canUseAdvancedAggregations = useMemo9(
3509
+ const canUseAdvancedAggregations = useMemo10(
3251
3510
  () => globalDemoMode || licenseInfo.features.advancedAggregations,
3252
3511
  [licenseInfo]
3253
3512
  );
3254
- const canUsePercentageMode = useMemo9(
3513
+ const canUsePercentageMode = useMemo10(
3255
3514
  () => globalDemoMode || licenseInfo.features.percentageMode,
3256
3515
  [licenseInfo]
3257
3516
  );
3258
- const canUseCharts = useMemo9(
3517
+ const canUseCharts = useMemo10(
3259
3518
  () => globalDemoMode || coreCanUseCharts(licenseInfo),
3260
3519
  [licenseInfo]
3261
3520
  );
3262
- const canUseAIAnalyst = useMemo9(
3521
+ const canUseAIAnalyst = useMemo10(
3263
3522
  () => globalDemoMode || coreCanUseAIAnalyst(licenseInfo),
3264
3523
  [licenseInfo]
3265
3524
  );
3266
- const showWatermark = useMemo9(
3525
+ const showWatermark = useMemo10(
3267
3526
  () => coreShouldShowWatermark(licenseInfo, globalDemoMode),
3268
3527
  [licenseInfo]
3269
3528
  );
3270
- const requirePro = useCallback9((feature) => {
3529
+ const requirePro = useCallback10((feature) => {
3271
3530
  if (!isPro) {
3272
3531
  logProRequired(feature);
3273
3532
  return false;
@@ -3302,23 +3561,23 @@ import {
3302
3561
  saveCalculatedFields,
3303
3562
  savePivotConfig
3304
3563
  } from "@smallwebco/tinypivot-core";
3305
- import { useCallback as useCallback10, useEffect as useEffect8, useMemo as useMemo10, useState as useState10 } from "react";
3564
+ import { useCallback as useCallback11, useEffect as useEffect9, useMemo as useMemo11, useState as useState11 } from "react";
3306
3565
  function usePivotTable(data) {
3307
3566
  const { canUsePivot, requirePro } = useLicense();
3308
- const [rowFields, setRowFieldsState] = useState10([]);
3309
- const [columnFields, setColumnFieldsState] = useState10([]);
3310
- const [valueFields, setValueFields] = useState10([]);
3311
- const [showRowTotals, setShowRowTotals] = useState10(true);
3312
- const [showColumnTotals, setShowColumnTotals] = useState10(true);
3313
- const [calculatedFields, setCalculatedFields] = useState10(() => loadCalculatedFields());
3314
- const [currentStorageKey, setCurrentStorageKey] = useState10(null);
3315
- const availableFields = useMemo10(() => {
3567
+ const [rowFields, setRowFieldsState] = useState11([]);
3568
+ const [columnFields, setColumnFieldsState] = useState11([]);
3569
+ const [valueFields, setValueFields] = useState11([]);
3570
+ const [showRowTotals, setShowRowTotals] = useState11(true);
3571
+ const [showColumnTotals, setShowColumnTotals] = useState11(true);
3572
+ const [calculatedFields, setCalculatedFields] = useState11(() => loadCalculatedFields());
3573
+ const [currentStorageKey, setCurrentStorageKey] = useState11(null);
3574
+ const availableFields = useMemo11(() => {
3316
3575
  return computeAvailableFields(data);
3317
3576
  }, [data]);
3318
- const unassignedFields = useMemo10(() => {
3577
+ const unassignedFields = useMemo11(() => {
3319
3578
  return getUnassignedFields(availableFields, rowFields, columnFields, valueFields);
3320
3579
  }, [availableFields, rowFields, columnFields, valueFields]);
3321
- const isConfigured = useMemo10(() => {
3580
+ const isConfigured = useMemo11(() => {
3322
3581
  return isPivotConfigured({
3323
3582
  rowFields,
3324
3583
  columnFields,
@@ -3327,7 +3586,7 @@ function usePivotTable(data) {
3327
3586
  showColumnTotals
3328
3587
  });
3329
3588
  }, [rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
3330
- const pivotResult = useMemo10(() => {
3589
+ const pivotResult = useMemo11(() => {
3331
3590
  if (!isConfigured)
3332
3591
  return null;
3333
3592
  if (!canUsePivot)
@@ -3341,7 +3600,7 @@ function usePivotTable(data) {
3341
3600
  calculatedFields
3342
3601
  });
3343
3602
  }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
3344
- useEffect8(() => {
3603
+ useEffect9(() => {
3345
3604
  if (data.length === 0)
3346
3605
  return;
3347
3606
  const newKeys = Object.keys(data[0]);
@@ -3374,7 +3633,7 @@ function usePivotTable(data) {
3374
3633
  }
3375
3634
  }
3376
3635
  }, [data]);
3377
- useEffect8(() => {
3636
+ useEffect9(() => {
3378
3637
  if (!currentStorageKey)
3379
3638
  return;
3380
3639
  const config = {
@@ -3387,7 +3646,7 @@ function usePivotTable(data) {
3387
3646
  };
3388
3647
  savePivotConfig(currentStorageKey, config);
3389
3648
  }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
3390
- const addRowField = useCallback10(
3649
+ const addRowField = useCallback11(
3391
3650
  (field) => {
3392
3651
  if (!rowFields.includes(field)) {
3393
3652
  setRowFieldsState((prev) => [...prev, field]);
@@ -3395,13 +3654,13 @@ function usePivotTable(data) {
3395
3654
  },
3396
3655
  [rowFields]
3397
3656
  );
3398
- const removeRowField = useCallback10((field) => {
3657
+ const removeRowField = useCallback11((field) => {
3399
3658
  setRowFieldsState((prev) => prev.filter((f) => f !== field));
3400
3659
  }, []);
3401
- const setRowFields = useCallback10((fields) => {
3660
+ const setRowFields = useCallback11((fields) => {
3402
3661
  setRowFieldsState(fields);
3403
3662
  }, []);
3404
- const addColumnField = useCallback10(
3663
+ const addColumnField = useCallback11(
3405
3664
  (field) => {
3406
3665
  if (!columnFields.includes(field)) {
3407
3666
  setColumnFieldsState((prev) => [...prev, field]);
@@ -3409,13 +3668,13 @@ function usePivotTable(data) {
3409
3668
  },
3410
3669
  [columnFields]
3411
3670
  );
3412
- const removeColumnField = useCallback10((field) => {
3671
+ const removeColumnField = useCallback11((field) => {
3413
3672
  setColumnFieldsState((prev) => prev.filter((f) => f !== field));
3414
3673
  }, []);
3415
- const setColumnFields = useCallback10((fields) => {
3674
+ const setColumnFields = useCallback11((fields) => {
3416
3675
  setColumnFieldsState(fields);
3417
3676
  }, []);
3418
- const addValueField = useCallback10(
3677
+ const addValueField = useCallback11(
3419
3678
  (field, aggregation = "sum") => {
3420
3679
  if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
3421
3680
  return;
@@ -3429,7 +3688,7 @@ function usePivotTable(data) {
3429
3688
  },
3430
3689
  [requirePro]
3431
3690
  );
3432
- const removeValueField = useCallback10((field, aggregation) => {
3691
+ const removeValueField = useCallback11((field, aggregation) => {
3433
3692
  setValueFields((prev) => {
3434
3693
  if (aggregation) {
3435
3694
  return prev.filter((v) => !(v.field === field && v.aggregation === aggregation));
@@ -3437,7 +3696,7 @@ function usePivotTable(data) {
3437
3696
  return prev.filter((v) => v.field !== field);
3438
3697
  });
3439
3698
  }, []);
3440
- const updateValueFieldAggregation = useCallback10(
3699
+ const updateValueFieldAggregation = useCallback11(
3441
3700
  (field, oldAgg, newAgg) => {
3442
3701
  setValueFields(
3443
3702
  (prev) => prev.map((v) => {
@@ -3450,12 +3709,12 @@ function usePivotTable(data) {
3450
3709
  },
3451
3710
  []
3452
3711
  );
3453
- const clearConfig = useCallback10(() => {
3712
+ const clearConfig = useCallback11(() => {
3454
3713
  setRowFieldsState([]);
3455
3714
  setColumnFieldsState([]);
3456
3715
  setValueFields([]);
3457
3716
  }, []);
3458
- const autoSuggestConfig = useCallback10(() => {
3717
+ const autoSuggestConfig = useCallback11(() => {
3459
3718
  if (!requirePro("Pivot Table - Auto Suggest"))
3460
3719
  return;
3461
3720
  if (availableFields.length === 0)
@@ -3467,7 +3726,7 @@ function usePivotTable(data) {
3467
3726
  setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
3468
3727
  }
3469
3728
  }, [availableFields, requirePro]);
3470
- const addCalculatedField = useCallback10((field) => {
3729
+ const addCalculatedField = useCallback11((field) => {
3471
3730
  setCalculatedFields((prev) => {
3472
3731
  const existing = prev.findIndex((f) => f.id === field.id);
3473
3732
  let updated;
@@ -3480,7 +3739,7 @@ function usePivotTable(data) {
3480
3739
  return updated;
3481
3740
  });
3482
3741
  }, []);
3483
- const removeCalculatedField = useCallback10((id) => {
3742
+ const removeCalculatedField = useCallback11((id) => {
3484
3743
  setCalculatedFields((prev) => {
3485
3744
  const updated = prev.filter((f) => f.id !== id);
3486
3745
  saveCalculatedFields(updated);
@@ -3522,8 +3781,8 @@ function usePivotTable(data) {
3522
3781
 
3523
3782
  // src/components/PivotConfig.tsx
3524
3783
  import { AGGREGATION_OPTIONS, getAggregationSymbol } from "@smallwebco/tinypivot-core";
3525
- import { useCallback as useCallback11, useMemo as useMemo11, useState as useState11 } from "react";
3526
- import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
3784
+ import { useCallback as useCallback12, useMemo as useMemo12, useState as useState12 } from "react";
3785
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
3527
3786
  function aggregationRequiresPro(agg) {
3528
3787
  return agg !== "sum";
3529
3788
  }
@@ -3564,15 +3823,15 @@ function PivotConfig({
3564
3823
  onRemoveCalculatedField,
3565
3824
  onUpdateCalculatedField
3566
3825
  }) {
3567
- const [fieldSearch, setFieldSearch] = useState11("");
3568
- const [showCalcModal, setShowCalcModal] = useState11(false);
3569
- const [editingCalcField, setEditingCalcField] = useState11(null);
3826
+ const [fieldSearch, setFieldSearch] = useState12("");
3827
+ const [showCalcModal, setShowCalcModal] = useState12(false);
3828
+ const [editingCalcField, setEditingCalcField] = useState12(null);
3570
3829
  const { canUseAdvancedAggregations } = useLicense();
3571
- const isAggregationAvailable = useCallback11((agg) => {
3830
+ const isAggregationAvailable = useCallback12((agg) => {
3572
3831
  return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
3573
3832
  }, [canUseAdvancedAggregations]);
3574
- const numericFieldNames = useMemo11(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
3575
- const calculatedFieldsAsStats = useMemo11(() => {
3833
+ const numericFieldNames = useMemo12(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
3834
+ const calculatedFieldsAsStats = useMemo12(() => {
3576
3835
  if (!calculatedFields)
3577
3836
  return [];
3578
3837
  return calculatedFields.map((calc) => ({
@@ -3586,11 +3845,11 @@ function PivotConfig({
3586
3845
  calcFormula: calc.formula
3587
3846
  }));
3588
3847
  }, [calculatedFields]);
3589
- const allAvailableFields = useMemo11(() => [
3848
+ const allAvailableFields = useMemo12(() => [
3590
3849
  ...availableFields.map((f) => ({ ...f, isCalculated: false })),
3591
3850
  ...calculatedFieldsAsStats
3592
3851
  ], [availableFields, calculatedFieldsAsStats]);
3593
- const assignedFields = useMemo11(() => {
3852
+ const assignedFields = useMemo12(() => {
3594
3853
  const rowSet = new Set(rowFields);
3595
3854
  const colSet = new Set(columnFields);
3596
3855
  const valueMap = new Map(valueFields.map((v) => [v.field, v]));
@@ -3600,7 +3859,7 @@ function PivotConfig({
3600
3859
  valueConfig: valueMap.get(f.field)
3601
3860
  }));
3602
3861
  }, [allAvailableFields, rowFields, columnFields, valueFields]);
3603
- const unassignedFields = useMemo11(() => {
3862
+ const unassignedFields = useMemo12(() => {
3604
3863
  const rowSet = new Set(rowFields);
3605
3864
  const colSet = new Set(columnFields);
3606
3865
  const valSet = new Set(valueFields.map((v) => v.field));
@@ -3608,7 +3867,7 @@ function PivotConfig({
3608
3867
  (f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
3609
3868
  );
3610
3869
  }, [allAvailableFields, rowFields, columnFields, valueFields]);
3611
- const filteredUnassignedFields = useMemo11(() => {
3870
+ const filteredUnassignedFields = useMemo12(() => {
3612
3871
  if (!fieldSearch.trim())
3613
3872
  return unassignedFields;
3614
3873
  const search = fieldSearch.toLowerCase().trim();
@@ -3619,13 +3878,13 @@ function PivotConfig({
3619
3878
  });
3620
3879
  }, [unassignedFields, fieldSearch]);
3621
3880
  const assignedCount = assignedFields.length;
3622
- const getFieldDisplayName = useCallback11((field) => {
3881
+ const getFieldDisplayName = useCallback12((field) => {
3623
3882
  if (field.isCalculated && field.calcName) {
3624
3883
  return field.calcName;
3625
3884
  }
3626
3885
  return field.field;
3627
3886
  }, []);
3628
- const handleDragStart = useCallback11(
3887
+ const handleDragStart = useCallback12(
3629
3888
  (field, event) => {
3630
3889
  event.dataTransfer?.setData("text/plain", field);
3631
3890
  event.dataTransfer.effectAllowed = "move";
@@ -3633,7 +3892,7 @@ function PivotConfig({
3633
3892
  },
3634
3893
  [onDragStart]
3635
3894
  );
3636
- const handleAggregationChange = useCallback11(
3895
+ const handleAggregationChange = useCallback12(
3637
3896
  (field, currentAgg, newAgg) => {
3638
3897
  if (!isAggregationAvailable(newAgg)) {
3639
3898
  console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
@@ -3643,7 +3902,7 @@ function PivotConfig({
3643
3902
  },
3644
3903
  [onUpdateAggregation, isAggregationAvailable]
3645
3904
  );
3646
- const toggleRowColumn = useCallback11(
3905
+ const toggleRowColumn = useCallback12(
3647
3906
  (field, currentAssignment) => {
3648
3907
  if (currentAssignment === "row") {
3649
3908
  onRemoveRowField(field);
@@ -3655,7 +3914,7 @@ function PivotConfig({
3655
3914
  },
3656
3915
  [onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
3657
3916
  );
3658
- const removeField = useCallback11(
3917
+ const removeField = useCallback12(
3659
3918
  (field, assignedTo, valueConfig) => {
3660
3919
  if (assignedTo === "row") {
3661
3920
  onRemoveRowField(field);
@@ -3667,15 +3926,15 @@ function PivotConfig({
3667
3926
  },
3668
3927
  [onRemoveRowField, onRemoveColumnField, onRemoveValueField]
3669
3928
  );
3670
- const handleTotalsToggle = useCallback11((checked) => {
3929
+ const handleTotalsToggle = useCallback12((checked) => {
3671
3930
  onShowRowTotalsChange(checked);
3672
3931
  onShowColumnTotalsChange(checked);
3673
3932
  }, [onShowRowTotalsChange, onShowColumnTotalsChange]);
3674
- const openCalcModal = useCallback11((field) => {
3933
+ const openCalcModal = useCallback12((field) => {
3675
3934
  setEditingCalcField(field || null);
3676
3935
  setShowCalcModal(true);
3677
3936
  }, []);
3678
- const handleSaveCalcField = useCallback11((field) => {
3937
+ const handleSaveCalcField = useCallback12((field) => {
3679
3938
  if (editingCalcField && onUpdateCalculatedField) {
3680
3939
  onUpdateCalculatedField(field);
3681
3940
  } else if (onAddCalculatedField) {
@@ -3684,14 +3943,14 @@ function PivotConfig({
3684
3943
  setShowCalcModal(false);
3685
3944
  setEditingCalcField(null);
3686
3945
  }, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
3687
- const handleCloseCalcModal = useCallback11(() => {
3946
+ const handleCloseCalcModal = useCallback12(() => {
3688
3947
  setShowCalcModal(false);
3689
3948
  setEditingCalcField(null);
3690
3949
  }, []);
3691
- return /* @__PURE__ */ jsxs6("div", { className: "vpg-pivot-config", children: [
3692
- /* @__PURE__ */ jsxs6("div", { className: "vpg-config-header", children: [
3693
- /* @__PURE__ */ jsxs6("h3", { className: "vpg-config-title", children: [
3694
- /* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
3950
+ return /* @__PURE__ */ jsxs7("div", { className: "vpg-pivot-config", children: [
3951
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-config-header", children: [
3952
+ /* @__PURE__ */ jsxs7("h3", { className: "vpg-config-title", children: [
3953
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3695
3954
  "path",
3696
3955
  {
3697
3956
  strokeLinecap: "round",
@@ -3702,13 +3961,13 @@ function PivotConfig({
3702
3961
  ) }),
3703
3962
  "Fields"
3704
3963
  ] }),
3705
- /* @__PURE__ */ jsx6("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx6(
3964
+ /* @__PURE__ */ jsx7("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx7(
3706
3965
  "button",
3707
3966
  {
3708
3967
  className: "vpg-action-btn vpg-clear-btn",
3709
3968
  title: "Clear all",
3710
3969
  onClick: onClearConfig,
3711
- children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
3970
+ children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3712
3971
  "path",
3713
3972
  {
3714
3973
  strokeLinecap: "round",
@@ -3720,9 +3979,9 @@ function PivotConfig({
3720
3979
  }
3721
3980
  ) })
3722
3981
  ] }),
3723
- assignedCount > 0 && /* @__PURE__ */ jsxs6("div", { className: "vpg-assigned-section", children: [
3724
- /* @__PURE__ */ jsx6("div", { className: "vpg-section-label", children: "Active" }),
3725
- /* @__PURE__ */ jsx6("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs6(
3982
+ assignedCount > 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-assigned-section", children: [
3983
+ /* @__PURE__ */ jsx7("div", { className: "vpg-section-label", children: "Active" }),
3984
+ /* @__PURE__ */ jsx7("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs7(
3726
3985
  "div",
3727
3986
  {
3728
3987
  className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
@@ -3731,12 +3990,12 @@ function PivotConfig({
3731
3990
  onDragStart: (e) => handleDragStart(field.field, e),
3732
3991
  onDragEnd,
3733
3992
  children: [
3734
- /* @__PURE__ */ jsxs6("div", { className: "vpg-item-main", children: [
3735
- /* @__PURE__ */ jsx6("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : getAggregationSymbol(field.valueConfig?.aggregation || "sum") }),
3736
- /* @__PURE__ */ jsx6("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
3993
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-item-main", children: [
3994
+ /* @__PURE__ */ jsx7("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : getAggregationSymbol(field.valueConfig?.aggregation || "sum") }),
3995
+ /* @__PURE__ */ jsx7("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
3737
3996
  ] }),
3738
- /* @__PURE__ */ jsxs6("div", { className: "vpg-item-actions", children: [
3739
- (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx6(
3997
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-item-actions", children: [
3998
+ (field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx7(
3740
3999
  "button",
3741
4000
  {
3742
4001
  className: "vpg-toggle-btn",
@@ -3745,14 +4004,14 @@ function PivotConfig({
3745
4004
  e.stopPropagation();
3746
4005
  toggleRowColumn(field.field, field.assignedTo);
3747
4006
  },
3748
- children: /* @__PURE__ */ jsx6(
4007
+ children: /* @__PURE__ */ jsx7(
3749
4008
  "svg",
3750
4009
  {
3751
4010
  className: "vpg-icon-xs",
3752
4011
  fill: "none",
3753
4012
  stroke: "currentColor",
3754
4013
  viewBox: "0 0 24 24",
3755
- children: /* @__PURE__ */ jsx6(
4014
+ children: /* @__PURE__ */ jsx7(
3756
4015
  "path",
3757
4016
  {
3758
4017
  strokeLinecap: "round",
@@ -3765,7 +4024,7 @@ function PivotConfig({
3765
4024
  )
3766
4025
  }
3767
4026
  ),
3768
- field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx6(
4027
+ field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx7(
3769
4028
  "select",
3770
4029
  {
3771
4030
  className: "vpg-agg-select",
@@ -3779,7 +4038,7 @@ function PivotConfig({
3779
4038
  );
3780
4039
  },
3781
4040
  onClick: (e) => e.stopPropagation(),
3782
- children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs6(
4041
+ children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs7(
3783
4042
  "option",
3784
4043
  {
3785
4044
  value: agg.value,
@@ -3795,7 +4054,7 @@ function PivotConfig({
3795
4054
  ))
3796
4055
  }
3797
4056
  ),
3798
- /* @__PURE__ */ jsx6(
4057
+ /* @__PURE__ */ jsx7(
3799
4058
  "button",
3800
4059
  {
3801
4060
  className: "vpg-remove-btn",
@@ -3813,14 +4072,14 @@ function PivotConfig({
3813
4072
  field.field
3814
4073
  )) })
3815
4074
  ] }),
3816
- /* @__PURE__ */ jsxs6("div", { className: "vpg-unassigned-section", children: [
3817
- /* @__PURE__ */ jsx6("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs6("div", { className: "vpg-section-label", children: [
4075
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-unassigned-section", children: [
4076
+ /* @__PURE__ */ jsx7("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs7("div", { className: "vpg-section-label", children: [
3818
4077
  "Available",
3819
4078
  " ",
3820
- /* @__PURE__ */ jsx6("span", { className: "vpg-count", children: unassignedFields.length })
4079
+ /* @__PURE__ */ jsx7("span", { className: "vpg-count", children: unassignedFields.length })
3821
4080
  ] }) }),
3822
- /* @__PURE__ */ jsxs6("div", { className: "vpg-field-search", children: [
3823
- /* @__PURE__ */ jsx6("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4081
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-field-search", children: [
4082
+ /* @__PURE__ */ jsx7("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3824
4083
  "path",
3825
4084
  {
3826
4085
  strokeLinecap: "round",
@@ -3829,7 +4088,7 @@ function PivotConfig({
3829
4088
  d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
3830
4089
  }
3831
4090
  ) }),
3832
- /* @__PURE__ */ jsx6(
4091
+ /* @__PURE__ */ jsx7(
3833
4092
  "input",
3834
4093
  {
3835
4094
  type: "text",
@@ -3839,7 +4098,7 @@ function PivotConfig({
3839
4098
  className: "vpg-search-input"
3840
4099
  }
3841
4100
  ),
3842
- fieldSearch && /* @__PURE__ */ jsx6("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx6("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
4101
+ fieldSearch && /* @__PURE__ */ jsx7("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
3843
4102
  "path",
3844
4103
  {
3845
4104
  strokeLinecap: "round",
@@ -3849,8 +4108,8 @@ function PivotConfig({
3849
4108
  }
3850
4109
  ) }) })
3851
4110
  ] }),
3852
- /* @__PURE__ */ jsxs6("div", { className: "vpg-field-list", children: [
3853
- filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs6(
4111
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-field-list", children: [
4112
+ filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs7(
3854
4113
  "div",
3855
4114
  {
3856
4115
  className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
@@ -3859,10 +4118,10 @@ function PivotConfig({
3859
4118
  onDragStart: (e) => handleDragStart(field.field, e),
3860
4119
  onDragEnd,
3861
4120
  children: [
3862
- /* @__PURE__ */ jsx6("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
3863
- /* @__PURE__ */ jsx6("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
3864
- field.isCalculated ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
3865
- /* @__PURE__ */ jsx6(
4121
+ /* @__PURE__ */ jsx7("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
4122
+ /* @__PURE__ */ jsx7("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
4123
+ field.isCalculated ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
4124
+ /* @__PURE__ */ jsx7(
3866
4125
  "button",
3867
4126
  {
3868
4127
  className: "vpg-field-edit",
@@ -3876,7 +4135,7 @@ function PivotConfig({
3876
4135
  children: "\u270E"
3877
4136
  }
3878
4137
  ),
3879
- /* @__PURE__ */ jsx6(
4138
+ /* @__PURE__ */ jsx7(
3880
4139
  "button",
3881
4140
  {
3882
4141
  className: "vpg-field-delete",
@@ -3890,22 +4149,22 @@ function PivotConfig({
3890
4149
  children: "\xD7"
3891
4150
  }
3892
4151
  )
3893
- ] }) : /* @__PURE__ */ jsx6("span", { className: "vpg-unique-count", children: field.uniqueCount })
4152
+ ] }) : /* @__PURE__ */ jsx7("span", { className: "vpg-unique-count", children: field.uniqueCount })
3894
4153
  ]
3895
4154
  },
3896
4155
  field.field
3897
4156
  )),
3898
- filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs6("div", { className: "vpg-empty-hint", children: [
4157
+ filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs7("div", { className: "vpg-empty-hint", children: [
3899
4158
  'No fields match "',
3900
4159
  fieldSearch,
3901
4160
  '"'
3902
4161
  ] }),
3903
- unassignedFields.length === 0 && /* @__PURE__ */ jsx6("div", { className: "vpg-empty-hint", children: "All fields assigned" })
4162
+ unassignedFields.length === 0 && /* @__PURE__ */ jsx7("div", { className: "vpg-empty-hint", children: "All fields assigned" })
3904
4163
  ] })
3905
4164
  ] }),
3906
- /* @__PURE__ */ jsxs6("div", { className: "vpg-options-section", children: [
3907
- /* @__PURE__ */ jsxs6("label", { className: "vpg-option-toggle", children: [
3908
- /* @__PURE__ */ jsx6(
4165
+ /* @__PURE__ */ jsxs7("div", { className: "vpg-options-section", children: [
4166
+ /* @__PURE__ */ jsxs7("label", { className: "vpg-option-toggle", children: [
4167
+ /* @__PURE__ */ jsx7(
3909
4168
  "input",
3910
4169
  {
3911
4170
  type: "checkbox",
@@ -3913,14 +4172,14 @@ function PivotConfig({
3913
4172
  onChange: (e) => handleTotalsToggle(e.target.checked)
3914
4173
  }
3915
4174
  ),
3916
- /* @__PURE__ */ jsx6("span", { children: "Totals" })
4175
+ /* @__PURE__ */ jsx7("span", { children: "Totals" })
3917
4176
  ] }),
3918
- /* @__PURE__ */ jsxs6("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
3919
- /* @__PURE__ */ jsx6("span", { className: "vpg-calc-icon", children: "\u0192" }),
3920
- /* @__PURE__ */ jsx6("span", { children: "+ Calc" })
4177
+ /* @__PURE__ */ jsxs7("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
4178
+ /* @__PURE__ */ jsx7("span", { className: "vpg-calc-icon", children: "\u0192" }),
4179
+ /* @__PURE__ */ jsx7("span", { children: "+ Calc" })
3921
4180
  ] })
3922
4181
  ] }),
3923
- /* @__PURE__ */ jsx6(
4182
+ /* @__PURE__ */ jsx7(
3924
4183
  CalculatedFieldModal,
3925
4184
  {
3926
4185
  show: showCalcModal,
@@ -3935,8 +4194,8 @@ function PivotConfig({
3935
4194
 
3936
4195
  // src/components/PivotSkeleton.tsx
3937
4196
  import { getAggregationLabel as getAggregationLabel2, getAggregationSymbol as getAggregationSymbol2 } from "@smallwebco/tinypivot-core";
3938
- import { useCallback as useCallback12, useEffect as useEffect9, useMemo as useMemo12, useState as useState12 } from "react";
3939
- import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
4197
+ import { useCallback as useCallback13, useEffect as useEffect10, useMemo as useMemo13, useState as useState13 } from "react";
4198
+ import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
3940
4199
  function PivotSkeleton({
3941
4200
  rowFields,
3942
4201
  columnFields,
@@ -3959,7 +4218,7 @@ function PivotSkeleton({
3959
4218
  onReorderColumnFields
3960
4219
  }) {
3961
4220
  const { showWatermark, canUsePivot, isDemo } = useLicense();
3962
- const getValueFieldDisplayName = useCallback12((field) => {
4221
+ const getValueFieldDisplayName = useCallback13((field) => {
3963
4222
  if (field.startsWith("calc:")) {
3964
4223
  const calcId = field.replace("calc:", "");
3965
4224
  const calcField = calculatedFields?.find((c) => c.id === calcId);
@@ -3967,15 +4226,15 @@ function PivotSkeleton({
3967
4226
  }
3968
4227
  return field;
3969
4228
  }, [calculatedFields]);
3970
- const isCalculatedField = useCallback12((field) => {
4229
+ const isCalculatedField = useCallback13((field) => {
3971
4230
  return field.startsWith("calc:");
3972
4231
  }, []);
3973
- const [dragOverArea, setDragOverArea] = useState12(null);
3974
- const [reorderDragSource, setReorderDragSource] = useState12(null);
3975
- const [reorderDropTarget, setReorderDropTarget] = useState12(null);
3976
- const [sortDirection, setSortDirection] = useState12("asc");
3977
- const [sortTarget, setSortTarget] = useState12("row");
3978
- const toggleSort = useCallback12((target = "row") => {
4232
+ const [dragOverArea, setDragOverArea] = useState13(null);
4233
+ const [reorderDragSource, setReorderDragSource] = useState13(null);
4234
+ const [reorderDropTarget, setReorderDropTarget] = useState13(null);
4235
+ const [sortDirection, setSortDirection] = useState13("asc");
4236
+ const [sortTarget, setSortTarget] = useState13("row");
4237
+ const toggleSort = useCallback13((target = "row") => {
3979
4238
  if (sortTarget === target) {
3980
4239
  setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
3981
4240
  } else {
@@ -3983,13 +4242,13 @@ function PivotSkeleton({
3983
4242
  setSortDirection("asc");
3984
4243
  }
3985
4244
  }, [sortTarget]);
3986
- const [selectedCell, setSelectedCell] = useState12(null);
3987
- const [selectionStart, setSelectionStart] = useState12(null);
3988
- const [selectionEnd, setSelectionEnd] = useState12(null);
3989
- const [isSelecting, setIsSelecting] = useState12(false);
3990
- const [showCopyToast, setShowCopyToast] = useState12(false);
3991
- const [copyToastMessage, setCopyToastMessage] = useState12("");
3992
- const selectionBounds = useMemo12(() => {
4245
+ const [selectedCell, setSelectedCell] = useState13(null);
4246
+ const [selectionStart, setSelectionStart] = useState13(null);
4247
+ const [selectionEnd, setSelectionEnd] = useState13(null);
4248
+ const [isSelecting, setIsSelecting] = useState13(false);
4249
+ const [showCopyToast, setShowCopyToast] = useState13(false);
4250
+ const [copyToastMessage, setCopyToastMessage] = useState13("");
4251
+ const selectionBounds = useMemo13(() => {
3993
4252
  if (!selectionStart || !selectionEnd)
3994
4253
  return null;
3995
4254
  return {
@@ -3999,7 +4258,7 @@ function PivotSkeleton({
3999
4258
  maxCol: Math.max(selectionStart.col, selectionEnd.col)
4000
4259
  };
4001
4260
  }, [selectionStart, selectionEnd]);
4002
- const handleCellMouseDown = useCallback12(
4261
+ const handleCellMouseDown = useCallback13(
4003
4262
  (rowIndex, colIndex, event) => {
4004
4263
  event.preventDefault();
4005
4264
  if (event.shiftKey && selectedCell) {
@@ -4013,7 +4272,7 @@ function PivotSkeleton({
4013
4272
  },
4014
4273
  [selectedCell]
4015
4274
  );
4016
- const handleCellMouseEnter = useCallback12(
4275
+ const handleCellMouseEnter = useCallback13(
4017
4276
  (rowIndex, colIndex) => {
4018
4277
  if (isSelecting) {
4019
4278
  setSelectionEnd({ row: rowIndex, col: colIndex });
@@ -4021,7 +4280,7 @@ function PivotSkeleton({
4021
4280
  },
4022
4281
  [isSelecting]
4023
4282
  );
4024
- const isCellSelected = useCallback12(
4283
+ const isCellSelected = useCallback13(
4025
4284
  (rowIndex, colIndex) => {
4026
4285
  if (!selectionBounds) {
4027
4286
  return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
@@ -4031,12 +4290,12 @@ function PivotSkeleton({
4031
4290
  },
4032
4291
  [selectionBounds, selectedCell]
4033
4292
  );
4034
- useEffect9(() => {
4293
+ useEffect10(() => {
4035
4294
  const handleMouseUp = () => setIsSelecting(false);
4036
4295
  document.addEventListener("mouseup", handleMouseUp);
4037
4296
  return () => document.removeEventListener("mouseup", handleMouseUp);
4038
4297
  }, []);
4039
- const sortedRowIndices = useMemo12(() => {
4298
+ const sortedRowIndices = useMemo13(() => {
4040
4299
  if (!pivotResult)
4041
4300
  return [];
4042
4301
  const indices = pivotResult.rowHeaders.map((_, i) => i);
@@ -4064,7 +4323,7 @@ function PivotSkeleton({
4064
4323
  });
4065
4324
  return indices;
4066
4325
  }, [pivotResult, sortTarget, sortDirection]);
4067
- const copySelectionToClipboard = useCallback12(() => {
4326
+ const copySelectionToClipboard = useCallback13(() => {
4068
4327
  if (!selectionBounds || !pivotResult)
4069
4328
  return;
4070
4329
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
@@ -4090,7 +4349,7 @@ function PivotSkeleton({
4090
4349
  console.error("Copy failed:", err);
4091
4350
  });
4092
4351
  }, [selectionBounds, pivotResult, sortedRowIndices]);
4093
- useEffect9(() => {
4352
+ useEffect10(() => {
4094
4353
  const handleKeydown = (event) => {
4095
4354
  if (!selectionBounds)
4096
4355
  return;
@@ -4108,7 +4367,7 @@ function PivotSkeleton({
4108
4367
  document.addEventListener("keydown", handleKeydown);
4109
4368
  return () => document.removeEventListener("keydown", handleKeydown);
4110
4369
  }, [selectionBounds, copySelectionToClipboard]);
4111
- const selectionStats = useMemo12(() => {
4370
+ const selectionStats = useMemo13(() => {
4112
4371
  if (!selectionBounds || !pivotResult)
4113
4372
  return null;
4114
4373
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
@@ -4137,14 +4396,14 @@ function PivotSkeleton({
4137
4396
  avg
4138
4397
  };
4139
4398
  }, [selectionBounds, pivotResult, sortedRowIndices]);
4140
- const formatStatValue = useCallback12((val) => {
4399
+ const formatStatValue = useCallback13((val) => {
4141
4400
  if (Math.abs(val) >= 1e6)
4142
4401
  return `${(val / 1e6).toFixed(2)}M`;
4143
4402
  if (Math.abs(val) >= 1e3)
4144
4403
  return `${(val / 1e3).toFixed(2)}K`;
4145
4404
  return val.toFixed(2);
4146
4405
  }, []);
4147
- const columnHeaderCells = useMemo12(() => {
4406
+ const columnHeaderCells = useMemo13(() => {
4148
4407
  if (!pivotResult || pivotResult.headers.length === 0) {
4149
4408
  return [
4150
4409
  valueFields.map((vf) => ({
@@ -4172,13 +4431,13 @@ function PivotSkeleton({
4172
4431
  return result;
4173
4432
  }, [pivotResult, valueFields]);
4174
4433
  const hasActiveFilters = activeFilters && activeFilters.length > 0;
4175
- const filterSummary = useMemo12(() => {
4434
+ const filterSummary = useMemo13(() => {
4176
4435
  if (!activeFilters || activeFilters.length === 0)
4177
4436
  return "";
4178
4437
  return activeFilters.map((f) => f.column).join(", ");
4179
4438
  }, [activeFilters]);
4180
- const [showFilterTooltip, setShowFilterTooltip] = useState12(false);
4181
- const filterTooltipDetails = useMemo12(() => {
4439
+ const [showFilterTooltip, setShowFilterTooltip] = useState13(false);
4440
+ const filterTooltipDetails = useMemo13(() => {
4182
4441
  if (!activeFilters || activeFilters.length === 0)
4183
4442
  return [];
4184
4443
  return activeFilters.map((f) => {
@@ -4203,7 +4462,7 @@ function PivotSkeleton({
4203
4462
  };
4204
4463
  });
4205
4464
  }, [activeFilters]);
4206
- const handleDragOver = useCallback12(
4465
+ const handleDragOver = useCallback13(
4207
4466
  (area, event) => {
4208
4467
  event.preventDefault();
4209
4468
  event.dataTransfer.dropEffect = "move";
@@ -4211,10 +4470,10 @@ function PivotSkeleton({
4211
4470
  },
4212
4471
  []
4213
4472
  );
4214
- const handleDragLeave = useCallback12(() => {
4473
+ const handleDragLeave = useCallback13(() => {
4215
4474
  setDragOverArea(null);
4216
4475
  }, []);
4217
- const handleDrop = useCallback12(
4476
+ const handleDrop = useCallback13(
4218
4477
  (area, event) => {
4219
4478
  event.preventDefault();
4220
4479
  const field = event.dataTransfer?.getData("text/plain");
@@ -4244,7 +4503,7 @@ function PivotSkeleton({
4244
4503
  },
4245
4504
  [rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
4246
4505
  );
4247
- const handleChipDragStart = useCallback12(
4506
+ const handleChipDragStart = useCallback13(
4248
4507
  (zone, index, event) => {
4249
4508
  setReorderDragSource({ zone, index });
4250
4509
  event.dataTransfer.effectAllowed = "move";
@@ -4255,11 +4514,11 @@ function PivotSkeleton({
4255
4514
  },
4256
4515
  []
4257
4516
  );
4258
- const handleChipDragEnd = useCallback12(() => {
4517
+ const handleChipDragEnd = useCallback13(() => {
4259
4518
  setReorderDragSource(null);
4260
4519
  setReorderDropTarget(null);
4261
4520
  }, []);
4262
- const handleChipDragOver = useCallback12(
4521
+ const handleChipDragOver = useCallback13(
4263
4522
  (zone, index, event) => {
4264
4523
  event.preventDefault();
4265
4524
  if (reorderDragSource && reorderDragSource.zone === zone) {
@@ -4269,10 +4528,10 @@ function PivotSkeleton({
4269
4528
  },
4270
4529
  [reorderDragSource]
4271
4530
  );
4272
- const handleChipDragLeave = useCallback12(() => {
4531
+ const handleChipDragLeave = useCallback13(() => {
4273
4532
  setReorderDropTarget(null);
4274
4533
  }, []);
4275
- const handleChipDrop = useCallback12(
4534
+ const handleChipDrop = useCallback13(
4276
4535
  (zone, targetIndex, event) => {
4277
4536
  event.preventDefault();
4278
4537
  event.stopPropagation();
@@ -4298,13 +4557,13 @@ function PivotSkeleton({
4298
4557
  },
4299
4558
  [reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
4300
4559
  );
4301
- const isChipDragSource = useCallback12(
4560
+ const isChipDragSource = useCallback13(
4302
4561
  (zone, index) => {
4303
4562
  return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
4304
4563
  },
4305
4564
  [reorderDragSource]
4306
4565
  );
4307
- const isChipDropTarget = useCallback12(
4566
+ const isChipDropTarget = useCallback13(
4308
4567
  (zone, index) => {
4309
4568
  return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
4310
4569
  },
@@ -4312,25 +4571,25 @@ function PivotSkeleton({
4312
4571
  );
4313
4572
  const currentFontSize = fontSize;
4314
4573
  const rowHeaderWidth = 180;
4315
- const rowHeaderColWidth = useMemo12(() => {
4574
+ const rowHeaderColWidth = useMemo13(() => {
4316
4575
  const numCols = Math.max(rowFields.length, 1);
4317
4576
  return Math.max(rowHeaderWidth / numCols, 80);
4318
4577
  }, [rowFields.length]);
4319
- const getRowHeaderLeftOffset = useCallback12((fieldIdx) => {
4578
+ const getRowHeaderLeftOffset = useCallback13((fieldIdx) => {
4320
4579
  return fieldIdx * rowHeaderColWidth;
4321
4580
  }, [rowHeaderColWidth]);
4322
- return /* @__PURE__ */ jsxs7(
4581
+ return /* @__PURE__ */ jsxs8(
4323
4582
  "div",
4324
4583
  {
4325
4584
  className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
4326
4585
  children: [
4327
- showCopyToast && /* @__PURE__ */ jsxs7("div", { className: "vpg-toast", children: [
4328
- /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
4586
+ showCopyToast && /* @__PURE__ */ jsxs8("div", { className: "vpg-toast", children: [
4587
+ /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
4329
4588
  copyToastMessage
4330
4589
  ] }),
4331
- /* @__PURE__ */ jsxs7("div", { className: "vpg-skeleton-header", children: [
4332
- /* @__PURE__ */ jsxs7("div", { className: "vpg-skeleton-title", children: [
4333
- /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
4590
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-skeleton-header", children: [
4591
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-skeleton-title", children: [
4592
+ /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
4334
4593
  "path",
4335
4594
  {
4336
4595
  strokeLinecap: "round",
@@ -4339,24 +4598,24 @@ function PivotSkeleton({
4339
4598
  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"
4340
4599
  }
4341
4600
  ) }),
4342
- /* @__PURE__ */ jsx7("span", { children: "Pivot Table" })
4601
+ /* @__PURE__ */ jsx8("span", { children: "Pivot Table" })
4343
4602
  ] }),
4344
- /* @__PURE__ */ jsxs7("div", { className: "vpg-header-right", children: [
4345
- hasActiveFilters && /* @__PURE__ */ jsxs7(
4603
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-header-right", children: [
4604
+ hasActiveFilters && /* @__PURE__ */ jsxs8(
4346
4605
  "div",
4347
4606
  {
4348
4607
  className: "vpg-filter-indicator",
4349
4608
  onMouseEnter: () => setShowFilterTooltip(true),
4350
4609
  onMouseLeave: () => setShowFilterTooltip(false),
4351
4610
  children: [
4352
- /* @__PURE__ */ jsx7(
4611
+ /* @__PURE__ */ jsx8(
4353
4612
  "svg",
4354
4613
  {
4355
4614
  className: "vpg-filter-icon",
4356
4615
  fill: "none",
4357
4616
  stroke: "currentColor",
4358
4617
  viewBox: "0 0 24 24",
4359
- children: /* @__PURE__ */ jsx7(
4618
+ children: /* @__PURE__ */ jsx8(
4360
4619
  "path",
4361
4620
  {
4362
4621
  strokeLinecap: "round",
@@ -4367,11 +4626,11 @@ function PivotSkeleton({
4367
4626
  )
4368
4627
  }
4369
4628
  ),
4370
- /* @__PURE__ */ jsxs7("span", { className: "vpg-filter-text", children: [
4629
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-filter-text", children: [
4371
4630
  "Filtered:",
4372
4631
  " ",
4373
- /* @__PURE__ */ jsx7("strong", { children: filterSummary }),
4374
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs7("span", { className: "vpg-filter-count", children: [
4632
+ /* @__PURE__ */ jsx8("strong", { children: filterSummary }),
4633
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs8("span", { className: "vpg-filter-count", children: [
4375
4634
  "(",
4376
4635
  filteredRowCount.toLocaleString(),
4377
4636
  " ",
@@ -4382,13 +4641,13 @@ function PivotSkeleton({
4382
4641
  "rows)"
4383
4642
  ] })
4384
4643
  ] }),
4385
- showFilterTooltip && /* @__PURE__ */ jsxs7("div", { className: "vpg-filter-tooltip", children: [
4386
- /* @__PURE__ */ jsx7("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
4387
- filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs7("div", { className: "vpg-tooltip-filter", children: [
4388
- /* @__PURE__ */ jsx7("div", { className: "vpg-tooltip-column", children: filter.column }),
4389
- /* @__PURE__ */ jsx7("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ jsx7("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
4390
- filter.values.map((val, idx) => /* @__PURE__ */ jsx7("span", { className: "vpg-tooltip-value", children: val }, idx)),
4391
- filter.remaining > 0 && /* @__PURE__ */ jsxs7("span", { className: "vpg-tooltip-more", children: [
4644
+ showFilterTooltip && /* @__PURE__ */ jsxs8("div", { className: "vpg-filter-tooltip", children: [
4645
+ /* @__PURE__ */ jsx8("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
4646
+ filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs8("div", { className: "vpg-tooltip-filter", children: [
4647
+ /* @__PURE__ */ jsx8("div", { className: "vpg-tooltip-column", children: filter.column }),
4648
+ /* @__PURE__ */ jsx8("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ jsx8("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
4649
+ filter.values.map((val, idx) => /* @__PURE__ */ jsx8("span", { className: "vpg-tooltip-value", children: val }, idx)),
4650
+ filter.remaining > 0 && /* @__PURE__ */ jsxs8("span", { className: "vpg-tooltip-more", children: [
4392
4651
  "+",
4393
4652
  filter.remaining,
4394
4653
  " ",
@@ -4396,7 +4655,7 @@ function PivotSkeleton({
4396
4655
  ] })
4397
4656
  ] }) })
4398
4657
  ] }, filter.column)),
4399
- filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-tooltip-summary", children: [
4658
+ filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs8("div", { className: "vpg-tooltip-summary", children: [
4400
4659
  "Showing",
4401
4660
  " ",
4402
4661
  filteredRowCount.toLocaleString(),
@@ -4411,20 +4670,20 @@ function PivotSkeleton({
4411
4670
  ]
4412
4671
  }
4413
4672
  ),
4414
- isConfigured && /* @__PURE__ */ jsxs7("div", { className: "vpg-config-summary", children: [
4415
- /* @__PURE__ */ jsxs7("span", { className: "vpg-summary-badge vpg-rows", children: [
4673
+ isConfigured && /* @__PURE__ */ jsxs8("div", { className: "vpg-config-summary", children: [
4674
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-summary-badge vpg-rows", children: [
4416
4675
  rowFields.length,
4417
4676
  " ",
4418
4677
  "row",
4419
4678
  rowFields.length !== 1 ? "s" : ""
4420
4679
  ] }),
4421
- /* @__PURE__ */ jsxs7("span", { className: "vpg-summary-badge vpg-cols", children: [
4680
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-summary-badge vpg-cols", children: [
4422
4681
  columnFields.length,
4423
4682
  " ",
4424
4683
  "col",
4425
4684
  columnFields.length !== 1 ? "s" : ""
4426
4685
  ] }),
4427
- /* @__PURE__ */ jsxs7("span", { className: "vpg-summary-badge vpg-vals", children: [
4686
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-summary-badge vpg-vals", children: [
4428
4687
  valueFields.length,
4429
4688
  " ",
4430
4689
  "val",
@@ -4433,8 +4692,8 @@ function PivotSkeleton({
4433
4692
  ] })
4434
4693
  ] })
4435
4694
  ] }),
4436
- !canUsePivot ? /* @__PURE__ */ jsx7("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs7("div", { className: "vpg-pro-content", children: [
4437
- /* @__PURE__ */ jsx7("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx7(
4695
+ !canUsePivot ? /* @__PURE__ */ jsx8("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs8("div", { className: "vpg-pro-content", children: [
4696
+ /* @__PURE__ */ jsx8("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx8(
4438
4697
  "path",
4439
4698
  {
4440
4699
  strokeLinecap: "round",
@@ -4443,12 +4702,12 @@ function PivotSkeleton({
4443
4702
  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"
4444
4703
  }
4445
4704
  ) }),
4446
- /* @__PURE__ */ jsx7("h3", { children: "Pro Feature" }),
4447
- /* @__PURE__ */ jsx7("p", { children: "Pivot Table functionality requires a Pro license." }),
4448
- /* @__PURE__ */ jsx7("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
4449
- ] }) }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
4450
- /* @__PURE__ */ jsxs7("div", { className: "vpg-config-bar", children: [
4451
- /* @__PURE__ */ jsxs7(
4705
+ /* @__PURE__ */ jsx8("h3", { children: "Pro Feature" }),
4706
+ /* @__PURE__ */ jsx8("p", { children: "Pivot Table functionality requires a Pro license." }),
4707
+ /* @__PURE__ */ jsx8("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
4708
+ ] }) }) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
4709
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-config-bar", children: [
4710
+ /* @__PURE__ */ jsxs8(
4452
4711
  "div",
4453
4712
  {
4454
4713
  className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
@@ -4456,12 +4715,12 @@ function PivotSkeleton({
4456
4715
  onDragLeave: handleDragLeave,
4457
4716
  onDrop: (e) => handleDrop("row", e),
4458
4717
  children: [
4459
- /* @__PURE__ */ jsxs7("div", { className: "vpg-zone-header", children: [
4460
- /* @__PURE__ */ jsx7("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
4461
- /* @__PURE__ */ jsx7("span", { className: "vpg-zone-label", children: "Rows" })
4718
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-zone-header", children: [
4719
+ /* @__PURE__ */ jsx8("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
4720
+ /* @__PURE__ */ jsx8("span", { className: "vpg-zone-label", children: "Rows" })
4462
4721
  ] }),
4463
- /* @__PURE__ */ jsxs7("div", { className: "vpg-zone-chips", children: [
4464
- rowFields.map((field, idx) => /* @__PURE__ */ jsxs7(
4722
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-zone-chips", children: [
4723
+ rowFields.map((field, idx) => /* @__PURE__ */ jsxs8(
4465
4724
  "div",
4466
4725
  {
4467
4726
  className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -4472,9 +4731,9 @@ function PivotSkeleton({
4472
4731
  onDragLeave: handleChipDragLeave,
4473
4732
  onDrop: (e) => handleChipDrop("row", idx, e),
4474
4733
  children: [
4475
- /* @__PURE__ */ jsx7("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
4476
- /* @__PURE__ */ jsx7("span", { className: "vpg-mini-name", children: field }),
4477
- /* @__PURE__ */ jsx7(
4734
+ /* @__PURE__ */ jsx8("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
4735
+ /* @__PURE__ */ jsx8("span", { className: "vpg-mini-name", children: field }),
4736
+ /* @__PURE__ */ jsx8(
4478
4737
  "button",
4479
4738
  {
4480
4739
  className: "vpg-mini-remove",
@@ -4489,12 +4748,12 @@ function PivotSkeleton({
4489
4748
  },
4490
4749
  field
4491
4750
  )),
4492
- rowFields.length === 0 && /* @__PURE__ */ jsx7("span", { className: "vpg-zone-hint", children: "Drop here" })
4751
+ rowFields.length === 0 && /* @__PURE__ */ jsx8("span", { className: "vpg-zone-hint", children: "Drop here" })
4493
4752
  ] })
4494
4753
  ]
4495
4754
  }
4496
4755
  ),
4497
- /* @__PURE__ */ jsxs7(
4756
+ /* @__PURE__ */ jsxs8(
4498
4757
  "div",
4499
4758
  {
4500
4759
  className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
@@ -4502,12 +4761,12 @@ function PivotSkeleton({
4502
4761
  onDragLeave: handleDragLeave,
4503
4762
  onDrop: (e) => handleDrop("column", e),
4504
4763
  children: [
4505
- /* @__PURE__ */ jsxs7("div", { className: "vpg-zone-header", children: [
4506
- /* @__PURE__ */ jsx7("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
4507
- /* @__PURE__ */ jsx7("span", { className: "vpg-zone-label", children: "Columns" })
4764
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-zone-header", children: [
4765
+ /* @__PURE__ */ jsx8("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
4766
+ /* @__PURE__ */ jsx8("span", { className: "vpg-zone-label", children: "Columns" })
4508
4767
  ] }),
4509
- /* @__PURE__ */ jsxs7("div", { className: "vpg-zone-chips", children: [
4510
- columnFields.map((field, idx) => /* @__PURE__ */ jsxs7(
4768
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-zone-chips", children: [
4769
+ columnFields.map((field, idx) => /* @__PURE__ */ jsxs8(
4511
4770
  "div",
4512
4771
  {
4513
4772
  className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
@@ -4518,9 +4777,9 @@ function PivotSkeleton({
4518
4777
  onDragLeave: handleChipDragLeave,
4519
4778
  onDrop: (e) => handleChipDrop("column", idx, e),
4520
4779
  children: [
4521
- /* @__PURE__ */ jsx7("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
4522
- /* @__PURE__ */ jsx7("span", { className: "vpg-mini-name", children: field }),
4523
- /* @__PURE__ */ jsx7(
4780
+ /* @__PURE__ */ jsx8("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
4781
+ /* @__PURE__ */ jsx8("span", { className: "vpg-mini-name", children: field }),
4782
+ /* @__PURE__ */ jsx8(
4524
4783
  "button",
4525
4784
  {
4526
4785
  className: "vpg-mini-remove",
@@ -4535,12 +4794,12 @@ function PivotSkeleton({
4535
4794
  },
4536
4795
  field
4537
4796
  )),
4538
- columnFields.length === 0 && /* @__PURE__ */ jsx7("span", { className: "vpg-zone-hint", children: "Drop here" })
4797
+ columnFields.length === 0 && /* @__PURE__ */ jsx8("span", { className: "vpg-zone-hint", children: "Drop here" })
4539
4798
  ] })
4540
4799
  ]
4541
4800
  }
4542
4801
  ),
4543
- /* @__PURE__ */ jsxs7(
4802
+ /* @__PURE__ */ jsxs8(
4544
4803
  "div",
4545
4804
  {
4546
4805
  className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
@@ -4548,19 +4807,19 @@ function PivotSkeleton({
4548
4807
  onDragLeave: handleDragLeave,
4549
4808
  onDrop: (e) => handleDrop("value", e),
4550
4809
  children: [
4551
- /* @__PURE__ */ jsxs7("div", { className: "vpg-zone-header", children: [
4552
- /* @__PURE__ */ jsx7("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
4553
- /* @__PURE__ */ jsx7("span", { className: "vpg-zone-label", children: "Values" })
4810
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-zone-header", children: [
4811
+ /* @__PURE__ */ jsx8("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
4812
+ /* @__PURE__ */ jsx8("span", { className: "vpg-zone-label", children: "Values" })
4554
4813
  ] }),
4555
- /* @__PURE__ */ jsxs7("div", { className: "vpg-zone-chips", children: [
4556
- valueFields.map((vf) => /* @__PURE__ */ jsxs7(
4814
+ /* @__PURE__ */ jsxs8("div", { className: "vpg-zone-chips", children: [
4815
+ valueFields.map((vf) => /* @__PURE__ */ jsxs8(
4557
4816
  "div",
4558
4817
  {
4559
4818
  className: `vpg-mini-chip vpg-value-chip${isCalculatedField(vf.field) ? " vpg-calc-chip" : ""}`,
4560
4819
  children: [
4561
- /* @__PURE__ */ jsx7("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : getAggregationSymbol2(vf.aggregation) }),
4562
- /* @__PURE__ */ jsx7("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
4563
- /* @__PURE__ */ jsx7(
4820
+ /* @__PURE__ */ jsx8("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : getAggregationSymbol2(vf.aggregation) }),
4821
+ /* @__PURE__ */ jsx8("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
4822
+ /* @__PURE__ */ jsx8(
4564
4823
  "button",
4565
4824
  {
4566
4825
  className: "vpg-mini-remove",
@@ -4572,21 +4831,21 @@ function PivotSkeleton({
4572
4831
  },
4573
4832
  `${vf.field}-${vf.aggregation}`
4574
4833
  )),
4575
- valueFields.length === 0 && /* @__PURE__ */ jsx7("span", { className: "vpg-zone-hint", children: "Drop numeric" })
4834
+ valueFields.length === 0 && /* @__PURE__ */ jsx8("span", { className: "vpg-zone-hint", children: "Drop numeric" })
4576
4835
  ] })
4577
4836
  ]
4578
4837
  }
4579
4838
  )
4580
4839
  ] }),
4581
- (!isConfigured || !pivotResult) && /* @__PURE__ */ jsx7("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs7("div", { className: "vpg-placeholder-content", children: [
4582
- /* @__PURE__ */ jsx7(
4840
+ (!isConfigured || !pivotResult) && /* @__PURE__ */ jsx8("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs8("div", { className: "vpg-placeholder-content", children: [
4841
+ /* @__PURE__ */ jsx8(
4583
4842
  "svg",
4584
4843
  {
4585
4844
  className: "vpg-placeholder-icon",
4586
4845
  fill: "none",
4587
4846
  viewBox: "0 0 24 24",
4588
4847
  stroke: "currentColor",
4589
- children: /* @__PURE__ */ jsx7(
4848
+ children: /* @__PURE__ */ jsx8(
4590
4849
  "path",
4591
4850
  {
4592
4851
  strokeLinecap: "round",
@@ -4597,58 +4856,58 @@ function PivotSkeleton({
4597
4856
  )
4598
4857
  }
4599
4858
  ),
4600
- /* @__PURE__ */ jsx7("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
4859
+ /* @__PURE__ */ jsx8("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
4601
4860
  "Add a",
4602
4861
  " ",
4603
- /* @__PURE__ */ jsx7("strong", { children: "Values" }),
4862
+ /* @__PURE__ */ jsx8("strong", { children: "Values" }),
4604
4863
  " ",
4605
4864
  "field to see your pivot table"
4606
- ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
4865
+ ] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
4607
4866
  "Add",
4608
4867
  " ",
4609
- /* @__PURE__ */ jsx7("strong", { children: "Row" }),
4868
+ /* @__PURE__ */ jsx8("strong", { children: "Row" }),
4610
4869
  " ",
4611
4870
  "or",
4612
4871
  " ",
4613
- /* @__PURE__ */ jsx7("strong", { children: "Column" }),
4872
+ /* @__PURE__ */ jsx8("strong", { children: "Column" }),
4614
4873
  " ",
4615
4874
  "fields to group your data"
4616
4875
  ] }) : "Your pivot table will appear here" })
4617
4876
  ] }) }),
4618
- isConfigured && pivotResult && /* @__PURE__ */ jsx7("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs7("table", { className: "vpg-pivot-table", children: [
4619
- /* @__PURE__ */ jsx7("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs7("tr", { className: "vpg-column-header-row", children: [
4620
- levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ jsx7(
4877
+ isConfigured && pivotResult && /* @__PURE__ */ jsx8("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs8("table", { className: "vpg-pivot-table", children: [
4878
+ /* @__PURE__ */ jsx8("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs8("tr", { className: "vpg-column-header-row", children: [
4879
+ levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ jsx8(
4621
4880
  "th",
4622
4881
  {
4623
4882
  className: "vpg-row-header-label",
4624
4883
  rowSpan: columnHeaderCells.length,
4625
4884
  style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(fieldIdx)}px` },
4626
4885
  onClick: () => toggleSort("row"),
4627
- children: /* @__PURE__ */ jsxs7("div", { className: "vpg-header-content", children: [
4628
- /* @__PURE__ */ jsx7("span", { children: field }),
4629
- (fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ jsx7("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
4886
+ children: /* @__PURE__ */ jsxs8("div", { className: "vpg-header-content", children: [
4887
+ /* @__PURE__ */ jsx8("span", { children: field }),
4888
+ (fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ jsx8("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
4630
4889
  ] })
4631
4890
  },
4632
4891
  `row-header-${fieldIdx}`
4633
4892
  )),
4634
- headerRow.map((cell, idx) => /* @__PURE__ */ jsx7(
4893
+ headerRow.map((cell, idx) => /* @__PURE__ */ jsx8(
4635
4894
  "th",
4636
4895
  {
4637
4896
  className: "vpg-column-header-cell",
4638
4897
  colSpan: cell.colspan,
4639
4898
  onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
4640
- children: /* @__PURE__ */ jsxs7("div", { className: "vpg-header-content", children: [
4641
- /* @__PURE__ */ jsx7("span", { children: cell.label }),
4642
- levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx7("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
4899
+ children: /* @__PURE__ */ jsxs8("div", { className: "vpg-header-content", children: [
4900
+ /* @__PURE__ */ jsx8("span", { children: cell.label }),
4901
+ levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx8("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
4643
4902
  ] })
4644
4903
  },
4645
4904
  idx
4646
4905
  )),
4647
- pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx7("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
4906
+ pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx8("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
4648
4907
  ] }, `header-${levelIdx}`)) }),
4649
- /* @__PURE__ */ jsxs7("tbody", { children: [
4650
- sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs7("tr", { className: "vpg-data-row", children: [
4651
- pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx7(
4908
+ /* @__PURE__ */ jsxs8("tbody", { children: [
4909
+ sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs8("tr", { className: "vpg-data-row", children: [
4910
+ pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx8(
4652
4911
  "th",
4653
4912
  {
4654
4913
  className: "vpg-row-header-cell",
@@ -4659,7 +4918,7 @@ function PivotSkeleton({
4659
4918
  )),
4660
4919
  pivotResult.data[sortedIdx].map((cell, colIdx) => {
4661
4920
  const displayRowIdx = sortedRowIndices.indexOf(sortedIdx);
4662
- return /* @__PURE__ */ jsx7(
4921
+ return /* @__PURE__ */ jsx8(
4663
4922
  "td",
4664
4923
  {
4665
4924
  className: `vpg-data-cell ${isCellSelected(displayRowIdx, colIdx) ? "selected" : ""} ${cell.value === null ? "vpg-is-null" : ""}`,
@@ -4670,10 +4929,10 @@ function PivotSkeleton({
4670
4929
  colIdx
4671
4930
  );
4672
4931
  }),
4673
- pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx7("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
4932
+ pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx8("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
4674
4933
  ] }, sortedIdx)),
4675
- pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs7("tr", { className: "vpg-totals-row", children: [
4676
- /* @__PURE__ */ jsx7(
4934
+ pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs8("tr", { className: "vpg-totals-row", children: [
4935
+ /* @__PURE__ */ jsx8(
4677
4936
  "th",
4678
4937
  {
4679
4938
  className: "vpg-row-header-cell vpg-total-label",
@@ -4682,13 +4941,13 @@ function PivotSkeleton({
4682
4941
  children: "Total"
4683
4942
  }
4684
4943
  ),
4685
- pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx7("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
4686
- pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx7("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
4944
+ pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx8("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
4945
+ pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx8("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
4687
4946
  ] })
4688
4947
  ] })
4689
4948
  ] }) }),
4690
- isConfigured && pivotResult && /* @__PURE__ */ jsxs7("div", { className: "vpg-skeleton-footer", children: [
4691
- /* @__PURE__ */ jsxs7("span", { className: "vpg-footer-info", children: [
4949
+ isConfigured && pivotResult && /* @__PURE__ */ jsxs8("div", { className: "vpg-skeleton-footer", children: [
4950
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-footer-info", children: [
4692
4951
  pivotResult.rowHeaders.length,
4693
4952
  " ",
4694
4953
  "rows \xD7",
@@ -4696,30 +4955,30 @@ function PivotSkeleton({
4696
4955
  " ",
4697
4956
  "columns"
4698
4957
  ] }),
4699
- selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs7("div", { className: "vpg-selection-stats", children: [
4700
- /* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
4701
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Count:" }),
4702
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: selectionStats.count })
4958
+ selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs8("div", { className: "vpg-selection-stats", children: [
4959
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-stat", children: [
4960
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-label", children: "Count:" }),
4961
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-value", children: selectionStats.count })
4703
4962
  ] }),
4704
- selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs7(Fragment5, { children: [
4705
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-divider", children: "|" }),
4706
- /* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
4707
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Sum:" }),
4708
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
4963
+ selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs8(Fragment5, { children: [
4964
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-divider", children: "|" }),
4965
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-stat", children: [
4966
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-label", children: "Sum:" }),
4967
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
4709
4968
  ] }),
4710
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-divider", children: "|" }),
4711
- /* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
4712
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Avg:" }),
4713
- /* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
4969
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-divider", children: "|" }),
4970
+ /* @__PURE__ */ jsxs8("span", { className: "vpg-stat", children: [
4971
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-label", children: "Avg:" }),
4972
+ /* @__PURE__ */ jsx8("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
4714
4973
  ] })
4715
4974
  ] })
4716
4975
  ] })
4717
4976
  ] })
4718
4977
  ] }),
4719
- showWatermark && canUsePivot && /* @__PURE__ */ jsx7("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
4720
- /* @__PURE__ */ jsx7("span", { className: "vpg-demo-badge", children: "DEMO" }),
4721
- /* @__PURE__ */ jsx7("span", { children: "Pro features unlocked for evaluation" }),
4722
- /* @__PURE__ */ jsx7(
4978
+ showWatermark && canUsePivot && /* @__PURE__ */ jsx8("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
4979
+ /* @__PURE__ */ jsx8("span", { className: "vpg-demo-badge", children: "DEMO" }),
4980
+ /* @__PURE__ */ jsx8("span", { children: "Pro features unlocked for evaluation" }),
4981
+ /* @__PURE__ */ jsx8(
4723
4982
  "a",
4724
4983
  {
4725
4984
  href: "https://tiny-pivot.com/#pricing",
@@ -4729,14 +4988,14 @@ function PivotSkeleton({
4729
4988
  children: "Get Pro License \u2192"
4730
4989
  }
4731
4990
  )
4732
- ] }) : /* @__PURE__ */ jsx7("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
4991
+ ] }) : /* @__PURE__ */ jsx8("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
4733
4992
  ]
4734
4993
  }
4735
4994
  );
4736
4995
  }
4737
4996
 
4738
4997
  // src/components/DataGrid.tsx
4739
- import { Fragment as Fragment6, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
4998
+ import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
4740
4999
  var MIN_COL_WIDTH = 120;
4741
5000
  var MAX_COL_WIDTH = 350;
4742
5001
  function DataGrid({
@@ -4757,6 +5016,8 @@ function DataGrid({
4757
5016
  initialHeight = 600,
4758
5017
  minHeight = 300,
4759
5018
  maxHeight = 1200,
5019
+ numberFormat = "us",
5020
+ dateFormat = "iso",
4760
5021
  aiAnalyst,
4761
5022
  onCellClick,
4762
5023
  onExport,
@@ -4768,43 +5029,43 @@ function DataGrid({
4768
5029
  }) {
4769
5030
  const { showWatermark, canUsePivot, canUseCharts, canUseAIAnalyst, isDemo, isPro } = useLicense();
4770
5031
  const showAIAnalyst = aiAnalyst?.enabled && canUseAIAnalyst;
4771
- const currentTheme = useMemo13(() => {
5032
+ const currentTheme = useMemo14(() => {
4772
5033
  if (theme === "auto") {
4773
5034
  return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
4774
5035
  }
4775
5036
  return theme;
4776
5037
  }, [theme]);
4777
- const [currentFontSize, setCurrentFontSize] = useState13(initialFontSize);
4778
- const [globalSearchTerm, setGlobalSearchTerm] = useState13("");
4779
- const [showSearchInput, setShowSearchInput] = useState13(false);
4780
- const [currentPage, setCurrentPage] = useState13(1);
4781
- const [columnWidths, setColumnWidths] = useState13({});
4782
- const [resizingColumnId, setResizingColumnId] = useState13(null);
4783
- const [resizeStartX, setResizeStartX] = useState13(0);
4784
- const [resizeStartWidth, setResizeStartWidth] = useState13(0);
4785
- const [gridHeight, setGridHeight] = useState13(initialHeight);
4786
- const [isResizingVertically, setIsResizingVertically] = useState13(false);
4787
- const [verticalResizeStartY, setVerticalResizeStartY] = useState13(0);
4788
- const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState13(0);
4789
- const [showCopyToast, setShowCopyToast] = useState13(false);
4790
- const [copyToastMessage, setCopyToastMessage] = useState13("");
4791
- const [viewMode, setViewMode] = useState13("grid");
5038
+ const [currentFontSize, setCurrentFontSize] = useState14(initialFontSize);
5039
+ const [globalSearchTerm, setGlobalSearchTerm] = useState14("");
5040
+ const [showSearchInput, setShowSearchInput] = useState14(false);
5041
+ const [currentPage, setCurrentPage] = useState14(1);
5042
+ const [columnWidths, setColumnWidths] = useState14({});
5043
+ const [resizingColumnId, setResizingColumnId] = useState14(null);
5044
+ const [resizeStartX, setResizeStartX] = useState14(0);
5045
+ const [resizeStartWidth, setResizeStartWidth] = useState14(0);
5046
+ const [gridHeight, setGridHeight] = useState14(initialHeight);
5047
+ const [isResizingVertically, setIsResizingVertically] = useState14(false);
5048
+ const [verticalResizeStartY, setVerticalResizeStartY] = useState14(0);
5049
+ const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState14(0);
5050
+ const [showCopyToast, setShowCopyToast] = useState14(false);
5051
+ const [copyToastMessage, setCopyToastMessage] = useState14("");
5052
+ const [viewMode, setViewMode] = useState14("grid");
4792
5053
  const aiAnalystRef = useRef4(null);
4793
- const [aiLoadedData, setAiLoadedData] = useState13(null);
4794
- const [isLoadingFullData, setIsLoadingFullData] = useState13(false);
4795
- const displayData = useMemo13(() => aiLoadedData || data, [aiLoadedData, data]);
4796
- const [_chartConfig, setChartConfig] = useState13(null);
4797
- const handleChartConfigChange = useCallback13((config) => {
5054
+ const [aiLoadedData, setAiLoadedData] = useState14(null);
5055
+ const [isLoadingFullData, setIsLoadingFullData] = useState14(false);
5056
+ const displayData = useMemo14(() => aiLoadedData || data, [aiLoadedData, data]);
5057
+ const [_chartConfig, setChartConfig] = useState14(null);
5058
+ const handleChartConfigChange = useCallback14((config) => {
4798
5059
  setChartConfig(config);
4799
5060
  }, []);
4800
- const [showPivotConfig, setShowPivotConfig] = useState13(true);
4801
- const [draggingField, setDraggingField] = useState13(null);
4802
- const [activeFilterColumn, setActiveFilterColumn] = useState13(null);
4803
- const [filterDropdownPosition, setFilterDropdownPosition] = useState13({ top: 0, left: 0, maxHeight: 400 });
4804
- const [selectedCell, setSelectedCell] = useState13(null);
4805
- const [selectionStart, setSelectionStart] = useState13(null);
4806
- const [selectionEnd, setSelectionEnd] = useState13(null);
4807
- const [isSelecting, setIsSelecting] = useState13(false);
5061
+ const [showPivotConfig, setShowPivotConfig] = useState14(true);
5062
+ const [draggingField, setDraggingField] = useState14(null);
5063
+ const [activeFilterColumn, setActiveFilterColumn] = useState14(null);
5064
+ const [filterDropdownPosition, setFilterDropdownPosition] = useState14({ top: 0, left: 0, maxHeight: 400 });
5065
+ const [selectedCell, setSelectedCell] = useState14(null);
5066
+ const [selectionStart, setSelectionStart] = useState14(null);
5067
+ const [selectionEnd, setSelectionEnd] = useState14(null);
5068
+ const [isSelecting, setIsSelecting] = useState14(false);
4808
5069
  const tableContainerRef = useRef4(null);
4809
5070
  const tableBodyRef = useRef4(null);
4810
5071
  const fontSizeOptions = [
@@ -4828,9 +5089,12 @@ function DataGrid({
4828
5089
  activeFilters,
4829
5090
  // Numeric range filters
4830
5091
  setNumericRangeFilter,
4831
- getNumericRangeFilter
5092
+ getNumericRangeFilter,
5093
+ // Date range filters
5094
+ setDateRangeFilter,
5095
+ getDateRangeFilter
4832
5096
  } = useExcelGrid({ data: displayData, enableSorting: true, enableFiltering: true });
4833
- const filteredDataForPivot = useMemo13(() => {
5097
+ const filteredDataForPivot = useMemo14(() => {
4834
5098
  const filteredRows = table.getFilteredRowModel().rows;
4835
5099
  return filteredRows.map((row) => row.original);
4836
5100
  }, [table, columnFilters]);
@@ -4860,7 +5124,7 @@ function DataGrid({
4860
5124
  addCalculatedField,
4861
5125
  removeCalculatedField
4862
5126
  } = usePivotTable(filteredDataForPivot);
4863
- const activeFilterInfo = useMemo13(() => {
5127
+ const activeFilterInfo = useMemo14(() => {
4864
5128
  if (activeFilters.length === 0)
4865
5129
  return null;
4866
5130
  return activeFilters.map((f) => {
@@ -4877,6 +5141,19 @@ function DataGrid({
4877
5141
  isRange: true
4878
5142
  };
4879
5143
  }
5144
+ if (f.type === "dateRange" && f.dateRange) {
5145
+ const parts = [];
5146
+ if (f.dateRange.min !== null)
5147
+ parts.push(`from ${coreFormatDate(f.dateRange.min, dateFormat)}`);
5148
+ if (f.dateRange.max !== null)
5149
+ parts.push(`to ${coreFormatDate(f.dateRange.max, dateFormat)}`);
5150
+ return {
5151
+ column: f.column,
5152
+ valueCount: 1,
5153
+ displayText: parts.join(" "),
5154
+ isRange: true
5155
+ };
5156
+ }
4880
5157
  return {
4881
5158
  column: f.column,
4882
5159
  valueCount: f.values?.length || 0,
@@ -4884,9 +5161,9 @@ function DataGrid({
4884
5161
  isRange: false
4885
5162
  };
4886
5163
  });
4887
- }, [activeFilters]);
4888
- const rows = useMemo13(() => table.getFilteredRowModel().rows, [table, columnFilters]);
4889
- const searchFilteredData = useMemo13(() => {
5164
+ }, [activeFilters, dateFormat]);
5165
+ const rows = useMemo14(() => table.getFilteredRowModel().rows, [table, columnFilters]);
5166
+ const searchFilteredData = useMemo14(() => {
4890
5167
  if (!globalSearchTerm.trim() || !enableSearch) {
4891
5168
  return rows;
4892
5169
  }
@@ -4904,22 +5181,22 @@ function DataGrid({
4904
5181
  });
4905
5182
  }, [rows, globalSearchTerm, enableSearch, columnKeys]);
4906
5183
  const totalSearchedRows = searchFilteredData.length;
4907
- const totalPages = useMemo13(() => {
5184
+ const totalPages = useMemo14(() => {
4908
5185
  if (!enablePagination)
4909
5186
  return 1;
4910
5187
  return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
4911
5188
  }, [enablePagination, totalSearchedRows, pageSize]);
4912
- const paginatedRows = useMemo13(() => {
5189
+ const paginatedRows = useMemo14(() => {
4913
5190
  if (!enablePagination)
4914
5191
  return searchFilteredData;
4915
5192
  const start = (currentPage - 1) * pageSize;
4916
5193
  const end = start + pageSize;
4917
5194
  return searchFilteredData.slice(start, end);
4918
5195
  }, [enablePagination, searchFilteredData, currentPage, pageSize]);
4919
- useEffect10(() => {
5196
+ useEffect11(() => {
4920
5197
  setCurrentPage(1);
4921
5198
  }, [columnFilters, globalSearchTerm]);
4922
- const selectionBounds = useMemo13(() => {
5199
+ const selectionBounds = useMemo14(() => {
4923
5200
  if (!selectionStart || !selectionEnd)
4924
5201
  return null;
4925
5202
  return {
@@ -4929,7 +5206,7 @@ function DataGrid({
4929
5206
  maxCol: Math.max(selectionStart.col, selectionEnd.col)
4930
5207
  };
4931
5208
  }, [selectionStart, selectionEnd]);
4932
- const selectionStats = useMemo13(() => {
5209
+ const selectionStats = useMemo14(() => {
4933
5210
  if (!selectionBounds)
4934
5211
  return null;
4935
5212
  const { minRow, maxRow, minCol, maxCol } = selectionBounds;
@@ -4959,7 +5236,7 @@ function DataGrid({
4959
5236
  const avg = sum / values.length;
4960
5237
  return { count, sum, avg, numericCount: values.length };
4961
5238
  }, [selectionBounds, rows, columnKeys]);
4962
- useEffect10(() => {
5239
+ useEffect11(() => {
4963
5240
  if (typeof document === "undefined")
4964
5241
  return;
4965
5242
  if (displayData.length === 0)
@@ -4983,7 +5260,7 @@ function DataGrid({
4983
5260
  }
4984
5261
  setColumnWidths(widths);
4985
5262
  }, [displayData, columnKeys]);
4986
- const startColumnResize = useCallback13(
5263
+ const startColumnResize = useCallback14(
4987
5264
  (columnId, event) => {
4988
5265
  if (!enableColumnResize)
4989
5266
  return;
@@ -4995,7 +5272,7 @@ function DataGrid({
4995
5272
  },
4996
5273
  [enableColumnResize, columnWidths]
4997
5274
  );
4998
- useEffect10(() => {
5275
+ useEffect11(() => {
4999
5276
  if (!resizingColumnId)
5000
5277
  return;
5001
5278
  const handleResizeMove = (event) => {
@@ -5016,7 +5293,7 @@ function DataGrid({
5016
5293
  document.removeEventListener("mouseup", handleResizeEnd);
5017
5294
  };
5018
5295
  }, [resizingColumnId, resizeStartX, resizeStartWidth]);
5019
- const startVerticalResize = useCallback13(
5296
+ const startVerticalResize = useCallback14(
5020
5297
  (event) => {
5021
5298
  if (!enableVerticalResize)
5022
5299
  return;
@@ -5027,7 +5304,7 @@ function DataGrid({
5027
5304
  },
5028
5305
  [enableVerticalResize, gridHeight]
5029
5306
  );
5030
- useEffect10(() => {
5307
+ useEffect11(() => {
5031
5308
  if (!isResizingVertically)
5032
5309
  return;
5033
5310
  const handleVerticalResizeMove = (event) => {
@@ -5045,7 +5322,7 @@ function DataGrid({
5045
5322
  document.removeEventListener("mouseup", handleVerticalResizeEnd);
5046
5323
  };
5047
5324
  }, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
5048
- const handleExport = useCallback13(() => {
5325
+ const handleExport = useCallback14(() => {
5049
5326
  if (viewMode === "pivot") {
5050
5327
  if (!pivotResult)
5051
5328
  return;
@@ -5091,7 +5368,7 @@ function DataGrid({
5091
5368
  columnKeys,
5092
5369
  onExport
5093
5370
  ]);
5094
- const copySelectionToClipboard = useCallback13(() => {
5371
+ const copySelectionToClipboard = useCallback14(() => {
5095
5372
  if (!selectionBounds || !enableClipboard)
5096
5373
  return;
5097
5374
  const text = formatSelectionForClipboard(
@@ -5116,7 +5393,7 @@ function DataGrid({
5116
5393
  }
5117
5394
  );
5118
5395
  }, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
5119
- const handleMouseDown = useCallback13(
5396
+ const handleMouseDown = useCallback14(
5120
5397
  (rowIndex, colIndex, event) => {
5121
5398
  event.preventDefault();
5122
5399
  if (event.shiftKey && selectedCell) {
@@ -5140,7 +5417,7 @@ function DataGrid({
5140
5417
  },
5141
5418
  [selectedCell, rows, columnKeys, onCellClick]
5142
5419
  );
5143
- const handleMouseEnter = useCallback13(
5420
+ const handleMouseEnter = useCallback14(
5144
5421
  (rowIndex, colIndex) => {
5145
5422
  if (isSelecting) {
5146
5423
  setSelectionEnd({ row: rowIndex, col: colIndex });
@@ -5149,7 +5426,7 @@ function DataGrid({
5149
5426
  [isSelecting]
5150
5427
  );
5151
5428
  const isShowingAIData = aiLoadedData !== null;
5152
- const resetToFullData = useCallback13(async () => {
5429
+ const resetToFullData = useCallback14(async () => {
5153
5430
  if (aiAnalystRef.current?.selectedDataSource) {
5154
5431
  setIsLoadingFullData(true);
5155
5432
  try {
@@ -5170,37 +5447,37 @@ function DataGrid({
5170
5447
  }
5171
5448
  clearAllFilters();
5172
5449
  }, [clearAllFilters]);
5173
- const handleAIDataLoaded = useCallback13(
5450
+ const handleAIDataLoaded = useCallback14(
5174
5451
  (payload) => {
5175
5452
  setAiLoadedData(payload.data);
5176
5453
  onAIDataLoaded?.(payload);
5177
5454
  },
5178
5455
  [onAIDataLoaded]
5179
5456
  );
5180
- const handleAIConversationUpdate = useCallback13(
5457
+ const handleAIConversationUpdate = useCallback14(
5181
5458
  (payload) => {
5182
5459
  onAIConversationUpdate?.(payload);
5183
5460
  },
5184
5461
  [onAIConversationUpdate]
5185
5462
  );
5186
- const handleAIQueryExecuted = useCallback13(
5463
+ const handleAIQueryExecuted = useCallback14(
5187
5464
  (payload) => {
5188
5465
  onAIQueryExecuted?.(payload);
5189
5466
  },
5190
5467
  [onAIQueryExecuted]
5191
5468
  );
5192
- const handleAIError = useCallback13(
5469
+ const handleAIError = useCallback14(
5193
5470
  (payload) => {
5194
5471
  onAIError?.(payload);
5195
5472
  },
5196
5473
  [onAIError]
5197
5474
  );
5198
- useEffect10(() => {
5475
+ useEffect11(() => {
5199
5476
  const handleMouseUp = () => setIsSelecting(false);
5200
5477
  document.addEventListener("mouseup", handleMouseUp);
5201
5478
  return () => document.removeEventListener("mouseup", handleMouseUp);
5202
5479
  }, []);
5203
- useEffect10(() => {
5480
+ useEffect11(() => {
5204
5481
  const handleKeydown = (event) => {
5205
5482
  if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
5206
5483
  event.preventDefault();
@@ -5218,7 +5495,7 @@ function DataGrid({
5218
5495
  document.addEventListener("keydown", handleKeydown);
5219
5496
  return () => document.removeEventListener("keydown", handleKeydown);
5220
5497
  }, [selectionBounds, copySelectionToClipboard]);
5221
- const openFilterDropdown = useCallback13(
5498
+ const openFilterDropdown = useCallback14(
5222
5499
  (columnId, event) => {
5223
5500
  event.stopPropagation();
5224
5501
  const target = event.currentTarget;
@@ -5247,22 +5524,28 @@ function DataGrid({
5247
5524
  },
5248
5525
  []
5249
5526
  );
5250
- const closeFilterDropdown = useCallback13(() => {
5527
+ const closeFilterDropdown = useCallback14(() => {
5251
5528
  setActiveFilterColumn(null);
5252
5529
  }, []);
5253
- const handleFilter = useCallback13(
5530
+ const handleFilter = useCallback14(
5254
5531
  (columnId, values) => {
5255
5532
  setColumnFilter(columnId, values);
5256
5533
  },
5257
5534
  [setColumnFilter]
5258
5535
  );
5259
- const handleRangeFilter = useCallback13(
5536
+ const handleRangeFilter = useCallback14(
5260
5537
  (columnId, range) => {
5261
5538
  setNumericRangeFilter(columnId, range);
5262
5539
  },
5263
5540
  [setNumericRangeFilter]
5264
5541
  );
5265
- const handleSort = useCallback13(
5542
+ const handleDateRangeFilter = useCallback14(
5543
+ (columnId, range) => {
5544
+ setDateRangeFilter(columnId, range);
5545
+ },
5546
+ [setDateRangeFilter]
5547
+ );
5548
+ const handleSort = useCallback14(
5266
5549
  (columnId, direction) => {
5267
5550
  if (direction === null) {
5268
5551
  const current = getSortDirection(columnId);
@@ -5286,7 +5569,7 @@ function DataGrid({
5286
5569
  },
5287
5570
  [getSortDirection, toggleSort]
5288
5571
  );
5289
- const isCellSelected = useCallback13(
5572
+ const isCellSelected = useCallback14(
5290
5573
  (rowIndex, colIndex) => {
5291
5574
  if (!selectionBounds) {
5292
5575
  return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
@@ -5299,10 +5582,7 @@ function DataGrid({
5299
5582
  const formatStatValue = (value) => {
5300
5583
  if (value === null)
5301
5584
  return "-";
5302
- if (Math.abs(value) >= 1e3) {
5303
- return value.toLocaleString("en-US", { maximumFractionDigits: 2 });
5304
- }
5305
- return value.toLocaleString("en-US", { maximumFractionDigits: 4 });
5585
+ return coreFormatNumber(value, numberFormat);
5306
5586
  };
5307
5587
  const noFormatPatterns = /^(?:.*_)?(?:id|code|year|month|quarter|day|week|date|zip|phone|fax|ssn|ein|npi|ndc|gpi|hcpcs|icd|cpt|rx|bin|pcn|group|member|claim|rx_number|script|fill)(?:_.*)?$/i;
5308
5588
  const shouldFormatNumber = (columnId) => {
@@ -5314,68 +5594,71 @@ function DataGrid({
5314
5594
  if (value === "")
5315
5595
  return "";
5316
5596
  const stats = getColumnStats(columnId);
5597
+ if (stats.type === "date") {
5598
+ return coreFormatDate(value, dateFormat);
5599
+ }
5317
5600
  if (stats.type === "number") {
5318
5601
  const num = typeof value === "number" ? value : Number.parseFloat(String(value));
5319
5602
  if (Number.isNaN(num))
5320
5603
  return String(value);
5321
5604
  if (shouldFormatNumber(columnId) && Math.abs(num) >= 1e3) {
5322
- return num.toLocaleString("en-US", { maximumFractionDigits: 2 });
5605
+ return coreFormatNumber(num, numberFormat);
5323
5606
  }
5324
5607
  if (Number.isInteger(num)) {
5325
5608
  return String(num);
5326
5609
  }
5327
- return num.toLocaleString("en-US", { maximumFractionDigits: 4, useGrouping: false });
5610
+ return coreFormatNumber(num, numberFormat, { maximumFractionDigits: 4 });
5328
5611
  }
5329
5612
  return String(value);
5330
5613
  };
5331
- const totalTableWidth = useMemo13(() => {
5614
+ const totalTableWidth = useMemo14(() => {
5332
5615
  return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
5333
5616
  }, [columnKeys, columnWidths]);
5334
5617
  const activeFilterCount = columnFilters.length;
5335
- return /* @__PURE__ */ jsxs8(
5618
+ return /* @__PURE__ */ jsxs9(
5336
5619
  "div",
5337
5620
  {
5338
5621
  className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
5339
5622
  style: { height: `${gridHeight}px` },
5340
5623
  children: [
5341
- showCopyToast && /* @__PURE__ */ jsxs8("div", { className: "vpg-toast", children: [
5342
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
5624
+ showCopyToast && /* @__PURE__ */ jsxs9("div", { className: "vpg-toast", children: [
5625
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
5343
5626
  copyToastMessage
5344
5627
  ] }),
5345
- /* @__PURE__ */ jsxs8("div", { className: "vpg-toolbar", children: [
5346
- /* @__PURE__ */ jsxs8("div", { className: "vpg-toolbar-left", children: [
5347
- showPivot && /* @__PURE__ */ jsxs8("div", { className: "vpg-view-toggle", children: [
5348
- showAIAnalyst && /* @__PURE__ */ jsxs8(
5628
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-toolbar", children: [
5629
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-toolbar-left", children: [
5630
+ showPivot && /* @__PURE__ */ jsxs9("div", { className: "vpg-view-toggle", children: [
5631
+ showAIAnalyst && /* @__PURE__ */ jsxs9(
5349
5632
  "button",
5350
5633
  {
5351
5634
  className: `vpg-view-btn vpg-ai-btn ${viewMode === "ai" ? "active" : ""}`,
5352
5635
  onClick: () => setViewMode("ai"),
5353
5636
  children: [
5354
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z" }) }),
5637
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z" }) }),
5355
5638
  "AI Analyst"
5356
5639
  ]
5357
5640
  }
5358
5641
  ),
5359
- aiAnalyst?.enabled && !canUseAIAnalyst && /* @__PURE__ */ jsxs8(
5642
+ aiAnalyst?.enabled && !canUseAIAnalyst && /* @__PURE__ */ jsxs9(
5360
5643
  "button",
5361
5644
  {
5362
5645
  className: "vpg-view-btn vpg-ai-btn vpg-pro-feature",
5363
5646
  title: "AI Analyst (Pro feature)",
5364
5647
  onClick: (e) => e.preventDefault(),
5365
5648
  children: [
5366
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z" }) }),
5649
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z" }) }),
5367
5650
  "AI Analyst",
5368
- /* @__PURE__ */ jsx8("span", { className: "vpg-pro-badge", children: "Pro" })
5651
+ /* @__PURE__ */ jsx9("span", { className: "vpg-pro-badge", children: "Pro" })
5369
5652
  ]
5370
5653
  }
5371
5654
  ),
5372
- /* @__PURE__ */ jsxs8(
5655
+ /* @__PURE__ */ jsxs9(
5373
5656
  "button",
5374
5657
  {
5375
5658
  className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
5376
5659
  onClick: () => setViewMode("grid"),
5377
5660
  children: [
5378
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5661
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5379
5662
  "path",
5380
5663
  {
5381
5664
  strokeLinecap: "round",
@@ -5388,13 +5671,13 @@ function DataGrid({
5388
5671
  ]
5389
5672
  }
5390
5673
  ),
5391
- /* @__PURE__ */ jsxs8(
5674
+ /* @__PURE__ */ jsxs9(
5392
5675
  "button",
5393
5676
  {
5394
5677
  className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
5395
5678
  onClick: () => setViewMode("pivot"),
5396
5679
  children: [
5397
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5680
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5398
5681
  "path",
5399
5682
  {
5400
5683
  strokeLinecap: "round",
@@ -5407,14 +5690,14 @@ function DataGrid({
5407
5690
  ]
5408
5691
  }
5409
5692
  ),
5410
- /* @__PURE__ */ jsxs8(
5693
+ /* @__PURE__ */ jsxs9(
5411
5694
  "button",
5412
5695
  {
5413
5696
  className: `vpg-view-btn vpg-chart-btn ${viewMode === "chart" ? "active" : ""} ${!canUseCharts ? "vpg-pro-feature" : ""}`,
5414
5697
  title: canUseCharts ? "Chart Builder" : "Chart Builder (Pro feature)",
5415
5698
  onClick: () => canUseCharts && setViewMode("chart"),
5416
5699
  children: [
5417
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5700
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5418
5701
  "path",
5419
5702
  {
5420
5703
  strokeLinecap: "round",
@@ -5424,19 +5707,19 @@ function DataGrid({
5424
5707
  }
5425
5708
  ) }),
5426
5709
  "Chart",
5427
- !canUseCharts && /* @__PURE__ */ jsx8("span", { className: "vpg-pro-badge", children: "Pro" })
5710
+ !canUseCharts && /* @__PURE__ */ jsx9("span", { className: "vpg-pro-badge", children: "Pro" })
5428
5711
  ]
5429
5712
  }
5430
5713
  )
5431
5714
  ] }),
5432
- viewMode === "grid" && /* @__PURE__ */ jsxs8(Fragment6, { children: [
5433
- enableSearch && /* @__PURE__ */ jsx8("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx8(
5715
+ viewMode === "grid" && /* @__PURE__ */ jsxs9(Fragment6, { children: [
5716
+ enableSearch && /* @__PURE__ */ jsx9("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx9(
5434
5717
  "button",
5435
5718
  {
5436
5719
  className: "vpg-icon-btn",
5437
5720
  title: "Search (Ctrl+F)",
5438
5721
  onClick: () => setShowSearchInput(true),
5439
- children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5722
+ children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5440
5723
  "path",
5441
5724
  {
5442
5725
  strokeLinecap: "round",
@@ -5446,15 +5729,15 @@ function DataGrid({
5446
5729
  }
5447
5730
  ) })
5448
5731
  }
5449
- ) : /* @__PURE__ */ jsxs8("div", { className: "vpg-search-box", children: [
5450
- /* @__PURE__ */ jsx8(
5732
+ ) : /* @__PURE__ */ jsxs9("div", { className: "vpg-search-box", children: [
5733
+ /* @__PURE__ */ jsx9(
5451
5734
  "svg",
5452
5735
  {
5453
5736
  className: "vpg-search-icon",
5454
5737
  fill: "none",
5455
5738
  stroke: "currentColor",
5456
5739
  viewBox: "0 0 24 24",
5457
- children: /* @__PURE__ */ jsx8(
5740
+ children: /* @__PURE__ */ jsx9(
5458
5741
  "path",
5459
5742
  {
5460
5743
  strokeLinecap: "round",
@@ -5465,7 +5748,7 @@ function DataGrid({
5465
5748
  )
5466
5749
  }
5467
5750
  ),
5468
- /* @__PURE__ */ jsx8(
5751
+ /* @__PURE__ */ jsx9(
5469
5752
  "input",
5470
5753
  {
5471
5754
  type: "text",
@@ -5482,14 +5765,14 @@ function DataGrid({
5482
5765
  autoFocus: true
5483
5766
  }
5484
5767
  ),
5485
- globalSearchTerm && /* @__PURE__ */ jsx8("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx8(
5768
+ globalSearchTerm && /* @__PURE__ */ jsx9("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx9(
5486
5769
  "svg",
5487
5770
  {
5488
5771
  className: "vpg-icon-xs",
5489
5772
  fill: "none",
5490
5773
  stroke: "currentColor",
5491
5774
  viewBox: "0 0 24 24",
5492
- children: /* @__PURE__ */ jsx8(
5775
+ children: /* @__PURE__ */ jsx9(
5493
5776
  "path",
5494
5777
  {
5495
5778
  strokeLinecap: "round",
@@ -5501,9 +5784,9 @@ function DataGrid({
5501
5784
  }
5502
5785
  ) })
5503
5786
  ] }) }),
5504
- /* @__PURE__ */ jsxs8("div", { className: "vpg-font-size-control", children: [
5505
- /* @__PURE__ */ jsx8("span", { className: "vpg-label", children: "Size:" }),
5506
- /* @__PURE__ */ jsx8("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx8(
5787
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-font-size-control", children: [
5788
+ /* @__PURE__ */ jsx9("span", { className: "vpg-label", children: "Size:" }),
5789
+ /* @__PURE__ */ jsx9("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx9(
5507
5790
  "button",
5508
5791
  {
5509
5792
  className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
@@ -5513,8 +5796,8 @@ function DataGrid({
5513
5796
  opt.value
5514
5797
  )) })
5515
5798
  ] }),
5516
- activeFilterCount > 0 && /* @__PURE__ */ jsxs8("div", { className: "vpg-filter-info", children: [
5517
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx8(
5799
+ activeFilterCount > 0 && /* @__PURE__ */ jsxs9("div", { className: "vpg-filter-info", children: [
5800
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx9(
5518
5801
  "path",
5519
5802
  {
5520
5803
  fillRule: "evenodd",
@@ -5522,28 +5805,28 @@ function DataGrid({
5522
5805
  clipRule: "evenodd"
5523
5806
  }
5524
5807
  ) }),
5525
- /* @__PURE__ */ jsxs8("span", { children: [
5808
+ /* @__PURE__ */ jsxs9("span", { children: [
5526
5809
  activeFilterCount,
5527
5810
  " ",
5528
5811
  "filter",
5529
5812
  activeFilterCount > 1 ? "s" : ""
5530
5813
  ] })
5531
5814
  ] }),
5532
- globalSearchTerm && /* @__PURE__ */ jsx8("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs8("span", { children: [
5815
+ globalSearchTerm && /* @__PURE__ */ jsx9("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs9("span", { children: [
5533
5816
  totalSearchedRows,
5534
5817
  " ",
5535
5818
  "match",
5536
5819
  totalSearchedRows !== 1 ? "es" : ""
5537
5820
  ] }) })
5538
5821
  ] }),
5539
- viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs8(Fragment6, { children: [
5540
- /* @__PURE__ */ jsxs8(
5822
+ viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs9(Fragment6, { children: [
5823
+ /* @__PURE__ */ jsxs9(
5541
5824
  "button",
5542
5825
  {
5543
5826
  className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
5544
5827
  onClick: () => setShowPivotConfig(!showPivotConfig),
5545
5828
  children: [
5546
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5829
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5547
5830
  "path",
5548
5831
  {
5549
5832
  strokeLinecap: "round",
@@ -5558,8 +5841,8 @@ function DataGrid({
5558
5841
  ]
5559
5842
  }
5560
5843
  ),
5561
- pivotIsConfigured && /* @__PURE__ */ jsxs8("div", { className: "vpg-pivot-status", children: [
5562
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx8(
5844
+ pivotIsConfigured && /* @__PURE__ */ jsxs9("div", { className: "vpg-pivot-status", children: [
5845
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx9(
5563
5846
  "path",
5564
5847
  {
5565
5848
  fillRule: "evenodd",
@@ -5567,13 +5850,13 @@ function DataGrid({
5567
5850
  clipRule: "evenodd"
5568
5851
  }
5569
5852
  ) }),
5570
- /* @__PURE__ */ jsx8("span", { children: "Pivot configured" })
5853
+ /* @__PURE__ */ jsx9("span", { children: "Pivot configured" })
5571
5854
  ] })
5572
5855
  ] })
5573
5856
  ] }),
5574
- /* @__PURE__ */ jsxs8("div", { className: "vpg-toolbar-right", children: [
5575
- viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs8("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
5576
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5857
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-toolbar-right", children: [
5858
+ viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs9("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
5859
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5577
5860
  "path",
5578
5861
  {
5579
5862
  strokeLinecap: "round",
@@ -5584,7 +5867,7 @@ function DataGrid({
5584
5867
  ) }),
5585
5868
  "Clear Filters"
5586
5869
  ] }),
5587
- viewMode === "grid" && isShowingAIData && /* @__PURE__ */ jsxs8(
5870
+ viewMode === "grid" && isShowingAIData && /* @__PURE__ */ jsxs9(
5588
5871
  "button",
5589
5872
  {
5590
5873
  className: `vpg-reset-data-btn${isLoadingFullData ? " vpg-loading-btn" : ""}`,
@@ -5592,7 +5875,7 @@ function DataGrid({
5592
5875
  title: "Reset to full dataset",
5593
5876
  onClick: resetToFullData,
5594
5877
  children: [
5595
- /* @__PURE__ */ jsx8("svg", { className: `vpg-icon${isLoadingFullData ? " vpg-spin" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5878
+ /* @__PURE__ */ jsx9("svg", { className: `vpg-icon${isLoadingFullData ? " vpg-spin" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5596
5879
  "path",
5597
5880
  {
5598
5881
  strokeLinecap: "round",
@@ -5601,17 +5884,17 @@ function DataGrid({
5601
5884
  d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
5602
5885
  }
5603
5886
  ) }),
5604
- /* @__PURE__ */ jsx8("span", { children: isLoadingFullData ? "Loading..." : "Full Data" })
5887
+ /* @__PURE__ */ jsx9("span", { children: isLoadingFullData ? "Loading..." : "Full Data" })
5605
5888
  ]
5606
5889
  }
5607
5890
  ),
5608
- enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx8(
5891
+ enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx9(
5609
5892
  "button",
5610
5893
  {
5611
5894
  className: "vpg-icon-btn",
5612
5895
  title: "Copy selection (Ctrl+C)",
5613
5896
  onClick: copySelectionToClipboard,
5614
- children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5897
+ children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5615
5898
  "path",
5616
5899
  {
5617
5900
  strokeLinecap: "round",
@@ -5622,14 +5905,14 @@ function DataGrid({
5622
5905
  ) })
5623
5906
  }
5624
5907
  ),
5625
- enableExport && viewMode === "grid" && /* @__PURE__ */ jsxs8(
5908
+ enableExport && viewMode === "grid" && /* @__PURE__ */ jsxs9(
5626
5909
  "button",
5627
5910
  {
5628
5911
  className: "vpg-export-btn",
5629
5912
  title: "Export to CSV",
5630
5913
  onClick: handleExport,
5631
5914
  children: [
5632
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5915
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5633
5916
  "path",
5634
5917
  {
5635
5918
  strokeLinecap: "round",
@@ -5642,7 +5925,7 @@ function DataGrid({
5642
5925
  ]
5643
5926
  }
5644
5927
  ),
5645
- enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ jsxs8(
5928
+ enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ jsxs9(
5646
5929
  "button",
5647
5930
  {
5648
5931
  className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
@@ -5650,7 +5933,7 @@ function DataGrid({
5650
5933
  title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
5651
5934
  onClick: () => isPro && handleExport(),
5652
5935
  children: [
5653
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5936
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5654
5937
  "path",
5655
5938
  {
5656
5939
  strokeLinecap: "round",
@@ -5666,7 +5949,7 @@ function DataGrid({
5666
5949
  )
5667
5950
  ] })
5668
5951
  ] }),
5669
- showAIAnalyst && aiAnalyst && /* @__PURE__ */ jsx8("div", { className: "vpg-ai-view", style: { display: viewMode === "ai" ? void 0 : "none" }, children: /* @__PURE__ */ jsx8(
5952
+ showAIAnalyst && aiAnalyst && /* @__PURE__ */ jsx9("div", { className: "vpg-ai-view", style: { display: viewMode === "ai" ? void 0 : "none" }, children: /* @__PURE__ */ jsx9(
5670
5953
  AIAnalyst,
5671
5954
  {
5672
5955
  ref: aiAnalystRef,
@@ -5678,13 +5961,13 @@ function DataGrid({
5678
5961
  onError: handleAIError
5679
5962
  }
5680
5963
  ) }),
5681
- viewMode === "grid" && /* @__PURE__ */ jsxs8("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
5682
- loading && /* @__PURE__ */ jsxs8("div", { className: "vpg-loading", children: [
5683
- /* @__PURE__ */ jsx8("div", { className: "vpg-spinner" }),
5684
- /* @__PURE__ */ jsx8("span", { children: "Loading data..." })
5964
+ viewMode === "grid" && /* @__PURE__ */ jsxs9("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
5965
+ loading && /* @__PURE__ */ jsxs9("div", { className: "vpg-loading", children: [
5966
+ /* @__PURE__ */ jsx9("div", { className: "vpg-spinner" }),
5967
+ /* @__PURE__ */ jsx9("span", { children: "Loading data..." })
5685
5968
  ] }),
5686
- !loading && displayData.length === 0 && /* @__PURE__ */ jsxs8("div", { className: "vpg-empty", children: [
5687
- /* @__PURE__ */ jsx8("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5969
+ !loading && displayData.length === 0 && /* @__PURE__ */ jsxs9("div", { className: "vpg-empty", children: [
5970
+ /* @__PURE__ */ jsx9("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5688
5971
  "path",
5689
5972
  {
5690
5973
  strokeLinecap: "round",
@@ -5693,10 +5976,10 @@ function DataGrid({
5693
5976
  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"
5694
5977
  }
5695
5978
  ) }) }),
5696
- /* @__PURE__ */ jsx8("span", { children: "No data available" })
5979
+ /* @__PURE__ */ jsx9("span", { children: "No data available" })
5697
5980
  ] }),
5698
- !loading && displayData.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs8("div", { className: "vpg-empty", children: [
5699
- /* @__PURE__ */ jsx8("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
5981
+ !loading && displayData.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs9("div", { className: "vpg-empty", children: [
5982
+ /* @__PURE__ */ jsx9("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5700
5983
  "path",
5701
5984
  {
5702
5985
  strokeLinecap: "round",
@@ -5705,11 +5988,11 @@ function DataGrid({
5705
5988
  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"
5706
5989
  }
5707
5990
  ) }) }),
5708
- /* @__PURE__ */ jsx8("span", { children: "No matching records" }),
5709
- /* @__PURE__ */ jsx8("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
5991
+ /* @__PURE__ */ jsx9("span", { children: "No matching records" }),
5992
+ /* @__PURE__ */ jsx9("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
5710
5993
  ] }),
5711
- !loading && filteredRowCount > 0 && /* @__PURE__ */ jsx8("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs8("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
5712
- /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsx8("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ jsxs8(
5994
+ !loading && filteredRowCount > 0 && /* @__PURE__ */ jsx9("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs9("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
5995
+ /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsx9("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ jsxs9(
5713
5996
  "th",
5714
5997
  {
5715
5998
  className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
@@ -5724,16 +6007,16 @@ function DataGrid({
5724
6007
  }
5725
6008
  },
5726
6009
  children: [
5727
- /* @__PURE__ */ jsxs8("div", { className: "vpg-header-content", children: [
5728
- /* @__PURE__ */ jsx8("span", { className: "vpg-header-text", children: colId }),
5729
- /* @__PURE__ */ jsxs8("div", { className: "vpg-header-icons", children: [
5730
- getSortDirection(colId) && /* @__PURE__ */ jsx8("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx8(
6010
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-header-content", children: [
6011
+ /* @__PURE__ */ jsx9("span", { className: "vpg-header-text", children: colId }),
6012
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-header-icons", children: [
6013
+ getSortDirection(colId) && /* @__PURE__ */ jsx9("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx9(
5731
6014
  "svg",
5732
6015
  {
5733
6016
  className: "vpg-icon-sm",
5734
6017
  fill: "currentColor",
5735
6018
  viewBox: "0 0 20 20",
5736
- children: /* @__PURE__ */ jsx8(
6019
+ children: /* @__PURE__ */ jsx9(
5737
6020
  "path",
5738
6021
  {
5739
6022
  fillRule: "evenodd",
@@ -5742,13 +6025,13 @@ function DataGrid({
5742
6025
  }
5743
6026
  )
5744
6027
  }
5745
- ) : /* @__PURE__ */ jsx8(
6028
+ ) : /* @__PURE__ */ jsx9(
5746
6029
  "svg",
5747
6030
  {
5748
6031
  className: "vpg-icon-sm",
5749
6032
  fill: "currentColor",
5750
6033
  viewBox: "0 0 20 20",
5751
- children: /* @__PURE__ */ jsx8(
6034
+ children: /* @__PURE__ */ jsx9(
5752
6035
  "path",
5753
6036
  {
5754
6037
  fillRule: "evenodd",
@@ -5758,13 +6041,13 @@ function DataGrid({
5758
6041
  )
5759
6042
  }
5760
6043
  ) }),
5761
- hasActiveFilter(colId) && /* @__PURE__ */ jsx8("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx8(
6044
+ hasActiveFilter(colId) && /* @__PURE__ */ jsx9("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx9(
5762
6045
  "svg",
5763
6046
  {
5764
6047
  className: "vpg-icon-xs",
5765
6048
  fill: "currentColor",
5766
6049
  viewBox: "0 0 20 20",
5767
- children: /* @__PURE__ */ jsx8(
6050
+ children: /* @__PURE__ */ jsx9(
5768
6051
  "path",
5769
6052
  {
5770
6053
  fillRule: "evenodd",
@@ -5774,14 +6057,14 @@ function DataGrid({
5774
6057
  )
5775
6058
  }
5776
6059
  ) }),
5777
- /* @__PURE__ */ jsx8("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx8(
6060
+ /* @__PURE__ */ jsx9("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx9(
5778
6061
  "svg",
5779
6062
  {
5780
6063
  className: "vpg-icon-sm",
5781
6064
  fill: "none",
5782
6065
  stroke: "currentColor",
5783
6066
  viewBox: "0 0 24 24",
5784
- children: /* @__PURE__ */ jsx8(
6067
+ children: /* @__PURE__ */ jsx9(
5785
6068
  "path",
5786
6069
  {
5787
6070
  strokeLinecap: "round",
@@ -5794,7 +6077,7 @@ function DataGrid({
5794
6077
  ) })
5795
6078
  ] })
5796
6079
  ] }),
5797
- enableColumnResize && /* @__PURE__ */ jsx8(
6080
+ enableColumnResize && /* @__PURE__ */ jsx9(
5798
6081
  "div",
5799
6082
  {
5800
6083
  className: "vpg-resize-handle",
@@ -5805,7 +6088,7 @@ function DataGrid({
5805
6088
  },
5806
6089
  colId
5807
6090
  )) }) }),
5808
- /* @__PURE__ */ jsx8("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx8("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx8(
6091
+ /* @__PURE__ */ jsx9("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx9("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx9(
5809
6092
  "td",
5810
6093
  {
5811
6094
  className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
@@ -5823,8 +6106,8 @@ function DataGrid({
5823
6106
  )) }, row.id)) })
5824
6107
  ] }) })
5825
6108
  ] }),
5826
- viewMode === "pivot" && /* @__PURE__ */ jsxs8("div", { className: "vpg-pivot-container", children: [
5827
- showPivotConfig && canUsePivot && /* @__PURE__ */ jsx8("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx8(
6109
+ viewMode === "pivot" && /* @__PURE__ */ jsxs9("div", { className: "vpg-pivot-container", children: [
6110
+ showPivotConfig && canUsePivot && /* @__PURE__ */ jsx9("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx9(
5828
6111
  PivotConfig,
5829
6112
  {
5830
6113
  availableFields: pivotAvailableFields,
@@ -5852,7 +6135,7 @@ function DataGrid({
5852
6135
  onUpdateCalculatedField: addCalculatedField
5853
6136
  }
5854
6137
  ) }),
5855
- /* @__PURE__ */ jsx8("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx8(
6138
+ /* @__PURE__ */ jsx9("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx9(
5856
6139
  PivotSkeleton,
5857
6140
  {
5858
6141
  rowFields: pivotRowFields,
@@ -5878,10 +6161,10 @@ function DataGrid({
5878
6161
  }
5879
6162
  ) })
5880
6163
  ] }),
5881
- viewMode === "chart" && /* @__PURE__ */ jsxs8("div", { className: "vpg-chart-view", children: [
5882
- activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ jsxs8("div", { className: "vpg-chart-filter-bar", children: [
5883
- /* @__PURE__ */ jsx8("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx8("path", { fillRule: "evenodd", d: "M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z", clipRule: "evenodd" }) }),
5884
- /* @__PURE__ */ jsxs8("span", { children: [
6164
+ viewMode === "chart" && /* @__PURE__ */ jsxs9("div", { className: "vpg-chart-view", children: [
6165
+ activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "vpg-chart-filter-bar", children: [
6166
+ /* @__PURE__ */ jsx9("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx9("path", { fillRule: "evenodd", d: "M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z", clipRule: "evenodd" }) }),
6167
+ /* @__PURE__ */ jsxs9("span", { children: [
5885
6168
  "Chart showing",
5886
6169
  filteredRowCount.toLocaleString(),
5887
6170
  " ",
@@ -5890,9 +6173,9 @@ function DataGrid({
5890
6173
  " ",
5891
6174
  "records"
5892
6175
  ] }),
5893
- /* @__PURE__ */ jsx8("button", { className: "vpg-chart-clear-filters", onClick: clearAllFilters, children: "Clear filters" })
6176
+ /* @__PURE__ */ jsx9("button", { className: "vpg-chart-clear-filters", onClick: clearAllFilters, children: "Clear filters" })
5894
6177
  ] }),
5895
- /* @__PURE__ */ jsx8(
6178
+ /* @__PURE__ */ jsx9(
5896
6179
  ChartBuilder,
5897
6180
  {
5898
6181
  data: filteredDataForPivot,
@@ -5901,55 +6184,55 @@ function DataGrid({
5901
6184
  }
5902
6185
  )
5903
6186
  ] }),
5904
- /* @__PURE__ */ jsxs8("div", { className: "vpg-footer", children: [
5905
- /* @__PURE__ */ jsx8("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
5906
- /* @__PURE__ */ jsxs8("span", { children: [
6187
+ /* @__PURE__ */ jsxs9("div", { className: "vpg-footer", children: [
6188
+ /* @__PURE__ */ jsx9("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
6189
+ /* @__PURE__ */ jsxs9("span", { children: [
5907
6190
  ((currentPage - 1) * pageSize + 1).toLocaleString(),
5908
6191
  "-",
5909
6192
  Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
5910
6193
  ] }),
5911
- /* @__PURE__ */ jsx8("span", { className: "vpg-separator", children: "of" }),
5912
- /* @__PURE__ */ jsx8("span", { children: totalSearchedRows.toLocaleString() }),
5913
- totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs8("span", { className: "vpg-filtered-note", children: [
6194
+ /* @__PURE__ */ jsx9("span", { className: "vpg-separator", children: "of" }),
6195
+ /* @__PURE__ */ jsx9("span", { children: totalSearchedRows.toLocaleString() }),
6196
+ totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs9("span", { className: "vpg-filtered-note", children: [
5914
6197
  "(",
5915
6198
  totalRowCount.toLocaleString(),
5916
6199
  " ",
5917
6200
  "total)"
5918
6201
  ] })
5919
- ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs8("span", { children: [
6202
+ ] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs9("span", { children: [
5920
6203
  totalRowCount.toLocaleString(),
5921
6204
  " ",
5922
6205
  "records"
5923
- ] }) : /* @__PURE__ */ jsxs8(Fragment6, { children: [
5924
- /* @__PURE__ */ jsx8("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
5925
- /* @__PURE__ */ jsx8("span", { className: "vpg-separator", children: "of" }),
5926
- /* @__PURE__ */ jsx8("span", { children: totalRowCount.toLocaleString() }),
5927
- /* @__PURE__ */ jsx8("span", { className: "vpg-separator", children: "records" })
5928
- ] }) : viewMode === "pivot" ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
5929
- /* @__PURE__ */ jsx8("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
5930
- /* @__PURE__ */ jsx8("span", { className: "vpg-separator", children: "\u2022" }),
5931
- /* @__PURE__ */ jsxs8("span", { children: [
6206
+ ] }) : /* @__PURE__ */ jsxs9(Fragment6, { children: [
6207
+ /* @__PURE__ */ jsx9("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
6208
+ /* @__PURE__ */ jsx9("span", { className: "vpg-separator", children: "of" }),
6209
+ /* @__PURE__ */ jsx9("span", { children: totalRowCount.toLocaleString() }),
6210
+ /* @__PURE__ */ jsx9("span", { className: "vpg-separator", children: "records" })
6211
+ ] }) : viewMode === "pivot" ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
6212
+ /* @__PURE__ */ jsx9("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
6213
+ /* @__PURE__ */ jsx9("span", { className: "vpg-separator", children: "\u2022" }),
6214
+ /* @__PURE__ */ jsxs9("span", { children: [
5932
6215
  totalRowCount.toLocaleString(),
5933
6216
  " ",
5934
6217
  "source records"
5935
6218
  ] })
5936
- ] }) : /* @__PURE__ */ jsxs8(Fragment6, { children: [
5937
- /* @__PURE__ */ jsx8("span", { className: "vpg-chart-label", children: "Chart Builder" }),
5938
- /* @__PURE__ */ jsx8("span", { className: "vpg-separator", children: "\u2022" }),
5939
- /* @__PURE__ */ jsxs8("span", { children: [
6219
+ ] }) : /* @__PURE__ */ jsxs9(Fragment6, { children: [
6220
+ /* @__PURE__ */ jsx9("span", { className: "vpg-chart-label", children: "Chart Builder" }),
6221
+ /* @__PURE__ */ jsx9("span", { className: "vpg-separator", children: "\u2022" }),
6222
+ /* @__PURE__ */ jsxs9("span", { children: [
5940
6223
  totalRowCount.toLocaleString(),
5941
6224
  " ",
5942
6225
  "records"
5943
6226
  ] })
5944
6227
  ] }) }),
5945
- enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs8("div", { className: "vpg-pagination", children: [
5946
- /* @__PURE__ */ jsx8(
6228
+ enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "vpg-pagination", children: [
6229
+ /* @__PURE__ */ jsx9(
5947
6230
  "button",
5948
6231
  {
5949
6232
  className: "vpg-page-btn",
5950
6233
  disabled: currentPage === 1,
5951
6234
  onClick: () => setCurrentPage(1),
5952
- children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
6235
+ children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5953
6236
  "path",
5954
6237
  {
5955
6238
  strokeLinecap: "round",
@@ -5960,13 +6243,13 @@ function DataGrid({
5960
6243
  ) })
5961
6244
  }
5962
6245
  ),
5963
- /* @__PURE__ */ jsx8(
6246
+ /* @__PURE__ */ jsx9(
5964
6247
  "button",
5965
6248
  {
5966
6249
  className: "vpg-page-btn",
5967
6250
  disabled: currentPage === 1,
5968
6251
  onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
5969
- children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
6252
+ children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5970
6253
  "path",
5971
6254
  {
5972
6255
  strokeLinecap: "round",
@@ -5977,7 +6260,7 @@ function DataGrid({
5977
6260
  ) })
5978
6261
  }
5979
6262
  ),
5980
- /* @__PURE__ */ jsxs8("span", { className: "vpg-page-info", children: [
6263
+ /* @__PURE__ */ jsxs9("span", { className: "vpg-page-info", children: [
5981
6264
  "Page",
5982
6265
  " ",
5983
6266
  currentPage,
@@ -5986,13 +6269,13 @@ function DataGrid({
5986
6269
  " ",
5987
6270
  totalPages
5988
6271
  ] }),
5989
- /* @__PURE__ */ jsx8(
6272
+ /* @__PURE__ */ jsx9(
5990
6273
  "button",
5991
6274
  {
5992
6275
  className: "vpg-page-btn",
5993
6276
  disabled: currentPage === totalPages,
5994
6277
  onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
5995
- children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
6278
+ children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
5996
6279
  "path",
5997
6280
  {
5998
6281
  strokeLinecap: "round",
@@ -6003,13 +6286,13 @@ function DataGrid({
6003
6286
  ) })
6004
6287
  }
6005
6288
  ),
6006
- /* @__PURE__ */ jsx8(
6289
+ /* @__PURE__ */ jsx9(
6007
6290
  "button",
6008
6291
  {
6009
6292
  className: "vpg-page-btn",
6010
6293
  disabled: currentPage === totalPages,
6011
6294
  onClick: () => setCurrentPage(totalPages),
6012
- children: /* @__PURE__ */ jsx8("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8(
6295
+ children: /* @__PURE__ */ jsx9("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9(
6013
6296
  "path",
6014
6297
  {
6015
6298
  strokeLinecap: "round",
@@ -6021,45 +6304,45 @@ function DataGrid({
6021
6304
  }
6022
6305
  )
6023
6306
  ] }),
6024
- viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs8("div", { className: "vpg-selection-stats", children: [
6025
- /* @__PURE__ */ jsxs8("span", { className: "vpg-stat", children: [
6026
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-label", children: "Count:" }),
6027
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-value", children: selectionStats.count })
6307
+ viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs9("div", { className: "vpg-selection-stats", children: [
6308
+ /* @__PURE__ */ jsxs9("span", { className: "vpg-stat", children: [
6309
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-label", children: "Count:" }),
6310
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-value", children: selectionStats.count })
6028
6311
  ] }),
6029
- selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs8(Fragment6, { children: [
6030
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-divider", children: "|" }),
6031
- /* @__PURE__ */ jsxs8("span", { className: "vpg-stat", children: [
6032
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-label", children: "Sum:" }),
6033
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
6312
+ selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs9(Fragment6, { children: [
6313
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-divider", children: "|" }),
6314
+ /* @__PURE__ */ jsxs9("span", { className: "vpg-stat", children: [
6315
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-label", children: "Sum:" }),
6316
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
6034
6317
  ] }),
6035
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-divider", children: "|" }),
6036
- /* @__PURE__ */ jsxs8("span", { className: "vpg-stat", children: [
6037
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-label", children: "Avg:" }),
6038
- /* @__PURE__ */ jsx8("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
6318
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-divider", children: "|" }),
6319
+ /* @__PURE__ */ jsxs9("span", { className: "vpg-stat", children: [
6320
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-label", children: "Avg:" }),
6321
+ /* @__PURE__ */ jsx9("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
6039
6322
  ] })
6040
6323
  ] })
6041
6324
  ] }),
6042
- /* @__PURE__ */ jsx8("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs8("div", { className: "vpg-demo-banner", children: [
6043
- /* @__PURE__ */ jsx8("span", { className: "vpg-demo-badge", children: "DEMO" }),
6044
- /* @__PURE__ */ jsx8("span", { children: "Pro features enabled" }),
6045
- /* @__PURE__ */ jsx8("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
6046
- ] }) : showWatermark ? /* @__PURE__ */ jsx8("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs8("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
6047
- /* @__PURE__ */ jsxs8("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: [
6048
- /* @__PURE__ */ jsx8("rect", { x: "3", y: "3", width: "7", height: "7" }),
6049
- /* @__PURE__ */ jsx8("rect", { x: "14", y: "3", width: "7", height: "7" }),
6050
- /* @__PURE__ */ jsx8("rect", { x: "14", y: "14", width: "7", height: "7" }),
6051
- /* @__PURE__ */ jsx8("rect", { x: "3", y: "14", width: "7", height: "7" })
6325
+ /* @__PURE__ */ jsx9("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs9("div", { className: "vpg-demo-banner", children: [
6326
+ /* @__PURE__ */ jsx9("span", { className: "vpg-demo-badge", children: "DEMO" }),
6327
+ /* @__PURE__ */ jsx9("span", { children: "Pro features enabled" }),
6328
+ /* @__PURE__ */ jsx9("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
6329
+ ] }) : showWatermark ? /* @__PURE__ */ jsx9("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs9("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
6330
+ /* @__PURE__ */ jsxs9("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: [
6331
+ /* @__PURE__ */ jsx9("rect", { x: "3", y: "3", width: "7", height: "7" }),
6332
+ /* @__PURE__ */ jsx9("rect", { x: "14", y: "3", width: "7", height: "7" }),
6333
+ /* @__PURE__ */ jsx9("rect", { x: "14", y: "14", width: "7", height: "7" }),
6334
+ /* @__PURE__ */ jsx9("rect", { x: "3", y: "14", width: "7", height: "7" })
6052
6335
  ] }),
6053
6336
  "Powered by TinyPivot"
6054
6337
  ] }) }) : null })
6055
6338
  ] }),
6056
- enableVerticalResize && /* @__PURE__ */ jsx8("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs8("div", { className: "vpg-resize-grip", children: [
6057
- /* @__PURE__ */ jsx8("span", {}),
6058
- /* @__PURE__ */ jsx8("span", {}),
6059
- /* @__PURE__ */ jsx8("span", {})
6339
+ enableVerticalResize && /* @__PURE__ */ jsx9("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs9("div", { className: "vpg-resize-grip", children: [
6340
+ /* @__PURE__ */ jsx9("span", {}),
6341
+ /* @__PURE__ */ jsx9("span", {}),
6342
+ /* @__PURE__ */ jsx9("span", {})
6060
6343
  ] }) }),
6061
6344
  activeFilterColumn && typeof document !== "undefined" && createPortal2(
6062
- /* @__PURE__ */ jsx8(
6345
+ /* @__PURE__ */ jsx9(
6063
6346
  "div",
6064
6347
  {
6065
6348
  className: "vpg-filter-portal",
@@ -6070,7 +6353,7 @@ function DataGrid({
6070
6353
  maxHeight: `${filterDropdownPosition.maxHeight}px`,
6071
6354
  zIndex: 9999
6072
6355
  },
6073
- children: /* @__PURE__ */ jsx8(
6356
+ children: /* @__PURE__ */ jsx9(
6074
6357
  ColumnFilter,
6075
6358
  {
6076
6359
  columnId: activeFilterColumn,
@@ -6079,8 +6362,12 @@ function DataGrid({
6079
6362
  selectedValues: getColumnFilterValues(activeFilterColumn),
6080
6363
  sortDirection: getSortDirection(activeFilterColumn),
6081
6364
  numericRange: getNumericRangeFilter(activeFilterColumn),
6365
+ dateRange: getDateRangeFilter(activeFilterColumn),
6366
+ numberFormat,
6367
+ dateFormat,
6082
6368
  onFilter: (values) => handleFilter(activeFilterColumn, values),
6083
6369
  onRangeFilter: (range) => handleRangeFilter(activeFilterColumn, range),
6370
+ onDateRangeFilter: (range) => handleDateRangeFilter(activeFilterColumn, range),
6084
6371
  onSort: (dir) => handleSort(activeFilterColumn, dir),
6085
6372
  onClose: closeFilterDropdown
6086
6373
  }