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