@elastic/eui 92.0.0 → 92.1.1

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.
Files changed (156) hide show
  1. package/dist/eui_theme_dark.css +3 -18
  2. package/dist/eui_theme_dark.min.css +1 -1
  3. package/dist/eui_theme_light.css +3 -18
  4. package/dist/eui_theme_light.min.css +1 -1
  5. package/es/components/aspect_ratio/aspect_ratio.js +1 -1
  6. package/es/components/collapsible_nav_beta/collapsible_nav_body_footer.js +7 -3
  7. package/es/components/collapsible_nav_beta/collapsible_nav_body_footer.styles.js +4 -4
  8. package/es/components/datagrid/body/{data_grid_cell.js → cell/data_grid_cell.js} +111 -244
  9. package/es/components/datagrid/body/{data_grid_cell_actions.js → cell/data_grid_cell_actions.js} +5 -5
  10. package/es/components/datagrid/body/{data_grid_cell_popover.js → cell/data_grid_cell_popover.js} +4 -4
  11. package/es/components/datagrid/body/{data_grid_cell_wrapper.js → cell/data_grid_cell_wrapper.js} +1 -1
  12. package/es/components/datagrid/body/cell/focus_utils.js +166 -0
  13. package/es/components/datagrid/body/cell/index.js +11 -0
  14. package/es/components/datagrid/body/data_grid_body.js +0 -2
  15. package/es/components/datagrid/body/data_grid_body_custom.js +1 -7
  16. package/es/components/datagrid/body/data_grid_body_virtualized.js +1 -7
  17. package/es/components/datagrid/body/footer/data_grid_footer_row.js +1 -2
  18. package/es/components/datagrid/body/header/data_grid_control_header_cell.js +3 -6
  19. package/es/components/datagrid/body/header/data_grid_header_cell.js +27 -12
  20. package/es/components/datagrid/body/header/data_grid_header_cell_wrapper.js +45 -116
  21. package/es/components/datagrid/body/header/data_grid_header_row.js +5 -10
  22. package/es/components/datagrid/body/header/use_data_grid_header.js +3 -14
  23. package/es/components/datagrid/data_grid.js +2 -12
  24. package/es/components/datagrid/utils/focus.js +25 -54
  25. package/es/components/datagrid/utils/scrolling.js +1 -1
  26. package/es/components/flyout/flyout_resizable.js +10 -10
  27. package/es/components/flyout/flyout_resizable.styles.js +12 -6
  28. package/es/components/resizable_container/helpers.js +5 -6
  29. package/es/components/resizable_container/resizable_button.js +13 -4
  30. package/es/components/resizable_container/resizable_button.styles.js +18 -8
  31. package/es/components/resizable_container/resizable_container.js +28 -22
  32. package/es/components/steps/step_number.styles.js +6 -7
  33. package/es/components/tree_view/tree_view.js +9 -2
  34. package/eui.d.ts +130 -90
  35. package/i18ntokens.json +108 -72
  36. package/lib/components/aspect_ratio/aspect_ratio.js +1 -1
  37. package/lib/components/collapsible_nav_beta/collapsible_nav_body_footer.js +7 -3
  38. package/lib/components/collapsible_nav_beta/collapsible_nav_body_footer.styles.js +4 -4
  39. package/lib/components/datagrid/body/{data_grid_cell.js → cell/data_grid_cell.js} +111 -244
  40. package/lib/components/datagrid/body/{data_grid_cell_actions.js → cell/data_grid_cell_actions.js} +5 -5
  41. package/lib/components/datagrid/body/{data_grid_cell_popover.js → cell/data_grid_cell_popover.js} +4 -4
  42. package/lib/components/datagrid/body/{data_grid_cell_wrapper.js → cell/data_grid_cell_wrapper.js} +1 -1
  43. package/lib/components/datagrid/body/cell/focus_utils.js +174 -0
  44. package/lib/components/datagrid/body/cell/index.js +32 -0
  45. package/lib/components/datagrid/body/data_grid_body.js +0 -2
  46. package/lib/components/datagrid/body/data_grid_body_custom.js +2 -8
  47. package/lib/components/datagrid/body/data_grid_body_virtualized.js +2 -8
  48. package/lib/components/datagrid/body/footer/data_grid_footer_row.js +5 -6
  49. package/lib/components/datagrid/body/header/data_grid_control_header_cell.js +3 -6
  50. package/lib/components/datagrid/body/header/data_grid_header_cell.js +35 -20
  51. package/lib/components/datagrid/body/header/data_grid_header_cell_wrapper.js +47 -119
  52. package/lib/components/datagrid/body/header/data_grid_header_row.js +5 -10
  53. package/lib/components/datagrid/body/header/use_data_grid_header.js +10 -24
  54. package/lib/components/datagrid/data_grid.js +4 -14
  55. package/lib/components/datagrid/utils/focus.js +26 -56
  56. package/lib/components/datagrid/utils/scrolling.js +2 -2
  57. package/lib/components/flyout/flyout_resizable.js +10 -10
  58. package/lib/components/flyout/flyout_resizable.styles.js +12 -6
  59. package/lib/components/resizable_container/helpers.js +7 -7
  60. package/lib/components/resizable_container/resizable_button.js +13 -4
  61. package/lib/components/resizable_container/resizable_button.styles.js +18 -8
  62. package/lib/components/resizable_container/resizable_container.js +28 -22
  63. package/lib/components/steps/step_number.styles.js +6 -7
  64. package/lib/components/tree_view/tree_view.js +9 -2
  65. package/optimize/es/components/aspect_ratio/aspect_ratio.js +1 -1
  66. package/optimize/es/components/collapsible_nav_beta/collapsible_nav_body_footer.js +7 -3
  67. package/optimize/es/components/collapsible_nav_beta/collapsible_nav_body_footer.styles.js +4 -4
  68. package/optimize/es/components/datagrid/body/{data_grid_cell.js → cell/data_grid_cell.js} +111 -244
  69. package/optimize/es/components/datagrid/body/{data_grid_cell_actions.js → cell/data_grid_cell_actions.js} +5 -5
  70. package/optimize/es/components/datagrid/body/{data_grid_cell_popover.js → cell/data_grid_cell_popover.js} +4 -4
  71. package/optimize/es/components/datagrid/body/{data_grid_cell_wrapper.js → cell/data_grid_cell_wrapper.js} +1 -1
  72. package/optimize/es/components/datagrid/body/cell/focus_utils.js +153 -0
  73. package/optimize/es/components/datagrid/body/cell/index.js +11 -0
  74. package/optimize/es/components/datagrid/body/data_grid_body_custom.js +1 -5
  75. package/optimize/es/components/datagrid/body/data_grid_body_virtualized.js +1 -5
  76. package/optimize/es/components/datagrid/body/footer/data_grid_footer_row.js +1 -2
  77. package/optimize/es/components/datagrid/body/header/data_grid_control_header_cell.js +2 -4
  78. package/optimize/es/components/datagrid/body/header/data_grid_header_cell.js +25 -10
  79. package/optimize/es/components/datagrid/body/header/data_grid_header_cell_wrapper.js +41 -115
  80. package/optimize/es/components/datagrid/body/header/data_grid_header_row.js +4 -8
  81. package/optimize/es/components/datagrid/body/header/use_data_grid_header.js +3 -13
  82. package/optimize/es/components/datagrid/data_grid.js +2 -12
  83. package/optimize/es/components/datagrid/utils/focus.js +25 -54
  84. package/optimize/es/components/datagrid/utils/scrolling.js +1 -1
  85. package/optimize/es/components/flyout/flyout_resizable.js +10 -10
  86. package/optimize/es/components/flyout/flyout_resizable.styles.js +12 -6
  87. package/optimize/es/components/resizable_container/helpers.js +5 -6
  88. package/optimize/es/components/resizable_container/resizable_button.js +5 -2
  89. package/optimize/es/components/resizable_container/resizable_button.styles.js +18 -8
  90. package/optimize/es/components/resizable_container/resizable_container.js +28 -22
  91. package/optimize/es/components/steps/step_number.styles.js +6 -7
  92. package/optimize/es/components/tree_view/tree_view.js +9 -2
  93. package/optimize/lib/components/aspect_ratio/aspect_ratio.js +1 -1
  94. package/optimize/lib/components/collapsible_nav_beta/collapsible_nav_body_footer.js +7 -3
  95. package/optimize/lib/components/collapsible_nav_beta/collapsible_nav_body_footer.styles.js +4 -4
  96. package/optimize/lib/components/datagrid/body/{data_grid_cell.js → cell/data_grid_cell.js} +111 -244
  97. package/optimize/lib/components/datagrid/body/{data_grid_cell_actions.js → cell/data_grid_cell_actions.js} +5 -5
  98. package/optimize/lib/components/datagrid/body/{data_grid_cell_popover.js → cell/data_grid_cell_popover.js} +4 -4
  99. package/optimize/lib/components/datagrid/body/{data_grid_cell_wrapper.js → cell/data_grid_cell_wrapper.js} +1 -1
  100. package/optimize/lib/components/datagrid/body/cell/focus_utils.js +163 -0
  101. package/optimize/lib/components/datagrid/body/cell/index.js +32 -0
  102. package/optimize/lib/components/datagrid/body/data_grid_body_custom.js +2 -6
  103. package/optimize/lib/components/datagrid/body/data_grid_body_virtualized.js +2 -6
  104. package/optimize/lib/components/datagrid/body/footer/data_grid_footer_row.js +5 -6
  105. package/optimize/lib/components/datagrid/body/header/data_grid_control_header_cell.js +2 -4
  106. package/optimize/lib/components/datagrid/body/header/data_grid_header_cell.js +25 -10
  107. package/optimize/lib/components/datagrid/body/header/data_grid_header_cell_wrapper.js +41 -115
  108. package/optimize/lib/components/datagrid/body/header/data_grid_header_row.js +4 -8
  109. package/optimize/lib/components/datagrid/body/header/use_data_grid_header.js +4 -14
  110. package/optimize/lib/components/datagrid/data_grid.js +4 -14
  111. package/optimize/lib/components/datagrid/utils/focus.js +26 -56
  112. package/optimize/lib/components/datagrid/utils/scrolling.js +2 -2
  113. package/optimize/lib/components/flyout/flyout_resizable.js +10 -10
  114. package/optimize/lib/components/flyout/flyout_resizable.styles.js +12 -6
  115. package/optimize/lib/components/resizable_container/helpers.js +7 -7
  116. package/optimize/lib/components/resizable_container/resizable_button.js +5 -2
  117. package/optimize/lib/components/resizable_container/resizable_button.styles.js +18 -8
  118. package/optimize/lib/components/resizable_container/resizable_container.js +28 -22
  119. package/optimize/lib/components/steps/step_number.styles.js +6 -7
  120. package/optimize/lib/components/tree_view/tree_view.js +9 -2
  121. package/package.json +1 -1
  122. package/src/components/datagrid/body/header/_data_grid_header_row.scss +8 -7
  123. package/test-env/components/aspect_ratio/aspect_ratio.js +1 -1
  124. package/test-env/components/collapsible_nav_beta/collapsible_nav_body_footer.js +7 -3
  125. package/test-env/components/collapsible_nav_beta/collapsible_nav_body_footer.styles.js +4 -4
  126. package/test-env/components/datagrid/body/{data_grid_cell.js → cell/data_grid_cell.js} +111 -244
  127. package/test-env/components/datagrid/body/{data_grid_cell_actions.js → cell/data_grid_cell_actions.js} +5 -5
  128. package/test-env/components/datagrid/body/{data_grid_cell_popover.js → cell/data_grid_cell_popover.js} +4 -4
  129. package/test-env/components/datagrid/body/{data_grid_cell_wrapper.js → cell/data_grid_cell_wrapper.js} +1 -1
  130. package/test-env/components/datagrid/body/cell/focus_utils.js +172 -0
  131. package/test-env/components/datagrid/body/cell/index.js +32 -0
  132. package/test-env/components/datagrid/body/data_grid_body.js +0 -2
  133. package/test-env/components/datagrid/body/data_grid_body_custom.js +2 -8
  134. package/test-env/components/datagrid/body/data_grid_body_virtualized.js +2 -8
  135. package/test-env/components/datagrid/body/footer/data_grid_footer_row.js +5 -6
  136. package/test-env/components/datagrid/body/header/data_grid_control_header_cell.js +3 -6
  137. package/test-env/components/datagrid/body/header/data_grid_header_cell.js +25 -10
  138. package/test-env/components/datagrid/body/header/data_grid_header_cell_wrapper.js +44 -116
  139. package/test-env/components/datagrid/body/header/data_grid_header_row.js +5 -10
  140. package/test-env/components/datagrid/body/header/use_data_grid_header.js +4 -14
  141. package/test-env/components/datagrid/data_grid.js +4 -14
  142. package/test-env/components/datagrid/utils/focus.js +26 -56
  143. package/test-env/components/datagrid/utils/scrolling.js +2 -2
  144. package/test-env/components/flyout/flyout_resizable.js +10 -10
  145. package/test-env/components/flyout/flyout_resizable.styles.js +12 -6
  146. package/test-env/components/resizable_container/helpers.js +7 -7
  147. package/test-env/components/resizable_container/resizable_button.js +13 -4
  148. package/test-env/components/resizable_container/resizable_button.styles.js +18 -8
  149. package/test-env/components/resizable_container/resizable_container.js +28 -22
  150. package/test-env/components/steps/step_number.styles.js +6 -7
  151. package/test-env/components/tree_view/tree_view.js +9 -2
  152. package/es/components/datagrid/body/header/header_is_interactive.js +0 -58
  153. package/lib/components/datagrid/body/header/header_is_interactive.js +0 -63
  154. package/optimize/es/components/datagrid/body/header/header_is_interactive.js +0 -53
  155. package/optimize/lib/components/datagrid/body/header/header_is_interactive.js +0 -61
  156. package/test-env/components/datagrid/body/header/header_is_interactive.js +0 -61
