@cdx-ui/data-grid 0.3.12 → 0.3.13
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/lib/module/DataGrid.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { I18nManager, Platform, View } from 'react-native';
|
|
5
5
|
import { Checkbox, Icon, IconButton, Input, Skeleton, Table, TablePagination, Text } from '@cdx-ui/components';
|
|
6
|
-
import { Check, Close, FilterList, KeyboardArrowDown, KeyboardArrowUp, Search } from '@cdx-ui/icons';
|
|
6
|
+
import { Check, Close, FilterList, KeyboardArrowDown, KeyboardArrowRight, KeyboardArrowUp, Search } from '@cdx-ui/icons';
|
|
7
7
|
import { dataAttributes, mergeDataAttributes } from '@cdx-ui/primitives';
|
|
8
8
|
import { cn, useControllableState } from '@cdx-ui/utils';
|
|
9
9
|
import { normalizePinnedColumns, resolveColumnAlign, resolveColumnHeaderAlign } from './adapter/columns';
|
|
10
|
-
import { DEFAULT_PINNED_COLUMN_WIDTH, SELECT_COLUMN_WIDTH, buildPinnedOffsets, isColumnPinningActive, pinnedCellStyle, pinnedEdgeGuidesImage, pinnedFieldSet, warnPinnedFlexColumns } from './adapter/pinning';
|
|
10
|
+
import { DEFAULT_PINNED_COLUMN_WIDTH, DETAIL_PANEL_TOGGLE_WIDTH, SELECT_COLUMN_WIDTH, buildPinnedOffsets, isColumnPinningActive, pinnedCellStyle, pinnedEdgeGuidesImage, pinnedFieldSet, warnPinnedFlexColumns } from './adapter/pinning';
|
|
11
11
|
import { getTypedCellText } from './adapter/columnTypes';
|
|
12
|
-
import { DataGridFilterPanel } from './DataGridFilterPanel';
|
|
13
|
-
import { dataGridBodyVariants, dataGridCellVariants, dataGridEmptyOverlayVariants, dataGridFilterInputVariants, dataGridFooterVariants, dataGridHeadVariants, dataGridHeaderCellInnerVariants, dataGridHeaderLabelVariants, dataGridHeaderVariants, dataGridMainVariants, dataGridOverlayVariants, dataGridPaginationRangeVariants, dataGridPaginationVariants, dataGridPinnedEdgeVariants, dataGridPinnedSurfaceVariants, dataGridRootVariants, dataGridSelectCellVariants, dataGridSelectHeadVariants, dataGridSortButtonVariants, dataGridTableVariants, dataGridToolbarActionsVariants, dataGridToolbarSearchVariants, dataGridToolbarVariants } from './styles';
|
|
14
|
-
import { DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PAGINATION_MODEL, EMPTY_SELECTION, SELECT_COLUMN_ID } from './types';
|
|
12
|
+
import { DataGridFilterPanel, useDataGridFilterPanel } from './DataGridFilterPanel';
|
|
13
|
+
import { dataGridBodyVariants, dataGridCellTextVariants, dataGridCellVariants, dataGridDetailPanelCellVariants, dataGridDetailToggleCellVariants, dataGridEmptyOverlayVariants, dataGridFilterInputVariants, dataGridFooterVariants, dataGridHeadVariants, dataGridHeaderCellInnerVariants, dataGridHeaderLabelVariants, dataGridHeaderVariants, dataGridMainVariants, dataGridOverlayVariants, dataGridPaginationRangeVariants, dataGridPaginationVariants, dataGridPinnedEdgeVariants, dataGridPinnedSurfaceVariants, dataGridRootVariants, dataGridSelectCellVariants, dataGridSelectHeadVariants, dataGridSortButtonVariants, dataGridTableVariants, dataGridToolbarActionsVariants, dataGridToolbarSearchVariants, dataGridToolbarVariants, dataGridTreeCellInnerVariants, dataGridTreeContentVariants, dataGridTreeToggleSlotVariants } from './styles';
|
|
14
|
+
import { DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PAGINATION_MODEL, DETAIL_PANEL_TOGGLE_ID, EMPTY_ROW_ID_SET, EMPTY_SELECTION, SELECT_COLUMN_ID } from './types';
|
|
15
15
|
import { resolveRowId, useDataGridTable } from './useDataGridTable';
|
|
16
16
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
17
|
const MAX_SKELETON_ROW_COUNT = 10;
|
|
18
|
+
/** Matches the detail panel cell's `px-4`. */
|
|
19
|
+
const DETAIL_PANEL_INSET = 16;
|
|
20
|
+
const TREE_INDENT = 24;
|
|
18
21
|
const DEFAULT_WEB_COLUMN_WIDTH = 100;
|
|
19
22
|
const WEB_TABLE_CONTAINER_STYLE = {
|
|
20
23
|
overflow: 'visible'
|
|
@@ -49,7 +52,7 @@ function effectiveFlex(column, pinned) {
|
|
|
49
52
|
}
|
|
50
53
|
return Math.max(column.flex ?? 0, 0);
|
|
51
54
|
}
|
|
52
|
-
function webColumnWidths(columns,
|
|
55
|
+
function webColumnWidths(columns, leadingWidth, pinned = new Set()) {
|
|
53
56
|
const totalFlex = columns.reduce((total, column) => total + effectiveFlex(column, pinned), 0);
|
|
54
57
|
const widths = new Map();
|
|
55
58
|
if (totalFlex === 0) {
|
|
@@ -62,7 +65,7 @@ function webColumnWidths(columns, checkboxSelection, pinned = new Set()) {
|
|
|
62
65
|
}
|
|
63
66
|
return widths;
|
|
64
67
|
}
|
|
65
|
-
const fixedWidth =
|
|
68
|
+
const fixedWidth = leadingWidth + columns.reduce((total, column) => {
|
|
66
69
|
if (effectiveFlex(column, pinned) > 0) {
|
|
67
70
|
return total;
|
|
68
71
|
}
|
|
@@ -152,7 +155,7 @@ function defaultCellContent(value) {
|
|
|
152
155
|
}
|
|
153
156
|
function DefaultLoadingRows({
|
|
154
157
|
columns,
|
|
155
|
-
|
|
158
|
+
leadingColumnIds,
|
|
156
159
|
rowCount,
|
|
157
160
|
columnWidths,
|
|
158
161
|
orderedColumnIds,
|
|
@@ -160,7 +163,7 @@ function DefaultLoadingRows({
|
|
|
160
163
|
offsets
|
|
161
164
|
}) {
|
|
162
165
|
const colByField = new Map(columns.map(column => [column.field, column]));
|
|
163
|
-
const ids = orderedColumnIds ??
|
|
166
|
+
const ids = orderedColumnIds ?? [...leadingColumnIds, ...columns.map(column => column.field)];
|
|
164
167
|
return /*#__PURE__*/_jsx(_Fragment, {
|
|
165
168
|
children: Array.from({
|
|
166
169
|
length: rowCount
|
|
@@ -179,6 +182,12 @@ function DefaultLoadingRows({
|
|
|
179
182
|
})
|
|
180
183
|
}, columnId);
|
|
181
184
|
}
|
|
185
|
+
if (columnId === DETAIL_PANEL_TOGGLE_ID) {
|
|
186
|
+
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
187
|
+
className: cn(dataGridDetailToggleCellVariants(), pinnedClassName(pin, false)),
|
|
188
|
+
style: mergePinnedStyle(undefined, pin, offsets, columnId, false)
|
|
189
|
+
}, columnId);
|
|
190
|
+
}
|
|
182
191
|
const column = colByField.get(columnId);
|
|
183
192
|
if (!column) {
|
|
184
193
|
return null;
|
|
@@ -225,6 +234,7 @@ function DataGridInner(props) {
|
|
|
225
234
|
showToolbar = false,
|
|
226
235
|
headerFilters = false,
|
|
227
236
|
pinnedColumns,
|
|
237
|
+
columnVisibilityModel,
|
|
228
238
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
229
239
|
noRowsOverlay,
|
|
230
240
|
loadingOverlay,
|
|
@@ -233,8 +243,49 @@ function DataGridInner(props) {
|
|
|
233
243
|
style,
|
|
234
244
|
label,
|
|
235
245
|
'aria-label': ariaLabel,
|
|
236
|
-
'aria-labelledby': ariaLabelledBy
|
|
246
|
+
'aria-labelledby': ariaLabelledBy,
|
|
247
|
+
treeData = false,
|
|
248
|
+
getTreeDataPath,
|
|
249
|
+
groupingColDef,
|
|
250
|
+
defaultGroupingExpansionDepth,
|
|
251
|
+
isGroupExpandedByDefault,
|
|
252
|
+
rowSelectionPropagation,
|
|
253
|
+
getDetailPanelContent
|
|
237
254
|
} = props;
|
|
255
|
+
const treeActive = treeData && getTreeDataPath !== undefined;
|
|
256
|
+
const isColumnVisible = useCallback(column => columnVisibilityModel?.[column.field] !== false, [columnVisibilityModel]);
|
|
257
|
+
const treeField = treeActive ? columns.find(isColumnVisible)?.field : undefined;
|
|
258
|
+
const gridColumns = useMemo(() => {
|
|
259
|
+
if (treeField === undefined || groupingColDef === undefined) {
|
|
260
|
+
return columns;
|
|
261
|
+
}
|
|
262
|
+
return columns.map(column => column.field === treeField ? {
|
|
263
|
+
...column,
|
|
264
|
+
...groupingColDef,
|
|
265
|
+
field: column.field
|
|
266
|
+
} : column);
|
|
267
|
+
}, [columns, groupingColDef, treeField]);
|
|
268
|
+
const visibleColumns = useMemo(() => gridColumns.filter(isColumnVisible), [gridColumns, isColumnVisible]);
|
|
269
|
+
const selectColumn = checkboxSelection && !treeActive;
|
|
270
|
+
const treeCheckbox = checkboxSelection && treeActive;
|
|
271
|
+
const detailPanel = getDetailPanelContent !== undefined;
|
|
272
|
+
const leadingColumnIds = useMemo(() => [...(selectColumn ? [SELECT_COLUMN_ID] : []), ...(detailPanel ? [DETAIL_PANEL_TOGGLE_ID] : [])], [detailPanel, selectColumn]);
|
|
273
|
+
const leadingWidth = (selectColumn ? SELECT_COLUMN_WIDTH : 0) + (detailPanel ? DETAIL_PANEL_TOGGLE_WIDTH : 0);
|
|
274
|
+
const [detailPanelExpandedRowIds, setDetailPanelExpandedRowIds] = useControllableState({
|
|
275
|
+
prop: props.detailPanelExpandedRowIds,
|
|
276
|
+
defaultProp: props.defaultDetailPanelExpandedRowIds ?? EMPTY_ROW_ID_SET,
|
|
277
|
+
onChange: ids => props.onDetailPanelExpandedRowIdsChange?.(new Set(ids))
|
|
278
|
+
});
|
|
279
|
+
const resolvedDetailIds = detailPanelExpandedRowIds ?? EMPTY_ROW_ID_SET;
|
|
280
|
+
const toggleDetailPanel = id => {
|
|
281
|
+
const next = new Set(resolvedDetailIds);
|
|
282
|
+
if (next.has(id)) {
|
|
283
|
+
next.delete(id);
|
|
284
|
+
} else {
|
|
285
|
+
next.add(id);
|
|
286
|
+
}
|
|
287
|
+
setDetailPanelExpandedRowIds(next);
|
|
288
|
+
};
|
|
238
289
|
const [sortModel, setSortModel] = useControllableState({
|
|
239
290
|
prop: props.sortModel,
|
|
240
291
|
defaultProp: props.defaultSortModel ?? [],
|
|
@@ -272,18 +323,25 @@ function DataGridInner(props) {
|
|
|
272
323
|
const resolvedQuickFilter = quickFilter ?? '';
|
|
273
324
|
const resolvedSelection = rowSelectionModel ?? EMPTY_SELECTION;
|
|
274
325
|
const knownFields = useMemo(() => new Set(columns.map(column => column.field)), [columns]);
|
|
275
|
-
const columnPinning = useMemo(() => normalizePinnedColumns(pinnedColumns, knownFields,
|
|
326
|
+
const columnPinning = useMemo(() => normalizePinnedColumns(pinnedColumns, knownFields, selectColumn, detailPanel), [pinnedColumns, knownFields, selectColumn, detailPanel]);
|
|
276
327
|
const pinningActive = isColumnPinningActive(columnPinning);
|
|
277
328
|
const pinnedFields = useMemo(() => pinnedFieldSet(columnPinning), [columnPinning]);
|
|
278
329
|
const {
|
|
279
330
|
table,
|
|
280
331
|
setQuickFilter: setQuickFilterWithPageReset,
|
|
281
332
|
setColumnFilter,
|
|
282
|
-
setFilterModel: setFilterModelWithPageReset
|
|
333
|
+
setFilterModel: setFilterModelWithPageReset,
|
|
334
|
+
tree
|
|
283
335
|
} = useDataGridTable({
|
|
284
336
|
rows,
|
|
285
|
-
columns,
|
|
337
|
+
columns: gridColumns,
|
|
286
338
|
getRowId,
|
|
339
|
+
detailPanel,
|
|
340
|
+
treeData: treeActive,
|
|
341
|
+
getTreeDataPath,
|
|
342
|
+
defaultGroupingExpansionDepth,
|
|
343
|
+
isGroupExpandedByDefault,
|
|
344
|
+
rowSelectionPropagation,
|
|
287
345
|
checkboxSelection,
|
|
288
346
|
disableColumnSorting,
|
|
289
347
|
paginationMode,
|
|
@@ -301,18 +359,19 @@ function DataGridInner(props) {
|
|
|
301
359
|
onQuickFilterChange: value => setQuickFilter(value),
|
|
302
360
|
rowSelectionModel: resolvedSelection,
|
|
303
361
|
onRowSelectionModelChange: model => setRowSelectionModel(model),
|
|
304
|
-
columnPinning
|
|
362
|
+
columnPinning,
|
|
363
|
+
columnVisibility: columnVisibilityModel
|
|
305
364
|
});
|
|
306
365
|
const colByField = useMemo(() => {
|
|
307
366
|
const map = new Map();
|
|
308
|
-
for (const col of
|
|
367
|
+
for (const col of gridColumns) {
|
|
309
368
|
map.set(col.field, col);
|
|
310
369
|
}
|
|
311
370
|
return map;
|
|
312
|
-
}, [
|
|
313
|
-
warnPinnedFlexColumns(
|
|
314
|
-
const columnWidths = useMemo(() => webColumnWidths(
|
|
315
|
-
const hasFlexColumns = useMemo(() =>
|
|
371
|
+
}, [gridColumns]);
|
|
372
|
+
warnPinnedFlexColumns(visibleColumns, pinnedFields);
|
|
373
|
+
const columnWidths = useMemo(() => webColumnWidths(visibleColumns, leadingWidth, pinnedFields), [leadingWidth, visibleColumns, pinnedFields]);
|
|
374
|
+
const hasFlexColumns = useMemo(() => visibleColumns.some(column => effectiveFlex(column, pinnedFields) > 0), [visibleColumns, pinnedFields]);
|
|
316
375
|
const pinnedOffsets = useMemo(() => pinningActive ? buildPinnedOffsets(columnPinning, colByField) : null, [pinningActive, columnPinning, colByField]);
|
|
317
376
|
const orderedLeafColumnIds = useMemo(() => {
|
|
318
377
|
if (!pinningActive) {
|
|
@@ -340,7 +399,7 @@ function DataGridInner(props) {
|
|
|
340
399
|
const pageCount = Math.max(table.getPageCount(), 1);
|
|
341
400
|
const selectedCount = table.getFilteredSelectedRowModel().rows.length;
|
|
342
401
|
const filterableCount = table.getFilteredRowModel().rows.length;
|
|
343
|
-
const headerSelectState = selectedCount === 0 ? {
|
|
402
|
+
const headerSelectState = tree?.headerSelection ?? (selectedCount === 0 ? {
|
|
344
403
|
checked: false,
|
|
345
404
|
indeterminate: false
|
|
346
405
|
} : selectedCount === filterableCount ? {
|
|
@@ -349,7 +408,8 @@ function DataGridInner(props) {
|
|
|
349
408
|
} : {
|
|
350
409
|
checked: false,
|
|
351
410
|
indeterminate: true
|
|
352
|
-
};
|
|
411
|
+
});
|
|
412
|
+
const leafColumnCount = table.getVisibleLeafColumns().length;
|
|
353
413
|
const accessibleName = ariaLabel ?? label;
|
|
354
414
|
const totalCount = paginationMode === 'server' ? rowCount ?? rows.length : filterableCount;
|
|
355
415
|
const filterValueFor = field => {
|
|
@@ -357,14 +417,65 @@ function DataGridInner(props) {
|
|
|
357
417
|
return typeof value === 'string' ? value : '';
|
|
358
418
|
};
|
|
359
419
|
const showToolbarBar = showToolbar || toolbarActions != null;
|
|
360
|
-
const filterPanelColumns = useMemo(() =>
|
|
361
|
-
|
|
420
|
+
const filterPanelColumns = useMemo(() => gridColumns.filter(column => column.filterable !== false), [gridColumns]);
|
|
421
|
+
// Header filter cells and the column menu open the panel through `filterPanel.openForField`.
|
|
422
|
+
const filterPanel = useDataGridFilterPanel({
|
|
423
|
+
columns: filterPanelColumns,
|
|
424
|
+
filterModel: resolvedFilterModel,
|
|
425
|
+
onFilterModelChange: setFilterModel
|
|
426
|
+
});
|
|
427
|
+
const filterPanelOpen = filterPanel.opener !== null && filterPanelColumns.length > 0;
|
|
428
|
+
const filterPanelAnchored = filterPanel.opener?.field !== undefined;
|
|
362
429
|
const filterPanelButtonRef = useRef(null);
|
|
363
430
|
const showFilterPanelButton = showToolbar && filterPanelColumns.length > 0;
|
|
431
|
+
const mainRef = useRef(null);
|
|
432
|
+
const [viewportWidth, setViewportWidth] = useState(undefined);
|
|
433
|
+
useEffect(() => {
|
|
434
|
+
const main = mainRef.current;
|
|
435
|
+
if (Platform.OS !== 'web' || !detailPanel || main === null || typeof ResizeObserver === 'undefined') {
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
const observer = new ResizeObserver(() => setViewportWidth(main.clientWidth));
|
|
439
|
+
observer.observe(main);
|
|
440
|
+
return () => observer.disconnect();
|
|
441
|
+
}, [detailPanel]);
|
|
442
|
+
const detailPanelContentStyle = useMemo(() => viewportWidth === undefined ? undefined : {
|
|
443
|
+
position: 'sticky',
|
|
444
|
+
insetInlineStart: DETAIL_PANEL_INSET,
|
|
445
|
+
width: viewportWidth - DETAIL_PANEL_INSET * 2
|
|
446
|
+
}, [viewportWidth]);
|
|
447
|
+
const rootRef = useRef(null);
|
|
448
|
+
const searchRef = useRef(null);
|
|
449
|
+
const bodyFocusRef = useRef(null);
|
|
450
|
+
useEffect(() => {
|
|
451
|
+
if (Platform.OS !== 'web') {
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
const root = rootRef.current;
|
|
455
|
+
const onFocusIn = event => {
|
|
456
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
457
|
+
bodyFocusRef.current = target !== null && root?.contains(target.closest('tbody')) === true ? target : null;
|
|
458
|
+
};
|
|
459
|
+
document.addEventListener('focusin', onFocusIn);
|
|
460
|
+
return () => document.removeEventListener('focusin', onFocusIn);
|
|
461
|
+
}, []);
|
|
462
|
+
// Only when the focused row control was removed: focus that left the grid stays where it went.
|
|
463
|
+
useEffect(() => {
|
|
464
|
+
const focused = bodyFocusRef.current;
|
|
465
|
+
if (Platform.OS !== 'web' || focused === null || focused.isConnected) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
bodyFocusRef.current = null;
|
|
469
|
+
const active = document.activeElement;
|
|
470
|
+
if (active === null || active === document.body) {
|
|
471
|
+
searchRef.current?.focus();
|
|
472
|
+
}
|
|
473
|
+
}, [visibleRows]);
|
|
364
474
|
return /*#__PURE__*/_jsxs(View, {
|
|
475
|
+
ref: rootRef,
|
|
365
476
|
className: cn(dataGridRootVariants({
|
|
366
477
|
autoHeight
|
|
367
|
-
}), className, filterPanelOpen && 'overflow-visible'),
|
|
478
|
+
}), className, filterPanelOpen && !filterPanelAnchored && 'overflow-visible'),
|
|
368
479
|
style: style,
|
|
369
480
|
...mergeDataAttributes({}, dataAttributes({
|
|
370
481
|
slot: 'data-grid'
|
|
@@ -377,6 +488,7 @@ function DataGridInner(props) {
|
|
|
377
488
|
children: [/*#__PURE__*/_jsx(Input.Icon, {
|
|
378
489
|
as: Search
|
|
379
490
|
}), /*#__PURE__*/_jsx(Input.Field, {
|
|
491
|
+
ref: searchRef,
|
|
380
492
|
value: resolvedQuickFilter,
|
|
381
493
|
onChangeText: setQuickFilterWithPageReset,
|
|
382
494
|
placeholder: "Search",
|
|
@@ -392,12 +504,12 @@ function DataGridInner(props) {
|
|
|
392
504
|
accessibilityState: {
|
|
393
505
|
expanded: filterPanelOpen
|
|
394
506
|
},
|
|
395
|
-
onPress: () =>
|
|
507
|
+
onPress: () => filterPanel.toggle(filterPanelButtonRef)
|
|
396
508
|
}) : null, toolbarActions ? /*#__PURE__*/_jsx(View, {
|
|
397
509
|
className: dataGridToolbarActionsVariants(),
|
|
398
510
|
children: toolbarActions
|
|
399
511
|
}) : null]
|
|
400
|
-
}) : null,
|
|
512
|
+
}) : null, filterPanelOpen && filterPanel.opener ? /*#__PURE__*/_jsx(DataGridFilterPanel, {
|
|
401
513
|
columns: filterPanelColumns,
|
|
402
514
|
filterModel: resolvedFilterModel,
|
|
403
515
|
onFilterModelChange: setFilterModelWithPageReset,
|
|
@@ -411,9 +523,10 @@ function DataGridInner(props) {
|
|
|
411
523
|
});
|
|
412
524
|
}
|
|
413
525
|
},
|
|
414
|
-
onClose:
|
|
415
|
-
|
|
526
|
+
onClose: filterPanel.close,
|
|
527
|
+
opener: filterPanel.opener
|
|
416
528
|
}) : null, /*#__PURE__*/_jsxs(View, {
|
|
529
|
+
ref: mainRef,
|
|
417
530
|
className: dataGridMainVariants({
|
|
418
531
|
autoHeight,
|
|
419
532
|
overlay: isEmpty || loading && loadingOverlay != null
|
|
@@ -431,10 +544,14 @@ function DataGridInner(props) {
|
|
|
431
544
|
children: [label ? /*#__PURE__*/_jsx(Table.Caption, {
|
|
432
545
|
children: label
|
|
433
546
|
}) : null, Platform.OS === 'web' && hasFlexColumns ? /*#__PURE__*/_jsx("colgroup", {
|
|
434
|
-
children: (orderedLeafColumnIds ??
|
|
547
|
+
children: (orderedLeafColumnIds ?? [...leadingColumnIds, ...visibleColumns.map(column => column.field)]).map(columnId => columnId === SELECT_COLUMN_ID ? /*#__PURE__*/_jsx("col", {
|
|
435
548
|
style: {
|
|
436
549
|
width: SELECT_COLUMN_WIDTH
|
|
437
550
|
}
|
|
551
|
+
}, columnId) : columnId === DETAIL_PANEL_TOGGLE_ID ? /*#__PURE__*/_jsx("col", {
|
|
552
|
+
style: {
|
|
553
|
+
width: DETAIL_PANEL_TOGGLE_WIDTH
|
|
554
|
+
}
|
|
438
555
|
}, columnId) : /*#__PURE__*/_jsx("col", {
|
|
439
556
|
style: {
|
|
440
557
|
width: columnWidths.get(columnId),
|
|
@@ -464,7 +581,14 @@ function DataGridInner(props) {
|
|
|
464
581
|
})
|
|
465
582
|
}, header.id);
|
|
466
583
|
}
|
|
584
|
+
if (header.id === DETAIL_PANEL_TOGGLE_ID) {
|
|
585
|
+
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
586
|
+
className: cn(dataGridHeadVariants(), dataGridDetailToggleCellVariants(), pinnedClassName(pin, true)),
|
|
587
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, header.id, true)
|
|
588
|
+
}, header.id);
|
|
589
|
+
}
|
|
467
590
|
const col = colByField.get(header.column.id);
|
|
591
|
+
const isTreeColumn = header.column.id === treeField;
|
|
468
592
|
const sorted = header.column.getIsSorted();
|
|
469
593
|
const canSort = !disableColumnSorting && header.column.getCanSort();
|
|
470
594
|
const headerAlign = resolveColumnHeaderAlign(col);
|
|
@@ -485,6 +609,13 @@ function DataGridInner(props) {
|
|
|
485
609
|
sorted: sorted !== false
|
|
486
610
|
})
|
|
487
611
|
}) : null;
|
|
612
|
+
const headerLabel = /*#__PURE__*/_jsxs(_Fragment, {
|
|
613
|
+
children: [headerAlign === 'end' ? sortButton : null, /*#__PURE__*/_jsx(Text, {
|
|
614
|
+
numberOfLines: 1,
|
|
615
|
+
className: dataGridHeaderLabelVariants(),
|
|
616
|
+
children: col?.renderHeader ? col.renderHeader() : headerName
|
|
617
|
+
}), headerAlign === 'end' ? null : sortButton]
|
|
618
|
+
});
|
|
488
619
|
return /*#__PURE__*/_jsx(Table.Head, {
|
|
489
620
|
align: headerAlign,
|
|
490
621
|
className: cn(dataGridHeadVariants(), pinnedClassName(pin, true)),
|
|
@@ -495,26 +626,39 @@ function DataGridInner(props) {
|
|
|
495
626
|
'aria-sort': sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : 'none'
|
|
496
627
|
} : {})
|
|
497
628
|
} : {}),
|
|
498
|
-
children: /*#__PURE__*/_jsxs(View, {
|
|
629
|
+
children: isTreeColumn ? /*#__PURE__*/_jsxs(View, {
|
|
630
|
+
className: dataGridTreeCellInnerVariants(),
|
|
631
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
632
|
+
className: dataGridTreeToggleSlotVariants()
|
|
633
|
+
}), treeCheckbox ? /*#__PURE__*/_jsx(Checkbox, {
|
|
634
|
+
value: "select-all",
|
|
635
|
+
isChecked: headerSelectState.checked,
|
|
636
|
+
isIndeterminate: headerSelectState.indeterminate,
|
|
637
|
+
onChange: () => tree?.toggleAllRowsSelected(),
|
|
638
|
+
accessibilityLabel: "Select all",
|
|
639
|
+
"aria-label": "Select all"
|
|
640
|
+
}) : null, /*#__PURE__*/_jsx(View, {
|
|
641
|
+
className: cn(dataGridHeaderCellInnerVariants({
|
|
642
|
+
align: headerAlign
|
|
643
|
+
}), 'flex-1'),
|
|
644
|
+
children: headerLabel
|
|
645
|
+
})]
|
|
646
|
+
}) : /*#__PURE__*/_jsx(View, {
|
|
499
647
|
className: dataGridHeaderCellInnerVariants({
|
|
500
648
|
align: headerAlign,
|
|
501
649
|
fitToColumn: Platform.OS === 'web' && columnWidths.has(header.column.id)
|
|
502
650
|
}),
|
|
503
|
-
children:
|
|
504
|
-
numberOfLines: 1,
|
|
505
|
-
className: dataGridHeaderLabelVariants(),
|
|
506
|
-
children: col?.renderHeader ? col.renderHeader() : headerName
|
|
507
|
-
}), headerAlign === 'end' ? null : sortButton]
|
|
651
|
+
children: headerLabel
|
|
508
652
|
})
|
|
509
653
|
}, header.id);
|
|
510
654
|
})
|
|
511
655
|
}, headerGroup.id)), headerFilters ? /*#__PURE__*/_jsx(Table.Row, {
|
|
512
|
-
children: (pinningActive ? [...table.getStartVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns(), ...table.getEndVisibleLeafColumns()] : table.
|
|
656
|
+
children: (pinningActive ? [...table.getStartVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns(), ...table.getEndVisibleLeafColumns()] : table.getVisibleLeafColumns()).map(column => {
|
|
513
657
|
const pin = pinMetaFor(column.id, columnPinning);
|
|
514
|
-
if (column.id === SELECT_COLUMN_ID) {
|
|
658
|
+
if (column.id === SELECT_COLUMN_ID || column.id === DETAIL_PANEL_TOGGLE_ID) {
|
|
515
659
|
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
516
660
|
align: "center",
|
|
517
|
-
className: cn(dataGridSelectHeadVariants(), pinnedClassName(pin, true)),
|
|
661
|
+
className: cn(dataGridSelectHeadVariants(), column.id === DETAIL_PANEL_TOGGLE_ID && 'w-12 px-2', pinnedClassName(pin, true)),
|
|
518
662
|
style: mergePinnedStyle(undefined, pin, pinnedOffsets, column.id, true)
|
|
519
663
|
}, column.id);
|
|
520
664
|
}
|
|
@@ -546,19 +690,47 @@ function DataGridInner(props) {
|
|
|
546
690
|
}), /*#__PURE__*/_jsx(Table.Body, {
|
|
547
691
|
className: dataGridBodyVariants(),
|
|
548
692
|
children: loading && loadingOverlay == null ? /*#__PURE__*/_jsx(DefaultLoadingRows, {
|
|
549
|
-
columns:
|
|
550
|
-
|
|
693
|
+
columns: visibleColumns,
|
|
694
|
+
leadingColumnIds: leadingColumnIds,
|
|
551
695
|
rowCount: Math.min(resolvedPagination.pageSize, MAX_SKELETON_ROW_COUNT),
|
|
552
696
|
columnWidths: columnWidths,
|
|
553
697
|
orderedColumnIds: orderedLeafColumnIds,
|
|
554
698
|
pinning: columnPinning,
|
|
555
699
|
offsets: pinnedOffsets
|
|
556
|
-
}) : isEmpty ? null : visibleRows.
|
|
700
|
+
}) : isEmpty ? null : visibleRows.flatMap(row => {
|
|
557
701
|
const rowId = resolveRowId(row.original, getRowId);
|
|
558
|
-
const cells = pinningActive ? [...row.getStartVisibleCells(), ...row.getCenterVisibleCells(), ...row.getEndVisibleCells()] : row.
|
|
559
|
-
|
|
702
|
+
const cells = pinningActive ? [...row.getStartVisibleCells(), ...row.getCenterVisibleCells(), ...row.getEndVisibleCells()] : row.getVisibleCells();
|
|
703
|
+
const detailContent = getDetailPanelContent?.({
|
|
704
|
+
id: rowId,
|
|
705
|
+
row: row.original
|
|
706
|
+
});
|
|
707
|
+
const hasDetailPanel = detailContent != null;
|
|
708
|
+
const detailOpen = hasDetailPanel && resolvedDetailIds.has(rowId);
|
|
709
|
+
const treeLabel = treeActive ? [...getTreeDataPath(row.original)].reverse().join(', ') : '';
|
|
710
|
+
const dataRow = /*#__PURE__*/_jsx(Table.Row, {
|
|
711
|
+
className: detailOpen ? 'web:[&>*]:border-b-0' : undefined,
|
|
560
712
|
children: cells.map(cell => {
|
|
561
713
|
const pin = pinMetaFor(cell.column.id, columnPinning);
|
|
714
|
+
if (cell.column.id === DETAIL_PANEL_TOGGLE_ID) {
|
|
715
|
+
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
716
|
+
align: "center",
|
|
717
|
+
className: cn(dataGridDetailToggleCellVariants(), pinnedClassName(pin, false)),
|
|
718
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, cell.column.id, false),
|
|
719
|
+
children: hasDetailPanel ? /*#__PURE__*/_jsx(IconButton, {
|
|
720
|
+
as: detailOpen ? KeyboardArrowDown : KeyboardArrowRight,
|
|
721
|
+
variant: "ghost",
|
|
722
|
+
color: "neutral",
|
|
723
|
+
size: "small",
|
|
724
|
+
iconClassName: detailOpen ? undefined : 'rtl:-scale-x-100',
|
|
725
|
+
accessibilityLabel: `${detailOpen ? 'Collapse' : 'Expand'} row ${String(rowId)}`,
|
|
726
|
+
accessibilityState: {
|
|
727
|
+
expanded: detailOpen
|
|
728
|
+
},
|
|
729
|
+
"aria-expanded": detailOpen,
|
|
730
|
+
onPress: () => toggleDetailPanel(rowId)
|
|
731
|
+
}) : null
|
|
732
|
+
}, cell.id);
|
|
733
|
+
}
|
|
562
734
|
if (cell.column.id === SELECT_COLUMN_ID) {
|
|
563
735
|
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
564
736
|
align: "center",
|
|
@@ -594,14 +766,81 @@ function DataGridInner(props) {
|
|
|
594
766
|
const typedText = getTypedCellText(col, value, row.original);
|
|
595
767
|
content = typedText !== undefined ? typedText : defaultCellContent(value);
|
|
596
768
|
}
|
|
769
|
+
if (tree && cell.column.id === treeField) {
|
|
770
|
+
const canExpand = row.subRows.length > 0;
|
|
771
|
+
const expanded = canExpand && tree.isRowExpanded(row.id);
|
|
772
|
+
const status = tree.selectionStatus(row.id);
|
|
773
|
+
content = /*#__PURE__*/_jsxs(View, {
|
|
774
|
+
className: dataGridTreeCellInnerVariants(),
|
|
775
|
+
style: {
|
|
776
|
+
paddingStart: row.depth * TREE_INDENT
|
|
777
|
+
},
|
|
778
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
779
|
+
className: dataGridTreeToggleSlotVariants(),
|
|
780
|
+
children: canExpand ? /*#__PURE__*/_jsx(IconButton, {
|
|
781
|
+
as: expanded ? KeyboardArrowDown : KeyboardArrowRight,
|
|
782
|
+
variant: "ghost",
|
|
783
|
+
color: "neutral",
|
|
784
|
+
size: "small",
|
|
785
|
+
iconClassName: expanded ? undefined : 'rtl:-scale-x-100',
|
|
786
|
+
accessibilityLabel: `${expanded ? 'Collapse' : 'Expand'} ${treeLabel}`,
|
|
787
|
+
accessibilityState: {
|
|
788
|
+
expanded
|
|
789
|
+
},
|
|
790
|
+
"aria-expanded": expanded,
|
|
791
|
+
onPress: () => tree.toggleRowExpanded(row.id)
|
|
792
|
+
}) : null
|
|
793
|
+
}), treeCheckbox ? /*#__PURE__*/_jsx(Checkbox, {
|
|
794
|
+
value: String(rowId),
|
|
795
|
+
isChecked: status === 'all',
|
|
796
|
+
isIndeterminate: status === 'some',
|
|
797
|
+
onChange: () => tree.toggleRowSelected(row),
|
|
798
|
+
accessibilityLabel: `Select ${treeLabel}`,
|
|
799
|
+
"aria-label": `Select ${treeLabel}`
|
|
800
|
+
}) : null, /*#__PURE__*/_jsx(View, {
|
|
801
|
+
className: dataGridTreeContentVariants(),
|
|
802
|
+
children: typeof content === 'string' || typeof content === 'number' ? /*#__PURE__*/_jsx(Text, {
|
|
803
|
+
numberOfLines: 1,
|
|
804
|
+
children: content
|
|
805
|
+
}) : content
|
|
806
|
+
})]
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
const align = resolveColumnAlign(col);
|
|
810
|
+
const cellText = !col?.renderCell && (typeof content === 'string' || typeof content === 'number') ? String(content) : undefined;
|
|
597
811
|
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
598
|
-
align:
|
|
812
|
+
align: align,
|
|
813
|
+
...(Platform.OS === 'web' && cellText ? {
|
|
814
|
+
title: cellText
|
|
815
|
+
} : {}),
|
|
599
816
|
className: cn(dataGridCellVariants(), pinnedClassName(pin, false)),
|
|
600
817
|
style: mergePinnedStyle(cellStyle(col, columnWidths.get(cell.column.id)), pin, pinnedOffsets, cell.column.id, false),
|
|
601
|
-
children:
|
|
818
|
+
children: cellText !== undefined ? /*#__PURE__*/_jsx(Text, {
|
|
819
|
+
numberOfLines: 1,
|
|
820
|
+
className: dataGridCellTextVariants({
|
|
821
|
+
align,
|
|
822
|
+
fitToColumn: Platform.OS === 'web' && columnWidths.has(cell.column.id)
|
|
823
|
+
}),
|
|
824
|
+
children: cellText
|
|
825
|
+
}) : content
|
|
602
826
|
}, cell.id);
|
|
603
827
|
})
|
|
604
828
|
}, row.id);
|
|
829
|
+
if (!detailOpen) {
|
|
830
|
+
return [dataRow];
|
|
831
|
+
}
|
|
832
|
+
return [dataRow, /*#__PURE__*/_jsx(Table.Row, {
|
|
833
|
+
className: "web:hover:bg-transparent",
|
|
834
|
+
testID: `data-grid-detail-panel-${String(rowId)}`,
|
|
835
|
+
children: /*#__PURE__*/_jsx(Table.Cell, {
|
|
836
|
+
colSpan: leafColumnCount,
|
|
837
|
+
className: dataGridDetailPanelCellVariants(),
|
|
838
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
839
|
+
style: detailPanelContentStyle,
|
|
840
|
+
children: detailContent
|
|
841
|
+
})
|
|
842
|
+
})
|
|
843
|
+
}, `${row.id}:detail`)];
|
|
605
844
|
})
|
|
606
845
|
})]
|
|
607
846
|
}), isEmpty ? /*#__PURE__*/_jsx(View, {
|