@vesture/react 0.2.7 → 0.2.8
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.css +63 -3
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.js +204 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1116,12 +1116,18 @@ var body3 = "DataGrid_body__7xivx77";
|
|
|
1116
1116
|
var cell = "DataGrid_cell__7xivx79";
|
|
1117
1117
|
var checkboxCell = "DataGrid_checkboxCell__7xivx7a";
|
|
1118
1118
|
var container = "DataGrid_container__7xivx71";
|
|
1119
|
-
var editInput = "
|
|
1119
|
+
var editInput = "DataGrid_editInput__7xivx7v";
|
|
1120
1120
|
var emptyState = "DataGrid_emptyState__7xivx7b";
|
|
1121
1121
|
var filterCell = "DataGrid_filterCell__7xivx7j";
|
|
1122
1122
|
var filterInput = "DataGrid_filterInput__7xivx7k";
|
|
1123
1123
|
var filterRow = "DataGrid_filterRow__7xivx7i";
|
|
1124
1124
|
var gridWrapper = "DataGrid_gridWrapper__7xivx7m";
|
|
1125
|
+
var groupAggregateItem = "DataGrid_groupAggregateItem__7xivx7u";
|
|
1126
|
+
var groupAggregates = "DataGrid_groupAggregates__7xivx7t";
|
|
1127
|
+
var groupChevron = "DataGrid_groupChevron__7xivx7q";
|
|
1128
|
+
var groupCount = "DataGrid_groupCount__7xivx7s";
|
|
1129
|
+
var groupLabel = "DataGrid_groupLabel__7xivx7r";
|
|
1130
|
+
var groupRow = "DataGrid_groupRow__7xivx7p";
|
|
1125
1131
|
var headerButton = "DataGrid_headerButton__7xivx74";
|
|
1126
1132
|
var headerCell = "DataGrid_headerCell__7xivx73";
|
|
1127
1133
|
var headerRow = "DataGrid_headerRow__7xivx72";
|
|
@@ -1206,6 +1212,40 @@ function getCellValue(column, row3) {
|
|
|
1206
1212
|
}
|
|
1207
1213
|
return row3[column.key];
|
|
1208
1214
|
}
|
|
1215
|
+
function getGroupValue(row3, groupBy, column) {
|
|
1216
|
+
if (column) {
|
|
1217
|
+
return String(getCellValue(column, row3) ?? "");
|
|
1218
|
+
}
|
|
1219
|
+
return String(row3[groupBy] ?? "");
|
|
1220
|
+
}
|
|
1221
|
+
function formatAggregateNumber(value) {
|
|
1222
|
+
return Number.isInteger(value) ? value : value.toFixed(2);
|
|
1223
|
+
}
|
|
1224
|
+
function computeAggregate(column, rows) {
|
|
1225
|
+
const { aggregate } = column;
|
|
1226
|
+
if (!aggregate) return null;
|
|
1227
|
+
if (typeof aggregate === "function") {
|
|
1228
|
+
return aggregate(rows);
|
|
1229
|
+
}
|
|
1230
|
+
if (aggregate === "count") {
|
|
1231
|
+
return rows.length;
|
|
1232
|
+
}
|
|
1233
|
+
const values = rows.map((r) => Number(getCellValue(column, r)) || 0);
|
|
1234
|
+
switch (aggregate) {
|
|
1235
|
+
case "sum":
|
|
1236
|
+
return formatAggregateNumber(values.reduce((a, b) => a + b, 0));
|
|
1237
|
+
case "avg":
|
|
1238
|
+
return formatAggregateNumber(
|
|
1239
|
+
values.length ? values.reduce((a, b) => a + b, 0) / values.length : 0
|
|
1240
|
+
);
|
|
1241
|
+
case "min":
|
|
1242
|
+
return formatAggregateNumber(values.length ? Math.min(...values) : 0);
|
|
1243
|
+
case "max":
|
|
1244
|
+
return formatAggregateNumber(values.length ? Math.max(...values) : 0);
|
|
1245
|
+
default:
|
|
1246
|
+
return null;
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1209
1249
|
function DataGridInner({
|
|
1210
1250
|
columns,
|
|
1211
1251
|
data,
|
|
@@ -1229,6 +1269,13 @@ function DataGridInner({
|
|
|
1229
1269
|
pageSize,
|
|
1230
1270
|
onPageChange,
|
|
1231
1271
|
enableExport = false,
|
|
1272
|
+
groupBy: controlledGroupBy,
|
|
1273
|
+
defaultGroupBy,
|
|
1274
|
+
onGroupByChange,
|
|
1275
|
+
expandedGroups: controlledExpandedGroups,
|
|
1276
|
+
defaultExpandedGroups,
|
|
1277
|
+
onExpandedGroupsChange,
|
|
1278
|
+
groupRowHeight,
|
|
1232
1279
|
onRowClick,
|
|
1233
1280
|
onRowDoubleClick,
|
|
1234
1281
|
onCellClick
|
|
@@ -1248,10 +1295,31 @@ function DataGridInner({
|
|
|
1248
1295
|
const [scrollTop, setScrollTop] = useState8(0);
|
|
1249
1296
|
const [editingRowId, setEditingRowId] = useState8(null);
|
|
1250
1297
|
const [editDraft, setEditDraft] = useState8({});
|
|
1298
|
+
const [uncontrolledGroupBy, setUncontrolledGroupBy] = useState8(defaultGroupBy);
|
|
1299
|
+
const [uncontrolledExpandedGroups, setUncontrolledExpandedGroups] = useState8(defaultExpandedGroups);
|
|
1251
1300
|
const editingEnabled = Boolean(onRowEdit);
|
|
1252
1301
|
const sort = controlledSort !== void 0 ? controlledSort : uncontrolledSort;
|
|
1253
1302
|
const filters = controlledFilters !== void 0 ? controlledFilters : uncontrolledFilters;
|
|
1254
1303
|
const selectedIds = controlledSelectedIds ?? uncontrolledSelectedIds;
|
|
1304
|
+
const groupBy = controlledGroupBy !== void 0 ? controlledGroupBy : uncontrolledGroupBy;
|
|
1305
|
+
const expandedGroups = controlledExpandedGroups !== void 0 ? controlledExpandedGroups : uncontrolledExpandedGroups;
|
|
1306
|
+
const setExpandedGroups = (next) => {
|
|
1307
|
+
if (controlledExpandedGroups === void 0) {
|
|
1308
|
+
setUncontrolledExpandedGroups(next);
|
|
1309
|
+
}
|
|
1310
|
+
onExpandedGroupsChange?.(next);
|
|
1311
|
+
};
|
|
1312
|
+
const isGroupExpanded = (key) => expandedGroups === void 0 ? true : expandedGroups.has(key);
|
|
1313
|
+
const toggleGroupExpanded = (key, allGroupKeys) => {
|
|
1314
|
+
const current2 = expandedGroups ?? new Set(allGroupKeys);
|
|
1315
|
+
const next = new Set(current2);
|
|
1316
|
+
if (next.has(key)) {
|
|
1317
|
+
next.delete(key);
|
|
1318
|
+
} else {
|
|
1319
|
+
next.add(key);
|
|
1320
|
+
}
|
|
1321
|
+
setExpandedGroups(next);
|
|
1322
|
+
};
|
|
1255
1323
|
const setSort = (next) => {
|
|
1256
1324
|
if (controlledSort === void 0) {
|
|
1257
1325
|
setUncontrolledSort(next);
|
|
@@ -1315,6 +1383,44 @@ function DataGridInner({
|
|
|
1315
1383
|
);
|
|
1316
1384
|
return sort.direction === "desc" ? sorted.reverse() : sorted;
|
|
1317
1385
|
}, [filteredData, sort, columns, serverSide, data]);
|
|
1386
|
+
const groupColumn = useMemo2(
|
|
1387
|
+
() => groupBy ? columns.find((c) => c.key === groupBy) : void 0,
|
|
1388
|
+
[columns, groupBy]
|
|
1389
|
+
);
|
|
1390
|
+
const groupedMap = useMemo2(() => {
|
|
1391
|
+
if (!groupBy) return null;
|
|
1392
|
+
const map = /* @__PURE__ */ new Map();
|
|
1393
|
+
for (const row3 of sortedData) {
|
|
1394
|
+
const key = getGroupValue(row3, groupBy, groupColumn);
|
|
1395
|
+
const existing = map.get(key);
|
|
1396
|
+
if (existing) {
|
|
1397
|
+
existing.push(row3);
|
|
1398
|
+
} else {
|
|
1399
|
+
map.set(key, [row3]);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
return map;
|
|
1403
|
+
}, [sortedData, groupBy, groupColumn]);
|
|
1404
|
+
const flatEntries = useMemo2(() => {
|
|
1405
|
+
if (!groupedMap) {
|
|
1406
|
+
return sortedData.map((row3) => ({ type: "data", row: row3 }));
|
|
1407
|
+
}
|
|
1408
|
+
const entries = [];
|
|
1409
|
+
for (const [key, rows] of groupedMap) {
|
|
1410
|
+
const collapsed = !isGroupExpanded(key);
|
|
1411
|
+
entries.push({ type: "group", key, rows, collapsed });
|
|
1412
|
+
if (!collapsed) {
|
|
1413
|
+
for (const row3 of rows) {
|
|
1414
|
+
entries.push({ type: "data", row: row3 });
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
return entries;
|
|
1419
|
+
}, [groupedMap, expandedGroups, sortedData]);
|
|
1420
|
+
const visibleDataRows = useMemo2(
|
|
1421
|
+
() => flatEntries.filter((e) => e.type === "data").map((e) => e.row),
|
|
1422
|
+
[flatEntries]
|
|
1423
|
+
);
|
|
1318
1424
|
const exportToExcel = useCallback2(
|
|
1319
1425
|
async (options) => {
|
|
1320
1426
|
const XLSX = await import("xlsx");
|
|
@@ -1348,13 +1454,13 @@ function DataGridInner({
|
|
|
1348
1454
|
}, [columns, data]);
|
|
1349
1455
|
const hasFilterableColumns = columns.some((c) => c.filterable);
|
|
1350
1456
|
const showPagination = page !== void 0 && pageSize !== void 0 && onPageChange !== void 0;
|
|
1351
|
-
const allSelected =
|
|
1352
|
-
const someSelected = !allSelected &&
|
|
1457
|
+
const allSelected = visibleDataRows.length > 0 && visibleDataRows.every((r) => selectedIds.has(getRowId(r)));
|
|
1458
|
+
const someSelected = !allSelected && visibleDataRows.some((r) => selectedIds.has(getRowId(r)));
|
|
1353
1459
|
const toggleAll = () => {
|
|
1354
1460
|
if (allSelected) {
|
|
1355
1461
|
setSelectedIds(/* @__PURE__ */ new Set());
|
|
1356
1462
|
} else {
|
|
1357
|
-
setSelectedIds(new Set(
|
|
1463
|
+
setSelectedIds(new Set(visibleDataRows.map(getRowId)));
|
|
1358
1464
|
}
|
|
1359
1465
|
};
|
|
1360
1466
|
const toggleRow = (id) => {
|
|
@@ -1479,11 +1585,47 @@ function DataGridInner({
|
|
|
1479
1585
|
setEditingRowId(null);
|
|
1480
1586
|
setEditDraft({});
|
|
1481
1587
|
};
|
|
1482
|
-
const
|
|
1483
|
-
const
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1588
|
+
const resolvedGroupRowHeight = groupRowHeight ?? rowHeight;
|
|
1589
|
+
const rowOffsets = groupedMap ? (() => {
|
|
1590
|
+
const offsets = new Array(flatEntries.length);
|
|
1591
|
+
let acc = 0;
|
|
1592
|
+
for (let i = 0; i < flatEntries.length; i++) {
|
|
1593
|
+
offsets[i] = acc;
|
|
1594
|
+
acc += flatEntries[i].type === "group" ? resolvedGroupRowHeight : rowHeight;
|
|
1595
|
+
}
|
|
1596
|
+
return offsets;
|
|
1597
|
+
})() : null;
|
|
1598
|
+
function findIndexAtOffset(offsets, target) {
|
|
1599
|
+
let lo = 0;
|
|
1600
|
+
let hi = offsets.length - 1;
|
|
1601
|
+
let ans = 0;
|
|
1602
|
+
while (lo <= hi) {
|
|
1603
|
+
const mid = lo + hi >> 1;
|
|
1604
|
+
if (offsets[mid] <= target) {
|
|
1605
|
+
ans = mid;
|
|
1606
|
+
lo = mid + 1;
|
|
1607
|
+
} else {
|
|
1608
|
+
hi = mid - 1;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
return ans;
|
|
1612
|
+
}
|
|
1613
|
+
let totalHeight;
|
|
1614
|
+
let startIndex;
|
|
1615
|
+
let endIndex;
|
|
1616
|
+
if (rowOffsets) {
|
|
1617
|
+
totalHeight = rowOffsets.length ? rowOffsets[rowOffsets.length - 1] + (flatEntries[flatEntries.length - 1].type === "group" ? resolvedGroupRowHeight : rowHeight) : 0;
|
|
1618
|
+
const rawStart = rowOffsets.length ? findIndexAtOffset(rowOffsets, scrollTop) : 0;
|
|
1619
|
+
startIndex = Math.max(0, rawStart - overscan);
|
|
1620
|
+
const rawEnd = rowOffsets.length ? findIndexAtOffset(rowOffsets, scrollTop + height) + 1 : 0;
|
|
1621
|
+
endIndex = Math.min(flatEntries.length, rawEnd + overscan);
|
|
1622
|
+
} else {
|
|
1623
|
+
totalHeight = sortedData.length * rowHeight;
|
|
1624
|
+
const visibleCount = Math.ceil(height / rowHeight) + overscan * 2;
|
|
1625
|
+
startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
|
|
1626
|
+
endIndex = Math.min(flatEntries.length, startIndex + visibleCount);
|
|
1627
|
+
}
|
|
1628
|
+
const visibleEntries = flatEntries.slice(startIndex, endIndex);
|
|
1487
1629
|
const totalWidth = (selectable ? CHECKBOX_COLUMN_WIDTH : 0) + (editingEnabled ? ACTIONS_COLUMN_WIDTH : 0) + columns.reduce((sum, c) => sum + widthOf(c), 0);
|
|
1488
1630
|
return /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
1489
1631
|
/* @__PURE__ */ jsxs17("div", { className: gridWrapper, children: [
|
|
@@ -1657,13 +1799,64 @@ function DataGridInner({
|
|
|
1657
1799
|
width: totalWidth,
|
|
1658
1800
|
minWidth: "100%"
|
|
1659
1801
|
},
|
|
1660
|
-
children:
|
|
1802
|
+
children: visibleEntries.map((entry, i) => {
|
|
1661
1803
|
const index = startIndex + i;
|
|
1804
|
+
const top = rowOffsets ? rowOffsets[index] : index * rowHeight;
|
|
1805
|
+
if (entry.type === "group") {
|
|
1806
|
+
const isExpanded = !entry.collapsed;
|
|
1807
|
+
const groupLabelText = groupColumn ? typeof groupColumn.header === "string" ? groupColumn.header : groupColumn.key : groupBy;
|
|
1808
|
+
const aggregateColumns = columns.filter((c) => c.aggregate);
|
|
1809
|
+
return /* @__PURE__ */ jsxs17(
|
|
1810
|
+
"div",
|
|
1811
|
+
{
|
|
1812
|
+
className: groupRow,
|
|
1813
|
+
style: {
|
|
1814
|
+
top,
|
|
1815
|
+
height: resolvedGroupRowHeight,
|
|
1816
|
+
width: totalWidth
|
|
1817
|
+
},
|
|
1818
|
+
role: "row",
|
|
1819
|
+
children: [
|
|
1820
|
+
/* @__PURE__ */ jsx34(
|
|
1821
|
+
"button",
|
|
1822
|
+
{
|
|
1823
|
+
type: "button",
|
|
1824
|
+
className: groupChevron,
|
|
1825
|
+
"data-expanded": isExpanded || void 0,
|
|
1826
|
+
onClick: () => toggleGroupExpanded(
|
|
1827
|
+
entry.key,
|
|
1828
|
+
Array.from(groupedMap.keys())
|
|
1829
|
+
),
|
|
1830
|
+
"aria-label": isExpanded ? `Collapse group ${entry.key}` : `Expand group ${entry.key}`,
|
|
1831
|
+
children: "\u203A"
|
|
1832
|
+
}
|
|
1833
|
+
),
|
|
1834
|
+
/* @__PURE__ */ jsxs17("span", { className: groupLabel, children: [
|
|
1835
|
+
groupLabelText,
|
|
1836
|
+
": ",
|
|
1837
|
+
entry.key
|
|
1838
|
+
] }),
|
|
1839
|
+
/* @__PURE__ */ jsxs17("span", { className: groupCount, children: [
|
|
1840
|
+
entry.rows.length,
|
|
1841
|
+
" row",
|
|
1842
|
+
entry.rows.length === 1 ? "" : "s"
|
|
1843
|
+
] }),
|
|
1844
|
+
aggregateColumns.length > 0 ? /* @__PURE__ */ jsx34("span", { className: groupAggregates, children: aggregateColumns.map((c) => /* @__PURE__ */ jsxs17("span", { className: groupAggregateItem, children: [
|
|
1845
|
+
typeof c.header === "string" ? c.header : c.key,
|
|
1846
|
+
": ",
|
|
1847
|
+
computeAggregate(c, entry.rows)
|
|
1848
|
+
] }, c.key)) }) : null
|
|
1849
|
+
]
|
|
1850
|
+
},
|
|
1851
|
+
`group-${entry.key}`
|
|
1852
|
+
);
|
|
1853
|
+
}
|
|
1854
|
+
const rowData = entry.row;
|
|
1662
1855
|
const id = getRowId(rowData);
|
|
1663
1856
|
const isSelected = selectedIds.has(id);
|
|
1664
1857
|
const isEditing = editingRowId === id;
|
|
1665
1858
|
const style = {
|
|
1666
|
-
top
|
|
1859
|
+
top,
|
|
1667
1860
|
height: rowHeight,
|
|
1668
1861
|
width: totalWidth
|
|
1669
1862
|
};
|