@embeddable.com/remarkable-ui 2.0.38 → 2.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  styles
3
- } from "./chunk-3SAVZAMC.js";
3
+ } from "./chunk-ZH2EV2SD.js";
4
4
 
5
5
  // src/components/charts/bars/BarChart.tsx
6
6
  import { useRef } from "react";
@@ -609,7 +609,7 @@ var LineChart = ({ options = {}, data, onSegmentClick, ...props }) => {
609
609
  import styles5 from "./KpiChart.module-2LUIN66C.module.css";
610
610
 
611
611
  // src/components/charts/kpis/components/KpiChartChange.tsx
612
- import styles4 from "./KpiChartChange.module-BAW7YCOW.module.css";
612
+ import styles4 from "./KpiChartChange.module-H77VT5RD.module.css";
613
613
  import clsx from "clsx";
614
614
  import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-react";
615
615
  import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
@@ -707,16 +707,7 @@ var KpiChart = ({
707
707
  {
708
708
  condition: autoResizeValueFontSize,
709
709
  wrapper: (children) => /* @__PURE__ */ jsx5(AutoTextSize, { mode: "boxoneline", minFontSizePx: 1, maxFontSizePx: 999, children }),
710
- children: /* @__PURE__ */ jsx5(
711
- "h2",
712
- {
713
- title: displayValue?.toString(),
714
- style: {
715
- fontSize: valueFontSize
716
- },
717
- children: displayValue
718
- }
719
- )
710
+ children: /* @__PURE__ */ jsx5("h2", { title: displayValue?.toString(), style: { fontSize: valueFontSize }, children: displayValue })
720
711
  }
721
712
  ) }),