@@ -25,17 +25,16 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
25
25
  import classNames from 'classnames';
26
26
  import React, { Component, createRef, memo } from 'react';
27
27
  import { createPortal } from 'react-dom';
28
- import { tabbable } from 'tabbable';
29
- import { keys } from '../../../services';
30
- import { EuiScreenReaderOnly } from '../../accessibility';
31
- import { EuiFocusTrap } from '../../focus_trap';
32
- import { EuiI18n } from '../../i18n';
33
- import { EuiTextBlockTruncate } from '../../text_truncate';
34
- import { hasResizeObserver } from '../../observer/resize_observer/resize_observer';
35
- import { DataGridFocusContext } from '../utils/focus';
28
+ import { IS_JEST_ENVIRONMENT } from '../../../../utils';
29
+ import { keys } from '../../../../services';
30
+ import { EuiScreenReaderOnly } from '../../../accessibility';
31
+ import { EuiI18n } from '../../../i18n';
32
+ import { EuiTextBlockTruncate } from '../../../text_truncate';
33
+ import { hasResizeObserver } from '../../../observer/resize_observer/resize_observer';
34
+ import { DataGridFocusContext } from '../../utils/focus';
36
35
  import { EuiDataGridCellActions, EuiDataGridCellPopoverActions } from './data_grid_cell_actions';
