@cdx-ui/data-grid 0.3.12 → 0.3.14
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/coverage.svg +1 -1
- package/lib/commonjs/DataGrid.js +279 -40
- package/lib/commonjs/DataGrid.js.map +1 -1
- package/lib/commonjs/DataGridFilterPanel.js +136 -9
- package/lib/commonjs/DataGridFilterPanel.js.map +1 -1
- package/lib/commonjs/adapter/columns.js +16 -8
- package/lib/commonjs/adapter/columns.js.map +1 -1
- package/lib/commonjs/adapter/pinning.js +5 -1
- package/lib/commonjs/adapter/pinning.js.map +1 -1
- package/lib/commonjs/adapter/selectColumn.js +11 -0
- package/lib/commonjs/adapter/selectColumn.js.map +1 -1
- package/lib/commonjs/adapter/treeData.js +195 -0
- package/lib/commonjs/adapter/treeData.js.map +1 -0
- package/lib/commonjs/styles.js +48 -2
- package/lib/commonjs/styles.js.map +1 -1
- package/lib/commonjs/types.js +11 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/useDataGridTable.js +143 -12
- package/lib/commonjs/useDataGridTable.js.map +1 -1
- package/lib/module/DataGrid.js +285 -46
- package/lib/module/DataGrid.js.map +1 -1
- package/lib/module/DataGridFilterPanel.js +139 -13
- package/lib/module/DataGridFilterPanel.js.map +1 -1
- package/lib/module/adapter/columns.js +17 -9
- package/lib/module/adapter/columns.js.map +1 -1
- package/lib/module/adapter/pinning.js +5 -1
- package/lib/module/adapter/pinning.js.map +1 -1
- package/lib/module/adapter/selectColumn.js +11 -1
- package/lib/module/adapter/selectColumn.js.map +1 -1
- package/lib/module/adapter/treeData.js +187 -0
- package/lib/module/adapter/treeData.js.map +1 -0
- package/lib/module/styles.js +47 -1
- package/lib/module/styles.js.map +1 -1
- package/lib/module/types.js +10 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDataGridTable.js +147 -16
- package/lib/module/useDataGridTable.js.map +1 -1
- package/lib/typescript/DataGrid.d.ts.map +1 -1
- package/lib/typescript/DataGridFilterPanel.d.ts +39 -4
- package/lib/typescript/DataGridFilterPanel.d.ts.map +1 -1
- package/lib/typescript/adapter/columns.d.ts +1 -1
- package/lib/typescript/adapter/columns.d.ts.map +1 -1
- package/lib/typescript/adapter/pinning.d.ts +1 -0
- package/lib/typescript/adapter/pinning.d.ts.map +1 -1
- package/lib/typescript/adapter/selectColumn.d.ts +8 -0
- package/lib/typescript/adapter/selectColumn.d.ts.map +1 -1
- package/lib/typescript/adapter/treeData.d.ts +36 -0
- package/lib/typescript/adapter/treeData.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/styles.d.ts +12 -1
- package/lib/typescript/styles.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +68 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/useDataGridTable.d.ts +25 -3
- package/lib/typescript/useDataGridTable.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/DataGrid.tsx +399 -59
- package/src/DataGridFilterPanel.tsx +188 -17
- package/src/adapter/columns.ts +21 -7
- package/src/adapter/pinning.ts +10 -1
- package/src/adapter/selectColumn.ts +12 -1
- package/src/adapter/treeData.ts +228 -0
- package/src/index.ts +4 -0
- package/src/styles.ts +57 -1
- package/src/types.ts +76 -0
- package/src/useDataGridTable.ts +217 -15
package/coverage.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="108" height="20" role="img" aria-label="coverage:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="108" height="20" role="img" aria-label="coverage: 88.3%"><title>coverage: 88.3%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="108" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="47" height="20" fill="#4b0"/><rect width="108" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="835" y="150" fill-opacity=".8" filter="url(#blur)" textLength="370">88.3%</text><text x="835" y="150" fill-opacity=".3" textLength="370">88.3%</text></g><text x="835" y="140" textLength="370">88.3%</text></g></g></svg>
|
package/lib/commonjs/DataGrid.js
CHANGED
|
@@ -19,6 +19,9 @@ var _types = require("./types");
|
|
|
19
19
|
var _useDataGridTable = require("./useDataGridTable");
|
|
20
20
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
21
|
const MAX_SKELETON_ROW_COUNT = 10;
|
|
22
|
+
/** Matches the detail panel cell's `px-4`. */
|
|
23
|
+
const DETAIL_PANEL_INSET = 16;
|
|
24
|
+
const TREE_INDENT = 24;
|
|
22
25
|
const DEFAULT_WEB_COLUMN_WIDTH = 100;
|
|
23
26
|
const WEB_TABLE_CONTAINER_STYLE = {
|
|
24
27
|
overflow: 'visible'
|
|
@@ -53,7 +56,7 @@ function effectiveFlex(column, pinned) {
|
|
|
53
56
|
}
|
|
54
57
|
return Math.max(column.flex ?? 0, 0);
|
|
55
58
|
}
|
|
56
|
-
function webColumnWidths(columns,
|
|
59
|
+
function webColumnWidths(columns, leadingWidth, pinned = new Set()) {
|
|
57
60
|
const totalFlex = columns.reduce((total, column) => total + effectiveFlex(column, pinned), 0);
|
|
58
61
|
const widths = new Map();
|
|
59
62
|
if (totalFlex === 0) {
|
|
@@ -66,7 +69,7 @@ function webColumnWidths(columns, checkboxSelection, pinned = new Set()) {
|
|
|
66
69
|
}
|
|
67
70
|
return widths;
|
|
68
71
|
}
|
|
69
|
-
const fixedWidth =
|
|
72
|
+
const fixedWidth = leadingWidth + columns.reduce((total, column) => {
|
|
70
73
|
if (effectiveFlex(column, pinned) > 0) {
|
|
71
74
|
return total;
|
|
72
75
|
}
|
|
@@ -156,7 +159,7 @@ function defaultCellContent(value) {
|
|
|
156
159
|
}
|
|
157
160
|
function DefaultLoadingRows({
|
|
158
161
|
columns,
|
|
159
|
-
|
|
162
|
+
leadingColumnIds,
|
|
160
163
|
rowCount,
|
|
161
164
|
columnWidths,
|
|
162
165
|
orderedColumnIds,
|
|
@@ -164,7 +167,7 @@ function DefaultLoadingRows({
|
|
|
164
167
|
offsets
|
|
165
168
|
}) {
|
|
166
169
|
const colByField = new Map(columns.map(column => [column.field, column]));
|
|
167
|
-
const ids = orderedColumnIds ??
|
|
170
|
+
const ids = orderedColumnIds ?? [...leadingColumnIds, ...columns.map(column => column.field)];
|
|
168
171
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
169
172
|
children: Array.from({
|
|
170
173
|
length: rowCount
|
|
@@ -183,6 +186,12 @@ function DefaultLoadingRows({
|
|
|
183
186
|
})
|
|
184
187
|
}, columnId);
|
|
185
188
|
}
|
|
189
|
+
if (columnId === _types.DETAIL_PANEL_TOGGLE_ID) {
|
|
190
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
191
|
+
className: (0, _utils.cn)((0, _styles.dataGridDetailToggleCellVariants)(), pinnedClassName(pin, false)),
|
|
192
|
+
style: mergePinnedStyle(undefined, pin, offsets, columnId, false)
|
|
193
|
+
}, columnId);
|
|
194
|
+
}
|
|
186
195
|
const column = colByField.get(columnId);
|
|
187
196
|
if (!column) {
|
|
188
197
|
return null;
|
|
@@ -229,6 +238,7 @@ function DataGridInner(props) {
|
|
|
229
238
|
showToolbar = false,
|
|
230
239
|
headerFilters = false,
|
|
231
240
|
pinnedColumns,
|
|
241
|
+
columnVisibilityModel,
|
|
232
242
|
pageSizeOptions = _types.DEFAULT_PAGE_SIZE_OPTIONS,
|
|
233
243
|
noRowsOverlay,
|
|
234
244
|
loadingOverlay,
|
|
@@ -237,8 +247,49 @@ function DataGridInner(props) {
|
|
|
237
247
|
style,
|
|
238
248
|
label,
|
|
239
249
|
'aria-label': ariaLabel,
|
|
240
|
-
'aria-labelledby': ariaLabelledBy
|
|
250
|
+
'aria-labelledby': ariaLabelledBy,
|
|
251
|
+
treeData = false,
|
|
252
|
+
getTreeDataPath,
|
|
253
|
+
groupingColDef,
|
|
254
|
+
defaultGroupingExpansionDepth,
|
|
255
|
+
isGroupExpandedByDefault,
|
|
256
|
+
rowSelectionPropagation,
|
|
257
|
+
getDetailPanelContent
|
|
241
258
|
} = props;
|
|
259
|
+
const treeActive = treeData && getTreeDataPath !== undefined;
|
|
260
|
+
const isColumnVisible = (0, _react.useCallback)(column => columnVisibilityModel?.[column.field] !== false, [columnVisibilityModel]);
|
|
261
|
+
const treeField = treeActive ? columns.find(isColumnVisible)?.field : undefined;
|
|
262
|
+
const gridColumns = (0, _react.useMemo)(() => {
|
|
263
|
+
if (treeField === undefined || groupingColDef === undefined) {
|
|
264
|
+
return columns;
|
|
265
|
+
}
|
|
266
|
+
return columns.map(column => column.field === treeField ? {
|
|
267
|
+
...column,
|
|
268
|
+
...groupingColDef,
|
|
269
|
+
field: column.field
|
|
270
|
+
} : column);
|
|
271
|
+
}, [columns, groupingColDef, treeField]);
|
|
272
|
+
const visibleColumns = (0, _react.useMemo)(() => gridColumns.filter(isColumnVisible), [gridColumns, isColumnVisible]);
|
|
273
|
+
const selectColumn = checkboxSelection && !treeActive;
|
|
274
|
+
const treeCheckbox = checkboxSelection && treeActive;
|
|
275
|
+
const detailPanel = getDetailPanelContent !== undefined;
|
|
276
|
+
const leadingColumnIds = (0, _react.useMemo)(() => [...(selectColumn ? [_types.SELECT_COLUMN_ID] : []), ...(detailPanel ? [_types.DETAIL_PANEL_TOGGLE_ID] : [])], [detailPanel, selectColumn]);
|
|
277
|
+
const leadingWidth = (selectColumn ? _pinning.SELECT_COLUMN_WIDTH : 0) + (detailPanel ? _pinning.DETAIL_PANEL_TOGGLE_WIDTH : 0);
|
|
278
|
+
const [detailPanelExpandedRowIds, setDetailPanelExpandedRowIds] = (0, _utils.useControllableState)({
|
|
279
|
+
prop: props.detailPanelExpandedRowIds,
|
|
280
|
+
defaultProp: props.defaultDetailPanelExpandedRowIds ?? _types.EMPTY_ROW_ID_SET,
|
|
281
|
+
onChange: ids => props.onDetailPanelExpandedRowIdsChange?.(new Set(ids))
|
|
282
|
+
});
|
|
283
|
+
const resolvedDetailIds = detailPanelExpandedRowIds ?? _types.EMPTY_ROW_ID_SET;
|
|
284
|
+
const toggleDetailPanel = id => {
|
|
285
|
+
const next = new Set(resolvedDetailIds);
|
|
286
|
+
if (next.has(id)) {
|
|
287
|
+
next.delete(id);
|
|
288
|
+
} else {
|
|
289
|
+
next.add(id);
|
|
290
|
+
}
|
|
291
|
+
setDetailPanelExpandedRowIds(next);
|
|
292
|
+
};
|
|
242
293
|
const [sortModel, setSortModel] = (0, _utils.useControllableState)({
|
|
243
294
|
prop: props.sortModel,
|
|
244
295
|
defaultProp: props.defaultSortModel ?? [],
|
|
@@ -276,18 +327,25 @@ function DataGridInner(props) {
|
|
|
276
327
|
const resolvedQuickFilter = quickFilter ?? '';
|
|
277
328
|
const resolvedSelection = rowSelectionModel ?? _types.EMPTY_SELECTION;
|
|
278
329
|
const knownFields = (0, _react.useMemo)(() => new Set(columns.map(column => column.field)), [columns]);
|
|
279
|
-
const columnPinning = (0, _react.useMemo)(() => (0, _columns.normalizePinnedColumns)(pinnedColumns, knownFields,
|
|
330
|
+
const columnPinning = (0, _react.useMemo)(() => (0, _columns.normalizePinnedColumns)(pinnedColumns, knownFields, selectColumn, detailPanel), [pinnedColumns, knownFields, selectColumn, detailPanel]);
|
|
280
331
|
const pinningActive = (0, _pinning.isColumnPinningActive)(columnPinning);
|
|
281
332
|
const pinnedFields = (0, _react.useMemo)(() => (0, _pinning.pinnedFieldSet)(columnPinning), [columnPinning]);
|
|
282
333
|
const {
|
|
283
334
|
table,
|
|
284
335
|
setQuickFilter: setQuickFilterWithPageReset,
|
|
285
336
|
setColumnFilter,
|
|
286
|
-
setFilterModel: setFilterModelWithPageReset
|
|
337
|
+
setFilterModel: setFilterModelWithPageReset,
|
|
338
|
+
tree
|
|
287
339
|
} = (0, _useDataGridTable.useDataGridTable)({
|
|
288
340
|
rows,
|
|
289
|
-
columns,
|
|
341
|
+
columns: gridColumns,
|
|
290
342
|
getRowId,
|
|
343
|
+
detailPanel,
|
|
344
|
+
treeData: treeActive,
|
|
345
|
+
getTreeDataPath,
|
|
346
|
+
defaultGroupingExpansionDepth,
|
|
347
|
+
isGroupExpandedByDefault,
|
|
348
|
+
rowSelectionPropagation,
|
|
291
349
|
checkboxSelection,
|
|
292
350
|
disableColumnSorting,
|
|
293
351
|
paginationMode,
|
|
@@ -305,18 +363,19 @@ function DataGridInner(props) {
|
|
|
305
363
|
onQuickFilterChange: value => setQuickFilter(value),
|
|
306
364
|
rowSelectionModel: resolvedSelection,
|
|
307
365
|
onRowSelectionModelChange: model => setRowSelectionModel(model),
|
|
308
|
-
columnPinning
|
|
366
|
+
columnPinning,
|
|
367
|
+
columnVisibility: columnVisibilityModel
|
|
309
368
|
});
|
|
310
369
|
const colByField = (0, _react.useMemo)(() => {
|
|
311
370
|
const map = new Map();
|
|
312
|
-
for (const col of
|
|
371
|
+
for (const col of gridColumns) {
|
|
313
372
|
map.set(col.field, col);
|
|
314
373
|
}
|
|
315
374
|
return map;
|
|
316
|
-
}, [
|
|
317
|
-
(0, _pinning.warnPinnedFlexColumns)(
|
|
318
|
-
const columnWidths = (0, _react.useMemo)(() => webColumnWidths(
|
|
319
|
-
const hasFlexColumns = (0, _react.useMemo)(() =>
|
|
375
|
+
}, [gridColumns]);
|
|
376
|
+
(0, _pinning.warnPinnedFlexColumns)(visibleColumns, pinnedFields);
|
|
377
|
+
const columnWidths = (0, _react.useMemo)(() => webColumnWidths(visibleColumns, leadingWidth, pinnedFields), [leadingWidth, visibleColumns, pinnedFields]);
|
|
378
|
+
const hasFlexColumns = (0, _react.useMemo)(() => visibleColumns.some(column => effectiveFlex(column, pinnedFields) > 0), [visibleColumns, pinnedFields]);
|
|
320
379
|
const pinnedOffsets = (0, _react.useMemo)(() => pinningActive ? (0, _pinning.buildPinnedOffsets)(columnPinning, colByField) : null, [pinningActive, columnPinning, colByField]);
|
|
321
380
|
const orderedLeafColumnIds = (0, _react.useMemo)(() => {
|
|
322
381
|
if (!pinningActive) {
|
|
@@ -344,7 +403,7 @@ function DataGridInner(props) {
|
|
|
344
403
|
const pageCount = Math.max(table.getPageCount(), 1);
|
|
345
404
|
const selectedCount = table.getFilteredSelectedRowModel().rows.length;
|
|
346
405
|
const filterableCount = table.getFilteredRowModel().rows.length;
|
|
347
|
-
const headerSelectState = selectedCount === 0 ? {
|
|
406
|
+
const headerSelectState = tree?.headerSelection ?? (selectedCount === 0 ? {
|
|
348
407
|
checked: false,
|
|
349
408
|
indeterminate: false
|
|
350
409
|
} : selectedCount === filterableCount ? {
|
|
@@ -353,7 +412,8 @@ function DataGridInner(props) {
|
|
|
353
412
|
} : {
|
|
354
413
|
checked: false,
|
|
355
414
|
indeterminate: true
|
|
356
|
-
};
|
|
415
|
+
});
|
|
416
|
+
const leafColumnCount = table.getVisibleLeafColumns().length;
|
|
357
417
|
const accessibleName = ariaLabel ?? label;
|
|
358
418
|
const totalCount = paginationMode === 'server' ? rowCount ?? rows.length : filterableCount;
|
|
359
419
|
const filterValueFor = field => {
|
|
@@ -361,14 +421,65 @@ function DataGridInner(props) {
|
|
|
361
421
|
return typeof value === 'string' ? value : '';
|
|
362
422
|
};
|
|
363
423
|
const showToolbarBar = showToolbar || toolbarActions != null;
|
|
364
|
-
const filterPanelColumns = (0, _react.useMemo)(() =>
|
|
365
|
-
|
|
424
|
+
const filterPanelColumns = (0, _react.useMemo)(() => gridColumns.filter(column => column.filterable !== false), [gridColumns]);
|
|
425
|
+
// Header filter cells and the column menu open the panel through `filterPanel.openForField`.
|
|
426
|
+
const filterPanel = (0, _DataGridFilterPanel.useDataGridFilterPanel)({
|
|
427
|
+
columns: filterPanelColumns,
|
|
428
|
+
filterModel: resolvedFilterModel,
|
|
429
|
+
onFilterModelChange: setFilterModel
|
|
430
|
+
});
|
|
431
|
+
const filterPanelOpen = filterPanel.opener !== null && filterPanelColumns.length > 0;
|
|
432
|
+
const filterPanelAnchored = filterPanel.opener?.field !== undefined;
|
|
366
433
|
const filterPanelButtonRef = (0, _react.useRef)(null);
|
|
367
434
|
const showFilterPanelButton = showToolbar && filterPanelColumns.length > 0;
|
|
435
|
+
const mainRef = (0, _react.useRef)(null);
|
|
436
|
+
const [viewportWidth, setViewportWidth] = (0, _react.useState)(undefined);
|
|
437
|
+
(0, _react.useEffect)(() => {
|
|
438
|
+
const main = mainRef.current;
|
|
439
|
+
if (_reactNative.Platform.OS !== 'web' || !detailPanel || main === null || typeof ResizeObserver === 'undefined') {
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
const observer = new ResizeObserver(() => setViewportWidth(main.clientWidth));
|
|
443
|
+
observer.observe(main);
|
|
444
|
+
return () => observer.disconnect();
|
|
445
|
+
}, [detailPanel]);
|
|
446
|
+
const detailPanelContentStyle = (0, _react.useMemo)(() => viewportWidth === undefined ? undefined : {
|
|
447
|
+
position: 'sticky',
|
|
448
|
+
insetInlineStart: DETAIL_PANEL_INSET,
|
|
449
|
+
width: viewportWidth - DETAIL_PANEL_INSET * 2
|
|
450
|
+
}, [viewportWidth]);
|
|
451
|
+
const rootRef = (0, _react.useRef)(null);
|
|
452
|
+
const searchRef = (0, _react.useRef)(null);
|
|
453
|
+
const bodyFocusRef = (0, _react.useRef)(null);
|
|
454
|
+
(0, _react.useEffect)(() => {
|
|
455
|
+
if (_reactNative.Platform.OS !== 'web') {
|
|
456
|
+
return undefined;
|
|
457
|
+
}
|
|
458
|
+
const root = rootRef.current;
|
|
459
|
+
const onFocusIn = event => {
|
|
460
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
461
|
+
bodyFocusRef.current = target !== null && root?.contains(target.closest('tbody')) === true ? target : null;
|
|
462
|
+
};
|
|
463
|
+
document.addEventListener('focusin', onFocusIn);
|
|
464
|
+
return () => document.removeEventListener('focusin', onFocusIn);
|
|
465
|
+
}, []);
|
|
466
|
+
// Only when the focused row control was removed: focus that left the grid stays where it went.
|
|
467
|
+
(0, _react.useEffect)(() => {
|
|
468
|
+
const focused = bodyFocusRef.current;
|
|
469
|
+
if (_reactNative.Platform.OS !== 'web' || focused === null || focused.isConnected) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
bodyFocusRef.current = null;
|
|
473
|
+
const active = document.activeElement;
|
|
474
|
+
if (active === null || active === document.body) {
|
|
475
|
+
searchRef.current?.focus();
|
|
476
|
+
}
|
|
477
|
+
}, [visibleRows]);
|
|
368
478
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
479
|
+
ref: rootRef,
|
|
369
480
|
className: (0, _utils.cn)((0, _styles.dataGridRootVariants)({
|
|
370
481
|
autoHeight
|
|
371
|
-
}), className, filterPanelOpen && 'overflow-visible'),
|
|
482
|
+
}), className, filterPanelOpen && !filterPanelAnchored && 'overflow-visible'),
|
|
372
483
|
style: style,
|
|
373
484
|
...(0, _primitives.mergeDataAttributes)({}, (0, _primitives.dataAttributes)({
|
|
374
485
|
slot: 'data-grid'
|
|
@@ -381,6 +492,7 @@ function DataGridInner(props) {
|
|
|
381
492
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Input.Icon, {
|
|
382
493
|
as: _icons.Search
|
|
383
494
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Input.Field, {
|
|
495
|
+
ref: searchRef,
|
|
384
496
|
value: resolvedQuickFilter,
|
|
385
497
|
onChangeText: setQuickFilterWithPageReset,
|
|
386
498
|
placeholder: "Search",
|
|
@@ -396,12 +508,12 @@ function DataGridInner(props) {
|
|
|
396
508
|
accessibilityState: {
|
|
397
509
|
expanded: filterPanelOpen
|
|
398
510
|
},
|
|
399
|
-
onPress: () =>
|
|
511
|
+
onPress: () => filterPanel.toggle(filterPanelButtonRef)
|
|
400
512
|
}) : null, toolbarActions ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
401
513
|
className: (0, _styles.dataGridToolbarActionsVariants)(),
|
|
402
514
|
children: toolbarActions
|
|
403
515
|
}) : null]
|
|
404
|
-
}) : null,
|
|
516
|
+
}) : null, filterPanelOpen && filterPanel.opener ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_DataGridFilterPanel.DataGridFilterPanel, {
|
|
405
517
|
columns: filterPanelColumns,
|
|
406
518
|
filterModel: resolvedFilterModel,
|
|
407
519
|
onFilterModelChange: setFilterModelWithPageReset,
|
|
@@ -415,9 +527,10 @@ function DataGridInner(props) {
|
|
|
415
527
|
});
|
|
416
528
|
}
|
|
417
529
|
},
|
|
418
|
-
onClose:
|
|
419
|
-
|
|
530
|
+
onClose: filterPanel.close,
|
|
531
|
+
opener: filterPanel.opener
|
|
420
532
|
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
533
|
+
ref: mainRef,
|
|
421
534
|
className: (0, _styles.dataGridMainVariants)({
|
|
422
535
|
autoHeight,
|
|
423
536
|
overlay: isEmpty || loading && loadingOverlay != null
|
|
@@ -435,10 +548,14 @@ function DataGridInner(props) {
|
|
|
435
548
|
children: [label ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Caption, {
|
|
436
549
|
children: label
|
|
437
550
|
}) : null, _reactNative.Platform.OS === 'web' && hasFlexColumns ? /*#__PURE__*/(0, _jsxRuntime.jsx)("colgroup", {
|
|
438
|
-
children: (orderedLeafColumnIds ??
|
|
551
|
+
children: (orderedLeafColumnIds ?? [...leadingColumnIds, ...visibleColumns.map(column => column.field)]).map(columnId => columnId === _types.SELECT_COLUMN_ID ? /*#__PURE__*/(0, _jsxRuntime.jsx)("col", {
|
|
439
552
|
style: {
|
|
440
553
|
width: _pinning.SELECT_COLUMN_WIDTH
|
|
441
554
|
}
|
|
555
|
+
}, columnId) : columnId === _types.DETAIL_PANEL_TOGGLE_ID ? /*#__PURE__*/(0, _jsxRuntime.jsx)("col", {
|
|
556
|
+
style: {
|
|
557
|
+
width: _pinning.DETAIL_PANEL_TOGGLE_WIDTH
|
|
558
|
+
}
|
|
442
559
|
}, columnId) : /*#__PURE__*/(0, _jsxRuntime.jsx)("col", {
|
|
443
560
|
style: {
|
|
444
561
|
width: columnWidths.get(columnId),
|
|
@@ -468,7 +585,14 @@ function DataGridInner(props) {
|
|
|
468
585
|
})
|
|
469
586
|
}, header.id);
|
|
470
587
|
}
|
|
588
|
+
if (header.id === _types.DETAIL_PANEL_TOGGLE_ID) {
|
|
589
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
590
|
+
className: (0, _utils.cn)((0, _styles.dataGridHeadVariants)(), (0, _styles.dataGridDetailToggleCellVariants)(), pinnedClassName(pin, true)),
|
|
591
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, header.id, true)
|
|
592
|
+
}, header.id);
|
|
593
|
+
}
|
|
471
594
|
const col = colByField.get(header.column.id);
|
|
595
|
+
const isTreeColumn = header.column.id === treeField;
|
|
472
596
|
const sorted = header.column.getIsSorted();
|
|
473
597
|
const canSort = !disableColumnSorting && header.column.getCanSort();
|
|
474
598
|
const headerAlign = (0, _columns.resolveColumnHeaderAlign)(col);
|
|
@@ -489,6 +613,13 @@ function DataGridInner(props) {
|
|
|
489
613
|
sorted: sorted !== false
|
|
490
614
|
})
|
|
491
615
|
}) : null;
|
|
616
|
+
const headerLabel = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
617
|
+
children: [headerAlign === 'end' ? sortButton : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Text, {
|
|
618
|
+
numberOfLines: 1,
|
|
619
|
+
className: (0, _styles.dataGridHeaderLabelVariants)(),
|
|
620
|
+
children: col?.renderHeader ? col.renderHeader() : headerName
|
|
621
|
+
}), headerAlign === 'end' ? null : sortButton]
|
|
622
|
+
});
|
|
492
623
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Head, {
|
|
493
624
|
align: headerAlign,
|
|
494
625
|
className: (0, _utils.cn)((0, _styles.dataGridHeadVariants)(), pinnedClassName(pin, true)),
|
|
@@ -499,26 +630,39 @@ function DataGridInner(props) {
|
|
|
499
630
|
'aria-sort': sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : 'none'
|
|
500
631
|
} : {})
|
|
501
632
|
} : {}),
|
|
502
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
633
|
+
children: isTreeColumn ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
634
|
+
className: (0, _styles.dataGridTreeCellInnerVariants)(),
|
|
635
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
636
|
+
className: (0, _styles.dataGridTreeToggleSlotVariants)()
|
|
637
|
+
}), treeCheckbox ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Checkbox, {
|
|
638
|
+
value: "select-all",
|
|
639
|
+
isChecked: headerSelectState.checked,
|
|
640
|
+
isIndeterminate: headerSelectState.indeterminate,
|
|
641
|
+
onChange: () => tree?.toggleAllRowsSelected(),
|
|
642
|
+
accessibilityLabel: "Select all",
|
|
643
|
+
"aria-label": "Select all"
|
|
644
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
645
|
+
className: (0, _utils.cn)((0, _styles.dataGridHeaderCellInnerVariants)({
|
|
646
|
+
align: headerAlign
|
|
647
|
+
}), 'flex-1'),
|
|
648
|
+
children: headerLabel
|
|
649
|
+
})]
|
|
650
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
503
651
|
className: (0, _styles.dataGridHeaderCellInnerVariants)({
|
|
504
652
|
align: headerAlign,
|
|
505
653
|
fitToColumn: _reactNative.Platform.OS === 'web' && columnWidths.has(header.column.id)
|
|
506
654
|
}),
|
|
507
|
-
children:
|
|
508
|
-
numberOfLines: 1,
|
|
509
|
-
className: (0, _styles.dataGridHeaderLabelVariants)(),
|
|
510
|
-
children: col?.renderHeader ? col.renderHeader() : headerName
|
|
511
|
-
}), headerAlign === 'end' ? null : sortButton]
|
|
655
|
+
children: headerLabel
|
|
512
656
|
})
|
|
513
657
|
}, header.id);
|
|
514
658
|
})
|
|
515
659
|
}, headerGroup.id)), headerFilters ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Row, {
|
|
516
|
-
children: (pinningActive ? [...table.getStartVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns(), ...table.getEndVisibleLeafColumns()] : table.
|
|
660
|
+
children: (pinningActive ? [...table.getStartVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns(), ...table.getEndVisibleLeafColumns()] : table.getVisibleLeafColumns()).map(column => {
|
|
517
661
|
const pin = pinMetaFor(column.id, columnPinning);
|
|
518
|
-
if (column.id === _types.SELECT_COLUMN_ID) {
|
|
662
|
+
if (column.id === _types.SELECT_COLUMN_ID || column.id === _types.DETAIL_PANEL_TOGGLE_ID) {
|
|
519
663
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
520
664
|
align: "center",
|
|
521
|
-
className: (0, _utils.cn)((0, _styles.dataGridSelectHeadVariants)(), pinnedClassName(pin, true)),
|
|
665
|
+
className: (0, _utils.cn)((0, _styles.dataGridSelectHeadVariants)(), column.id === _types.DETAIL_PANEL_TOGGLE_ID && 'w-12 px-2', pinnedClassName(pin, true)),
|
|
522
666
|
style: mergePinnedStyle(undefined, pin, pinnedOffsets, column.id, true)
|
|
523
667
|
}, column.id);
|
|
524
668
|
}
|
|
@@ -550,19 +694,47 @@ function DataGridInner(props) {
|
|
|
550
694
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Body, {
|
|
551
695
|
className: (0, _styles.dataGridBodyVariants)(),
|
|
552
696
|
children: loading && loadingOverlay == null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(DefaultLoadingRows, {
|
|
553
|
-
columns:
|
|
554
|
-
|
|
697
|
+
columns: visibleColumns,
|
|
698
|
+
leadingColumnIds: leadingColumnIds,
|
|
555
699
|
rowCount: Math.min(resolvedPagination.pageSize, MAX_SKELETON_ROW_COUNT),
|
|
556
700
|
columnWidths: columnWidths,
|
|
557
701
|
orderedColumnIds: orderedLeafColumnIds,
|
|
558
702
|
pinning: columnPinning,
|
|
559
703
|
offsets: pinnedOffsets
|
|
560
|
-
}) : isEmpty ? null : visibleRows.
|
|
704
|
+
}) : isEmpty ? null : visibleRows.flatMap(row => {
|
|
561
705
|
const rowId = (0, _useDataGridTable.resolveRowId)(row.original, getRowId);
|
|
562
|
-
const cells = pinningActive ? [...row.getStartVisibleCells(), ...row.getCenterVisibleCells(), ...row.getEndVisibleCells()] : row.
|
|
563
|
-
|
|
706
|
+
const cells = pinningActive ? [...row.getStartVisibleCells(), ...row.getCenterVisibleCells(), ...row.getEndVisibleCells()] : row.getVisibleCells();
|
|
707
|
+
const detailContent = getDetailPanelContent?.({
|
|
708
|
+
id: rowId,
|
|
709
|
+
row: row.original
|
|
710
|
+
});
|
|
711
|
+
const hasDetailPanel = detailContent != null;
|
|
712
|
+
const detailOpen = hasDetailPanel && resolvedDetailIds.has(rowId);
|
|
713
|
+
const treeLabel = treeActive ? [...getTreeDataPath(row.original)].reverse().join(', ') : '';
|
|
714
|
+
const dataRow = /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Row, {
|
|
715
|
+
className: detailOpen ? 'web:[&>*]:border-b-0' : undefined,
|
|
564
716
|
children: cells.map(cell => {
|
|
565
717
|
const pin = pinMetaFor(cell.column.id, columnPinning);
|
|
718
|
+
if (cell.column.id === _types.DETAIL_PANEL_TOGGLE_ID) {
|
|
719
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
720
|
+
align: "center",
|
|
721
|
+
className: (0, _utils.cn)((0, _styles.dataGridDetailToggleCellVariants)(), pinnedClassName(pin, false)),
|
|
722
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, cell.column.id, false),
|
|
723
|
+
children: hasDetailPanel ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.IconButton, {
|
|
724
|
+
as: detailOpen ? _icons.KeyboardArrowDown : _icons.KeyboardArrowRight,
|
|
725
|
+
variant: "ghost",
|
|
726
|
+
color: "neutral",
|
|
727
|
+
size: "small",
|
|
728
|
+
iconClassName: detailOpen ? undefined : 'rtl:-scale-x-100',
|
|
729
|
+
accessibilityLabel: `${detailOpen ? 'Collapse' : 'Expand'} row ${String(rowId)}`,
|
|
730
|
+
accessibilityState: {
|
|
731
|
+
expanded: detailOpen
|
|
732
|
+
},
|
|
733
|
+
"aria-expanded": detailOpen,
|
|
734
|
+
onPress: () => toggleDetailPanel(rowId)
|
|
735
|
+
}) : null
|
|
736
|
+
}, cell.id);
|
|
737
|
+
}
|
|
566
738
|
if (cell.column.id === _types.SELECT_COLUMN_ID) {
|
|
567
739
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
568
740
|
align: "center",
|
|
@@ -598,14 +770,81 @@ function DataGridInner(props) {
|
|
|
598
770
|
const typedText = (0, _columnTypes.getTypedCellText)(col, value, row.original);
|
|
599
771
|
content = typedText !== undefined ? typedText : defaultCellContent(value);
|
|
600
772
|
}
|
|
773
|
+
if (tree && cell.column.id === treeField) {
|
|
774
|
+
const canExpand = row.subRows.length > 0;
|
|
775
|
+
const expanded = canExpand && tree.isRowExpanded(row.id);
|
|
776
|
+
const status = tree.selectionStatus(row.id);
|
|
777
|
+
content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
778
|
+
className: (0, _styles.dataGridTreeCellInnerVariants)(),
|
|
779
|
+
style: {
|
|
780
|
+
paddingStart: row.depth * TREE_INDENT
|
|
781
|
+
},
|
|
782
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
783
|
+
className: (0, _styles.dataGridTreeToggleSlotVariants)(),
|
|
784
|
+
children: canExpand ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.IconButton, {
|
|
785
|
+
as: expanded ? _icons.KeyboardArrowDown : _icons.KeyboardArrowRight,
|
|
786
|
+
variant: "ghost",
|
|
787
|
+
color: "neutral",
|
|
788
|
+
size: "small",
|
|
789
|
+
iconClassName: expanded ? undefined : 'rtl:-scale-x-100',
|
|
790
|
+
accessibilityLabel: `${expanded ? 'Collapse' : 'Expand'} ${treeLabel}`,
|
|
791
|
+
accessibilityState: {
|
|
792
|
+
expanded
|
|
793
|
+
},
|
|
794
|
+
"aria-expanded": expanded,
|
|
795
|
+
onPress: () => tree.toggleRowExpanded(row.id)
|
|
796
|
+
}) : null
|
|
797
|
+
}), treeCheckbox ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Checkbox, {
|
|
798
|
+
value: String(rowId),
|
|
799
|
+
isChecked: status === 'all',
|
|
800
|
+
isIndeterminate: status === 'some',
|
|
801
|
+
onChange: () => tree.toggleRowSelected(row),
|
|
802
|
+
accessibilityLabel: `Select ${treeLabel}`,
|
|
803
|
+
"aria-label": `Select ${treeLabel}`
|
|
804
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
805
|
+
className: (0, _styles.dataGridTreeContentVariants)(),
|
|
806
|
+
children: typeof content === 'string' || typeof content === 'number' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Text, {
|
|
807
|
+
numberOfLines: 1,
|
|
808
|
+
children: content
|
|
809
|
+
}) : content
|
|
810
|
+
})]
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
const align = (0, _columns.resolveColumnAlign)(col);
|
|
814
|
+
const cellText = !col?.renderCell && (typeof content === 'string' || typeof content === 'number') ? String(content) : undefined;
|
|
601
815
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
602
|
-
align:
|
|
816
|
+
align: align,
|
|
817
|
+
...(_reactNative.Platform.OS === 'web' && cellText ? {
|
|
818
|
+
title: cellText
|
|
819
|
+
} : {}),
|
|
603
820
|
className: (0, _utils.cn)((0, _styles.dataGridCellVariants)(), pinnedClassName(pin, false)),
|
|
604
821
|
style: mergePinnedStyle(cellStyle(col, columnWidths.get(cell.column.id)), pin, pinnedOffsets, cell.column.id, false),
|
|
605
|
-
children:
|
|
822
|
+
children: cellText !== undefined ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Text, {
|
|
823
|
+
numberOfLines: 1,
|
|
824
|
+
className: (0, _styles.dataGridCellTextVariants)({
|
|
825
|
+
align,
|
|
826
|
+
fitToColumn: _reactNative.Platform.OS === 'web' && columnWidths.has(cell.column.id)
|
|
827
|
+
}),
|
|
828
|
+
children: cellText
|
|
829
|
+
}) : content
|
|
606
830
|
}, cell.id);
|
|
607
831
|
})
|
|
608
832
|
}, row.id);
|
|
833
|
+
if (!detailOpen) {
|
|
834
|
+
return [dataRow];
|
|
835
|
+
}
|
|
836
|
+
return [dataRow, /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Row, {
|
|
837
|
+
className: "web:hover:bg-transparent",
|
|
838
|
+
testID: `data-grid-detail-panel-${String(rowId)}`,
|
|
839
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Table.Cell, {
|
|
840
|
+
colSpan: leafColumnCount,
|
|
841
|
+
className: (0, _styles.dataGridDetailPanelCellVariants)(),
|
|
842
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
843
|
+
style: detailPanelContentStyle,
|
|
844
|
+
children: detailContent
|
|
845
|
+
})
|
|
846
|
+
})
|
|
847
|
+
}, `${row.id}:detail`)];
|
|
609
848
|
})
|
|
610
849
|
})]
|
|
611
850
|
}), isEmpty ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|