722
713
  /* @__PURE__ */ jsx5("div", { className: styles5.kpiComparisonContainer, style: { fontSize: trendFontSize }, children: /* @__PURE__ */ jsx5("div", { style: { visibility: hasComparisonValue ? "visible" : "hidden" }, children: /* @__PURE__ */ jsx5(
@@ -933,7 +924,7 @@ var PieChart = ({
933
924
 
934
925
  // src/components/charts/tables/HeatMap/HeatMap.tsx
935
926
  import { useMemo, useCallback } from "react";
936
- import tableStyles from "./tables.module-6DZDKDSH.module.css";
927
+ import tableStyles from "./tables.module-6REGLCSQ.module.css";
937
928
  import clsx2 from "clsx";
938
929
 
939
930
  // src/components/charts/tables/HeatMap/HeatMap.utils.ts
@@ -1221,71 +1212,89 @@ var HeatMap = ({
1221
1212
  };
1222
1213
 
1223
1214
  // src/components/charts/tables/PivotTable/PivotTable.tsx
1224
- import { useEffect, useMemo as useMemo2, useState as useState2 } from "react";
1225
- import tableStyles2 from "./tables.module-6DZDKDSH.module.css";
1215
+ import { Fragment as Fragment3, useMemo as useMemo3, useState as useState3 } from "react";
1216
+ import tableStyles2 from "./tables.module-6REGLCSQ.module.css";
1226
1217
  import clsx3 from "clsx";
1227
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1218
+ import { IconLoader2, IconChevronDown, IconChevronRight } from "@tabler/icons-react";
1219
+
1220
+ // src/components/charts/tables/PivotTable/PivotTable.utils.ts
1221
+ import { useEffect, useMemo as useMemo2, useState as useState2 } from "react";
1228
1222
  var isNumber = (v) => typeof v === "number" && !Number.isNaN(v);
1229
1223
  var getPercentageDisplay = (percentage, percentageDecimalPlaces) => {
1230
1224
  return `${percentage.toFixed(percentageDecimalPlaces)}%`;
1231
1225
  };
1232
- var PivotTable = ({
1233
- columnWidth,
1234
- firstColumnWidth,
1235
- data,
1236
- measures,
1237
- rowDimension,
1238
- columnDimension,
1239
- progressive = true,
1240
- batchSize = 100,
1241
- batchDelayMs = 0,
1242
- rowTotalsFor = [],
1243
- columnTotalsFor = [],
1244
- totalLabel = "Total",
1245
- className
1246
- }) => {
1247
- const rowValues = useMemo2(() => {
1248
- const s = /* @__PURE__ */ new Set();
1249
- for (const d of data) {
1250
- const rowValue = d[rowDimension.key];
1251
- if (rowValue != null) s.add(rowValue);
1252
- }
1253
- return Array.from(s);
1254
- }, [data, rowDimension.key]);
1255
- const columnValues = useMemo2(() => {
1256
- const s = /* @__PURE__ */ new Set();
1257
- for (const d of data) {
1258
- const columnValue = d[columnDimension.key];
1259
- if (columnValue != null) s.add(columnValue);
1226
+ var getCellDisplayValue2 = (value, measure, dataObject, denominatorTotal) => {
1227
+ if (measure.showAsPercentage) {
1228
+ if (isNumber(Number(value)) && isNumber(denominatorTotal) && denominatorTotal > 0) {
1229
+ return getPercentageDisplay(
1230
+ value / denominatorTotal * 100,
1231
+ measure.percentageDecimalPlaces ?? 0
1232
+ );
1260
1233
  }
1261
- return Array.from(s);
1262
- }, [data, columnDimension.key]);
1263
- const cellMap = useMemo2(() => {
1264
- const map = /* @__PURE__ */ new Map();
1265
- for (const d of data) {
1266
- const r = String(d[rowDimension.key]);
1267
- const c = String(d[columnDimension.key]);
1268
- if (!map.has(r)) map.set(r, /* @__PURE__ */ new Map());
1269
- map.get(r).set(c, d);
1234
+ }
1235
+ return measure.accessor ? measure.accessor(dataObject) : value;
1236
+ };
1237
+ var buildCellMap = (rows, rowKey, colKey) => {
1238
+ const map = /* @__PURE__ */ new Map();
1239
+ for (const d of rows) {
1240
+ const r = String(d[rowKey]);
1241
+ const c = String(d[colKey]);
1242
+ if (!map.has(r)) map.set(r, /* @__PURE__ */ new Map());
1243
+ map.get(r).set(c, d);
1244
+ }
1245
+ return map;
1246
+ };
1247
+ var getMeasureTotal = (totalsMap, key, measureIndex, measuresCount) => {
1248
+ const totals = totalsMap.get(key) ?? Array(measuresCount).fill(0);
1249
+ return measureIndex >= 0 ? totals[measureIndex] ?? 0 : 0;
1250
+ };
1251
+ var computeSubRowTotal = (cellMap, rowKey, columnValues, measureKey) => {
1252
+ let total = 0;
1253
+ for (const columnValue of columnValues) {
1254
+ const data = cellMap.get(rowKey)?.get(String(columnValue)) ?? {};
1255
+ const val = Number(data?.[measureKey]);
1256
+ if (!Number.isNaN(val)) total += val;
1257
+ }
1258
+ return total;
1259
+ };
1260
+ var useProgressiveRows = (rowValues, options) => {
1261
+ const { progressive, batchSize, batchDelayMs } = options;
1262
+ const [visibleCount, setVisibleCount] = useState2(
1263
+ () => progressive ? Math.min(batchSize, rowValues.length) : rowValues.length
1264
+ );
1265
+ useEffect(() => {
1266
+ if (!progressive) {
1267
+ setVisibleCount(rowValues.length);
1268
+ return;
1270
1269
  }
1271
- return map;
1272
- }, [data, rowDimension.key, columnDimension.key]);
1273
- const rowTotalsSet = useMemo2(() => new Set(rowTotalsFor), [rowTotalsFor]);
1274
- const columnTotalsSet = useMemo2(() => new Set(columnTotalsFor), [columnTotalsFor]);
1275
- const hasRowTotals = rowTotalsSet.size > 0;
1276
- const hasColumnTotals = columnTotalsSet.size > 0;
1277
- const measureIndexByKey = useMemo2(() => {
1278
- const map = /* @__PURE__ */ new Map();
1279
- measures.forEach((m, i) => map.set(String(m.key), i));
1280
- return map;
1281
- }, [measures]);
1282
- const { colTotals, rowTotals, grandTotals } = useMemo2(() => {
1270
+ let cancelled = false;
1271
+ let t = null;
1272
+ setVisibleCount(Math.min(batchSize, rowValues.length));
1273
+ const tick = () => {
1274
+ setVisibleCount((prev) => {
1275
+ const next = Math.min(prev + batchSize, rowValues.length);
1276
+ if (next < rowValues.length && !cancelled) {
1277
+ t = window.setTimeout(tick, batchDelayMs);
1278
+ }
1279
+ return next;
1280
+ });
1281
+ };
1282
+ t = window.setTimeout(tick, batchDelayMs);
1283
+ return () => {
1284
+ cancelled = true;
1285
+ if (t !== null) window.clearTimeout(t);
1286
+ };
1287
+ }, [progressive, batchSize, batchDelayMs, rowValues.length]);
1288
+ return progressive ? rowValues.slice(0, visibleCount) : rowValues;
1289
+ };
1290
+ var usePivotTotals = (data, measures, rowDimensionKey, columnDimensionKey, columnValues, rowValues) => {
1291
+ return useMemo2(() => {
1283
1292
  const cTotals = /* @__PURE__ */ new Map();
1284
1293
  const rTotals = /* @__PURE__ */ new Map();
1285
1294
  const gTotals = measures.map(() => 0);
1286
1295
  for (const d of data) {
1287
- const r = String(d[rowDimension.key]);
1288
- const c = String(d[columnDimension.key]);
1296
+ const r = String(d[rowDimensionKey]);
1297
+ const c = String(d[columnDimensionKey]);
1289
1298
  const cArr = cTotals.get(c) ?? measures.map(() => 0);
1290
1299
  const rArr = rTotals.get(r) ?? measures.map(() => 0);
1291
1300
  measures.forEach((m, i) => {
@@ -1315,34 +1324,146 @@ var PivotTable = ({
1315
1324
  );
1316
1325
  }
1317
1326
  return { colTotals: cTotals, rowTotals: rTotals, grandTotals: gTotals };
1318
- }, [data, measures, rowDimension.key, columnDimension.key, columnValues, rowValues]);
1319
- const [visibleCount, setVisibleCount] = useState2(
1320
- () => progressive ? Math.min(batchSize, rowValues.length) : rowValues.length
1321
- );
1322
- useEffect(() => {
1323
- if (!progressive) {
1324
- setVisibleCount(rowValues.length);
1325
- return;
1327
+ }, [data, measures, rowDimensionKey, columnDimensionKey, columnValues, rowValues]);
1328
+ };
1329
+
1330
+ // src/components/charts/tables/PivotTable/PivotTable.tsx
1331
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1332
+ var PivotTable = ({
1333
+ columnWidth,
1334
+ firstColumnWidth,
1335
+ data,
1336
+ measures,
1337
+ rowDimension,
1338
+ columnDimension,
1339
+ progressive = true,
1340
+ batchSize = 100,
1341
+ batchDelayMs = 0,
1342
+ rowTotalsFor = [],
1343
+ columnTotalsFor = [],
1344
+ totalLabel = "Total",
1345
+ className,
1346
+ expandableRows = false,
1347
+ subRowsByRow,
1348
+ loadingRows,
1349
+ onRowExpand,
1350
+ subRowDimension
1351
+ }) => {
1352
+ const effectiveSubRowDimension = subRowDimension ?? rowDimension;
1353
+ const rowValues = useMemo3(() => {
1354
+ const s = /* @__PURE__ */ new Set();
1355
+ for (const d of data) {
1356
+ const rowValue = d[rowDimension.key];
1357
+ if (rowValue != null) s.add(rowValue);
1326
1358
  }
1327
- let cancelled = false;
1328
- let t = null;
1329
- setVisibleCount(0);
1330
- const tick = () => {
1331
- setVisibleCount((prev) => {
1332
- const next = Math.min(prev + batchSize, rowValues.length);
1333
- if (next < rowValues.length && !cancelled) {
1334
- t = window.setTimeout(tick, batchDelayMs);
1359
+ return Array.from(s);
1360
+ }, [data, rowDimension.key]);
1361
+ const columnValues = useMemo3(() => {
1362
+ const s = /* @__PURE__ */ new Set();
1363
+ for (const d of data) {
1364
+ const columnValue = d[columnDimension.key];
1365
+ if (columnValue != null) s.add(columnValue);
1366
+ }
1367
+ return Array.from(s);
1368
+ }, [data, columnDimension.key]);
1369
+ const cellMap = useMemo3(
1370
+ () => buildCellMap(data, rowDimension.key, columnDimension.key),
1371
+ [data, rowDimension.key, columnDimension.key]
1372
+ );
1373
+ const rowTotalsSet = useMemo3(() => new Set(rowTotalsFor), [rowTotalsFor]);
1374
+ const columnTotalsSet = useMemo3(() => new Set(columnTotalsFor), [columnTotalsFor]);
1375
+ const hasRowTotals = rowTotalsSet.size > 0;
1376
+ const hasColumnTotals = columnTotalsSet.size > 0;
1377
+ const measureIndexByKey = useMemo3(() => {
1378
+ const map = /* @__PURE__ */ new Map();
1379
+ measures.forEach((m, i) => map.set(String(m.key), i));
1380
+ return map;
1381
+ }, [measures]);
1382
+ const { colTotals, rowTotals, grandTotals } = usePivotTotals(
1383
+ data,
1384
+ measures,
1385
+ rowDimension.key,
1386
+ columnDimension.key,
1387
+ columnValues,
1388
+ rowValues
1389
+ );
1390
+ const [expandedRows, setExpandedRows] = useState3(() => /* @__PURE__ */ new Set());
1391
+ const handleRowExpand = (rowKey) => {
1392
+ setExpandedRows((prev) => {
1393
+ const next = new Set(prev);
1394
+ const wasExpanded = next.has(rowKey);
1395
+ if (wasExpanded) {
1396
+ next.delete(rowKey);
1397
+ } else {
1398
+ next.add(rowKey);
1399
+ if (!subRowsByRow?.has(rowKey)) {
1400
+ onRowExpand?.(rowKey);
1335
1401
  }
1336
- return next;
1337
- });
1338
- };
1339
- t = window.setTimeout(tick, batchDelayMs);
1340
- return () => {
1341
- cancelled = true;
1342
- if (t !== null) window.clearTimeout(t);
1343
- };
1344
- }, [progressive, batchSize, batchDelayMs, rowValues.length, data]);
1345
- const visibleRows = progressive ? rowValues.slice(0, visibleCount) : rowValues;
1402
+ }
1403
+ return next;
1404
+ });
1405
+ };
1406
+ const visibleRows = useProgressiveRows(rowValues, {
1407
+ progressive,
1408
+ batchSize,
1409
+ batchDelayMs
1410
+ });
1411
+ const renderMeasureCells = (rowCellMap, rowKey, keyPrefix) => columnValues.flatMap(
1412
+ (columnValue) => measures.map((measure, idx) => {
1413
+ const object = rowCellMap.get(rowKey)?.get(String(columnValue)) ?? {};
1414
+ const value = object?.[measure.key];
1415
+ const key = `${keyPrefix}-${columnValue}-${measure.key}-${idx}`;
1416
+ const mi = measureIndexByKey.get(String(measure.key)) ?? -1;
1417
+ const colTotal = getMeasureTotal(colTotals, String(columnValue), mi, measures.length);
1418
+ const displayValue = getCellDisplayValue2(value, measure, object, colTotal);
1419
+ return /* @__PURE__ */ jsx9("td", { title: displayValue, children: displayValue }, key);
1420
+ })
1421
+ );
1422
+ const renderRowTotalCells = (getTotalValue, keyPrefix) => {
1423
+ if (!hasRowTotals) return null;
1424
+ return measures.filter((measure) => rowTotalsSet.has(measure.key)).map((measure, idx) => {
1425
+ const measureIndex = measureIndexByKey.get(measure.key) ?? -1;
1426
+ const key = `${keyPrefix}-${measure.key}-${idx}`;
1427
+ const value = getTotalValue(measure.key, measureIndex);
1428
+ const displayValue = getCellDisplayValue2(
1429
+ value,
1430
+ measure,
1431
+ { [measure.key]: value },
1432
+ grandTotals[measureIndex] || 1
1433
+ );
1434
+ return /* @__PURE__ */ jsx9("td", { className: tableStyles2.boltCell, title: displayValue, children: displayValue }, key);
1435
+ });
1436
+ };
1437
+ const renderSubRows = (rowKey, subRows) => {
1438
+ const subRowValues = Array.from(
1439
+ new Set(subRows.map((sr) => sr[effectiveSubRowDimension.key]).filter((v) => v != null))
1440
+ );
1441
+ const subRowCellMap = buildCellMap(subRows, effectiveSubRowDimension.key, columnDimension.key);
1442
+ return subRowValues.map((subRowValue, subRowIdx) => {
1443
+ const subRowDimensionValue = effectiveSubRowDimension.formatValue ? effectiveSubRowDimension.formatValue(subRowValue) : subRowValue;
1444
+ return /* @__PURE__ */ jsxs4("tr", { className: tableStyles2.subRow, children: [
1445
+ /* @__PURE__ */ jsx9(
1446
+ "th",
1447
+ {
1448
+ scope: "row",
1449
+ className: clsx3(tableStyles2.stickyFirstColumn, tableStyles2.subRowFirstColumn),
1450
+ style: getTableCellWidthStyle(firstColumnWidth),
1451
+ title: subRowDimensionValue,
1452
+ children: /* @__PURE__ */ jsx9("span", { children: subRowDimensionValue })
1453
+ }
1454
+ ),
1455
+ renderMeasureCells(
1456
+ subRowCellMap,
1457
+ String(subRowValue),
1458
+ `sub-cell-${rowKey}-${subRowIdx}`
1459
+ ),
1460
+ renderRowTotalCells(
1461
+ (key) => computeSubRowTotal(subRowCellMap, String(subRowValue), columnValues, key),
1462
+ `sub-total-${rowKey}-${subRowIdx}`
1463
+ )
1464
+ ] }, `sub-${rowKey}-${subRowIdx}`);
1465
+ });
1466
+ };
1346
1467
  return /* @__PURE__ */ jsx9("div", { className: clsx3(tableStyles2.tableFullContainer, className), children: /* @__PURE__ */ jsx9(
1347
1468
  "div",
1348
1469
  {
@@ -1365,6 +1486,7 @@ var PivotTable = ({
1365
1486
  rowSpan: 1,
1366
1487
  title: columnDimension.label,
1367
1488
  className: tableStyles2.stickyFirstColumn,
1489
+ style: getTableCellWidthStyle(firstColumnWidth),
1368
1490
  children: columnDimension.label
1369
1491
  }
1370
1492
  ),
@@ -1432,56 +1554,58 @@ var PivotTable = ({
1432
1554
  ] }),
1433
1555
  /* @__PURE__ */ jsxs4("tbody", { children: [
1434
1556
  visibleRows.map((row) => {
1557
+ const rowKey = String(row);
1558
+ const isExpanded = expandedRows.has(rowKey);
1559
+ const isLoading = loadingRows?.has(rowKey) ?? false;
1560
+ const subRows = subRowsByRow?.get(rowKey) ?? [];
1561
+ const hasLoadedSubRows = subRows.length > 0;
1435
1562
  const rowDimensionValue = rowDimension.formatValue ? rowDimension.formatValue(row) : row;
1436
- return /* @__PURE__ */ jsxs4("tr", { children: [
1437
- /* @__PURE__ */ jsx9(
1438
- "th",
1563
+ const ariaLabel = expandableRows ? isLoading ? "Loading" : isExpanded ? `Collapse ${rowDimensionValue}` : `Expand ${rowDimensionValue}` : "";
1564
+ const showSubRows = isExpanded && !isLoading && hasLoadedSubRows;
1565
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
1566
+ /* @__PURE__ */ jsxs4(
1567
+ "tr",
1439
1568
  {
1440
- scope: "row",
1569
+ className: clsx3(isExpanded && tableStyles2.expandedRow),
1441
1570
  title: rowDimensionValue,
1442
- className: tableStyles2.stickyFirstColumn,
1443
- children: rowDimensionValue
1444
- }
1445
- ),
1446
- columnValues.flatMap(
1447
- (columnValue) => measures.map((measure, idx) => {
1448
- const object = cellMap.get(String(row))?.get(String(columnValue)) ?? {};
1449
- const value = object?.[measure.key];
1450
- const key = `cell-${row}-${columnValue}-${measure.key}-${idx}`;
1451
- const getDisplayValue = () => {
1452
- if (measure.showAsPercentage) {
1453
- const mi = measureIndexByKey.get(String(measure.key)) ?? -1;
1454
- const totalsForCol = colTotals.get(String(columnValue)) ?? measures.map(() => 0);
1455
- const colTotal = mi >= 0 ? totalsForCol[mi] ?? 0 : 0;
1456
- const shouldShowPct = measure.showAsPercentage && isNumber(Number(value)) && isNumber(colTotal) && colTotal > 0;
1457
- if (shouldShowPct) {
1458
- const percentage = value / colTotal * 100;
1459
- return `${percentage.toFixed(measure.percentageDecimalPlaces ?? 0)}%`;
1571
+ children: [
1572
+ /* @__PURE__ */ jsx9(
1573
+ "th",
1574
+ {
1575
+ scope: "row",
1576
+ title: rowDimensionValue,
1577
+ className: clsx3(
1578
+ tableStyles2.stickyFirstColumn,
1579
+ expandableRows && tableStyles2.expandableRowCell
1580
+ ),
1581
+ onClick: () => expandableRows && handleRowExpand(rowKey),
1582
+ onKeyDown: (e) => {
1583
+ if (expandableRows && (e.key === "Enter" || e.key === " ")) {
1584
+ e.preventDefault();
1585
+ handleRowExpand(rowKey);
1586
+ }
1587
+ },
1588
+ tabIndex: expandableRows ? 0 : void 0,
1589
+ role: expandableRows ? "button" : void 0,
1590
+ "aria-expanded": expandableRows ? isExpanded : void 0,
1591
+ style: getTableCellWidthStyle(firstColumnWidth),
1592
+ "aria-label": ariaLabel,
1593
+ children: /* @__PURE__ */ jsxs4("span", { className: tableStyles2.firstColumnCell, children: [
1594
+ expandableRows && /* @__PURE__ */ jsx9(Fragment4, { children: isLoading ? /* @__PURE__ */ jsx9(IconLoader2, { className: tableStyles2.subRowLoading }) : isExpanded ? /* @__PURE__ */ jsx9(IconChevronDown, {}) : /* @__PURE__ */ jsx9(IconChevronRight, {}) }),
1595
+ /* @__PURE__ */ jsx9("span", { children: rowDimensionValue })
1596
+ ] })
1460
1597
  }
1461
- }
1462
- return measure.accessor ? measure.accessor(object) : value;
1463
- };
1464
- const columnValueDisplay = getDisplayValue();
1465
- return /* @__PURE__ */ jsx9("td", { title: columnValueDisplay, children: columnValueDisplay }, key);
1466
- })
1467
- ),
1468
- hasRowTotals && measures.filter((measure) => rowTotalsSet.has(measure.key)).map((measure, idx) => {
1469
- const totalsForRow = rowTotals.get(String(row)) ?? measures.map(() => 0);
1470
- const measureIndex = measureIndexByKey.get(measure.key) ?? -1;
1471
- const key = `row-total-${String(row)}-${measure.key}-${idx}`;
1472
- const value = measureIndex >= 0 ? totalsForRow[measureIndex] ?? 0 : 0;
1473
- let displayValue = value;
1474
- if (measure.showAsPercentage) {
1475
- displayValue = getPercentageDisplay(
1476
- value / (grandTotals[measureIndex] || 1) * 100,
1477
- measure.percentageDecimalPlaces ?? 0
1478
- );
1479
- } else if (measure.accessor) {
1480
- displayValue = measure.accessor({ [measure.key]: value });
1598
+ ),
1599
+ renderMeasureCells(cellMap, String(row), `cell-${row}`),
1600
+ renderRowTotalCells(
1601
+ (_key, mi) => getMeasureTotal(rowTotals, String(row), mi, measures.length),
1602
+ `row-total-${String(row)}`
1603
+ )
1604
+ ]
1481
1605
  }
1482
- return /* @__PURE__ */ jsx9("td", { className: tableStyles2.boltCell, title: displayValue, children: displayValue }, key);
1483
- })
1484
- ] }, `row-${row}`);
1606
+ ),
1607
+ showSubRows && renderSubRows(rowKey, subRows)
1608
+ ] }, `row-group-${rowKey}`);
1485
1609
  }),
1486
1610
  hasColumnTotals && /* @__PURE__ */ jsxs4("tr", { className: tableStyles2.stickyLastRow, children: [
1487
1611
  /* @__PURE__ */ jsx9(
@@ -1490,16 +1614,21 @@ var PivotTable = ({
1490
1614
  scope: "row",
1491
1615
  className: clsx3(tableStyles2.stickyFirstColumn, tableStyles2.boltCell),
1492
1616
  title: totalLabel,
1617
+ style: getTableCellWidthStyle(firstColumnWidth),
1493
1618
  children: totalLabel
1494
1619
  }
1495
1620
  ),
1496
1621
  columnValues.flatMap(
1497
1622
  (columnValue) => measures.map((measure, idx) => {
1498
1623
  const show = columnTotalsSet.has(String(measure.key));
1499
- const totalsForCol = colTotals.get(String(columnValue)) ?? measures.map(() => 0);
1500
- const mi = measures.findIndex((mm) => String(mm.key) === String(measure.key));
1624
+ const mi = measureIndexByKey.get(String(measure.key)) ?? -1;
1501
1625
  const key = `col-total-${String(columnValue)}-${measure.key}-${idx}`;
1502
- const value = totalsForCol[mi] ?? 0;
1626
+ const value = getMeasureTotal(
1627
+ colTotals,
1628
+ String(columnValue),
1629
+ mi,
1630
+ measures.length
1631
+ );
1503
1632
  let displayValue = value;
1504
1633
  if (measure.showAsPercentage) {
1505
1634
  displayValue = getPercentageDisplay(
@@ -1514,7 +1643,7 @@ var PivotTable = ({
1514
1643
  })
1515
1644
  ),
1516
1645
  hasRowTotals && measures.filter((measure) => rowTotalsSet.has(measure.key)).map((measure, idx) => {
1517
- const measureIndex = measures.findIndex((m) => String(m.key) === measure.key);
1646
+ const measureIndex = measureIndexByKey.get(measure.key) ?? -1;
1518
1647
  const key = `grand-total-${measure.key}-${idx}`;
1519
1648
  const value = grandTotals[measureIndex] ?? 0;
1520
1649
  let displayValue = value;
@@ -1539,7 +1668,7 @@ var PivotTable = ({
1539
1668
 
1540
1669
  // src/components/charts/tables/Table/TablePaginated/TablePaginated.tsx
1541
1670
  import * as React from "react";
1542
- import styles11 from "./tables.module-6DZDKDSH.module.css";
1671
+ import styles11 from "./tables.module-6REGLCSQ.module.css";
1543
1672
  import clsx7 from "clsx";
1544
1673
 
1545
1674
  // src/components/charts/tables/Table/components/TableHeader/TableHeader.tsx
@@ -1558,9 +1687,9 @@ var TableHeaderAlign = {
1558
1687
  };
1559
1688
 
1560
1689
  // src/components/charts/tables/Table/components/TableHeader/TableHeader.tsx
1561
- import tableStyles3 from "./tables.module-6DZDKDSH.module.css";
1690
+ import tableStyles3 from "./tables.module-6REGLCSQ.module.css";
1562
1691
  import clsx4 from "clsx";
1563
- import { useEffect as useEffect3, useState as useState3 } from "react";
1692
+ import { useEffect as useEffect3, useState as useState4 } from "react";
1564
1693
 
1565
1694
  // src/hooks/useDebounce.hook.ts
1566
1695
  import { useRef as useRef6, useEffect as useEffect2, useCallback as useCallback2 } from "react";
@@ -1603,7 +1732,7 @@ var TableHeader = ({
1603
1732
  showIndex,
1604
1733
  onSortChange
1605
1734
  }) => {
1606
- const [currentSort, setCurrentSort] = useState3(sort);
1735
+ const [currentSort, setCurrentSort] = useState4(sort);
1607
1736
  const debouncedUpdateState = useDebounce((value) => {
1608
1737
  if (value === void 0 && value === sort) {
1609
1738
  return;
@@ -1669,7 +1798,7 @@ import clsx6 from "clsx";
1669
1798
 
1670
1799
  // src/components/shared/ActionIcon/ActionIcon.tsx
1671
1800
  import clsx5 from "clsx";
1672
- import styles9 from "./ActionIcon.module-UMIOEH5M.module.css";
1801
+ import styles9 from "./ActionIcon.module-NQH2HPCG.module.css";
1673
1802
  import { jsx as jsx11 } from "react/jsx-runtime";
1674
1803
  var ActionIcon = ({ icon: Icon, className, ...props }) => {
1675
1804
  return /* @__PURE__ */ jsx11("button", { className: clsx5(styles9.actionIcon, className), ...props, children: /* @__PURE__ */ jsx11(Icon, { className: styles9.icon }) });
@@ -1677,8 +1806,8 @@ var ActionIcon = ({ icon: Icon, className, ...props }) => {
1677
1806
 
1678
1807
  // src/components/charts/tables/Table/components/TableBody/TableBody.tsx
1679
1808
  import { IconCopy, IconCopyCheckFilled } from "@tabler/icons-react";
1680
- import { useState as useState4 } from "react";
1681
- import tableStyles4 from "./tables.module-6DZDKDSH.module.css";
1809
+ import { useState as useState5 } from "react";
1810
+ import tableStyles4 from "./tables.module-6REGLCSQ.module.css";
1682
1811
  import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1683
1812
  var TableBody = ({
1684
1813
  headers,
@@ -1735,7 +1864,7 @@ var TableBodyCellWithCopy = ({
1735
1864
  children,
1736
1865
  style
1737
1866
  }) => {
1738
- const [isPressedCopy, setIsPressedCopy] = useState4(false);
1867
+ const [isPressedCopy, setIsPressedCopy] = useState5(false);
1739
1868
  const handleCopy = () => {
1740
1869
  setIsPressedCopy(true);
1741
1870
  if (value !== void 0) {
@@ -1771,7 +1900,7 @@ var TableBodyCellWithCopy = ({
1771
1900
  // src/components/charts/tables/Table/components/TablePagination/TablePagination.tsx
1772
1901
  import {
1773
1902
  IconChevronLeft,
1774
- IconChevronRight,
1903
+ IconChevronRight as IconChevronRight2,
1775
1904
  IconChevronsLeft,
1776
1905
  IconChevronsRight
1777
1906
  } from "@tabler/icons-react";
@@ -1826,7 +1955,7 @@ var TablePagination = ({
1826
1955
  /* @__PURE__ */ jsx13(
1827
1956
  ActionIcon,
1828
1957
  {
1829
- icon: IconChevronRight,
1958
+ icon: IconChevronRight2,
1830
1959
  onClick: () => {
1831
1960
  onPageChange(page + 1);
1832
1961
  },
@@ -1905,13 +2034,13 @@ var TablePaginated = React.forwardRef(
1905
2034
  TablePaginated.displayName = "TablePaginated";
1906
2035
 
1907
2036
  // src/components/charts/tables/Table/TablePaginated/TablePaginated.hooks.ts
1908
- import { useMemo as useMemo3 } from "react";
2037
+ import { useMemo as useMemo4 } from "react";
1909
2038
  var useTableGetRowsPerPage = ({
1910
2039
  availableHeight,
1911
2040
  headerHeight,
1912
2041
  rowHeight,
1913
2042
  footerHeight = 0
1914
- }) => useMemo3(() => {
2043
+ }) => useMemo4(() => {
1915
2044
  const h = availableHeight;
1916
2045
  if (!h) return 0;
1917
2046
  let available = h - headerHeight - footerHeight;
@@ -1922,7 +2051,7 @@ var useTableGetRowsPerPage = ({
1922
2051
 
1923
2052
  // src/components/charts/tables/Table/TableScrollable/TableScrollable.tsx
1924
2053
  import clsx8 from "clsx";
1925
- import tableStyles5 from "./tables.module-6DZDKDSH.module.css";
2054
+ import tableStyles5 from "./tables.module-6REGLCSQ.module.css";
1926
2055
 
1927
2056
  // src/components/charts/tables/Table/TableScrollable/TableScrollable.hooks.ts
1928
2057
  import { useEffect as useEffect5, useRef as useRef7 } from "react";
@@ -2037,13 +2166,13 @@ var TableScrollable = forwardRef2(
2037
2166
  TableScrollable.displayName = "TableScrollable";
2038
2167
 
2039
2168
  // src/components/editors/dates/DateRangePicker/DateRangePicker.tsx
2040
- import { useState as useState5 } from "react";
2169
+ import { useState as useState6 } from "react";
2041
2170
  import { DayPicker } from "react-day-picker";
2042
2171
  import "./DateRangePicker-PLOUUN7Q.css";
2043
2172
 
2044
2173
  // src/components/editors/dates/DateRangePicker/DateRangePickerChevron.tsx
2045
- import { IconCaretDownFilled as IconCaretDownFilled2 } from "@tabler/icons-react";
2046
- import styles12 from "./DateRangePickerChevron.module-ABYY5R7C.module.css";
2174
+ import { IconCaretLeftFilled } from "@tabler/icons-react";
2175
+ import styles12 from "./DateRangePickerChevron.module-U3RB6ZHO.module.css";
2047
2176
  import clsx9 from "clsx";
2048
2177
  import { jsx as jsx16 } from "react/jsx-runtime";
2049
2178
  var SMALL_SIZE = 18;
@@ -2051,7 +2180,7 @@ var DateRangePickerChevron = ({
2051
2180
  orientation,
2052
2181
  size
2053
2182
  }) => {
2054
- const rotation = orientation === "left" ? "rotate(90deg)" : orientation === "right" ? "rotate(-90deg)" : void 0;
2183
+ const rotation = orientation === "left" ? void 0 : "rotate(180deg)";
2055
2184
  const isSmallChevron = size === SMALL_SIZE;
2056
2185
  return /* @__PURE__ */ jsx16(
2057
2186
  "button",
@@ -2060,7 +2189,7 @@ var DateRangePickerChevron = ({
2060
2189
  style: {
2061
2190
  transform: rotation
2062
2191
  },
2063
- children: /* @__PURE__ */ jsx16(IconCaretDownFilled2, {})
2192
+ children: /* @__PURE__ */ jsx16(IconCaretLeftFilled, {})
2064
2193
  }
2065
2194
  );
2066
2195
  };
@@ -2083,7 +2212,7 @@ var DateRangePicker = ({
2083
2212
  locale = "en",
2084
2213
  onChange
2085
2214
  }) => {
2086
- const [month, setMonth] = useState5(value?.from ?? /* @__PURE__ */ new Date());
2215
+ const [month, setMonth] = useState6(value?.from ?? /* @__PURE__ */ new Date());
2087
2216
  const handleChange = (range) => {
2088
2217
  if (range?.to) {
2089
2218
  range.to = endOfDayUTC(range.to);
@@ -2114,7 +2243,7 @@ var DateRangePicker = ({
2114
2243
  };
2115
2244
 
2116
2245
  // src/components/editors/dates/DateRangePickerField/DateRangePickerField.tsx
2117
- import { useState as useState6 } from "react";
2246
+ import { useState as useState7 } from "react";
2118
2247
 
2119
2248
  // src/components/shared/Field/FieldHeader.tsx
2120
2249
  import clsx10 from "clsx";
@@ -2165,14 +2294,14 @@ var Dropdown = ({
2165
2294
 
2166
2295
  // src/components/editors/selects/shared/SelectFieldTrigger/SelectFieldTrigger.tsx
2167
2296
  import styles15 from "./SelectFieldTrigger.module-M6BRE7IY.module.css";
2168
- import { IconCaretDownFilled as IconCaretDownFilled3, IconLoader2, IconX } from "@tabler/icons-react";
2297
+ import { IconCaretDownFilled as IconCaretDownFilled2, IconLoader2 as IconLoader22, IconX } from "@tabler/icons-react";
2169
2298
  import clsx12 from "clsx";
2170
2299
  import { forwardRef as forwardRef3 } from "react";
2171
2300
 
2172
2301
  // src/components/shared/GhostButton/GhostButton.tsx
2173
2302
  import React3 from "react";
2174
2303
  import clsx11 from "clsx";
2175
- import styles14 from "./GhostButton.module-43KOFC6W.module.css";
2304
+ import styles14 from "./GhostButton.module-JZ7YOOU5.module.css";
2176
2305
  import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
2177
2306
  var GhostButton = React3.forwardRef(
2178
2307
  ({ startIcon: StartIcon, endIcon: EndIcon, children, className, ...props }, ref) => {
@@ -2207,7 +2336,7 @@ var SelectFieldTrigger = forwardRef3(
2207
2336
  onClear?.();
2208
2337
  };
2209
2338
  if (variant === "ghost") {
2210
- return /* @__PURE__ */ jsxs13(GhostButton, { ref, endIcon: isLoading ? IconLoader2 : IconCaretDownFilled3, ...props, children: [
2339
+ return /* @__PURE__ */ jsxs13(GhostButton, { ref, endIcon: isLoading ? IconLoader22 : IconCaretDownFilled2, ...props, children: [
2211
2340
  displayValue,
2212
2341
  showClearButton && /* @__PURE__ */ jsx21(IconX, { onPointerDown: handleClear })
2213
2342
  ] });
@@ -2226,7 +2355,7 @@ var SelectFieldTrigger = forwardRef3(
2226
2355
  StartIcon && /* @__PURE__ */ jsx21(StartIcon, {}),
2227
2356
  /* @__PURE__ */ jsx21("span", { children: displayValue }),
2228
2357
  showClearButton && /* @__PURE__ */ jsx21(IconX, { onPointerDown: handleClear }),
2229
- isLoading ? /* @__PURE__ */ jsx21(IconLoader2, { className: styles15.loading }) : /* @__PURE__ */ jsx21(IconCaretDownFilled3, {})
2358
+ isLoading ? /* @__PURE__ */ jsx21(IconLoader22, { className: styles15.loading }) : /* @__PURE__ */ jsx21(IconCaretDownFilled2, {})
2230
2359
  ]
2231
2360
  }
2232
2361
  );
@@ -2316,7 +2445,7 @@ var FieldFeedback = ({ message, variant, className }) => {
2316
2445
  };
2317
2446
 
2318
2447
  // src/components/shared/Button/Button.tsx
2319
- import styles18 from "./Button.module-GOXSST7L.module.css";
2448
+ import styles18 from "./Button.module-LD3OBJVA.module.css";
2320
2449
  import clsx15 from "clsx";
2321
2450
  import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
2322
2451
  var Button = ({
@@ -2362,8 +2491,8 @@ var DateRangePickerField = ({
2362
2491
  avoidCollisions,
2363
2492
  onChange
2364
2493
  }) => {
2365
- const [isOpen, setIsOpen] = useState6(false);
2366
- const [currentDateRange, setCurrentDateRange] = useState6(value);
2494
+ const [isOpen, setIsOpen] = useState7(false);
2495
+ const [currentDateRange, setCurrentDateRange] = useState7(value);
2367
2496
  const valueLabel = getDateRangePickerLabel(value, displayValue);
2368
2497
  const hasError = error || !!errorMessage;
2369
2498
  const handleChange = () => {
@@ -2537,10 +2666,10 @@ NumberField.displayName = "NumberField";
2537
2666
 
2538
2667
  // src/components/editors/inputs/TextField/TextField.tsx
2539
2668
  import { forwardRef as forwardRef6 } from "react";
2540
- import { Fragment as Fragment3, jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
2669
+ import { Fragment as Fragment5, jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
2541
2670
  var TextField = forwardRef6(
2542
2671
  ({ value = "", placeholder = "Enter text", maxLength, error, errorMessage, ...props }, ref) => {
2543
- return /* @__PURE__ */ jsxs17(Fragment3, { children: [
2672
+ return /* @__PURE__ */ jsxs17(Fragment5, { children: [
2544
2673
  /* @__PURE__ */ jsx28(
2545
2674
  InputField,
2546
2675
  {
@@ -2561,7 +2690,7 @@ var TextField = forwardRef6(
2561
2690
  TextField.displayName = "TextField";
2562
2691
 
2563
2692
  // src/components/editors/selects/MultiSelectField/MultiSelectField.tsx
2564
- import { Fragment as Fragment4, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef10, useState as useState7 } from "react";
2693
+ import { Fragment as Fragment6, useEffect as useEffect8, useMemo as useMemo5, useRef as useRef10, useState as useState8 } from "react";
2565
2694
 
2566
2695
  // src/components/editors/selects/shared/SelectFieldContent/SelectFieldOptions/SelectFieldOption/SelectFieldOption.tsx
2567
2696
  import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
@@ -2672,10 +2801,10 @@ var MultiSelectField = ({
2672
2801
  error = false,
2673
2802
  errorMessage
2674
2803
  }) => {
2675
- const [isOpen, setIsOpen] = useState7(false);
2676
- const [searchValue, setSearchValue] = useState7("");
2677
- const [preValues, setPreValues] = useState7(values);
2678
- const [selectedLabel, setSelectedLabel] = useState7("");
2804
+ const [isOpen, setIsOpen] = useState8(false);
2805
+ const [searchValue, setSearchValue] = useState8("");
2806
+ const [preValues, setPreValues] = useState8(values);
2807
+ const [selectedLabel, setSelectedLabel] = useState8("");
2679
2808
  const searchFieldRef = useRef10(null);
2680
2809
  useSelectSearchFocus(isOpen, searchFieldRef);
2681
2810
  useEffect8(() => {
@@ -2697,9 +2826,9 @@ var MultiSelectField = ({
2697
2826
  setSelectedLabel(`(${selectedOptions.length}) ${newLabel}`);
2698
2827
  }
2699
2828
  }, [values, options, isLoading]);
2700
- const debouncedSearch = useMemo4(() => onSearch ? debounce(onSearch) : void 0, [onSearch]);
2829
+ const debouncedSearch = useMemo5(() => onSearch ? debounce(onSearch) : void 0, [onSearch]);
2701
2830
  const displayOptions = isSearchable && !onSearch ? options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase())) : options;
2702
- const groupedOptions = useMemo4(() => groupOptionsByCategory(displayOptions), [displayOptions]);
2831
+ const groupedOptions = useMemo5(() => groupOptionsByCategory(displayOptions), [displayOptions]);
2703
2832
  const isSubmitDisabled = preValues.every((preValue) => values.includes(preValue)) && values.every((value) => preValues.includes(value));
2704
2833
  const handleSelectOption = (e, newValue) => {
2705
2834
  e.preventDefault();
@@ -2765,7 +2894,7 @@ var MultiSelectField = ({
2765
2894
  }
2766
2895
  ),
2767
2896
  /* @__PURE__ */ jsxs19(SelectFieldContentList, { disabled: isLoading, children: [
2768
- groupedOptions ? Object.entries(groupedOptions).map(([category, categoryOptions]) => /* @__PURE__ */ jsxs19(Fragment4, { children: [
2897
+ groupedOptions ? Object.entries(groupedOptions).map(([category, categoryOptions]) => /* @__PURE__ */ jsxs19(Fragment6, { children: [
2769
2898
  /* @__PURE__ */ jsx31(SelectFieldCategory, { label: category }),
2770
2899
  categoryOptions.map((option) => /* @__PURE__ */ jsx31(
2771
2900
  SelectListOption,
@@ -2807,7 +2936,7 @@ var MultiSelectField = ({
2807
2936
  };
2808
2937
 
2809
2938
  // src/components/editors/selects/SingleSelectField/SingleSelectField.tsx
2810
- import { Fragment as Fragment5, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef11, useState as useState8 } from "react";
2939
+ import { Fragment as Fragment7, useEffect as useEffect9, useMemo as useMemo6, useRef as useRef11, useState as useState9 } from "react";
2811
2940
  import { IconSearch as IconSearch2 } from "@tabler/icons-react";
2812
2941
  import styles24 from "./selects.module-MRJADSDF.module.css";
2813
2942
  import { jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
@@ -2832,9 +2961,9 @@ var SingleSelectField = ({
2832
2961
  align,
2833
2962
  variant
2834
2963
  }) => {
2835
- const [isOpen, setIsOpen] = useState8(false);
2836
- const [searchValue, setSearchValue] = useState8("");
2837
- const [selectedLabel, setSelectedLabel] = useState8(value);
2964
+ const [isOpen, setIsOpen] = useState9(false);
2965
+ const [searchValue, setSearchValue] = useState9("");
2966
+ const [selectedLabel, setSelectedLabel] = useState9(value);
2838
2967
  const searchFieldRef = useRef11(null);
2839
2968
  useSelectSearchFocus(isOpen, searchFieldRef);
2840
2969
  useEffect9(() => {
@@ -2847,9 +2976,9 @@ var SingleSelectField = ({
2847
2976
  setSelectedLabel(option.label);
2848
2977
  }
2849
2978
  }, [value, options]);
2850
- const debouncedSearch = useMemo5(() => onSearch ? debounce(onSearch) : void 0, [onSearch]);
2979
+ const debouncedSearch = useMemo6(() => onSearch ? debounce(onSearch) : void 0, [onSearch]);
2851
2980
  const displayOptions = searchable && !onSearch ? options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase())) : options;
2852
- const groupedOptions = useMemo5(() => groupOptionsByCategory(displayOptions), [displayOptions]);
2981
+ const groupedOptions = useMemo6(() => groupOptionsByCategory(displayOptions), [displayOptions]);
2853
2982
  const handleChange = (newValue) => {
2854
2983
  setSearchValue("");
2855
2984
  onChange(newValue ?? "");
@@ -2908,7 +3037,7 @@ var SingleSelectField = ({
2908
3037
  }
2909
3038
  ),
2910
3039
  /* @__PURE__ */ jsxs20(SelectFieldContentList, { disabled: isLoading, children: [
2911
- groupedOptions ? Object.entries(groupedOptions).map(([category, categoryOptions]) => /* @__PURE__ */ jsxs20(Fragment5, { children: [
3040
+ groupedOptions ? Object.entries(groupedOptions).map(([category, categoryOptions]) => /* @__PURE__ */ jsxs20(Fragment7, { children: [
2912
3041
  /* @__PURE__ */ jsx32(SelectFieldCategory, { label: category }),
2913
3042
  categoryOptions.map((option) => /* @__PURE__ */ jsx32(
2914
3043
  SelectListOption,
@@ -2991,7 +3120,7 @@ var Switch = ({
2991
3120
 
2992
3121
  // src/components/shared/ButtonIcon/ButtonIcon.tsx
2993
3122
  import clsx19 from "clsx";
2994
- import styles26 from "./ButtonIcon.module-JHFZQSMJ.module.css";
3123
+ import styles26 from "./ButtonIcon.module-Y74WWGDY.module.css";
2995
3124
  import { jsx as jsx34 } from "react/jsx-runtime";
2996
3125
  var ButtonIcon = ({
2997
3126
  icon: Icon,
@@ -3012,7 +3141,7 @@ var ButtonIcon = ({
3012
3141
 
3013
3142
  // src/components/shared/Card/Card.tsx
3014
3143
  import React4 from "react";
3015
- import styles27 from "./Card.module-AAOKM6DN.module.css";
3144
+ import styles27 from "./Card.module-YBJG5NGD.module.css";
3016
3145
  import clsx20 from "clsx";
3017
3146
  import { IconInfoCircle } from "@tabler/icons-react";
3018
3147