@cdx-ui/data-grid 0.3.11 → 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/README.md +3 -1
- package/coverage.svg +1 -1
- package/lib/commonjs/DataGrid.js +490 -81
- package/lib/commonjs/DataGrid.js.map +1 -1
- package/lib/commonjs/DataGridFilterPanel.js +547 -0
- package/lib/commonjs/DataGridFilterPanel.js.map +1 -0
- package/lib/commonjs/adapter/columnTypes.js +256 -0
- package/lib/commonjs/adapter/columnTypes.js.map +1 -0
- package/lib/commonjs/adapter/columns.js +140 -4
- package/lib/commonjs/adapter/columns.js.map +1 -1
- package/lib/commonjs/adapter/filterOperators.js +422 -0
- package/lib/commonjs/adapter/filterOperators.js.map +1 -0
- package/lib/commonjs/adapter/pinning.js +105 -0
- package/lib/commonjs/adapter/pinning.js.map +1 -0
- 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/index.js +26 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/numberCells.js +280 -0
- package/lib/commonjs/numberCells.js.map +1 -0
- package/lib/commonjs/styles.js +107 -1
- package/lib/commonjs/styles.js.map +1 -1
- package/lib/commonjs/types.js +39 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/useDataGridTable.js +234 -18
- package/lib/commonjs/useDataGridTable.js.map +1 -1
- package/lib/module/DataGrid.js +497 -88
- package/lib/module/DataGrid.js.map +1 -1
- package/lib/module/DataGridFilterPanel.js +540 -0
- package/lib/module/DataGridFilterPanel.js.map +1 -0
- package/lib/module/adapter/columnTypes.js +240 -0
- package/lib/module/adapter/columnTypes.js.map +1 -0
- package/lib/module/adapter/columns.js +137 -4
- package/lib/module/adapter/columns.js.map +1 -1
- package/lib/module/adapter/filterOperators.js +406 -0
- package/lib/module/adapter/filterOperators.js.map +1 -0
- package/lib/module/adapter/pinning.js +94 -0
- package/lib/module/adapter/pinning.js.map +1 -0
- 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/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/numberCells.js +275 -0
- package/lib/module/numberCells.js.map +1 -0
- package/lib/module/styles.js +106 -0
- package/lib/module/styles.js.map +1 -1
- package/lib/module/types.js +38 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDataGridTable.js +238 -22
- package/lib/module/useDataGridTable.js.map +1 -1
- package/lib/typescript/DataGrid.d.ts.map +1 -1
- package/lib/typescript/DataGridFilterPanel.d.ts +52 -0
- package/lib/typescript/DataGridFilterPanel.d.ts.map +1 -0
- package/lib/typescript/adapter/columnTypes.d.ts +32 -0
- package/lib/typescript/adapter/columnTypes.d.ts.map +1 -0
- package/lib/typescript/adapter/columns.d.ts +14 -5
- package/lib/typescript/adapter/columns.d.ts.map +1 -1
- package/lib/typescript/adapter/filterOperators.d.ts +43 -0
- package/lib/typescript/adapter/filterOperators.d.ts.map +1 -0
- package/lib/typescript/adapter/pinning.d.ts +26 -0
- package/lib/typescript/adapter/pinning.d.ts.map +1 -0
- 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 +4 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/numberCells.d.ts +46 -0
- package/lib/typescript/numberCells.d.ts.map +1 -0
- package/lib/typescript/styles.d.ts +32 -0
- package/lib/typescript/styles.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +154 -7
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/useDataGridTable.d.ts +40 -4
- package/lib/typescript/useDataGridTable.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/DataGrid.tsx +745 -95
- package/src/DataGridFilterPanel.tsx +648 -0
- package/src/adapter/columnTypes.ts +327 -0
- package/src/adapter/columns.test.ts +75 -1
- package/src/adapter/columns.ts +192 -3
- package/src/adapter/filterOperators.test.ts +292 -0
- package/src/adapter/filterOperators.ts +524 -0
- package/src/adapter/pinning.ts +134 -0
- package/src/adapter/selectColumn.ts +12 -1
- package/src/adapter/treeData.ts +228 -0
- package/src/index.ts +19 -0
- package/src/numberCells.tsx +379 -0
- package/src/styles.ts +131 -0
- package/src/types.ts +190 -7
- package/src/useDataGridTable.test.ts +69 -0
- package/src/useDataGridTable.ts +338 -17
package/lib/module/DataGrid.js
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { useMemo } from 'react';
|
|
4
|
-
import { Platform, View } from 'react-native';
|
|
5
|
-
import { Checkbox, IconButton, Input, Skeleton, Table, TablePagination, Text } from '@cdx-ui/components';
|
|
6
|
-
import { KeyboardArrowDown, KeyboardArrowUp, Search } from '@cdx-ui/icons';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { I18nManager, Platform, View } from 'react-native';
|
|
5
|
+
import { Checkbox, Icon, IconButton, Input, Skeleton, Table, TablePagination, Text } from '@cdx-ui/components';
|
|
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
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { normalizePinnedColumns, resolveColumnAlign, resolveColumnHeaderAlign } from './adapter/columns';
|
|
10
|
+
import { DEFAULT_PINNED_COLUMN_WIDTH, DETAIL_PANEL_TOGGLE_WIDTH, SELECT_COLUMN_WIDTH, buildPinnedOffsets, isColumnPinningActive, pinnedCellStyle, pinnedEdgeGuidesImage, pinnedFieldSet, warnPinnedFlexColumns } from './adapter/pinning';
|
|
11
|
+
import { getTypedCellText } from './adapter/columnTypes';
|
|
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';
|
|
12
15
|
import { resolveRowId, useDataGridTable } from './useDataGridTable';
|
|
13
|
-
import { jsx as _jsx,
|
|
16
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
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;
|
|
15
21
|
const DEFAULT_WEB_COLUMN_WIDTH = 100;
|
|
16
|
-
const SELECT_COLUMN_WIDTH = 56;
|
|
17
22
|
const WEB_TABLE_CONTAINER_STYLE = {
|
|
18
23
|
overflow: 'visible'
|
|
19
24
|
};
|
|
25
|
+
// Same token as the pinned cells' `border-stroke-secondary` divider.
|
|
26
|
+
const PINNED_EDGE_COLOR = 'var(--color-stroke-secondary)';
|
|
20
27
|
function cellStyle(col, webWidth) {
|
|
21
28
|
if (!col) {
|
|
22
29
|
return undefined;
|
|
@@ -39,36 +46,96 @@ function cellStyle(col, webWidth) {
|
|
|
39
46
|
}
|
|
40
47
|
return Object.keys(style).length > 0 ? style : undefined;
|
|
41
48
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
49
|
+
function effectiveFlex(column, pinned) {
|
|
50
|
+
if (pinned.has(column.field)) {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
return Math.max(column.flex ?? 0, 0);
|
|
54
|
+
}
|
|
55
|
+
function webColumnWidths(columns, leadingWidth, pinned = new Set()) {
|
|
56
|
+
const totalFlex = columns.reduce((total, column) => total + effectiveFlex(column, pinned), 0);
|
|
44
57
|
const widths = new Map();
|
|
45
58
|
if (totalFlex === 0) {
|
|
46
59
|
for (const column of columns) {
|
|
47
|
-
if (column.
|
|
60
|
+
if (pinned.has(column.field)) {
|
|
61
|
+
widths.set(column.field, Math.max(column.width ?? DEFAULT_PINNED_COLUMN_WIDTH, column.minWidth ?? 0));
|
|
62
|
+
} else if (column.width !== undefined) {
|
|
48
63
|
widths.set(column.field, column.width);
|
|
49
64
|
}
|
|
50
65
|
}
|
|
51
66
|
return widths;
|
|
52
67
|
}
|
|
53
|
-
const fixedWidth =
|
|
54
|
-
if ((column
|
|
68
|
+
const fixedWidth = leadingWidth + columns.reduce((total, column) => {
|
|
69
|
+
if (effectiveFlex(column, pinned) > 0) {
|
|
55
70
|
return total;
|
|
56
71
|
}
|
|
57
|
-
|
|
72
|
+
const fallback = pinned.has(column.field) ? DEFAULT_PINNED_COLUMN_WIDTH : DEFAULT_WEB_COLUMN_WIDTH;
|
|
73
|
+
return total + Math.max(column.width ?? fallback, column.minWidth ?? 0);
|
|
58
74
|
}, 0);
|
|
59
75
|
for (const column of columns) {
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
const flex = effectiveFlex(column, pinned);
|
|
77
|
+
if (flex > 0) {
|
|
78
|
+
const share = flex / totalFlex;
|
|
62
79
|
const percentage = share * 100;
|
|
63
80
|
const fixedShare = fixedWidth * share;
|
|
64
81
|
const width = `calc(${percentage.toString()}% - ${fixedShare.toString()}px)`;
|
|
65
82
|
widths.set(column.field, column.minWidth === undefined ? width : `max(${column.minWidth.toString()}px, ${width})`);
|
|
66
83
|
} else {
|
|
67
|
-
|
|
84
|
+
const fallback = pinned.has(column.field) ? DEFAULT_PINNED_COLUMN_WIDTH : DEFAULT_WEB_COLUMN_WIDTH;
|
|
85
|
+
widths.set(column.field, Math.max(column.width ?? fallback, column.minWidth ?? 0));
|
|
68
86
|
}
|
|
69
87
|
}
|
|
70
88
|
return widths;
|
|
71
89
|
}
|
|
90
|
+
function pinMetaFor(columnId, pinning) {
|
|
91
|
+
const startIndex = pinning.start.indexOf(columnId);
|
|
92
|
+
if (startIndex >= 0) {
|
|
93
|
+
return {
|
|
94
|
+
edge: 'start',
|
|
95
|
+
isEdgeDivider: startIndex === pinning.start.length - 1
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const endIndex = pinning.end.indexOf(columnId);
|
|
99
|
+
if (endIndex >= 0) {
|
|
100
|
+
return {
|
|
101
|
+
edge: 'end',
|
|
102
|
+
isEdgeDivider: endIndex === 0
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
edge: false,
|
|
107
|
+
isEdgeDivider: false
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function mergePinnedStyle(base, pin, offsets, columnId, isHeader) {
|
|
111
|
+
if (!pin.edge || offsets == null) {
|
|
112
|
+
return base;
|
|
113
|
+
}
|
|
114
|
+
const offset = pin.edge === 'start' ? offsets.start.get(columnId) ?? 0 : offsets.end.get(columnId) ?? 0;
|
|
115
|
+
return {
|
|
116
|
+
...base,
|
|
117
|
+
...pinnedCellStyle(pin.edge, offset, isHeader)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function pinnedClassName(pin, isHeader) {
|
|
121
|
+
if (!pin.edge) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return cn(dataGridPinnedSurfaceVariants({
|
|
125
|
+
header: isHeader
|
|
126
|
+
}), dataGridPinnedEdgeVariants({
|
|
127
|
+
edge: pin.isEdgeDivider ? pin.edge : 'none'
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
function BooleanCell({
|
|
131
|
+
value
|
|
132
|
+
}) {
|
|
133
|
+
return /*#__PURE__*/_jsx(Icon, {
|
|
134
|
+
as: value ? Check : Close,
|
|
135
|
+
accessibilityLabel: value ? 'Yes' : 'No',
|
|
136
|
+
className: "size-5"
|
|
137
|
+
});
|
|
138
|
+
}
|
|
72
139
|
function defaultCellContent(value) {
|
|
73
140
|
if (value == null) {
|
|
74
141
|
return '';
|
|
@@ -88,30 +155,52 @@ function defaultCellContent(value) {
|
|
|
88
155
|
}
|
|
89
156
|
function DefaultLoadingRows({
|
|
90
157
|
columns,
|
|
91
|
-
|
|
158
|
+
leadingColumnIds,
|
|
92
159
|
rowCount,
|
|
93
|
-
columnWidths
|
|
160
|
+
columnWidths,
|
|
161
|
+
orderedColumnIds,
|
|
162
|
+
pinning,
|
|
163
|
+
offsets
|
|
94
164
|
}) {
|
|
165
|
+
const colByField = new Map(columns.map(column => [column.field, column]));
|
|
166
|
+
const ids = orderedColumnIds ?? [...leadingColumnIds, ...columns.map(column => column.field)];
|
|
95
167
|
return /*#__PURE__*/_jsx(_Fragment, {
|
|
96
168
|
children: Array.from({
|
|
97
169
|
length: rowCount
|
|
98
|
-
}, (_, rowIndex) => /*#__PURE__*/
|
|
170
|
+
}, (_, rowIndex) => /*#__PURE__*/_jsx(Table.Row, {
|
|
99
171
|
className: "pointer-events-none web:hover:bg-surface-primary",
|
|
100
172
|
testID: rowIndex === 0 ? 'data-grid-default-loading-rows' : undefined,
|
|
101
|
-
children:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
173
|
+
children: ids.map(columnId => {
|
|
174
|
+
const pin = pinMetaFor(columnId, pinning);
|
|
175
|
+
if (columnId === SELECT_COLUMN_ID) {
|
|
176
|
+
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
177
|
+
align: "center",
|
|
178
|
+
className: cn(dataGridSelectCellVariants(), pinnedClassName(pin, false)),
|
|
179
|
+
style: mergePinnedStyle(undefined, pin, offsets, columnId, false),
|
|
180
|
+
children: /*#__PURE__*/_jsx(Skeleton, {
|
|
181
|
+
className: "size-5"
|
|
182
|
+
})
|
|
183
|
+
}, columnId);
|
|
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
|
+
}
|
|
191
|
+
const column = colByField.get(columnId);
|
|
192
|
+
if (!column) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
196
|
+
align: resolveColumnAlign(column),
|
|
197
|
+
className: cn(dataGridCellVariants(), pinnedClassName(pin, false)),
|
|
198
|
+
style: mergePinnedStyle(cellStyle(column, columnWidths.get(column.field)), pin, offsets, column.field, false),
|
|
199
|
+
children: /*#__PURE__*/_jsx(Skeleton, {
|
|
200
|
+
className: "h-4 w-3/5"
|
|
201
|
+
})
|
|
202
|
+
}, column.field);
|
|
203
|
+
})
|
|
115
204
|
}, rowIndex))
|
|
116
205
|
});
|
|
117
206
|
}
|
|
@@ -144,6 +233,8 @@ function DataGridInner(props) {
|
|
|
144
233
|
rowCount,
|
|
145
234
|
showToolbar = false,
|
|
146
235
|
headerFilters = false,
|
|
236
|
+
pinnedColumns,
|
|
237
|
+
columnVisibilityModel,
|
|
147
238
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
148
239
|
noRowsOverlay,
|
|
149
240
|
loadingOverlay,
|
|
@@ -152,8 +243,49 @@ function DataGridInner(props) {
|
|
|
152
243
|
style,
|
|
153
244
|
label,
|
|
154
245
|
'aria-label': ariaLabel,
|
|
155
|
-
'aria-labelledby': ariaLabelledBy
|
|
246
|
+
'aria-labelledby': ariaLabelledBy,
|
|
247
|
+
treeData = false,
|
|
248
|
+
getTreeDataPath,
|
|
249
|
+
groupingColDef,
|
|
250
|
+
defaultGroupingExpansionDepth,
|
|
251
|
+
isGroupExpandedByDefault,
|
|
252
|
+
rowSelectionPropagation,
|
|
253
|
+
getDetailPanelContent
|
|
156
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
|
+
};
|
|
157
289
|
const [sortModel, setSortModel] = useControllableState({
|
|
158
290
|
prop: props.sortModel,
|
|
159
291
|
defaultProp: props.defaultSortModel ?? [],
|
|
@@ -169,6 +301,11 @@ function DataGridInner(props) {
|
|
|
169
301
|
defaultProp: props.defaultFilterModel ?? [],
|
|
170
302
|
onChange: props.onFilterModelChange
|
|
171
303
|
});
|
|
304
|
+
const [filterLogicOperator, setFilterLogicOperator] = useControllableState({
|
|
305
|
+
prop: props.filterLogicOperator,
|
|
306
|
+
defaultProp: props.defaultFilterLogicOperator ?? 'and',
|
|
307
|
+
onChange: props.onFilterLogicOperatorChange
|
|
308
|
+
});
|
|
172
309
|
const [quickFilter, setQuickFilter] = useControllableState({
|
|
173
310
|
prop: props.quickFilter,
|
|
174
311
|
defaultProp: props.defaultQuickFilter ?? '',
|
|
@@ -182,16 +319,29 @@ function DataGridInner(props) {
|
|
|
182
319
|
const resolvedSortModel = sortModel ?? [];
|
|
183
320
|
const resolvedPagination = paginationModel ?? DEFAULT_PAGINATION_MODEL;
|
|
184
321
|
const resolvedFilterModel = filterModel ?? [];
|
|
322
|
+
const resolvedFilterLogicOperator = filterLogicOperator ?? 'and';
|
|
185
323
|
const resolvedQuickFilter = quickFilter ?? '';
|
|
186
324
|
const resolvedSelection = rowSelectionModel ?? EMPTY_SELECTION;
|
|
325
|
+
const knownFields = useMemo(() => new Set(columns.map(column => column.field)), [columns]);
|
|
326
|
+
const columnPinning = useMemo(() => normalizePinnedColumns(pinnedColumns, knownFields, selectColumn, detailPanel), [pinnedColumns, knownFields, selectColumn, detailPanel]);
|
|
327
|
+
const pinningActive = isColumnPinningActive(columnPinning);
|
|
328
|
+
const pinnedFields = useMemo(() => pinnedFieldSet(columnPinning), [columnPinning]);
|
|
187
329
|
const {
|
|
188
330
|
table,
|
|
189
331
|
setQuickFilter: setQuickFilterWithPageReset,
|
|
190
|
-
setColumnFilter
|
|
332
|
+
setColumnFilter,
|
|
333
|
+
setFilterModel: setFilterModelWithPageReset,
|
|
334
|
+
tree
|
|
191
335
|
} = useDataGridTable({
|
|
192
336
|
rows,
|
|
193
|
-
columns,
|
|
337
|
+
columns: gridColumns,
|
|
194
338
|
getRowId,
|
|
339
|
+
detailPanel,
|
|
340
|
+
treeData: treeActive,
|
|
341
|
+
getTreeDataPath,
|
|
342
|
+
defaultGroupingExpansionDepth,
|
|
343
|
+
isGroupExpandedByDefault,
|
|
344
|
+
rowSelectionPropagation,
|
|
195
345
|
checkboxSelection,
|
|
196
346
|
disableColumnSorting,
|
|
197
347
|
paginationMode,
|
|
@@ -204,25 +354,52 @@ function DataGridInner(props) {
|
|
|
204
354
|
onPaginationModelChange: model => setPaginationModel(model),
|
|
205
355
|
filterModel: resolvedFilterModel,
|
|
206
356
|
onFilterModelChange: model => setFilterModel(model),
|
|
357
|
+
filterLogicOperator: resolvedFilterLogicOperator,
|
|
207
358
|
quickFilter: resolvedQuickFilter,
|
|
208
359
|
onQuickFilterChange: value => setQuickFilter(value),
|
|
209
360
|
rowSelectionModel: resolvedSelection,
|
|
210
|
-
onRowSelectionModelChange: model => setRowSelectionModel(model)
|
|
361
|
+
onRowSelectionModelChange: model => setRowSelectionModel(model),
|
|
362
|
+
columnPinning,
|
|
363
|
+
columnVisibility: columnVisibilityModel
|
|
211
364
|
});
|
|
212
365
|
const colByField = useMemo(() => {
|
|
213
366
|
const map = new Map();
|
|
214
|
-
for (const col of
|
|
367
|
+
for (const col of gridColumns) {
|
|
215
368
|
map.set(col.field, col);
|
|
216
369
|
}
|
|
217
370
|
return map;
|
|
218
|
-
}, [
|
|
219
|
-
|
|
220
|
-
const
|
|
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]);
|
|
375
|
+
const pinnedOffsets = useMemo(() => pinningActive ? buildPinnedOffsets(columnPinning, colByField) : null, [pinningActive, columnPinning, colByField]);
|
|
376
|
+
const orderedLeafColumnIds = useMemo(() => {
|
|
377
|
+
if (!pinningActive) {
|
|
378
|
+
return undefined;
|
|
379
|
+
}
|
|
380
|
+
return [...table.getStartVisibleLeafColumns().map(column => column.id), ...table.getCenterVisibleLeafColumns().map(column => column.id), ...table.getEndVisibleLeafColumns().map(column => column.id)];
|
|
381
|
+
}, [pinningActive, table]);
|
|
382
|
+
const isEmpty = !loading && rows.length === 0;
|
|
383
|
+
const mainScrollStyle = useMemo(() => {
|
|
384
|
+
if (!pinningActive || pinnedOffsets == null) {
|
|
385
|
+
return undefined;
|
|
386
|
+
}
|
|
387
|
+
const guides = Platform.OS === 'web' && !isEmpty ? pinnedEdgeGuidesImage(pinnedOffsets, PINNED_EDGE_COLOR, I18nManager.isRTL) : undefined;
|
|
388
|
+
// Logical scroll-padding keeps focused cells out from under pinned edges (web).
|
|
389
|
+
return {
|
|
390
|
+
scrollPaddingInlineStart: pinnedOffsets.startTotal,
|
|
391
|
+
scrollPaddingInlineEnd: pinnedOffsets.endTotal,
|
|
392
|
+
...(guides ? {
|
|
393
|
+
backgroundImage: guides,
|
|
394
|
+
backgroundRepeat: 'no-repeat'
|
|
395
|
+
} : {})
|
|
396
|
+
};
|
|
397
|
+
}, [pinningActive, pinnedOffsets, isEmpty]);
|
|
221
398
|
const visibleRows = table.getRowModel().rows;
|
|
222
399
|
const pageCount = Math.max(table.getPageCount(), 1);
|
|
223
400
|
const selectedCount = table.getFilteredSelectedRowModel().rows.length;
|
|
224
401
|
const filterableCount = table.getFilteredRowModel().rows.length;
|
|
225
|
-
const headerSelectState = selectedCount === 0 ? {
|
|
402
|
+
const headerSelectState = tree?.headerSelection ?? (selectedCount === 0 ? {
|
|
226
403
|
checked: false,
|
|
227
404
|
indeterminate: false
|
|
228
405
|
} : selectedCount === filterableCount ? {
|
|
@@ -231,16 +408,74 @@ function DataGridInner(props) {
|
|
|
231
408
|
} : {
|
|
232
409
|
checked: false,
|
|
233
410
|
indeterminate: true
|
|
234
|
-
};
|
|
411
|
+
});
|
|
412
|
+
const leafColumnCount = table.getVisibleLeafColumns().length;
|
|
235
413
|
const accessibleName = ariaLabel ?? label;
|
|
236
|
-
const isEmpty = !loading && rows.length === 0;
|
|
237
414
|
const totalCount = paginationMode === 'server' ? rowCount ?? rows.length : filterableCount;
|
|
238
|
-
const filterValueFor = field =>
|
|
415
|
+
const filterValueFor = field => {
|
|
416
|
+
const value = resolvedFilterModel.find(item => item.field === field)?.value;
|
|
417
|
+
return typeof value === 'string' ? value : '';
|
|
418
|
+
};
|
|
239
419
|
const showToolbarBar = showToolbar || toolbarActions != null;
|
|
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;
|
|
429
|
+
const filterPanelButtonRef = useRef(null);
|
|
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]);
|
|
240
474
|
return /*#__PURE__*/_jsxs(View, {
|
|
475
|
+
ref: rootRef,
|
|
241
476
|
className: cn(dataGridRootVariants({
|
|
242
477
|
autoHeight
|
|
243
|
-
}), className),
|
|
478
|
+
}), className, filterPanelOpen && !filterPanelAnchored && 'overflow-visible'),
|
|
244
479
|
style: style,
|
|
245
480
|
...mergeDataAttributes({}, dataAttributes({
|
|
246
481
|
slot: 'data-grid'
|
|
@@ -253,20 +488,50 @@ function DataGridInner(props) {
|
|
|
253
488
|
children: [/*#__PURE__*/_jsx(Input.Icon, {
|
|
254
489
|
as: Search
|
|
255
490
|
}), /*#__PURE__*/_jsx(Input.Field, {
|
|
491
|
+
ref: searchRef,
|
|
256
492
|
value: resolvedQuickFilter,
|
|
257
493
|
onChangeText: setQuickFilterWithPageReset,
|
|
258
494
|
placeholder: "Search",
|
|
259
495
|
accessibilityLabel: "Search"
|
|
260
496
|
})]
|
|
497
|
+
}) : null, showFilterPanelButton ? /*#__PURE__*/_jsx(IconButton, {
|
|
498
|
+
ref: filterPanelButtonRef,
|
|
499
|
+
as: FilterList,
|
|
500
|
+
variant: "ghost",
|
|
501
|
+
color: "neutral",
|
|
502
|
+
size: "small",
|
|
503
|
+
accessibilityLabel: "Filters",
|
|
504
|
+
accessibilityState: {
|
|
505
|
+
expanded: filterPanelOpen
|
|
506
|
+
},
|
|
507
|
+
onPress: () => filterPanel.toggle(filterPanelButtonRef)
|
|
261
508
|
}) : null, toolbarActions ? /*#__PURE__*/_jsx(View, {
|
|
262
509
|
className: dataGridToolbarActionsVariants(),
|
|
263
510
|
children: toolbarActions
|
|
264
511
|
}) : null]
|
|
512
|
+
}) : null, filterPanelOpen && filterPanel.opener ? /*#__PURE__*/_jsx(DataGridFilterPanel, {
|
|
513
|
+
columns: filterPanelColumns,
|
|
514
|
+
filterModel: resolvedFilterModel,
|
|
515
|
+
onFilterModelChange: setFilterModelWithPageReset,
|
|
516
|
+
logicOperator: resolvedFilterLogicOperator,
|
|
517
|
+
onLogicOperatorChange: operator => {
|
|
518
|
+
setFilterLogicOperator(operator);
|
|
519
|
+
if (resolvedPagination.page !== 0) {
|
|
520
|
+
setPaginationModel({
|
|
521
|
+
...resolvedPagination,
|
|
522
|
+
page: 0
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
onClose: filterPanel.close,
|
|
527
|
+
opener: filterPanel.opener
|
|
265
528
|
}) : null, /*#__PURE__*/_jsxs(View, {
|
|
529
|
+
ref: mainRef,
|
|
266
530
|
className: dataGridMainVariants({
|
|
267
531
|
autoHeight,
|
|
268
532
|
overlay: isEmpty || loading && loadingOverlay != null
|
|
269
533
|
}),
|
|
534
|
+
style: mainScrollStyle,
|
|
270
535
|
children: [/*#__PURE__*/_jsxs(Table, {
|
|
271
536
|
className: cn(dataGridTableVariants(), Platform.OS === 'web' && hasFlexColumns ? 'table-fixed' : undefined),
|
|
272
537
|
containerStyle: Platform.OS === 'web' ? WEB_TABLE_CONTAINER_STYLE : undefined,
|
|
@@ -278,25 +543,34 @@ function DataGridInner(props) {
|
|
|
278
543
|
} : {}),
|
|
279
544
|
children: [label ? /*#__PURE__*/_jsx(Table.Caption, {
|
|
280
545
|
children: label
|
|
281
|
-
}) : null, Platform.OS === 'web' && hasFlexColumns ? /*#__PURE__*/
|
|
282
|
-
children: [
|
|
546
|
+
}) : null, Platform.OS === 'web' && hasFlexColumns ? /*#__PURE__*/_jsx("colgroup", {
|
|
547
|
+
children: (orderedLeafColumnIds ?? [...leadingColumnIds, ...visibleColumns.map(column => column.field)]).map(columnId => columnId === SELECT_COLUMN_ID ? /*#__PURE__*/_jsx("col", {
|
|
283
548
|
style: {
|
|
284
549
|
width: SELECT_COLUMN_WIDTH
|
|
285
550
|
}
|
|
286
|
-
}) :
|
|
551
|
+
}, columnId) : columnId === DETAIL_PANEL_TOGGLE_ID ? /*#__PURE__*/_jsx("col", {
|
|
552
|
+
style: {
|
|
553
|
+
width: DETAIL_PANEL_TOGGLE_WIDTH
|
|
554
|
+
}
|
|
555
|
+
}, columnId) : /*#__PURE__*/_jsx("col", {
|
|
287
556
|
style: {
|
|
288
|
-
width: columnWidths.get(
|
|
289
|
-
minWidth:
|
|
557
|
+
width: columnWidths.get(columnId),
|
|
558
|
+
minWidth: colByField.get(columnId)?.minWidth
|
|
290
559
|
}
|
|
291
|
-
},
|
|
560
|
+
}, columnId))
|
|
292
561
|
}) : null, /*#__PURE__*/_jsxs(Table.Header, {
|
|
293
562
|
className: dataGridHeaderVariants(),
|
|
294
|
-
children: [
|
|
563
|
+
children: [(pinningActive ? [{
|
|
564
|
+
id: 'pinned',
|
|
565
|
+
headers: [...table.getStartLeafHeaders(), ...table.getCenterLeafHeaders(), ...table.getEndLeafHeaders()]
|
|
566
|
+
}] : table.getHeaderGroups()).map(headerGroup => /*#__PURE__*/_jsx(Table.Row, {
|
|
295
567
|
children: headerGroup.headers.map(header => {
|
|
568
|
+
const pin = pinMetaFor(header.column.id, columnPinning);
|
|
296
569
|
if (header.id === SELECT_COLUMN_ID) {
|
|
297
570
|
return /*#__PURE__*/_jsx(Table.Head, {
|
|
298
571
|
align: "center",
|
|
299
|
-
className: dataGridSelectHeadVariants(),
|
|
572
|
+
className: cn(dataGridSelectHeadVariants(), pinnedClassName(pin, true)),
|
|
573
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, header.id, true),
|
|
300
574
|
children: /*#__PURE__*/_jsx(Checkbox, {
|
|
301
575
|
value: "select-all",
|
|
302
576
|
isChecked: headerSelectState.checked,
|
|
@@ -307,10 +581,17 @@ function DataGridInner(props) {
|
|
|
307
581
|
})
|
|
308
582
|
}, header.id);
|
|
309
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
|
+
}
|
|
310
590
|
const col = colByField.get(header.column.id);
|
|
591
|
+
const isTreeColumn = header.column.id === treeField;
|
|
311
592
|
const sorted = header.column.getIsSorted();
|
|
312
593
|
const canSort = !disableColumnSorting && header.column.getCanSort();
|
|
313
|
-
const headerAlign =
|
|
594
|
+
const headerAlign = resolveColumnHeaderAlign(col);
|
|
314
595
|
const headerName = col?.headerName ?? header.column.id;
|
|
315
596
|
const SortIcon = sorted === 'asc' ? KeyboardArrowUp : KeyboardArrowDown;
|
|
316
597
|
const sortButton = canSort ? /*#__PURE__*/_jsx(IconButton, {
|
|
@@ -328,50 +609,71 @@ function DataGridInner(props) {
|
|
|
328
609
|
sorted: sorted !== false
|
|
329
610
|
})
|
|
330
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
|
+
});
|
|
331
619
|
return /*#__PURE__*/_jsx(Table.Head, {
|
|
332
620
|
align: headerAlign,
|
|
333
|
-
className: dataGridHeadVariants(),
|
|
334
|
-
style: cellStyle(col, columnWidths.get(header.column.id)),
|
|
621
|
+
className: cn(dataGridHeadVariants(), pinnedClassName(pin, true)),
|
|
622
|
+
style: mergePinnedStyle(cellStyle(col, columnWidths.get(header.column.id)), pin, pinnedOffsets, header.column.id, true),
|
|
335
623
|
...(Platform.OS === 'web' ? {
|
|
336
624
|
title: col?.renderHeader ? undefined : headerName,
|
|
337
625
|
...(canSort ? {
|
|
338
626
|
'aria-sort': sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : 'none'
|
|
339
627
|
} : {})
|
|
340
628
|
} : {}),
|
|
341
|
-
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, {
|
|
342
647
|
className: dataGridHeaderCellInnerVariants({
|
|
343
648
|
align: headerAlign,
|
|
344
649
|
fitToColumn: Platform.OS === 'web' && columnWidths.has(header.column.id)
|
|
345
650
|
}),
|
|
346
|
-
children:
|
|
347
|
-
numberOfLines: 1,
|
|
348
|
-
className: dataGridHeaderLabelVariants(),
|
|
349
|
-
children: col?.renderHeader ? col.renderHeader() : headerName
|
|
350
|
-
}), headerAlign === 'end' ? null : sortButton]
|
|
651
|
+
children: headerLabel
|
|
351
652
|
})
|
|
352
653
|
}, header.id);
|
|
353
654
|
})
|
|
354
655
|
}, headerGroup.id)), headerFilters ? /*#__PURE__*/_jsx(Table.Row, {
|
|
355
|
-
children: table.
|
|
356
|
-
|
|
656
|
+
children: (pinningActive ? [...table.getStartVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns(), ...table.getEndVisibleLeafColumns()] : table.getVisibleLeafColumns()).map(column => {
|
|
657
|
+
const pin = pinMetaFor(column.id, columnPinning);
|
|
658
|
+
if (column.id === SELECT_COLUMN_ID || column.id === DETAIL_PANEL_TOGGLE_ID) {
|
|
357
659
|
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
358
660
|
align: "center",
|
|
359
|
-
className: dataGridSelectHeadVariants()
|
|
661
|
+
className: cn(dataGridSelectHeadVariants(), column.id === DETAIL_PANEL_TOGGLE_ID && 'w-12 px-2', pinnedClassName(pin, true)),
|
|
662
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, column.id, true)
|
|
360
663
|
}, column.id);
|
|
361
664
|
}
|
|
362
665
|
const col = colByField.get(column.id);
|
|
363
|
-
const headerAlign = col?.headerAlign ?? col?.align;
|
|
364
666
|
if (col?.filterable === false) {
|
|
365
667
|
return /*#__PURE__*/_jsx(Table.Head, {
|
|
366
|
-
align:
|
|
367
|
-
className: dataGridHeadVariants(),
|
|
368
|
-
style: cellStyle(col, columnWidths.get(column.id))
|
|
668
|
+
align: resolveColumnHeaderAlign(col),
|
|
669
|
+
className: cn(dataGridHeadVariants(), pinnedClassName(pin, true)),
|
|
670
|
+
style: mergePinnedStyle(cellStyle(col, columnWidths.get(column.id)), pin, pinnedOffsets, column.id, true)
|
|
369
671
|
}, column.id);
|
|
370
672
|
}
|
|
371
673
|
return /*#__PURE__*/_jsx(Table.Head, {
|
|
372
|
-
align:
|
|
373
|
-
className: dataGridHeadVariants(),
|
|
374
|
-
style: cellStyle(col, columnWidths.get(column.id)),
|
|
674
|
+
align: resolveColumnHeaderAlign(col),
|
|
675
|
+
className: cn(dataGridHeadVariants(), pinnedClassName(pin, true)),
|
|
676
|
+
style: mergePinnedStyle(cellStyle(col, columnWidths.get(column.id)), pin, pinnedOffsets, column.id, true),
|
|
375
677
|
children: /*#__PURE__*/_jsx(Input, {
|
|
376
678
|
size: "small",
|
|
377
679
|
className: dataGridFilterInputVariants(),
|
|
@@ -388,18 +690,52 @@ function DataGridInner(props) {
|
|
|
388
690
|
}), /*#__PURE__*/_jsx(Table.Body, {
|
|
389
691
|
className: dataGridBodyVariants(),
|
|
390
692
|
children: loading && loadingOverlay == null ? /*#__PURE__*/_jsx(DefaultLoadingRows, {
|
|
391
|
-
columns:
|
|
392
|
-
|
|
693
|
+
columns: visibleColumns,
|
|
694
|
+
leadingColumnIds: leadingColumnIds,
|
|
393
695
|
rowCount: Math.min(resolvedPagination.pageSize, MAX_SKELETON_ROW_COUNT),
|
|
394
|
-
columnWidths: columnWidths
|
|
395
|
-
|
|
696
|
+
columnWidths: columnWidths,
|
|
697
|
+
orderedColumnIds: orderedLeafColumnIds,
|
|
698
|
+
pinning: columnPinning,
|
|
699
|
+
offsets: pinnedOffsets
|
|
700
|
+
}) : isEmpty ? null : visibleRows.flatMap(row => {
|
|
396
701
|
const rowId = resolveRowId(row.original, getRowId);
|
|
397
|
-
|
|
398
|
-
|
|
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,
|
|
712
|
+
children: cells.map(cell => {
|
|
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
|
+
}
|
|
399
734
|
if (cell.column.id === SELECT_COLUMN_ID) {
|
|
400
735
|
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
401
736
|
align: "center",
|
|
402
|
-
className: dataGridSelectCellVariants(),
|
|
737
|
+
className: cn(dataGridSelectCellVariants(), pinnedClassName(pin, false)),
|
|
738
|
+
style: mergePinnedStyle(undefined, pin, pinnedOffsets, cell.column.id, false),
|
|
403
739
|
children: /*#__PURE__*/_jsx(Checkbox, {
|
|
404
740
|
value: String(rowId),
|
|
405
741
|
isChecked: row.getIsSelected(),
|
|
@@ -417,21 +753,94 @@ function DataGridInner(props) {
|
|
|
417
753
|
value,
|
|
418
754
|
row: row.original,
|
|
419
755
|
field: col.field,
|
|
420
|
-
id: rowId
|
|
756
|
+
id: rowId,
|
|
757
|
+
col
|
|
421
758
|
});
|
|
422
759
|
} else if (col?.valueFormatter) {
|
|
423
760
|
content = col.valueFormatter(value, row.original, col);
|
|
761
|
+
} else if (col?.type === 'boolean' && typeof value === 'boolean') {
|
|
762
|
+
content = /*#__PURE__*/_jsx(BooleanCell, {
|
|
763
|
+
value: value
|
|
764
|
+
});
|
|
424
765
|
} else {
|
|
425
|
-
|
|
766
|
+
const typedText = getTypedCellText(col, value, row.original);
|
|
767
|
+
content = typedText !== undefined ? typedText : defaultCellContent(value);
|
|
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
|
+
});
|
|
426
808
|
}
|
|
809
|
+
const align = resolveColumnAlign(col);
|
|
810
|
+
const cellText = !col?.renderCell && (typeof content === 'string' || typeof content === 'number') ? String(content) : undefined;
|
|
427
811
|
return /*#__PURE__*/_jsx(Table.Cell, {
|
|
428
|
-
align:
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
812
|
+
align: align,
|
|
813
|
+
...(Platform.OS === 'web' && cellText ? {
|
|
814
|
+
title: cellText
|
|
815
|
+
} : {}),
|
|
816
|
+
className: cn(dataGridCellVariants(), pinnedClassName(pin, false)),
|
|
817
|
+
style: mergePinnedStyle(cellStyle(col, columnWidths.get(cell.column.id)), pin, pinnedOffsets, cell.column.id, false),
|
|
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
|
|
432
826
|
}, cell.id);
|
|
433
827
|
})
|
|
434
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`)];
|
|
435
844
|
})
|
|
436
845
|
})]
|
|
437
846
|
}), isEmpty ? /*#__PURE__*/_jsx(View, {
|