@azrico/reactgrid 1.6.2 → 1.6.5
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/CHANGELOG.md +33 -19
- package/README.md +165 -164
- package/__tests__/context-menu.config.cjs +14 -0
- package/__tests__/context-menu.test.js +150 -0
- package/config/generate-theme.cjs +1 -1
- package/config/theme-extras.css +11 -16
- package/dist/src/example.js +27 -2
- package/dist/src/func/func_a11y.d.ts +14 -0
- package/dist/src/func/func_a11y.js +63 -10
- package/dist/src/func/func_grid.d.ts +6 -0
- package/dist/src/func/func_grid.js +15 -4
- package/dist/src/hooks/useGridEvents.js +16 -4
- package/dist/src/themes/azgrid-theme.css +12 -17
- package/dist/src/types/types.d.ts +4 -0
- package/dist/src/views/DataGrid.js +10 -22
- package/package.json +1 -1
- package/src/example.tsx +202 -186
- package/src/func/func_a11y.ts +62 -4
- package/src/func/func_grid.ts +351 -340
- package/src/hooks/useGridEvents.ts +171 -158
- package/src/themes/azgrid-theme.css +12 -17
- package/src/types/types.ts +157 -153
- package/src/views/DataGrid.tsx +9 -17
package/dist/src/example.js
CHANGED
|
@@ -30,6 +30,7 @@ const columns = [{
|
|
|
30
30
|
title: 'Name',
|
|
31
31
|
defaultFlex: 1
|
|
32
32
|
}, {
|
|
33
|
+
// typed columns are editable without editableColumns, items keep their case
|
|
33
34
|
name: 'job',
|
|
34
35
|
title: 'Job',
|
|
35
36
|
type: 'combo',
|
|
@@ -41,8 +42,20 @@ const columns = [{
|
|
|
41
42
|
type: 'number',
|
|
42
43
|
defaultFlex: 1,
|
|
43
44
|
ariaLabel: value => `${value} years`
|
|
45
|
+
}, {
|
|
46
|
+
// editable only for rows that are not saved yet (no id)
|
|
47
|
+
name: 'location',
|
|
48
|
+
title: 'Location',
|
|
49
|
+
type: 'select',
|
|
50
|
+
items: ['Shelf A', 'Shelf B', 'Back Room'],
|
|
51
|
+
editable: (value, cellProps) => {
|
|
52
|
+
var _cellProps$data;
|
|
53
|
+
return !(cellProps !== null && cellProps !== void 0 && (_cellProps$data = cellProps.data) !== null && _cellProps$data !== void 0 && _cellProps$data.id);
|
|
54
|
+
},
|
|
55
|
+
defaultFlex: 1
|
|
44
56
|
}];
|
|
45
|
-
|
|
57
|
+
// plain columns still need editableColumns
|
|
58
|
+
const editableColumns = ['name'];
|
|
46
59
|
function getData(delta, max = 200) {
|
|
47
60
|
const fd = [];
|
|
48
61
|
for (let index = 0; index < max; index++) {
|
|
@@ -50,7 +63,10 @@ function getData(delta, max = 200) {
|
|
|
50
63
|
__table_id: String(index),
|
|
51
64
|
name: 'user-' + index,
|
|
52
65
|
age: 5 + index,
|
|
53
|
-
job: 'None'
|
|
66
|
+
job: 'None',
|
|
67
|
+
location: 'Shelf A',
|
|
68
|
+
// every third row is saved, its location is readonly
|
|
69
|
+
id: index % 3 == 0 ? 'saved-' + index : undefined
|
|
54
70
|
};
|
|
55
71
|
if (delta[index] && typeof delta[index] === 'object') {
|
|
56
72
|
for (const key in delta[index]) {
|
|
@@ -139,6 +155,15 @@ function ExampleGrid() {
|
|
|
139
155
|
return [{
|
|
140
156
|
type: 'text',
|
|
141
157
|
content: product.name
|
|
158
|
+
}, {
|
|
159
|
+
title: 'Log row',
|
|
160
|
+
onClick: row => console.log('context menu: log', row)
|
|
161
|
+
}, {
|
|
162
|
+
title: 'Copy name',
|
|
163
|
+
onClick: row => {
|
|
164
|
+
var _navigator$clipboard, _row$name;
|
|
165
|
+
return (_navigator$clipboard = navigator.clipboard) === null || _navigator$clipboard === void 0 ? void 0 : _navigator$clipboard.writeText(String((_row$name = row === null || row === void 0 ? void 0 : row.name) !== null && _row$name !== void 0 ? _row$name : ''));
|
|
166
|
+
}
|
|
142
167
|
}];
|
|
143
168
|
}, []);
|
|
144
169
|
return _react.default.createElement("div", {
|
|
@@ -6,6 +6,8 @@ export type ColumnA11yOptions = {
|
|
|
6
6
|
gridEditable?: boolean;
|
|
7
7
|
/** false skips aria-readonly (for interactive special columns like the checkbox column) */
|
|
8
8
|
markReadonly?: boolean;
|
|
9
|
+
/** column id when the column object has no id/name (inovua's special columns) */
|
|
10
|
+
id?: string;
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* wraps column dom props to add ARIA attributes,
|
|
@@ -31,6 +33,18 @@ export type RootA11yOptions = {
|
|
|
31
33
|
ariaLabel?: string;
|
|
32
34
|
editable?: boolean;
|
|
33
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* sets aria-colindex/aria-sort on the header cells of the grid,
|
|
38
|
+
* attributes the consumer set in an object headerDOMProps are left alone
|
|
39
|
+
* @param grid computed props of the grid
|
|
40
|
+
* @param root root element of the grid
|
|
41
|
+
*/
|
|
42
|
+
export declare function apply_header_a11y(grid: GridType | null | undefined, root: Element): void;
|
|
43
|
+
/**
|
|
44
|
+
* true when a header cell was (re)mounted without its aria-colindex
|
|
45
|
+
* @param root root element of the grid
|
|
46
|
+
*/
|
|
47
|
+
export declare function has_unsynced_header(root: Element | null): boolean;
|
|
34
48
|
/**
|
|
35
49
|
* true while the grid is loading (loading prop or async datasource)
|
|
36
50
|
* @param grid computed props of the grid
|
|
@@ -4,11 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.apply_column_a11y = apply_column_a11y;
|
|
7
|
+
exports.apply_header_a11y = apply_header_a11y;
|
|
7
8
|
exports.apply_root_a11y = apply_root_a11y;
|
|
8
9
|
exports.apply_row_a11y = apply_row_a11y;
|
|
9
10
|
exports.get_grid_root = get_grid_root;
|
|
10
11
|
exports.get_grid_row_count = get_grid_row_count;
|
|
11
12
|
exports.get_root_a11y_key = get_root_a11y_key;
|
|
13
|
+
exports.has_unsynced_header = has_unsynced_header;
|
|
12
14
|
exports.is_grid_busy = is_grid_busy;
|
|
13
15
|
function set_default(target, key, value) {
|
|
14
16
|
if (target[key] === undefined && value !== undefined && value !== null) target[key] = value;
|
|
@@ -38,11 +40,13 @@ function is_cell_readonly(cellProps, gridEditable) {
|
|
|
38
40
|
* @returns a new column object
|
|
39
41
|
*/
|
|
40
42
|
function apply_column_a11y(col, options = {}) {
|
|
43
|
+
var _ref, _col$id;
|
|
41
44
|
const {
|
|
42
45
|
role = 'gridcell',
|
|
43
46
|
gridEditable = false,
|
|
44
47
|
markReadonly = true
|
|
45
48
|
} = options;
|
|
49
|
+
const id = (_ref = (_col$id = col.id) !== null && _col$id !== void 0 ? _col$id : col.name) !== null && _ref !== void 0 ? _ref : options.id;
|
|
46
50
|
const consumerCellDOMProps = col.cellDOMProps;
|
|
47
51
|
const consumerHeaderDOMProps = col.headerDOMProps;
|
|
48
52
|
const ariaLabel = col.ariaLabel;
|
|
@@ -58,25 +62,40 @@ function apply_column_a11y(col, options = {}) {
|
|
|
58
62
|
if (typeof ariaLabel === 'function' && data && !data.__group && !data.__summary) set_default(res, 'aria-label', ariaLabel(cellProps.value, data));
|
|
59
63
|
return res;
|
|
60
64
|
},
|
|
61
|
-
headerDOMProps:
|
|
62
|
-
const res = resolve_dom_props(consumerHeaderDOMProps, cellProps);
|
|
63
|
-
set_default(res, 'role', 'columnheader');
|
|
64
|
-
set_default(res, 'aria-colindex', cellProps.computedVisibleIndex + 1);
|
|
65
|
-
if (cellProps.computedSortable) set_default(res, 'aria-sort', get_sort_dir(cellProps.computedSortInfo));
|
|
66
|
-
return res;
|
|
67
|
-
}
|
|
65
|
+
headerDOMProps: get_header_dom_props(consumerHeaderDOMProps, id)
|
|
68
66
|
};
|
|
69
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* header DOM props as an object (inovua's prop types reject a function),
|
|
70
|
+
* aria-colindex/aria-sort change with the grid state and are set by apply_header_a11y
|
|
71
|
+
* @param consumer consumer's headerDOMProps
|
|
72
|
+
* @param id column id, looked up in the grid's columnsMap
|
|
73
|
+
*/
|
|
74
|
+
function get_header_dom_props(consumer, id) {
|
|
75
|
+
//a consumer function is kept (inovua runs it), it gets the attributes from the cell props
|
|
76
|
+
if (typeof consumer === 'function') return cellProps => {
|
|
77
|
+
const res = resolve_dom_props(consumer, cellProps);
|
|
78
|
+
set_default(res, 'role', 'columnheader');
|
|
79
|
+
set_default(res, 'data-column', id);
|
|
80
|
+
set_default(res, 'aria-colindex', cellProps.computedVisibleIndex + 1);
|
|
81
|
+
if (cellProps.computedSortable) set_default(res, 'aria-sort', get_sort_dir(cellProps.computedSortInfo));
|
|
82
|
+
return res;
|
|
83
|
+
};
|
|
84
|
+
const res = resolve_dom_props(consumer, undefined);
|
|
85
|
+
set_default(res, 'role', 'columnheader');
|
|
86
|
+
set_default(res, 'data-column', id);
|
|
87
|
+
return res;
|
|
88
|
+
}
|
|
70
89
|
/**
|
|
71
90
|
* adds ARIA attributes to a row, called from onRenderRow
|
|
72
91
|
* @param rowProps
|
|
73
92
|
* @param selectionEnabled
|
|
74
93
|
*/
|
|
75
94
|
function apply_row_a11y(rowProps, selectionEnabled) {
|
|
76
|
-
var
|
|
95
|
+
var _ref2, _rowProps$remoteRowIn;
|
|
77
96
|
//filler rows (showEmptyRows) are not data rows
|
|
78
97
|
if (rowProps.empty) return;
|
|
79
|
-
const index = (
|
|
98
|
+
const index = (_ref2 = (_rowProps$remoteRowIn = rowProps.remoteRowIndex) !== null && _rowProps$remoteRowIn !== void 0 ? _rowProps$remoteRowIn : rowProps.realIndex) !== null && _ref2 !== void 0 ? _ref2 : 0;
|
|
80
99
|
rowProps['role'] = 'row';
|
|
81
100
|
rowProps['aria-rowindex'] = index + 2; // 1-based, header row is 1
|
|
82
101
|
if (selectionEnabled) rowProps['aria-selected'] = rowProps.selected ? 'true' : 'false';
|
|
@@ -101,6 +120,34 @@ function get_grid_row_count(grid) {
|
|
|
101
120
|
const offset = g.computedLivePagination ? 0 : g.computedSkip || 0;
|
|
102
121
|
return Math.max(g.paginationCount || 0, offset + rendered);
|
|
103
122
|
}
|
|
123
|
+
const HEADER_CELL_SELECTOR = '[role="columnheader"][data-column]';
|
|
124
|
+
/**
|
|
125
|
+
* sets aria-colindex/aria-sort on the header cells of the grid,
|
|
126
|
+
* attributes the consumer set in an object headerDOMProps are left alone
|
|
127
|
+
* @param grid computed props of the grid
|
|
128
|
+
* @param root root element of the grid
|
|
129
|
+
*/
|
|
130
|
+
function apply_header_a11y(grid, root) {
|
|
131
|
+
const columnsMap = grid === null || grid === void 0 ? void 0 : grid.columnsMap;
|
|
132
|
+
if (!columnsMap) return;
|
|
133
|
+
root.querySelectorAll(HEADER_CELL_SELECTOR).forEach(el => {
|
|
134
|
+
//skip headers of grids nested in row details
|
|
135
|
+
if (el.closest('[role="grid"]') !== root) return;
|
|
136
|
+
const col = columnsMap[el.getAttribute('data-column')];
|
|
137
|
+
const own = col === null || col === void 0 ? void 0 : col.headerDOMProps;
|
|
138
|
+
//a function headerDOMProps sets the attributes itself
|
|
139
|
+
if (!own || typeof own !== 'object') return;
|
|
140
|
+
if (own['aria-colindex'] === undefined) set_attr(el, 'aria-colindex', col.computedVisibleIndex + 1);
|
|
141
|
+
if (own['aria-sort'] === undefined) set_attr(el, 'aria-sort', col.computedSortable ? get_sort_dir(col.computedSortInfo) : undefined);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* true when a header cell was (re)mounted without its aria-colindex
|
|
146
|
+
* @param root root element of the grid
|
|
147
|
+
*/
|
|
148
|
+
function has_unsynced_header(root) {
|
|
149
|
+
return !!(root !== null && root !== void 0 && root.querySelector(`${HEADER_CELL_SELECTOR}:not([aria-colindex])`));
|
|
150
|
+
}
|
|
104
151
|
/**
|
|
105
152
|
* true while the grid is loading (loading prop or async datasource)
|
|
106
153
|
* @param grid computed props of the grid
|
|
@@ -125,7 +172,12 @@ function get_root_a11y_key(grid, options) {
|
|
|
125
172
|
var _options$ariaLabel;
|
|
126
173
|
const g = grid;
|
|
127
174
|
if (!g) return '';
|
|
128
|
-
return [get_grid_row_count(g), (g.visibleColumns || []).length, (_options$ariaLabel = options.ariaLabel) !== null && _options$ariaLabel !== void 0 ? _options$ariaLabel : '', options.editable ? 1 : 0, is_grid_busy(g) ? 1 : 0
|
|
175
|
+
return [get_grid_row_count(g), (g.visibleColumns || []).length, (_options$ariaLabel = options.ariaLabel) !== null && _options$ariaLabel !== void 0 ? _options$ariaLabel : '', options.editable ? 1 : 0, is_grid_busy(g) ? 1 : 0,
|
|
176
|
+
//header cells: order and sort direction
|
|
177
|
+
(g.visibleColumns || []).map(c => {
|
|
178
|
+
var _c$computedSortInfo;
|
|
179
|
+
return `${c.id}:${((_c$computedSortInfo = c.computedSortInfo) === null || _c$computedSortInfo === void 0 ? void 0 : _c$computedSortInfo.dir) || 0}`;
|
|
180
|
+
}).join(',')].join('|');
|
|
129
181
|
}
|
|
130
182
|
/**
|
|
131
183
|
* sets ARIA attributes on the grid root element
|
|
@@ -144,5 +196,6 @@ function apply_root_a11y(grid, options) {
|
|
|
144
196
|
set_attr(el, 'aria-label', options.ariaLabel);
|
|
145
197
|
set_attr(el, 'aria-readonly', options.editable ? undefined : 'true');
|
|
146
198
|
set_attr(el, 'aria-busy', is_grid_busy(g) ? 'true' : undefined);
|
|
199
|
+
apply_header_a11y(g, el);
|
|
147
200
|
return el;
|
|
148
201
|
}
|
|
@@ -14,6 +14,12 @@ export declare function ApplyDataSource(datasource: any, props: any, remote?: {
|
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
16
|
export declare function applyColumnData(column_data: any): ColumnDefinition[];
|
|
17
|
+
/**
|
|
18
|
+
* converts select items to an editor dataSource, plain values keep their case as the id
|
|
19
|
+
* @param arr
|
|
20
|
+
* @param idProperty
|
|
21
|
+
* @param valueAsID false uses generated ids instead of the values
|
|
22
|
+
*/
|
|
17
23
|
export declare function to_datasource(arr: any[], idProperty: string, valueAsID?: boolean): any[];
|
|
18
24
|
/**
|
|
19
25
|
* Gets name of a column from its column object
|
|
@@ -20,10 +20,10 @@ var _object = require("@azrico/object");
|
|
|
20
20
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
21
|
// import NumericEditor from '@inovua/reactdatagrid-community/NumericEditor';
|
|
22
22
|
|
|
23
|
+
//editable is defaulted after types/extensions are applied, so they can tell if the consumer set it
|
|
23
24
|
const defaultColumnOptions = {
|
|
24
25
|
draggable: false,
|
|
25
|
-
lockable: false
|
|
26
|
-
editable: false
|
|
26
|
+
lockable: false
|
|
27
27
|
};
|
|
28
28
|
async function ApplyDataSource(datasource, props, remote = {}) {
|
|
29
29
|
let result_data = undefined;
|
|
@@ -90,6 +90,8 @@ function applyColumnData(column_data) {
|
|
|
90
90
|
let editableColumns = column_data.editableColumns || [];
|
|
91
91
|
let customColumns = column_data.customColumns || [];
|
|
92
92
|
if (!Array.isArray(mcols)) return [];
|
|
93
|
+
//columns given as objects are readonly unless something makes them editable
|
|
94
|
+
const object_columns = new Set();
|
|
93
95
|
/* ------------------------------- fix columns ------------------------------ */
|
|
94
96
|
mcols.map(r => {
|
|
95
97
|
if (r == null) return null;
|
|
@@ -108,6 +110,7 @@ function applyColumnData(column_data) {
|
|
|
108
110
|
...r,
|
|
109
111
|
...final_cl
|
|
110
112
|
};
|
|
113
|
+
object_columns.add(final_cl);
|
|
111
114
|
return final_cl;
|
|
112
115
|
}
|
|
113
116
|
return null;
|
|
@@ -182,8 +185,10 @@ function applyColumnData(column_data) {
|
|
|
182
185
|
col.editor = _BoolEditor.default;
|
|
183
186
|
break;
|
|
184
187
|
}
|
|
185
|
-
|
|
188
|
+
//typed columns are editable unless the consumer set editable (a function decides per cell)
|
|
189
|
+
if (col.editable === undefined) col.editable = true;
|
|
186
190
|
}
|
|
191
|
+
if (col.editable === undefined && object_columns.has(col)) col.editable = false;
|
|
187
192
|
//@ts-ignore
|
|
188
193
|
if (!col.editorProps) col.editorProps = {};
|
|
189
194
|
if (col.items) {
|
|
@@ -223,13 +228,19 @@ function applyColumnData(column_data) {
|
|
|
223
228
|
//console.log(final_columns);
|
|
224
229
|
return final_columns;
|
|
225
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* converts select items to an editor dataSource, plain values keep their case as the id
|
|
233
|
+
* @param arr
|
|
234
|
+
* @param idProperty
|
|
235
|
+
* @param valueAsID false uses generated ids instead of the values
|
|
236
|
+
*/
|
|
226
237
|
function to_datasource(arr, idProperty, valueAsID = true) {
|
|
227
238
|
const res = [];
|
|
228
239
|
let index = 0;
|
|
229
240
|
if (Array.isArray(arr)) {
|
|
230
241
|
arr.map(s => {
|
|
231
242
|
let elem = {};
|
|
232
|
-
if (valueAsID) elem[idProperty] = String(s)
|
|
243
|
+
if (valueAsID) elem[idProperty] = String(s);else elem[idProperty] = '_cid_' + index;
|
|
233
244
|
if (typeof s === 'object') elem = {
|
|
234
245
|
...elem,
|
|
235
246
|
...s
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useGridEvents = useGridEvents;
|
|
7
7
|
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _object = require("@azrico/object");
|
|
8
9
|
var _func_grid = require("../func/func_grid");
|
|
9
10
|
var _func_child = require("../func/func_child");
|
|
10
11
|
var _func_a11y = require("../func/func_a11y");
|
|
@@ -77,12 +78,23 @@ function useGridEvents(grid, props) {
|
|
|
77
78
|
}, [props.dataSource]);
|
|
78
79
|
/* ------------------------------- ContextMenu ------------------------------ */
|
|
79
80
|
const onRowContextMenu = _react.default.useCallback((rowProps, event) => {
|
|
80
|
-
if (!rowProps || !rowProps.data || _func_child.func_selection.has_selection()) {
|
|
81
|
+
if (event.defaultPrevented || !rowProps || !rowProps.data || _func_child.func_selection.has_selection()) {
|
|
81
82
|
update_menuRow(null, null);
|
|
82
83
|
return true;
|
|
83
84
|
}
|
|
84
|
-
event.preventDefault();
|
|
85
85
|
const realRow = (0, _func_grid.find_realData)(rowProps.dataSourceArray, event.target, rowProps.data);
|
|
86
|
+
const items = (0, _object.fn_eval)(latestProps.current.contextMenuItems, realRow) || [];
|
|
87
|
+
const resolvedItems = (Array.isArray(items) ? items : [items]).map(item => {
|
|
88
|
+
const value = (0, _object.fn_eval)(item, realRow);
|
|
89
|
+
return typeof value === 'string' ? {
|
|
90
|
+
title: value
|
|
91
|
+
} : value;
|
|
92
|
+
}).filter(item => item != null && typeof item === 'object');
|
|
93
|
+
if (!resolvedItems.length) {
|
|
94
|
+
update_menuRow(null, null);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
event.preventDefault();
|
|
86
98
|
const anEl = _func_child.func_selection.getVirtualElement(event.clientX, event.clientY);
|
|
87
99
|
update_menuRow(realRow, anEl);
|
|
88
100
|
return false;
|
|
@@ -100,13 +112,13 @@ function useGridEvents(grid, props) {
|
|
|
100
112
|
ariaLabel: latestProps.current.ariaLabel,
|
|
101
113
|
editable: !!latestProps.current.editable
|
|
102
114
|
});
|
|
103
|
-
// root attributes are set on the DOM
|
|
115
|
+
// root and header cell attributes are set on the DOM nodes, batched to once per frame
|
|
104
116
|
const scheduleRootSync = _react.default.useCallback((force = false) => {
|
|
105
117
|
var _latestProps$current$;
|
|
106
118
|
if (rootSyncFrame.current || typeof requestAnimationFrame === 'undefined') return;
|
|
107
119
|
const grid = (_latestProps$current$ = latestProps.current.liveGridRef) === null || _latestProps$current$ === void 0 || (_latestProps$current$ = _latestProps$current$.current) === null || _latestProps$current$ === void 0 ? void 0 : _latestProps$current$.current;
|
|
108
120
|
const key = (0, _func_a11y.get_root_a11y_key)(grid, getRootOptions());
|
|
109
|
-
if (!force && key && key === lastRoot.current.key && (0, _func_a11y.get_grid_root)(grid) === lastRoot.current.el) return;
|
|
121
|
+
if (!force && key && key === lastRoot.current.key && (0, _func_a11y.get_grid_root)(grid) === lastRoot.current.el && !(0, _func_a11y.has_unsynced_header)(lastRoot.current.el)) return;
|
|
110
122
|
rootSyncFrame.current = requestAnimationFrame(() => {
|
|
111
123
|
var _latestProps$current$2;
|
|
112
124
|
rootSyncFrame.current = 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* Token overrides for Inovua 5.10.2. Generated by config/generate-theme.cjs.
|
|
2
2
|
* index.css retains layout and icons. Public tokens are inherited; preset tokens
|
|
3
3
|
* are fallback implementation details. Do not set public defaults on the root. */
|
|
4
|
-
.azgrid-scope, .azgrid, .azgrid-theme-light {
|
|
4
|
+
.azgrid-scope, .azgrid, .azgrid-theme-light, .azgrid-context-menu {
|
|
5
5
|
--azgrid-preset-bg: #fff;
|
|
6
6
|
--azgrid-preset-fg: #555e68;
|
|
7
7
|
--azgrid-preset-border: #e4e3e2;
|
|
@@ -2010,23 +2010,18 @@
|
|
|
2010
2010
|
.azgrid-scope .inovua-react-toolkit-menu {
|
|
2011
2011
|
border-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
|
|
2012
2012
|
}
|
|
2013
|
-
/*
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2013
|
+
/* The row context menu is portaled to <body>, outside .azgrid-scope: these rules stay
|
|
2014
|
+
* unscoped and read the tokens from the theme class DataGrid puts on the menu.
|
|
2015
|
+
* Two classes exceed @azrico/controls' single-class menu rules. */
|
|
2016
|
+
.azgrid-context-menu.azrico-controls-contextmenu {
|
|
2017
|
+
--azrico-contextmenu-color: var(--azgrid-menu-fg, var(--azgrid-preset-menu-fg));
|
|
2018
|
+
--azrico-contextmenu-background: var(--azgrid-menu-bg, var(--azgrid-preset-menu-bg));
|
|
2019
|
+
--azrico-contextmenu-hover: var(--azgrid-menu-bg-hover, var(--azgrid-preset-menu-bg-hover));
|
|
2020
|
+
--azrico-contextmenu-focus: var(--azgrid-accent, var(--azgrid-preset-accent));
|
|
2021
|
+
--azrico-contextmenu-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
|
|
2022
|
+
--azrico-contextmenu-shadow: 0 3px 8px var(--azgrid-shadow-color, var(--azgrid-preset-shadow-color));
|
|
2023
|
+
--azrico-contextmenu-font: var(--azgrid-font-family, var(--azgrid-preset-font-family));
|
|
2017
2024
|
border: 1px solid var(--azgrid-menu-border, var(--azgrid-preset-menu-border));
|
|
2018
|
-
border-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
|
|
2019
|
-
box-shadow: 0 3px 8px var(--azgrid-shadow-color, var(--azgrid-preset-shadow-color));
|
|
2020
|
-
font-family: var(--azgrid-font-family, var(--azgrid-preset-font-family));
|
|
2021
|
-
}
|
|
2022
|
-
.azgrid-scope .azgrid-context-menu .MuiTypography-root,
|
|
2023
|
-
.azgrid-scope .azgrid-context-menu .MuiMenuItem-root {
|
|
2024
|
-
color: inherit;
|
|
2025
|
-
font-family: inherit;
|
|
2026
|
-
}
|
|
2027
|
-
.azgrid-scope .azgrid-context-menu .MuiMenuItem-root:hover,
|
|
2028
|
-
.azgrid-scope .azgrid-context-menu .MuiMenuItem-root.Mui-focusVisible {
|
|
2029
|
-
background: var(--azgrid-menu-bg-hover, var(--azgrid-preset-menu-bg-hover));
|
|
2030
2025
|
}
|
|
2031
2026
|
.azgrid-scope, .azgrid-scope * {
|
|
2032
2027
|
accent-color: var(--azgrid-accent, var(--azgrid-preset-accent));
|
|
@@ -73,6 +73,8 @@ export type AzGridProps = {
|
|
|
73
73
|
rightColumns?: string[];
|
|
74
74
|
customColumns?: CustomColumnDefinition[];
|
|
75
75
|
contextMenuItems?: ConvertableToMenuItem;
|
|
76
|
+
/** Extra classes on the row context menu, which is portaled to <body> */
|
|
77
|
+
contextMenuClassName?: string;
|
|
76
78
|
highlightedRow?: any;
|
|
77
79
|
RowDetail?: RowDetailsFunc;
|
|
78
80
|
selected?: RowSelectionValue;
|
|
@@ -100,6 +102,8 @@ export type AzGridProps = {
|
|
|
100
102
|
allowChildRows?: boolean;
|
|
101
103
|
looseCacheCheck?: boolean;
|
|
102
104
|
className?: string;
|
|
105
|
+
/** rendered after the grid, inside its container */
|
|
106
|
+
children?: React.ReactNode;
|
|
103
107
|
};
|
|
104
108
|
export type DataGridProps = ModifyFields<AzGridProps, {
|
|
105
109
|
columns: ColumnDefinition[];
|
|
@@ -11,7 +11,6 @@ require("../themes/grid.css");
|
|
|
11
11
|
var _func_grid = require("../func/func_grid");
|
|
12
12
|
var _contextMenu = require("@azrico/controls/context-menu");
|
|
13
13
|
var _react = _interopRequireDefault(require("react"));
|
|
14
|
-
var _styles = require("@mui/material/styles");
|
|
15
14
|
var _reactdatagridEnterprise = _interopRequireDefault(require("@inovua/reactdatagrid-enterprise"));
|
|
16
15
|
var _clsx = _interopRequireDefault(require("clsx"));
|
|
17
16
|
var _reactUseSize = require("react-use-size");
|
|
@@ -20,6 +19,8 @@ var _useColumnData = require("../hooks/useColumnData");
|
|
|
20
19
|
var _useDatasource = require("../hooks/useDatasource");
|
|
21
20
|
var _useGridSearch = require("../hooks/useGridSearch");
|
|
22
21
|
var _func_a11y = require("../func/func_a11y");
|
|
22
|
+
var _defaultRowIndexColumnId = require("@inovua/reactdatagrid-community/normalizeColumns/defaultRowIndexColumnId");
|
|
23
|
+
var _defaultCheckColumnId = require("@inovua/reactdatagrid-community/normalizeColumns/defaultCheckColumnId");
|
|
23
24
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
24
25
|
/* -------------------------------------------------------------------------- */
|
|
25
26
|
/* -------------------------------------------------------------------------- */
|
|
@@ -121,18 +122,6 @@ function AzGrid(props) {
|
|
|
121
122
|
*/
|
|
122
123
|
function DataGridEventsWrapper(props) {
|
|
123
124
|
var _props$theme;
|
|
124
|
-
const scopeRef = _react.default.useRef(null);
|
|
125
|
-
const hostTheme = (0, _styles.useTheme)();
|
|
126
|
-
// Keep the existing context menu and its portal in this grid's CSS scope.
|
|
127
|
-
const menuTheme = _react.default.useMemo(() => (0, _styles.createTheme)(hostTheme, {
|
|
128
|
-
components: {
|
|
129
|
-
MuiPopper: {
|
|
130
|
-
defaultProps: {
|
|
131
|
-
container: () => scopeRef.current
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}), [hostTheme]);
|
|
136
125
|
const themeClass = `azgrid-theme-${(_props$theme = props.theme) !== null && _props$theme !== void 0 ? _props$theme : props.dark ? 'dark' : 'light'}`;
|
|
137
126
|
/* -------------------------------------------------------------------------- */
|
|
138
127
|
const {
|
|
@@ -176,12 +165,14 @@ function DataGridEventsWrapper(props) {
|
|
|
176
165
|
},
|
|
177
166
|
rowIndexColumn: (0, _func_a11y.apply_column_a11y)(typeof opts.rowIndexColumn === 'object' ? opts.rowIndexColumn : {}, {
|
|
178
167
|
role: 'rowheader',
|
|
179
|
-
gridEditable
|
|
168
|
+
gridEditable,
|
|
169
|
+
id: _defaultRowIndexColumnId.id
|
|
180
170
|
})
|
|
181
171
|
};
|
|
182
172
|
if (opts.checkboxColumn) a11yProps.checkboxColumn = (0, _func_a11y.apply_column_a11y)(typeof opts.checkboxColumn === 'object' ? opts.checkboxColumn : {}, {
|
|
183
173
|
gridEditable,
|
|
184
|
-
markReadonly: false
|
|
174
|
+
markReadonly: false,
|
|
175
|
+
id: _defaultCheckColumnId.id
|
|
185
176
|
});
|
|
186
177
|
return {
|
|
187
178
|
...opts,
|
|
@@ -191,20 +182,17 @@ function DataGridEventsWrapper(props) {
|
|
|
191
182
|
};
|
|
192
183
|
}, [props.static_gridOptions, props.editable, onRowClick, onRowContextMenu, onRenderRow, onRenderLoadMask]);
|
|
193
184
|
/* -------------------------------------------------------------------------- */
|
|
194
|
-
//
|
|
185
|
+
// The menu is portaled to <body>, so it carries the theme class itself to get the theme tokens.
|
|
195
186
|
return _react.default.createElement("div", {
|
|
196
|
-
ref: scopeRef,
|
|
197
187
|
className: (0, _clsx.default)('azgrid-scope azgrid-flexed azgrid-flexlayout', themeClass)
|
|
198
|
-
}, _react.default.createElement(
|
|
199
|
-
|
|
200
|
-
}, _react.default.createElement(_contextMenu.ContextMenu, {
|
|
201
|
-
classname: "azgrid-context-menu",
|
|
188
|
+
}, props.contextMenuItems && _react.default.createElement(_contextMenu.ContextMenu, {
|
|
189
|
+
classname: (0, _clsx.default)('azgrid-context-menu', themeClass, props.contextMenuClassName),
|
|
202
190
|
menuAnchorEl: menuAnchorEl,
|
|
203
191
|
menuRow: menuRow,
|
|
204
192
|
close: update_menuRow,
|
|
205
193
|
dontAutoClose: false,
|
|
206
194
|
menu_items: props.contextMenuItems
|
|
207
|
-
})
|
|
195
|
+
}), props.details_dataSource ? _react.default.createElement(DataGridDetailsWrapper, {
|
|
208
196
|
...props,
|
|
209
197
|
static_gridOptions: static_gridOptions
|
|
210
198
|
}) : _react.default.createElement(DataGridSizeWrapper, {
|