37
36
  import { DefaultCellPopover } from './data_grid_cell_popover';
38
- import { IS_JEST_ENVIRONMENT } from '../../../utils';
37
+ import { HandleInteractiveChildren } from './focus_utils';
39
38
  import { jsx as ___EmotionJSX } from "@emotion/react";
40
39
  var EuiDataGridCellContent = /*#__PURE__*/memo(function (_ref) {
41
40
  var renderCellValue = _ref.renderCellValue,
@@ -85,7 +84,10 @@ var EuiDataGridCellContent = /*#__PURE__*/memo(function (_ref) {
85
84
  col: colIndex + 1,
86
85
  row: ariaRowIndex
87
86
  }
88
- })));
87
+ }), cellActions && ___EmotionJSX(React.Fragment, null, '. ', ___EmotionJSX(EuiI18n, {
88
+ token: "euiDataGridCell.expansionEnterPrompt",
89
+ default: "Press the Enter key to expand this cell."
90
+ }))));
89
91
  return ___EmotionJSX(React.Fragment, null, cellContent, screenReaderText, cellActions);
90
92
  });
91
93
  export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
@@ -106,43 +108,21 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
106
108
  _defineProperty(_assertThisInitialized(_this), "state", {
107
109
  cellProps: {},
108
110
  isFocused: false,
109
- isEntered: false,
110
- enableInteractions: false,
111
- disableCellTabIndex: false,
111
+ isHovered: false,
112
112
  cellTextAlign: 'Left'
113
113
  });
114
114
  _defineProperty(_assertThisInitialized(_this), "unsubscribeCell", void 0);
115
- _defineProperty(_assertThisInitialized(_this), "focusTimeout", void 0);
116
115
  _defineProperty(_assertThisInitialized(_this), "style", null);
