@azrico/reactgrid 1.6.6 → 1.6.7
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 +2 -0
- package/__tests__/context-menu.test.js +67 -1
- package/config/check-theme.cjs +23 -0
- package/config/generate-theme.cjs +2 -0
- package/config/theme-extras.css +9 -0
- package/dist/src/hooks/useGridEvents.js +10 -2
- package/dist/src/themes/azgrid-theme.css +29 -20
- package/dist/src/types/types.d.ts +2 -0
- package/dist/src/views/DataGrid.js +6 -2
- package/package.json +1 -1
- package/src/hooks/useGridEvents.ts +11 -2
- package/src/themes/azgrid-theme.css +29 -20
- package/src/types/types.ts +2 -0
- package/src/views/DataGrid.tsx +17 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. See [standa
|
|
|
4
4
|
|
|
5
5
|
### Unreleased
|
|
6
6
|
|
|
7
|
+
* Make closing the row context menu with Escape opt-in through `escapeClosesContextMenu` (default `false`).
|
|
8
|
+
* Keep the right-clicked row highlighted with the theme's hover colours while its context menu is open, preserving caller row classes and clearing the highlight on close. Correct row hover rules to use hover tokens instead of empty-state tokens.
|
|
7
9
|
* Add `dontAutoCloseContextMenu` to keep the row context menu open on outside clicks, and `hideContextMenu` to hide it while leaving the browser's context menu available.
|
|
8
10
|
* Fix columns with a `type` (`number`, `select`, `bool`, ...) staying read-only unless they were listed in `editableColumns`. A typed column is editable unless you set `editable: false`.
|
|
9
11
|
* Fix a typed column's `editable` function being replaced by `true`. Functions and booleans are kept, so per-cell editability works again.
|
|
@@ -11,7 +11,8 @@ jest.mock('@inovua/reactdatagrid-enterprise', () => {
|
|
|
11
11
|
class Grid extends React.Component {
|
|
12
12
|
render() {
|
|
13
13
|
mockGridProps = this.props;
|
|
14
|
-
|
|
14
|
+
const rowClassName = this.props.rowClassName?.({ data: { __table_id: 'real-row' } });
|
|
15
|
+
return React.createElement('div', { 'data-row-id': 'real-row', className: rowClassName },
|
|
15
16
|
React.createElement('span', { id: 'cell' }, 'Cell'));
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -63,6 +64,7 @@ test('omits ContextMenu entirely when there is no prop and leaves the native men
|
|
|
63
64
|
expect(rightClick().defaultPrevented).toBe(false);
|
|
64
65
|
expect(ContextMenu).not.toHaveBeenCalled();
|
|
65
66
|
expect(popup()).toBeNull();
|
|
67
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
66
68
|
});
|
|
67
69
|
|
|
68
70
|
test.each([
|
|
@@ -74,6 +76,7 @@ test.each([
|
|
|
74
76
|
render(items);
|
|
75
77
|
expect(rightClick().defaultPrevented).toBe(false);
|
|
76
78
|
expect(popup()).toBeNull();
|
|
79
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
77
80
|
});
|
|
78
81
|
|
|
79
82
|
test('resolves the real row before deciding whether to open and closes the previous menu for an empty row', () => {
|
|
@@ -118,17 +121,80 @@ test('passes the real row to onClick and closes the menu', () => {
|
|
|
118
121
|
const onClick = jest.fn();
|
|
119
122
|
render([{ title: 'Open', onClick }]);
|
|
120
123
|
rightClick();
|
|
124
|
+
expect(container.querySelector('.azgrid-row--menu-open')).not.toBeNull();
|
|
121
125
|
act(() => document.querySelector('[role="menuitem"]').click());
|
|
122
126
|
expect(onClick).toHaveBeenCalledWith(row, undefined);
|
|
123
127
|
expect(popup()).toBeNull();
|
|
128
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
124
129
|
});
|
|
125
130
|
|
|
126
131
|
test('clicking outside closes the menu', async () => {
|
|
127
132
|
render(['Open']);
|
|
128
133
|
rightClick();
|
|
134
|
+
expect(container.querySelector('.azgrid-row--menu-open')).not.toBeNull();
|
|
129
135
|
await act(() => new Promise((resolve) => setTimeout(resolve, 0)));
|
|
130
136
|
act(() => document.body.click());
|
|
131
137
|
expect(popup()).toBeNull();
|
|
138
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test.each(['light', 'dark', 'deco'])('keeps the menu row highlighted in %s when moving into the portal', (theme) => {
|
|
142
|
+
render(['Open'], { theme, escapeClosesContextMenu: true, gridOptions: { rowClassName: 'consumer-row' } });
|
|
143
|
+
rightClick();
|
|
144
|
+
const highlighted = container.querySelector('.azgrid-row--menu-open');
|
|
145
|
+
expect(highlighted.classList.contains('consumer-row')).toBe(true);
|
|
146
|
+
const menuItem = document.querySelector('[role="menuitem"]');
|
|
147
|
+
expect(container.contains(menuItem)).toBe(false);
|
|
148
|
+
act(() => menuItem.dispatchEvent(new MouseEvent('mouseover', { bubbles: true })));
|
|
149
|
+
expect(highlighted.classList.contains('azgrid-row--menu-open')).toBe(true);
|
|
150
|
+
act(() => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })));
|
|
151
|
+
expect(popup()).toBeNull();
|
|
152
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
153
|
+
expect(highlighted.classList.contains('consumer-row')).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('merges caller rowClassName functions and matches rows by ID rather than object identity', () => {
|
|
157
|
+
const rowClassName = jest.fn(() => 'consumer-row');
|
|
158
|
+
render(['Open'], { gridOptions: { rowClassName } });
|
|
159
|
+
rightClick();
|
|
160
|
+
const args = { data: { ...row }, props: {}, className: 'inovua-row' };
|
|
161
|
+
expect(mockGridProps.rowClassName(args)).toBe('consumer-row azgrid-row--menu-open');
|
|
162
|
+
expect(rowClassName).toHaveBeenLastCalledWith(args);
|
|
163
|
+
expect(mockGridProps.rowClassName({ data: staleRow })).toBe('consumer-row');
|
|
164
|
+
expect(mockGridProps.rowClassName({ data: {} })).toBe('consumer-row');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test.each([undefined, false])('Escape leaves the menu and highlight open when escapeClosesContextMenu is %s', (escapeClosesContextMenu) => {
|
|
168
|
+
render(['Open'], { escapeClosesContextMenu });
|
|
169
|
+
rightClick();
|
|
170
|
+
act(() => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })));
|
|
171
|
+
expect(popup()).not.toBeNull();
|
|
172
|
+
expect(container.querySelector('.azgrid-row--menu-open')).not.toBeNull();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('escapeClosesContextMenu can be disabled and enabled while the menu is open', () => {
|
|
176
|
+
const items = ['Open'];
|
|
177
|
+
render(items, { escapeClosesContextMenu: true });
|
|
178
|
+
rightClick();
|
|
179
|
+
render(items, { escapeClosesContextMenu: false });
|
|
180
|
+
act(() => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })));
|
|
181
|
+
expect(popup()).not.toBeNull();
|
|
182
|
+
render(items, { escapeClosesContextMenu: true });
|
|
183
|
+
act(() => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })));
|
|
184
|
+
expect(popup()).toBeNull();
|
|
185
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test('removing menu items clears the highlight and does not reopen the menu when items return', () => {
|
|
189
|
+
const items = ['Open'];
|
|
190
|
+
render(items);
|
|
191
|
+
rightClick();
|
|
192
|
+
expect(container.querySelector('.azgrid-row--menu-open')).not.toBeNull();
|
|
193
|
+
render();
|
|
194
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
195
|
+
render(items);
|
|
196
|
+
expect(popup()).toBeNull();
|
|
197
|
+
expect(container.querySelector('.azgrid-row--menu-open')).toBeNull();
|
|
132
198
|
});
|
|
133
199
|
|
|
134
200
|
test('dontAutoCloseContextMenu keeps the menu open on outside clicks and can be updated', async () => {
|
package/config/check-theme.cjs
CHANGED
|
@@ -5,6 +5,29 @@ const cssTree = require('css-tree');
|
|
|
5
5
|
const css = fs.readFileSync('src/themes/azgrid-theme.css', 'utf8');
|
|
6
6
|
cssTree.parse(css);
|
|
7
7
|
const theme = postcss.parse(css);
|
|
8
|
+
const selectorParser = require('postcss-selector-parser');
|
|
9
|
+
const { compare, selectorSpecificity } = require('@csstools/selector-specificity');
|
|
10
|
+
const specificity = selector => selectorSpecificity(selectorParser().astSync(selector).first);
|
|
11
|
+
const menuRowRule = theme.nodes.find(n => n.type === 'rule' && n.selector.includes('.azgrid-row--menu-open'));
|
|
12
|
+
assert(menuRowRule, 'missing open-menu row styles');
|
|
13
|
+
const menuPaint = Object.fromEntries(menuRowRule.nodes.filter(n => n.type === 'decl').map(d => [d.prop, d.value]));
|
|
14
|
+
assert.equal(menuPaint.background, 'var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover))');
|
|
15
|
+
assert.equal(menuPaint.color, 'var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover))');
|
|
16
|
+
for (const suffix of ['__row-hover-target', '__cell', '__row-index-column']) {
|
|
17
|
+
assert(menuRowRule.selectors.some(s => s.endsWith('.InovuaReactDataGrid' + suffix)), 'missing menu row surface ' + suffix);
|
|
18
|
+
}
|
|
19
|
+
theme.walkRules(rule => {
|
|
20
|
+
for (const selector of rule.selectors) {
|
|
21
|
+
if (!selector.includes('__row-hover-target:hover')) continue;
|
|
22
|
+
const surface = selector.includes('__row-index-column') ? '__row-index-column'
|
|
23
|
+
: selector.includes('__cell--over') ? '__cell' : '__row-hover-target';
|
|
24
|
+
const menuSelector = menuRowRule.selectors.find(s => s.endsWith('.InovuaReactDataGrid' + surface));
|
|
25
|
+
assert(compare(specificity(menuSelector), specificity(selector)) >= 0, 'menu highlight weaker than ' + selector);
|
|
26
|
+
for (const declaration of rule.nodes.filter(n => n.type === 'decl')) {
|
|
27
|
+
if (declaration.prop in menuPaint) assert.equal(declaration.value, menuPaint[declaration.prop], 'hover paint differs from menu highlight');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
8
31
|
const presets = new Set();
|
|
9
32
|
const used = new Set();
|
|
10
33
|
let important = [];
|
|
@@ -67,6 +67,8 @@ function tokenFor(selector, prop, literal) {
|
|
|
67
67
|
if (/loader-spinner/.test(selector)) return literal === '#7986cb' ? 'accent' : 'muted-fg';
|
|
68
68
|
if (/loader-loadbar/.test(selector)) return 'loading-fg';
|
|
69
69
|
if (/load-mask|loading/.test(selector)) return bg ? 'loading-bg' : 'loading-fg';
|
|
70
|
+
// :not(.row--empty) in row hover selectors does not describe an empty state.
|
|
71
|
+
if (/__row-hover-target:hover/.test(selector)) return bg ? 'row-bg-hover' : 'row-fg-hover';
|
|
70
72
|
if (/empty/.test(selector)) return bg ? 'empty-bg' : 'empty-fg';
|
|
71
73
|
if (/placeholder/.test(selector)) return 'filter-placeholder';
|
|
72
74
|
if (/sort-icon|selection-dragger|active-borders|checkbox/.test(selector)) {
|
package/config/theme-extras.css
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/* Keep the menu row in its hover state while the pointer is in the portaled menu.
|
|
2
|
+
* Match the strongest selected-row :hover selectors, including their cells. */
|
|
3
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target,
|
|
4
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target .InovuaReactDataGrid__cell,
|
|
5
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target .InovuaReactDataGrid__row-index-column {
|
|
6
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
7
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
8
|
+
}
|
|
9
|
+
|
|
1
10
|
/* Additional surfaces and typography not assigned colours by Inovua. */
|
|
2
11
|
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__row--active:not(.InovuaReactDataGrid__row--selected) .InovuaReactDataGrid__cell:not(.InovuaReactDataGrid__cell--no-background) {
|
|
3
12
|
background: var(--azgrid-row-bg-active, var(--azgrid-preset-row-bg-active));
|
|
@@ -78,8 +78,16 @@ function useGridEvents(grid, props) {
|
|
|
78
78
|
}, [props.dataSource]);
|
|
79
79
|
/* ------------------------------- ContextMenu ------------------------------ */
|
|
80
80
|
_react.default.useEffect(() => {
|
|
81
|
-
if (props.hideContextMenu) update_menuRow(null, null);
|
|
82
|
-
}, [props.hideContextMenu, update_menuRow]);
|
|
81
|
+
if (props.hideContextMenu || !props.contextMenuItems) update_menuRow(null, null);
|
|
82
|
+
}, [props.hideContextMenu, props.contextMenuItems, update_menuRow]);
|
|
83
|
+
_react.default.useEffect(() => {
|
|
84
|
+
if (!menuAnchorEl || !props.escapeClosesContextMenu) return;
|
|
85
|
+
const onKeyDown = event => {
|
|
86
|
+
if (event.key === 'Escape') update_menuRow(null, null);
|
|
87
|
+
};
|
|
88
|
+
document.addEventListener('keydown', onKeyDown);
|
|
89
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
90
|
+
}, [menuAnchorEl, props.escapeClosesContextMenu, update_menuRow]);
|
|
83
91
|
const onRowContextMenu = _react.default.useCallback((rowProps, event) => {
|
|
84
92
|
if (latestProps.current.hideContextMenu || event.defaultPrevented || !rowProps || !rowProps.data || _func_child.func_selection.has_selection()) {
|
|
85
93
|
update_menuRow(null, null);
|
|
@@ -1452,65 +1452,65 @@
|
|
|
1452
1452
|
}
|
|
1453
1453
|
|
|
1454
1454
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover {
|
|
1455
|
-
background: var(--azgrid-
|
|
1456
|
-
color: var(--azgrid-
|
|
1455
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1456
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
1459
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1460
|
-
background: var(--azgrid-
|
|
1460
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1461
1461
|
}
|
|
1462
1462
|
|
|
1463
1463
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1464
|
-
background: var(--azgrid-
|
|
1465
|
-
color: var(--azgrid-
|
|
1464
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1465
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1466
1466
|
}
|
|
1467
1467
|
|
|
1468
1468
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover {
|
|
1469
|
-
background: var(--azgrid-
|
|
1470
|
-
color: var(--azgrid-
|
|
1469
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1470
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1471
1471
|
}
|
|
1472
1472
|
|
|
1473
1473
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1474
|
-
background: var(--azgrid-
|
|
1474
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1475
1475
|
}
|
|
1476
1476
|
|
|
1477
1477
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1478
|
-
background: var(--azgrid-
|
|
1479
|
-
color: var(--azgrid-
|
|
1478
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1479
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1480
1480
|
}
|
|
1481
1481
|
|
|
1482
1482
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover,
|
|
1483
1483
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover {
|
|
1484
|
-
background: var(--azgrid-
|
|
1485
|
-
color: var(--azgrid-
|
|
1484
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1485
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1486
1486
|
}
|
|
1487
1487
|
|
|
1488
1488
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column,
|
|
1489
1489
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1490
|
-
background: var(--azgrid-
|
|
1490
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1491
1491
|
}
|
|
1492
1492
|
|
|
1493
1493
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over,
|
|
1494
1494
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1495
|
-
background: var(--azgrid-
|
|
1496
|
-
color: var(--azgrid-
|
|
1495
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1496
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1497
1497
|
}
|
|
1498
1498
|
|
|
1499
1499
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover,
|
|
1500
1500
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover {
|
|
1501
|
-
background: var(--azgrid-
|
|
1502
|
-
color: var(--azgrid-
|
|
1501
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1502
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1503
1503
|
}
|
|
1504
1504
|
|
|
1505
1505
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column,
|
|
1506
1506
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1507
|
-
background: var(--azgrid-
|
|
1507
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1508
1508
|
}
|
|
1509
1509
|
|
|
1510
1510
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over,
|
|
1511
1511
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1512
|
-
background: var(--azgrid-
|
|
1513
|
-
color: var(--azgrid-
|
|
1512
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1513
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1514
1514
|
}
|
|
1515
1515
|
|
|
1516
1516
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--focused .InovuaReactDataGrid__row--active>.InovuaReactDataGrid__row-active-borders-wrapper>.InovuaReactDataGrid__row-active-borders:before,
|
|
@@ -1934,6 +1934,15 @@
|
|
|
1934
1934
|
fill: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1935
1935
|
}
|
|
1936
1936
|
|
|
1937
|
+
/* Keep the menu row in its hover state while the pointer is in the portaled menu.
|
|
1938
|
+
* Match the strongest selected-row :hover selectors, including their cells. */
|
|
1939
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target,
|
|
1940
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target .InovuaReactDataGrid__cell,
|
|
1941
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target .InovuaReactDataGrid__row-index-column {
|
|
1942
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1943
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1937
1946
|
/* Additional surfaces and typography not assigned colours by Inovua. */
|
|
1938
1947
|
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__row--active:not(.InovuaReactDataGrid__row--selected) .InovuaReactDataGrid__cell:not(.InovuaReactDataGrid__cell--no-background) {
|
|
1939
1948
|
background: var(--azgrid-row-bg-active, var(--azgrid-preset-row-bg-active));
|
|
@@ -75,6 +75,8 @@ export type AzGridProps = {
|
|
|
75
75
|
contextMenuItems?: ConvertableToMenuItem;
|
|
76
76
|
/** Keep the context menu open when clicking outside (default false). */
|
|
77
77
|
dontAutoCloseContextMenu?: boolean;
|
|
78
|
+
/** Close the context menu on Escape (default false). */
|
|
79
|
+
escapeClosesContextMenu?: boolean;
|
|
78
80
|
/** Hide the grid context menu and leave the browser's context menu available. */
|
|
79
81
|
hideContextMenu?: boolean;
|
|
80
82
|
/** Extra classes on the row context menu, which is portaled to <body> */
|
|
@@ -121,7 +121,7 @@ function AzGrid(props) {
|
|
|
121
121
|
* @returns
|
|
122
122
|
*/
|
|
123
123
|
function DataGridEventsWrapper(props) {
|
|
124
|
-
var _props$theme, _props$dontAutoCloseC;
|
|
124
|
+
var _props$theme, _props$static_gridOpt, _props$dontAutoCloseC;
|
|
125
125
|
const themeClass = `azgrid-theme-${(_props$theme = props.theme) !== null && _props$theme !== void 0 ? _props$theme : props.dark ? 'dark' : 'light'}`;
|
|
126
126
|
/* -------------------------------------------------------------------------- */
|
|
127
127
|
const {
|
|
@@ -133,6 +133,9 @@ function DataGridEventsWrapper(props) {
|
|
|
133
133
|
menuAnchorEl,
|
|
134
134
|
menuRow
|
|
135
135
|
} = (0, _useGridEvents.useGridEvents)(props.gridRef.current, props);
|
|
136
|
+
const menuRowId = menuAnchorEl && !props.hideContextMenu && props.contextMenuItems ? (0, _func_grid.get_row_id)(menuRow) : undefined;
|
|
137
|
+
const consumerRowClassName = (_props$static_gridOpt = props.static_gridOptions) === null || _props$static_gridOpt === void 0 ? void 0 : _props$static_gridOpt.rowClassName;
|
|
138
|
+
const rowClassName = _react.default.useCallback(rowProps => (0, _clsx.default)(typeof consumerRowClassName === 'function' ? consumerRowClassName(rowProps) : consumerRowClassName, menuRowId != null && (0, _func_grid.get_row_id)(rowProps.data) === menuRowId && 'azgrid-row--menu-open'), [consumerRowClassName, menuRowId]);
|
|
136
139
|
/* -------------------------------------------------------------------------- */
|
|
137
140
|
/**
|
|
138
141
|
* Merge click events into grid options
|
|
@@ -146,6 +149,7 @@ function DataGridEventsWrapper(props) {
|
|
|
146
149
|
// internal row attributes first, consumer's onRenderRow last so it can override them
|
|
147
150
|
const consumerOnRenderRow = opts.onRenderRow;
|
|
148
151
|
const renderProps = {
|
|
152
|
+
rowClassName,
|
|
149
153
|
onRenderRow: consumerOnRenderRow ? rowProps => {
|
|
150
154
|
onRenderRow(rowProps);
|
|
151
155
|
consumerOnRenderRow(rowProps);
|
|
@@ -180,7 +184,7 @@ function DataGridEventsWrapper(props) {
|
|
|
180
184
|
...renderProps,
|
|
181
185
|
...a11yProps
|
|
182
186
|
};
|
|
183
|
-
}, [props.static_gridOptions, props.editable, onRowClick, onRowContextMenu, onRenderRow, onRenderLoadMask]);
|
|
187
|
+
}, [props.static_gridOptions, props.editable, onRowClick, onRowContextMenu, onRenderRow, onRenderLoadMask, rowClassName]);
|
|
184
188
|
/* -------------------------------------------------------------------------- */
|
|
185
189
|
// The menu is portaled to <body>, so it carries the theme class itself to get the theme tokens.
|
|
186
190
|
return _react.default.createElement("div", {
|
package/package.json
CHANGED
|
@@ -75,8 +75,17 @@ export function useGridEvents(grid: GridType, props: DataGridWrapperProps) {
|
|
|
75
75
|
|
|
76
76
|
/* ------------------------------- ContextMenu ------------------------------ */
|
|
77
77
|
React.useEffect(() => {
|
|
78
|
-
if (props.hideContextMenu) update_menuRow(null, null);
|
|
79
|
-
}, [props.hideContextMenu, update_menuRow]);
|
|
78
|
+
if (props.hideContextMenu || !props.contextMenuItems) update_menuRow(null, null);
|
|
79
|
+
}, [props.hideContextMenu, props.contextMenuItems, update_menuRow]);
|
|
80
|
+
|
|
81
|
+
React.useEffect(() => {
|
|
82
|
+
if (!menuAnchorEl || !props.escapeClosesContextMenu) return;
|
|
83
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
84
|
+
if (event.key === 'Escape') update_menuRow(null, null);
|
|
85
|
+
};
|
|
86
|
+
document.addEventListener('keydown', onKeyDown);
|
|
87
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
88
|
+
}, [menuAnchorEl, props.escapeClosesContextMenu, update_menuRow]);
|
|
80
89
|
|
|
81
90
|
const onRowContextMenu = React.useCallback((rowProps, event) => {
|
|
82
91
|
if (
|
|
@@ -1452,65 +1452,65 @@
|
|
|
1452
1452
|
}
|
|
1453
1453
|
|
|
1454
1454
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover {
|
|
1455
|
-
background: var(--azgrid-
|
|
1456
|
-
color: var(--azgrid-
|
|
1455
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1456
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
1459
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1460
|
-
background: var(--azgrid-
|
|
1460
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1461
1461
|
}
|
|
1462
1462
|
|
|
1463
1463
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1464
|
-
background: var(--azgrid-
|
|
1465
|
-
color: var(--azgrid-
|
|
1464
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1465
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1466
1466
|
}
|
|
1467
1467
|
|
|
1468
1468
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover {
|
|
1469
|
-
background: var(--azgrid-
|
|
1470
|
-
color: var(--azgrid-
|
|
1469
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1470
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1471
1471
|
}
|
|
1472
1472
|
|
|
1473
1473
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1474
|
-
background: var(--azgrid-
|
|
1474
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1475
1475
|
}
|
|
1476
1476
|
|
|
1477
1477
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--even:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1478
|
-
background: var(--azgrid-
|
|
1479
|
-
color: var(--azgrid-
|
|
1478
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1479
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1480
1480
|
}
|
|
1481
1481
|
|
|
1482
1482
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover,
|
|
1483
1483
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover {
|
|
1484
|
-
background: var(--azgrid-
|
|
1485
|
-
color: var(--azgrid-
|
|
1484
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1485
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1486
1486
|
}
|
|
1487
1487
|
|
|
1488
1488
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column,
|
|
1489
1489
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1490
|
-
background: var(--azgrid-
|
|
1490
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1491
1491
|
}
|
|
1492
1492
|
|
|
1493
1493
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over,
|
|
1494
1494
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1495
|
-
background: var(--azgrid-
|
|
1496
|
-
color: var(--azgrid-
|
|
1495
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1496
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1497
1497
|
}
|
|
1498
1498
|
|
|
1499
1499
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover,
|
|
1500
1500
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover {
|
|
1501
|
-
background: var(--azgrid-
|
|
1502
|
-
color: var(--azgrid-
|
|
1501
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1502
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1503
1503
|
}
|
|
1504
1504
|
|
|
1505
1505
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column,
|
|
1506
1506
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__row-index-column {
|
|
1507
|
-
background: var(--azgrid-
|
|
1507
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1508
1508
|
}
|
|
1509
1509
|
|
|
1510
1510
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--no-zebra:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over,
|
|
1511
1511
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row--odd:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty).InovuaReactDataGrid__row--selected .InovuaReactDataGrid__row-hover-target:hover .InovuaReactDataGrid__cell--over {
|
|
1512
|
-
background: var(--azgrid-
|
|
1513
|
-
color: var(--azgrid-
|
|
1512
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1513
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1514
1514
|
}
|
|
1515
1515
|
|
|
1516
1516
|
.azgrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--focused .InovuaReactDataGrid__row--active>.InovuaReactDataGrid__row-active-borders-wrapper>.InovuaReactDataGrid__row-active-borders:before,
|
|
@@ -1934,6 +1934,15 @@
|
|
|
1934
1934
|
fill: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1935
1935
|
}
|
|
1936
1936
|
|
|
1937
|
+
/* Keep the menu row in its hover state while the pointer is in the portaled menu.
|
|
1938
|
+
* Match the strongest selected-row :hover selectors, including their cells. */
|
|
1939
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target,
|
|
1940
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target .InovuaReactDataGrid__cell,
|
|
1941
|
+
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light.InovuaReactDataGrid--show-hover-rows .InovuaReactDataGrid__row.azgrid-row--menu-open:not(.InovuaReactDataGrid__row--scrolling):not(.InovuaReactDataGrid__row--empty) .InovuaReactDataGrid__row-hover-target .InovuaReactDataGrid__row-index-column {
|
|
1942
|
+
background: var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover));
|
|
1943
|
+
color: var(--azgrid-row-fg-hover, var(--azgrid-preset-row-fg-hover));
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1937
1946
|
/* Additional surfaces and typography not assigned colours by Inovua. */
|
|
1938
1947
|
.azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__row--active:not(.InovuaReactDataGrid__row--selected) .InovuaReactDataGrid__cell:not(.InovuaReactDataGrid__cell--no-background) {
|
|
1939
1948
|
background: var(--azgrid-row-bg-active, var(--azgrid-preset-row-bg-active));
|
package/src/types/types.ts
CHANGED
|
@@ -97,6 +97,8 @@ export type AzGridProps = {
|
|
|
97
97
|
contextMenuItems?: ConvertableToMenuItem;
|
|
98
98
|
/** Keep the context menu open when clicking outside (default false). */
|
|
99
99
|
dontAutoCloseContextMenu?: boolean;
|
|
100
|
+
/** Close the context menu on Escape (default false). */
|
|
101
|
+
escapeClosesContextMenu?: boolean;
|
|
100
102
|
/** Hide the grid context menu and leave the browser's context menu available. */
|
|
101
103
|
hideContextMenu?: boolean;
|
|
102
104
|
/** Extra classes on the row context menu, which is portaled to <body> */
|
package/src/views/DataGrid.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '@inovua/reactdatagrid-enterprise/index.css';
|
|
2
2
|
import '../themes/base_styles.css';
|
|
3
3
|
import '../themes/grid.css';
|
|
4
|
-
import { get_default_key } from '../func/func_grid';
|
|
4
|
+
import { get_default_key, get_row_id } from '../func/func_grid';
|
|
5
5
|
import { ContextMenu } from '@azrico/controls/context-menu';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
@@ -164,6 +164,20 @@ function DataGridEventsWrapper(props: DataGridWrapperProps) {
|
|
|
164
164
|
menuAnchorEl,
|
|
165
165
|
menuRow,
|
|
166
166
|
} = useGridEvents(props.gridRef.current, props);
|
|
167
|
+
const menuRowId =
|
|
168
|
+
menuAnchorEl && !props.hideContextMenu && props.contextMenuItems
|
|
169
|
+
? get_row_id(menuRow)
|
|
170
|
+
: undefined;
|
|
171
|
+
const consumerRowClassName = props.static_gridOptions?.rowClassName;
|
|
172
|
+
const rowClassName = React.useCallback(
|
|
173
|
+
(rowProps) => clsx(
|
|
174
|
+
typeof consumerRowClassName === 'function'
|
|
175
|
+
? consumerRowClassName(rowProps)
|
|
176
|
+
: consumerRowClassName,
|
|
177
|
+
menuRowId != null && get_row_id(rowProps.data) === menuRowId && 'azgrid-row--menu-open'
|
|
178
|
+
),
|
|
179
|
+
[consumerRowClassName, menuRowId]
|
|
180
|
+
);
|
|
167
181
|
/* -------------------------------------------------------------------------- */
|
|
168
182
|
/**
|
|
169
183
|
* Merge click events into grid options
|
|
@@ -178,6 +192,7 @@ function DataGridEventsWrapper(props: DataGridWrapperProps) {
|
|
|
178
192
|
// internal row attributes first, consumer's onRenderRow last so it can override them
|
|
179
193
|
const consumerOnRenderRow = opts.onRenderRow;
|
|
180
194
|
const renderProps: any = {
|
|
195
|
+
rowClassName,
|
|
181
196
|
onRenderRow: consumerOnRenderRow
|
|
182
197
|
? (rowProps) => {
|
|
183
198
|
onRenderRow(rowProps);
|
|
@@ -218,6 +233,7 @@ function DataGridEventsWrapper(props: DataGridWrapperProps) {
|
|
|
218
233
|
onRowContextMenu,
|
|
219
234
|
onRenderRow,
|
|
220
235
|
onRenderLoadMask,
|
|
236
|
+
rowClassName,
|
|
221
237
|
]);
|
|
222
238
|
|
|
223
239
|
/* -------------------------------------------------------------------------- */
|