117
- _defineProperty(_assertThisInitialized(_this), "getInteractables", function () {
118
- var tabbingRef = _this.cellContentsRef;
119
- if (tabbingRef) {
120
- return tabbingRef.querySelectorAll('[data-datagrid-interactable=true]');
121
- }
122
- return [];
116
+ _defineProperty(_assertThisInitialized(_this), "updateCellFocusContext", function () {
117
+ _this.context.setFocusedCell([_this.props.colIndex, _this.props.visibleRowIndex]);
123
118
  });
124
119
  _defineProperty(_assertThisInitialized(_this), "takeFocus", function (preventScroll) {
125
120
  var cell = _this.cellRef.current;
126
- if (cell) {
127
- // only update focus if we are not already focused on something in this cell
128
- var element = document.activeElement;
129
- while (element != null && element !== cell) {
130
- element = element.parentElement;
131
- }
132
- var doFocusUpdate = element !== cell;
133
- if (doFocusUpdate) {
134
- var interactables = _this.getInteractables();
135
- if (_this.isExpandable() === false && interactables.length === 1) {
136
- // Only one element can be interacted with
137
- interactables[0].focus({
138
- preventScroll: preventScroll
139
- });
140
- } else {
141
- cell.focus({
142
- preventScroll: preventScroll
143
- });
144
- }
145
- }
121
+ // Only focus the cell if not already focused on something in the cell
122
+ if (cell && !cell.contains(document.activeElement)) {
123
+ cell.focus({
124
+ preventScroll: preventScroll
125
+ });
146
126
  }
147
127
  });
148
128
  _defineProperty(_assertThisInitialized(_this), "recalculateAutoHeight", function () {
@@ -211,61 +191,8 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
211
191
  } else if (_this.contentObserver) {
212
192
  _this.contentObserver.disconnect();
213
193
  }
214
- _this.preventTabbing();
215
194
  _this.setCellTextAlign();
216
195
  });
217
- _defineProperty(_assertThisInitialized(_this), "onFocus", function (e) {
218
- // only perform this logic when the event's originating element (e.target) is
219
- // the wrapping element with the onFocus logic
220
- // reasons:
221
- // * the outcome is only meaningful when the focus shifts to the wrapping element
222
- // * if the cell children include portalled content React will bubble the focus
223
- // event up, which can trigger the focus() call below, causing focus lock fighting
224
- if (_this.cellRef.current === e.target) {
225
- var _this$props5 = _this.props,
226
- colIndex = _this$props5.colIndex,
227
- visibleRowIndex = _this$props5.visibleRowIndex;
228
- // focus in next tick to give potential focus capturing mechanisms time to release their traps
229
- // also clear any previous focus timeout that may still be queued
230
- if (EuiDataGridCell.activeFocusTimeoutId) {
231
- window.clearTimeout(EuiDataGridCell.activeFocusTimeoutId);
232
- }
233
- EuiDataGridCell.activeFocusTimeoutId = _this.focusTimeout = window.setTimeout(function () {
234
- _this.context.setFocusedCell([colIndex, visibleRowIndex]);
235
- var interactables = _this.getInteractables();
236
- if (interactables.length === 1 && _this.isExpandable() === false) {
237
- interactables[0].focus();
238
- _this.setState({
239
- disableCellTabIndex: true
240
- });
241
- }
242
- }, 0);
243
- }
244
- });
245
- _defineProperty(_assertThisInitialized(_this), "onBlur", function () {
246
- _this.setState({
247
- disableCellTabIndex: false
248
- });
249
- });
250
- _defineProperty(_assertThisInitialized(_this), "preventTabbing", function () {
251
- if (_this.cellContentsRef) {
252
- var tabbables = tabbable(_this.cellContentsRef);
253
- for (var i = 0; i < tabbables.length; i++) {
254
- var element = tabbables[i];
255
- element.setAttribute('tabIndex', '-1');
256
- element.setAttribute('data-datagrid-interactable', 'true');
257
- }
258
- }
259
- });
260
- _defineProperty(_assertThisInitialized(_this), "enableTabbing", function () {
261
- if (_this.cellContentsRef) {
262
- var interactables = _this.getInteractables();
263
- for (var i = 0; i < interactables.length; i++) {
264
- var element = interactables[i];
265
- element.removeAttribute('tabIndex');
266
- }
267
- }
268
- });
269
196
  _defineProperty(_assertThisInitialized(_this), "setCellTextAlign", function () {
270
197
  if (_this.cellContentsRef) {
271
198
  var columnType = _this.props.columnType;
@@ -318,14 +245,14 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
318
245
  setPopoverAnchorPosition("down".concat(_this.state.cellTextAlign));
319
246
 
320
247
  // Set popover contents with cell content
321
- var _this$props6 = _this.props,
322
- renderCellPopover = _this$props6.renderCellPopover,
323
- renderCellValue = _this$props6.renderCellValue,
324
- rowIndex = _this$props6.rowIndex,
325
- colIndex = _this$props6.colIndex,
326
- column = _this$props6.column,
327
- columnId = _this$props6.columnId,
328
- columnType = _this$props6.columnType;
248
+ var _this$props5 = _this.props,
249
+ renderCellPopover = _this$props5.renderCellPopover,
250
+ renderCellValue = _this$props5.renderCellValue,
251
+ rowIndex = _this$props5.rowIndex,
252
+ colIndex = _this$props5.colIndex,
253
+ column = _this$props5.column,
254
+ columnId = _this$props5.columnId,
255
+ columnType = _this$props5.columnType;
329
256
  var PopoverElement = renderCellPopover || DefaultCellPopover;
330
257
  var CellElement = renderCellValue;
331
258
  var sharedProps = {
@@ -350,14 +277,59 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
350
277
  setPopoverContent(popoverContent);
351
278
  }
352
279
  });
280
+ _defineProperty(_assertThisInitialized(_this), "handleCellKeyDown", function (event) {
281
+ if (_this.isExpandable()) {
282
+ if (_this.isPopoverOpen()) return;
283
+ var _this$props6 = _this.props,
284
+ openCellPopover = _this$props6.popoverContext.openCellPopover,
285
+ visibleRowIndex = _this$props6.visibleRowIndex,
286
+ colIndex = _this$props6.colIndex;
287
+ switch (event.key) {
288
+ case keys.ENTER:
289
+ case keys.F2:
290
+ event.preventDefault();
291
+ openCellPopover({
292
+ rowIndex: visibleRowIndex,
293
+ colIndex: colIndex
294
+ });
295
+ break;
296
+ }
297
+ }
298
+ });
299
+ _defineProperty(_assertThisInitialized(_this), "handleCellExpansionClick", function () {
300
+ var _this$props7 = _this.props,
301
+ _this$props7$popoverC = _this$props7.popoverContext,
302
+ openCellPopover = _this$props7$popoverC.openCellPopover,
303
+ closeCellPopover = _this$props7$popoverC.closeCellPopover,
304
+ visibleRowIndex = _this$props7.visibleRowIndex,
305
+ colIndex = _this$props7.colIndex;
306
+ if (_this.isPopoverOpen()) {
307
+ closeCellPopover();
308
+ } else {
309
+ openCellPopover({
310
+ rowIndex: visibleRowIndex,
311
+ colIndex: colIndex
312
+ });
313
+ }
314
+ });
315
+ _defineProperty(_assertThisInitialized(_this), "onMouseEnter", function () {
316
+ return _this.setState({
317
+ isHovered: true
318
+ });
319
+ });
320
+ _defineProperty(_assertThisInitialized(_this), "onMouseLeave", function () {
321
+ return _this.setState({
322
+ isHovered: false
323
+ });
324
+ });
353
325
  return _this;
354
326
  }
355
327
  _createClass(EuiDataGridCell, [{
356
328
  key: "componentDidMount",
357
329
  value: function componentDidMount() {
358
- var _this$props7 = this.props,
359
- colIndex = _this$props7.colIndex,
360
- visibleRowIndex = _this$props7.visibleRowIndex;
330
+ var _this$props8 = this.props,
331
+ colIndex = _this$props8.colIndex,
332
+ visibleRowIndex = _this$props8.visibleRowIndex;
361
333
  this.unsubscribeCell = this.context.onFocusUpdate([colIndex, visibleRowIndex], this.onFocusUpdate);
362
334
 
363
335
  // Account for virtualization - when a cell unmounts when scrolled out of view
@@ -376,7 +348,6 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
376
348
  }, {
377
349
  key: "componentWillUnmount",
378
350
  value: function componentWillUnmount() {
379
- window.clearTimeout(this.focusTimeout);
380
351
  if (this.unsubscribeCell) {
381
352
  this.unsubscribeCell();
382
353
  }
@@ -443,39 +414,33 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
443
414
  if (nextProps.style.width !== this.props.style.width) return true;
444
415
  }
445
416
  if (nextState.cellProps !== this.state.cellProps) return true;
446
- if (nextState.isEntered !== this.state.isEntered) return true;
447
417
  if (nextState.isFocused !== this.state.isFocused) return true;
448
- if (nextState.enableInteractions !== this.state.enableInteractions) return true;
449
- if (nextState.disableCellTabIndex !== this.state.disableCellTabIndex) return true;
418
+ if (nextState.isHovered !== this.state.isHovered) return true;
450
419
  return false;
451
420
  }
452
421
  }, {
453
422
  key: "render",
454
423
  value: function render() {
455
- var _classNames,
456
- _rowHeightsOptions$li,
457
- _this2 = this;
458
- var _this$props8 = this.props,
459
- width = _this$props8.width,
460
- _this$props8$popoverC = _this$props8.popoverContext,
461
- closeCellPopover = _this$props8$popoverC.closeCellPopover,
462
- openCellPopover = _this$props8$popoverC.openCellPopover,
463
- interactiveCellId = _this$props8.interactiveCellId,
464
- columnType = _this$props8.columnType,
465
- className = _this$props8.className,
466
- column = _this$props8.column,
467
- style = _this$props8.style,
468
- rowHeightUtils = _this$props8.rowHeightUtils,
469
- rowHeightsOptions = _this$props8.rowHeightsOptions,
470
- rowManager = _this$props8.rowManager,
471
- pagination = _this$props8.pagination,
472
- rest = _objectWithoutProperties(_this$props8, _excluded2);
424
+ var _classNames, _rowHeightsOptions$li;
425
+ var _this$props9 = this.props,
426
+ width = _this$props9.width,
427
+ popoverContext = _this$props9.popoverContext,
428
+ interactiveCellId = _this$props9.interactiveCellId,
429
+ columnType = _this$props9.columnType,
430
+ className = _this$props9.className,
431
+ column = _this$props9.column,
432
+ style = _this$props9.style,
433
+ rowHeightUtils = _this$props9.rowHeightUtils,
434
+ rowHeightsOptions = _this$props9.rowHeightsOptions,
435
+ rowManager = _this$props9.rowManager,
436
+ pagination = _this$props9.pagination,
437
+ rest = _objectWithoutProperties(_this$props9, _excluded2);
473
438
  var rowIndex = rest.rowIndex,
474
439
  visibleRowIndex = rest.visibleRowIndex,
475
440
  colIndex = rest.colIndex;
476
441
  var isExpandable = this.isExpandable();
477
442
  var popoverIsOpen = this.isPopoverOpen();
478
- var showCellActions = this.state.isFocused || this.state.isEntered || this.state.enableInteractions || popoverIsOpen;
443
+ var showCellActions = isExpandable && (popoverIsOpen || this.state.isFocused || this.state.isHovered);
479
444
  var cellClasses = classNames('euiDataGridRowCell', "euiDataGridRowCell--align".concat(this.state.cellTextAlign), (_classNames = {}, _defineProperty(_classNames, "euiDataGridRowCell--".concat(columnType), columnType), _defineProperty(_classNames, 'euiDataGridRowCell--open', popoverIsOpen), _classNames), className);
480
445
  var ariaRowIndex = pagination ? visibleRowIndex + 1 + pagination.pageSize * pagination.pageIndex : visibleRowIndex + 1;
481
446
  var _this$state$cellProps2 = this.state.cellProps,
@@ -496,68 +461,6 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
496
461
  // column width, can be undefined
497
462
  lineHeight: (_rowHeightsOptions$li = rowHeightsOptions === null || rowHeightsOptions === void 0 ? void 0 : rowHeightsOptions.lineHeight) !== null && _rowHeightsOptions$li !== void 0 ? _rowHeightsOptions$li : undefined
498
463
  }, cellPropsStyle);
499
- var handleCellKeyDown = function handleCellKeyDown(event) {
500
- if (isExpandable) {
501
- if (popoverIsOpen) {
502
- return;
503
- }
504
- switch (event.key) {
505
- case keys.ENTER:
506
- case keys.F2:
507
- event.preventDefault();
508
- openCellPopover({
509
- rowIndex: visibleRowIndex,
510
- colIndex: colIndex
511
- });
512
- break;
513
- }
514
- } else {
515
- if (event.key === keys.ENTER || event.key === keys.F2 || event.key === keys.ESCAPE) {
516
- var interactables = _this2.getInteractables();
517
- if (interactables.length >= 2) {
518
- switch (event.key) {
519
- case keys.ENTER:
520
- // `Enter` only activates the trap
521
- if (_this2.state.isEntered === false) {
522
- _this2.enableTabbing();
523
- _this2.setState({
524
- isEntered: true
525
- });
526
-
527
- // result of this keypress is focus shifts to the first interactive element
528
- // and then the browser fires the onClick event because that's how [Enter] works
529
- // so we need to prevent that default action otherwise entering the trap triggers the first element
530
- event.preventDefault();
531
- }
532
- break;
533
- case keys.F2:
534
- // toggle interactives' focus trap
535
- _this2.setState(function (_ref2) {
536
- var isEntered = _ref2.isEntered;
537
- if (isEntered) {
538
- _this2.preventTabbing();
539
- } else {
540
- _this2.enableTabbing();
541
- }
542
- return {
543
- isEntered: !isEntered
544
- };
545
- });
546
- break;
547
- case keys.ESCAPE:
548
- // `Escape` only de-activates the trap
549
- _this2.preventTabbing();
550
- if (_this2.state.isEntered === true) {
551
- _this2.setState({
552
- isEntered: false
553
- });
554
- }
555
- break;
556
- }
557
- }
558
- }
559
- }
560
- };
561
464
  var rowHeight = rowHeightUtils === null || rowHeightUtils === void 0 ? void 0 : rowHeightUtils.getRowHeightOption(rowIndex, rowHeightsOptions);
562
465
  var cellContentProps = _objectSpread(_objectSpread({}, rest), {}, {
563
466
  setCellProps: this.setCellProps,
@@ -573,40 +476,10 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
573
476
  isControlColumn: cellClasses.includes('euiDataGridRowCell--controlColumn'),
574
477
  ariaRowIndex: ariaRowIndex
575
478
  });
576
- var cellActions = showCellActions && ___EmotionJSX(React.Fragment, null, ___EmotionJSX(EuiDataGridCellActions, {
577
- rowIndex: rowIndex,
578
- colIndex: colIndex,
579
- column: column,
580
- onExpandClick: function onExpandClick() {
581
- if (popoverIsOpen) {
582
- closeCellPopover();
583
- } else {
584
- openCellPopover({
585
- rowIndex: visibleRowIndex,
586
- colIndex: colIndex
587
- });
588
- }
589
- }
590
- }), ___EmotionJSX("div", {
591
- ref: this.popoverAnchorRef,
592
- "data-test-subject": "cellPopoverAnchor"
593
- }));
594
- var cellContent = isExpandable ? ___EmotionJSX(EuiDataGridCellContent, _extends({}, cellContentProps, {
595
- cellActions: cellActions
596
- })) : ___EmotionJSX(EuiFocusTrap, {
597
- disabled: !this.state.isEntered,
598
- autoFocus: true,
599
- onDeactivation: function onDeactivation() {
600
- _this2.setState({
601
- isEntered: false
602
- }, _this2.preventTabbing);
603
- },
604
- clickOutsideDisables: true
605
- }, ___EmotionJSX(EuiDataGridCellContent, cellContentProps));
606
479
  var cell = ___EmotionJSX("div", _extends({
607
480
  role: "gridcell",
608
481
  "aria-rowindex": ariaRowIndex,
609
- tabIndex: this.state.isFocused && !this.state.disableCellTabIndex ? 0 : -1,
482
+ tabIndex: this.state.isFocused ? 0 : -1,
610
483
  ref: this.cellRef
611
484
  }, cellProps, {
612
485
  "data-test-subj": "dataGridRowCell"
@@ -620,20 +493,24 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
620
493
  ,
621
494
  "data-gridcell-visible-row-index": this.props.visibleRowIndex // Affected by sorting & pagination
622
495
  ,
623
- onKeyDown: handleCellKeyDown,
624
- onFocus: this.onFocus,
625
- onMouseEnter: function onMouseEnter() {
626
- _this2.setState({
627
- enableInteractions: true
628
- });
629
- },
630
- onMouseLeave: function onMouseLeave() {
631
- _this2.setState({
632
- enableInteractions: false
633
- });
634
- },
635
- onBlur: this.onBlur
636
- }), cellContent);
496
+ onKeyDown: this.handleCellKeyDown,
497
+ onMouseEnter: this.onMouseEnter,
498
+ onMouseLeave: this.onMouseLeave
499
+ }), ___EmotionJSX(HandleInteractiveChildren, {
500
+ cellEl: this.cellRef.current,
501
+ updateCellFocusContext: this.updateCellFocusContext,
502
+ renderFocusTrap: !isExpandable
503
+ }, ___EmotionJSX(EuiDataGridCellContent, _extends({}, cellContentProps, {
504
+ cellActions: showCellActions && ___EmotionJSX(React.Fragment, null, ___EmotionJSX(EuiDataGridCellActions, {
505
+ rowIndex: rowIndex,
506
+ colIndex: colIndex,
507
+ column: column,
508
+ onExpandClick: this.handleCellExpansionClick
509
+ }), ___EmotionJSX("div", {
510
+ ref: this.popoverAnchorRef,
511
+ "data-test-subject": "cellPopoverAnchor"
512
+ }))
513
+ }))));
637
514
  return rowManager && !IS_JEST_ENVIRONMENT ? /*#__PURE__*/createPortal(cell, rowManager.getRow({
638
515
  rowIndex: rowIndex,
639
516
  visibleRowIndex: visibleRowIndex,
@@ -645,14 +522,4 @@ export var EuiDataGridCell = /*#__PURE__*/function (_Component) {
645
522
  }]);
646
523
  return EuiDataGridCell;
647
524
  }(Component);
648
- // focus tracking is split between the entire grid & individual cells,
649
- // the parent grid owns which cell is focused,
650
- // but individual cells need to react to changes and also report that
651
- // they are focused in response to user actions like clicking on the cell
652
- // to avoid focus trap fighting, cells wait a tick after being clicked to allow
653
- // any existing traps to disconnect before the cell reports the new focus state to the parent grid
654
- // but because of this small delay, multiple cells could queue up focus and
655
- // create an infinite loop as the cells activate->deactivate->...
656
- // so we track the last timeout id and clear that request if superseded
657
- _defineProperty(EuiDataGridCell, "activeFocusTimeoutId", undefined);
658
525
  _defineProperty(EuiDataGridCell, "contextType", DataGridFocusContext);
@@ -10,11 +10,11 @@ import _extends from "@babel/runtime/helpers/extends";
10
10
  */
11
11
 
12
12
  import React, { useMemo, useCallback } from 'react';
13
- import { EuiI18n } from '../../i18n';
14
- import { EuiButtonIcon } from '../../button/button_icon';
15
- import { EuiButtonEmpty } from '../../button/button_empty';
16
- import { EuiFlexGroup, EuiFlexItem } from '../../flex';
17
- import { EuiPopoverFooter } from '../../popover';
13
+ import { EuiI18n } from '../../../i18n';
14
+ import { EuiButtonIcon } from '../../../button/button_icon';
15
+ import { EuiButtonEmpty } from '../../../button/button_empty';
16
+ import { EuiFlexGroup, EuiFlexItem } from '../../../flex';
17
+ import { EuiPopoverFooter } from '../../../popover';
18
18
  import { jsx as ___EmotionJSX } from "@emotion/react";
19
19
  export var EuiDataGridCellActions = function EuiDataGridCellActions(_ref) {
20
20
  var onExpandClick = _ref.onExpandClick,
@@ -13,8 +13,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
13
13
 
14
14
  import React, { createContext, useState, useCallback } from 'react';
15
15
  import classNames from 'classnames';
16
- import { keys } from '../../../services';
17
- import { EuiWrappingPopover } from '../../popover';
16
+ import { keys } from '../../../../services';
17
+ import { EuiWrappingPopover } from '../../../popover';
18
18
  export var DataGridCellPopoverContext = /*#__PURE__*/createContext({
19
19
  popoverIsOpen: false,
20
20
  cellLocation: {
@@ -152,8 +152,8 @@ export var useCellPopover = function useCellPopover() {
152
152
  /**
153
153
  * Popover content renderers
154
154
  */
155
- import { EuiText } from '../../text';
156
- import { EuiCodeBlock } from '../../code';
155
+ import { EuiText } from '../../../text';
156
+ import { EuiCodeBlock } from '../../../code';
157
157
  import { jsx as ___EmotionJSX } from "@emotion/react";
158
158
  export var DefaultCellPopover = function DefaultCellPopover(_ref2) {
159
159
  var schema = _ref2.schema,
@@ -12,7 +12,7 @@ var _excluded = ["colIndex", "visibleRowIndex", "style", "schema", "schemaDetect
12
12
 
13
13
  import React, { useContext, useMemo } from 'react';
14
14
  import classNames from 'classnames';
15
- import { DataGridSortingContext } from '../utils/sorting';
15
+ import { DataGridSortingContext } from '../../utils/sorting';
16
16
  import { DataGridCellPopoverContext } from './data_grid_cell_popover';
17
17
  import { EuiDataGridCell } from './data_grid_cell';
18
18
  import { jsx as ___EmotionJSX } from "@emotion/react";
@@ -0,0 +1,153 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ /*
3
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
4
+ * or more contributor license agreements. Licensed under the Elastic License
5
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
6
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
7
+ * Side Public License, v 1.
8
+ */
9
+
10
+ import React, { useEffect, useState, useMemo } from 'react';
11
+ import { tabbable } from 'tabbable';
12
+ import { keys } from '../../../../services';
13
+ import { EuiFocusTrap } from '../../../focus_trap';
14
+ import { EuiScreenReaderOnly } from '../../../accessibility';
15
+ import { EuiI18n } from '../../../i18n';
16
+
17
+ /**
18
+ * This internal utility component is used by all cells, both header and body/footer cells.
19
+ * It always handles:
20
+ * 1. Removing any interactive children from keyboard tab order on cell mount
21
+ * 2. Listening for focus on any interactive children and updating the cell focus context
22
+ *
23
+ * It should *only* render focus traps for:
24
+ * 1. Header cells that are `actions: false` but still have interactive children
25
+ * 2. Body cells that are `isExpandable: false` but still have interactive children
26
+ */
27
+ import { jsx as ___EmotionJSX } from "@emotion/react";
28
+ export var HandleInteractiveChildren = function HandleInteractiveChildren(_ref) {
29
+ var cellEl = _ref.cellEl,
30
+ children = _ref.children,
31
+ updateCellFocusContext = _ref.updateCellFocusContext,
32
+ renderFocusTrap = _ref.renderFocusTrap;
33
+ var _useState = useState(false),
34
+ _useState2 = _slicedToArray(_useState, 2),
35
+ hasInteractiveChildren = _useState2[0],
36
+ setHasInteractiveChildren = _useState2[1];
37
+
38
+ // On mount, disable all interactive children
39
+ useEffect(function () {
40
+ if (cellEl) {
41
+ var interactiveChildren = disableInteractives(cellEl);
42
+ if (renderFocusTrap) {
43
+ setHasInteractiveChildren(interactiveChildren.length > 0);
44
+ }
45
+ }
46
+ }, [cellEl, renderFocusTrap]);
47
+
48
+ // Ensure that any interactive children that are clicked update the latest cell focus context
49
+ useEffect(function () {
50
+ if (cellEl) {
51
+ var onFocus = function onFocus() {
52
+ return updateCellFocusContext();
53
+ };
54
+ cellEl.addEventListener('focus', onFocus, true); // useCapture listens for focus on children
55
+ return function () {
56
+ cellEl.removeEventListener('focus', onFocus, true);
57
+ };
58
+ }
59
+ }, [cellEl, updateCellFocusContext]);
60
+ var _children = useMemo(function () {
61
+ return ___EmotionJSX(React.Fragment, null, children);
62
+ }, [children]);
63
+ if (!cellEl) return _children; // Do nothing if cell has yet to mount or is unmounting
64
+ if (!renderFocusTrap) return _children; // Cells with default actions / expansion popovers do not need to trap
65
+ if (!hasInteractiveChildren) return _children; // No need to focus trap if no children are interactive
66
+
67
+ return ___EmotionJSX(FocusTrappedChildren, {
68
+ cellEl: cellEl
69
+ }, children);
70
+ };
71
+
72
+ /**
73
+ * Cells with interactive children but no cell popover expansion should render a
74
+ * focus trap that can be entered with the Enter key, which cycles keyboard tabs
75
+ * through the cell contents only, and exited with the Escape key
76
+ */
77
+ export var FocusTrappedChildren = function FocusTrappedChildren(_ref2) {
78
+ var cellEl = _ref2.cellEl,
79
+ children = _ref2.children;
80
+ var _useState3 = useState(false),
81
+ _useState4 = _slicedToArray(_useState3, 2),
82
+ isCellEntered = _useState4[0],
83
+ setIsCellEntered = _useState4[1];
84
+ useEffect(function () {
85
+ if (isCellEntered) {
86
+ enableAndFocusInteractives(cellEl);
87
+ } else {
88
+ disableInteractives(cellEl);
89
+ }
90
+ }, [isCellEntered, cellEl]);
91
+ useEffect(function () {
92
+ var onKeyUp = function onKeyUp(event) {
93
+ switch (event.key) {
94
+ case keys.ENTER:
95
+ case keys.F2:
96
+ event.preventDefault();
97
+ setIsCellEntered(true);
98
+ break;
99
+ case keys.ESCAPE:
100
+ event.preventDefault();
101
+ setIsCellEntered(function (isCellEntered) {
102
+ if (isCellEntered === true) {
103
+ requestAnimationFrame(function () {
104
+ return cellEl.focus();
105
+ }); // move focus to cell
106
+ return false;
107
+ }
108
+ return isCellEntered;
109
+ });
110
+ break;
111
+ }
112
+ };
113
+ cellEl.addEventListener('keyup', onKeyUp);
114
+ return function () {
115
+ cellEl.removeEventListener('keyup', onKeyUp);
116
+ };
117
+ }, [cellEl]);
118
+ return ___EmotionJSX(EuiFocusTrap, {
119
+ disabled: !isCellEntered,
120
+ onDeactivation: function onDeactivation() {
121
+ return setIsCellEntered(false);
122
+ },
123
+ clickOutsideDisables: true
124
+ }, children, ___EmotionJSX(EuiScreenReaderOnly, null, ___EmotionJSX("p", null, ' - ', ___EmotionJSX(EuiI18n
125
+ // eslint-disable-next-line local/i18n
126
+ , {
127
+ token: "euiDataGridCell.focusTrapEnterPrompt",
128
+ default: "Press the Enter key to interact with this cell's contents."
129
+ }))));
130
+ };
131
+
132
+ /**
133
+ * Utility fns for managing child interactive tabIndex state
134
+ */
135
+
136
+ var disableInteractives = function disableInteractives(cell) {
137
+ var interactives = tabbable(cell);
138
+ interactives.forEach(function (element) {
139
+ element.setAttribute('data-euigrid-tab-managed', 'true');
140
+ element.setAttribute('tabIndex', '-1');
141
+ });
142
+ return interactives;
143
+ };
144
+ var enableAndFocusInteractives = function enableAndFocusInteractives(cell) {
145
+ var interactives = cell.querySelectorAll('[data-euigrid-tab-managed]');
146
+ interactives.forEach(function (element, i) {
147
+ element.setAttribute('tabIndex', '0');
148
+ if (i === 0) {
149
+ element.focus();
150
+ }
151
+ });
152
+ return interactives;
153
+ };