@elastic/eui 95.9.0 → 95.10.0

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 (101) hide show
  1. package/dist/eui_theme_dark.css +35 -6
  2. package/dist/eui_theme_dark.min.css +1 -1
  3. package/dist/eui_theme_light.css +35 -6
  4. package/dist/eui_theme_light.min.css +1 -1
  5. package/es/components/basic_table/in_memory_table.js +2 -1
  6. package/es/components/datagrid/body/cell/data_grid_cell.js +2 -0
  7. package/es/components/datagrid/body/cell/focus_utils.js +57 -11
  8. package/es/components/datagrid/body/data_grid_body.js +1 -0
  9. package/es/components/datagrid/body/data_grid_body_custom.js +1 -0
  10. package/es/components/datagrid/body/data_grid_body_virtualized.js +1 -0
  11. package/es/components/datagrid/body/header/data_grid_header_cell.js +92 -83
  12. package/es/components/datagrid/body/header/data_grid_header_cell_wrapper.js +37 -22
  13. package/es/components/datagrid/controls/column_sorting.js +1 -0
  14. package/es/components/datagrid/data_grid.a11y.js +2 -0
  15. package/es/components/datagrid/utils/in_memory.js +1 -0
  16. package/es/components/date_picker/date_picker.js +32 -10
  17. package/es/components/date_picker/date_picker.styles.js +3 -2
  18. package/es/components/date_picker/date_picker_range.styles.js +1 -1
  19. package/es/components/form/super_select/super_select.styles.js +1 -1
  20. package/es/components/markdown_editor/plugins/markdown_default_plugins/parsing_plugins.js +15 -8
  21. package/es/components/markdown_editor/plugins/markdown_default_plugins/plugins.js +21 -4
  22. package/es/components/markdown_editor/plugins/markdown_default_plugins/processing_plugins.js +5 -2
  23. package/es/components/markdown_editor/plugins/markdown_link_validator.js +8 -2
  24. package/es/components/search_bar/filters/field_value_selection_filter.js +171 -152
  25. package/es/components/search_bar/search_bar.js +2 -1
  26. package/es/components/search_bar/search_filters.js +2 -1
  27. package/eui.d.ts +138 -69
  28. package/i18ntokens.json +78 -42
  29. package/lib/components/basic_table/in_memory_table.js +2 -1
  30. package/lib/components/datagrid/body/cell/data_grid_cell.js +2 -0
  31. package/lib/components/datagrid/body/cell/focus_utils.js +58 -12
  32. package/lib/components/datagrid/body/data_grid_body.js +1 -0
  33. package/lib/components/datagrid/body/data_grid_body_custom.js +1 -0
  34. package/lib/components/datagrid/body/data_grid_body_virtualized.js +1 -0
  35. package/lib/components/datagrid/body/header/data_grid_header_cell.js +98 -88
  36. package/lib/components/datagrid/body/header/data_grid_header_cell_wrapper.js +38 -23
  37. package/lib/components/datagrid/controls/column_sorting.js +1 -0
  38. package/lib/components/datagrid/data_grid.a11y.js +2 -0
  39. package/lib/components/datagrid/utils/in_memory.js +1 -0
  40. package/lib/components/date_picker/date_picker.js +32 -10
  41. package/lib/components/date_picker/date_picker.styles.js +3 -2
  42. package/lib/components/date_picker/date_picker_range.styles.js +1 -1
  43. package/lib/components/form/super_select/super_select.styles.js +1 -1
  44. package/lib/components/markdown_editor/plugins/markdown_default_plugins/parsing_plugins.js +26 -17
  45. package/lib/components/markdown_editor/plugins/markdown_default_plugins/plugins.js +21 -6
  46. package/lib/components/markdown_editor/plugins/markdown_default_plugins/processing_plugins.js +5 -2
  47. package/lib/components/markdown_editor/plugins/markdown_link_validator.js +9 -2
  48. package/lib/components/search_bar/filters/field_value_selection_filter.js +170 -151
  49. package/lib/components/search_bar/search_bar.js +2 -1
  50. package/lib/components/search_bar/search_filters.js +2 -1
  51. package/optimize/es/components/datagrid/body/cell/focus_utils.js +55 -10
  52. package/optimize/es/components/datagrid/body/header/data_grid_header_cell.js +90 -83
  53. package/optimize/es/components/datagrid/body/header/data_grid_header_cell_wrapper.js +33 -19
  54. package/optimize/es/components/datagrid/data_grid.a11y.js +2 -0
  55. package/optimize/es/components/date_picker/date_picker.js +15 -9
  56. package/optimize/es/components/date_picker/date_picker.styles.js +3 -2
  57. package/optimize/es/components/date_picker/date_picker_range.styles.js +1 -1
  58. package/optimize/es/components/form/super_select/super_select.styles.js +1 -1
  59. package/optimize/es/components/markdown_editor/plugins/markdown_default_plugins/parsing_plugins.js +14 -8
  60. package/optimize/es/components/markdown_editor/plugins/markdown_default_plugins/plugins.js +18 -4
  61. package/optimize/es/components/markdown_editor/plugins/markdown_default_plugins/processing_plugins.js +5 -2
  62. package/optimize/es/components/markdown_editor/plugins/markdown_link_validator.js +8 -2
  63. package/optimize/es/components/search_bar/filters/field_value_selection_filter.js +168 -151
  64. package/optimize/lib/components/datagrid/body/cell/focus_utils.js +56 -11
  65. package/optimize/lib/components/datagrid/body/header/data_grid_header_cell.js +92 -84
  66. package/optimize/lib/components/datagrid/body/header/data_grid_header_cell_wrapper.js +33 -19
  67. package/optimize/lib/components/datagrid/data_grid.a11y.js +2 -0
  68. package/optimize/lib/components/date_picker/date_picker.js +15 -9
  69. package/optimize/lib/components/date_picker/date_picker.styles.js +3 -2
  70. package/optimize/lib/components/date_picker/date_picker_range.styles.js +1 -1
  71. package/optimize/lib/components/form/super_select/super_select.styles.js +1 -1
  72. package/optimize/lib/components/markdown_editor/plugins/markdown_default_plugins/parsing_plugins.js +15 -11
  73. package/optimize/lib/components/markdown_editor/plugins/markdown_default_plugins/plugins.js +19 -6
  74. package/optimize/lib/components/markdown_editor/plugins/markdown_default_plugins/processing_plugins.js +5 -2
  75. package/optimize/lib/components/markdown_editor/plugins/markdown_link_validator.js +9 -2
  76. package/optimize/lib/components/search_bar/filters/field_value_selection_filter.js +167 -150
  77. package/package.json +1 -1
  78. package/src/components/datagrid/_data_grid_data_row.scss +5 -0
  79. package/src/components/datagrid/body/header/_data_grid_header_row.scss +27 -5
  80. package/test-env/components/basic_table/in_memory_table.js +2 -1
  81. package/test-env/components/datagrid/body/cell/data_grid_cell.js +2 -0
  82. package/test-env/components/datagrid/body/cell/focus_utils.js +58 -12
  83. package/test-env/components/datagrid/body/data_grid_body.js +1 -0
  84. package/test-env/components/datagrid/body/data_grid_body_custom.js +1 -0
  85. package/test-env/components/datagrid/body/data_grid_body_virtualized.js +1 -0
  86. package/test-env/components/datagrid/body/header/data_grid_header_cell.js +93 -84
  87. package/test-env/components/datagrid/body/header/data_grid_header_cell_wrapper.js +37 -22
  88. package/test-env/components/datagrid/controls/column_sorting.js +1 -0
  89. package/test-env/components/datagrid/data_grid.a11y.js +2 -0
  90. package/test-env/components/datagrid/utils/in_memory.js +1 -0
  91. package/test-env/components/date_picker/date_picker.js +32 -10
  92. package/test-env/components/date_picker/date_picker.styles.js +3 -2
  93. package/test-env/components/date_picker/date_picker_range.styles.js +1 -1
  94. package/test-env/components/form/super_select/super_select.styles.js +1 -1
  95. package/test-env/components/markdown_editor/plugins/markdown_default_plugins/parsing_plugins.js +15 -11
  96. package/test-env/components/markdown_editor/plugins/markdown_default_plugins/plugins.js +19 -6
  97. package/test-env/components/markdown_editor/plugins/markdown_default_plugins/processing_plugins.js +5 -2
  98. package/test-env/components/markdown_editor/plugins/markdown_link_validator.js +9 -2
  99. package/test-env/components/search_bar/filters/field_value_selection_filter.js +169 -151
  100. package/test-env/components/search_bar/search_bar.js +2 -1
  101. package/test-env/components/search_bar/search_filters.js +2 -1
@@ -9,8 +9,10 @@ var _react = _interopRequireWildcard(require("react"));
9
9
  var _propTypes = _interopRequireDefault(require("prop-types"));
10
10
  var _tabbable = require("tabbable");
11
11
  var _services = require("../../../../services");
12
+ var _accessibility = require("../../../../services/accessibility");
13
+ var _utils = require("../../../../utils");
12
14
  var _focus_trap = require("../../../focus_trap");
13
- var _accessibility = require("../../../accessibility");
15
+ var _accessibility2 = require("../../../accessibility");
14
16
  var _i18n = require("../../../i18n");
15
17
  var _react2 = require("@emotion/react");
16
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -41,7 +43,8 @@ var HandleInteractiveChildren = exports.HandleInteractiveChildren = function Han
41
43
  var cellEl = _ref.cellEl,
42
44
  children = _ref.children,
43
45
  updateCellFocusContext = _ref.updateCellFocusContext,
44
- renderFocusTrap = _ref.renderFocusTrap;
46
+ renderFocusTrap = _ref.renderFocusTrap,
47
+ onInteractiveChildrenFound = _ref.onInteractiveChildrenFound;
45
48
  var _useState = (0, _react.useState)(false),
46
49
  _useState2 = _slicedToArray(_useState, 2),
47
50
  hasInteractiveChildren = _useState2[0],
@@ -50,12 +53,11 @@ var HandleInteractiveChildren = exports.HandleInteractiveChildren = function Han
50
53
  // On mount, disable all interactive children
51
54
  (0, _react.useEffect)(function () {
52
55
  if (cellEl) {
53
- var interactiveChildren = disableInteractives(cellEl);
54
- if (renderFocusTrap) {
55
- setHasInteractiveChildren(interactiveChildren.length > 0);
56
- }
56
+ var interactives = disableInteractives(cellEl);
57
+ onInteractiveChildrenFound === null || onInteractiveChildrenFound === void 0 || onInteractiveChildrenFound(interactives);
58
+ setHasInteractiveChildren(interactives.length > 0);
57
59
  }
58
- }, [cellEl, renderFocusTrap]);
60
+ }, [cellEl, onInteractiveChildrenFound]);
59
61
 
60
62
  // Ensure that any interactive children that are clicked update the latest cell focus context
61
63
  (0, _react.useEffect)(function () {
@@ -89,7 +91,8 @@ var HandleInteractiveChildren = exports.HandleInteractiveChildren = function Han
89
91
  HandleInteractiveChildren.propTypes = {
90
92
  cellEl: _propTypes.default.oneOfType([_propTypes.default.any.isRequired, _propTypes.default.oneOf([null])]),
91
93
  updateCellFocusContext: _propTypes.default.func.isRequired,
92
- renderFocusTrap: _propTypes.default.bool
94
+ renderFocusTrap: _propTypes.default.bool,
95
+ onInteractiveChildrenFound: _propTypes.default.func
93
96
  };
94
97
  var FocusTrappedChildren = exports.FocusTrappedChildren = function FocusTrappedChildren(_ref2) {
95
98
  var cellEl = _ref2.cellEl,
@@ -98,6 +101,24 @@ var FocusTrappedChildren = exports.FocusTrappedChildren = function FocusTrappedC
98
101
  _useState4 = _slicedToArray(_useState3, 2),
99
102
  isCellEntered = _useState4[0],
100
103
  setIsCellEntered = _useState4[1];
104
+ var _useState5 = (0, _react.useState)(false),
105
+ _useState6 = _slicedToArray(_useState5, 2),
106
+ isExited = _useState6[0],
107
+ setExited = _useState6[1];
108
+ var keyboardHintAriaId = (0, _accessibility.useGeneratedHtmlId)({
109
+ prefix: 'euiDataGridCellHeader',
110
+ suffix: 'keyboardHint'
111
+ });
112
+ var exitedHintAriaId = (0, _accessibility.useGeneratedHtmlId)({
113
+ prefix: 'euiDataGridCellHeader',
114
+ suffix: 'exited'
115
+ });
116
+
117
+ // direct DOM manipulation as workaround to attach required hints
118
+ (0, _react.useEffect)(function () {
119
+ var currentAriaDescribedbyId = cellEl.getAttribute('aria-describedby');
120
+ cellEl.setAttribute('aria-describedby', "".concat(currentAriaDescribedbyId, " ").concat(exitedHintAriaId, " ").concat(keyboardHintAriaId, " "));
121
+ }, [cellEl, keyboardHintAriaId, exitedHintAriaId]);
101
122
  (0, _react.useEffect)(function () {
102
123
  if (isCellEntered) {
103
124
  enableAndFocusInteractives(cellEl);
@@ -117,28 +138,52 @@ var FocusTrappedChildren = exports.FocusTrappedChildren = function FocusTrappedC
117
138
  event.preventDefault();
118
139
  setIsCellEntered(function (isCellEntered) {
119
140
  if (isCellEntered === true) {
141
+ setExited(true);
120
142
  requestAnimationFrame(function () {
121
143
  return cellEl.focus();
122
144
  }); // move focus to cell
123
145
  return false;
146
+ } else if (
147
+ // when opened content is closed, we don't want Escape to return to the cell
148
+ // immediately but instead return focus to a trigger as expected
149
+ isCellEntered === false && (0, _utils.isDOMNode)(event.target) && (0, _utils.isDOMNode)(event.currentTarget) && event.currentTarget.contains(event.target)) {
150
+ return true;
124
151
  }
125
152
  return isCellEntered;
126
153
  });
127
154
  break;
128
155
  }
129
156
  };
157
+
158
+ // ensures the SR text is reset when navigating to a different cell
159
+ var onBlur = function onBlur() {
160
+ return setExited(false);
161
+ };
130
162
  cellEl.addEventListener('keyup', onKeyUp);
163
+ cellEl.addEventListener('blur', onBlur);
131
164
  return function () {
132
165
  cellEl.removeEventListener('keyup', onKeyUp);
166
+ cellEl.removeEventListener('blur', onBlur);
133
167
  };
134
168
  }, [cellEl]);
135
169
  return (0, _react2.jsx)(_focus_trap.EuiFocusTrap, {
136
170
  disabled: !isCellEntered,
171
+ clickOutsideDisables: true,
137
172
  onDeactivation: function onDeactivation() {
138
173
  return setIsCellEntered(false);
139
- },
140
- clickOutsideDisables: true
141
- }, children, (0, _react2.jsx)(_accessibility.EuiScreenReaderOnly, null, (0, _react2.jsx)("p", null, ' - ', (0, _react2.jsx)(_i18n.EuiI18n
174
+ }
175
+ }, children, (0, _react2.jsx)(_accessibility2.EuiScreenReaderOnly, null, (0, _react2.jsx)("p", {
176
+ id: exitedHintAriaId,
177
+ "aria-hidden": "true"
178
+ }, isExited && (0, _react2.jsx)(_i18n.EuiI18n
179
+ // eslint-disable-next-line local/i18n
180
+ , {
181
+ token: "euiDataGridCell.focusTrapExitPrompt",
182
+ default: "Exited cell content."
183
+ }))), (0, _react2.jsx)(_accessibility2.EuiScreenReaderOnly, null, (0, _react2.jsx)("p", {
184
+ id: keyboardHintAriaId,
185
+ "aria-hidden": "true"
186
+ }, !isCellEntered && (0, _react2.jsx)(_i18n.EuiI18n
142
187
  // eslint-disable-next-line local/i18n
143
188
  , {
144
189
  token: "euiDataGridCell.focusTrapEnterPrompt",
@@ -164,7 +209,8 @@ var enableAndFocusInteractives = function enableAndFocusInteractives(cell) {
164
209
  var interactives = cell.querySelectorAll('[data-euigrid-tab-managed]');
165
210
  interactives.forEach(function (element, i) {
166
211
  element.setAttribute('tabIndex', '0');
167
- if (i === 0) {
212
+ // focus the first element only if we're on the cell and not inside of it
213
+ if (i === 0 && !cell.contains(document.activeElement)) {
168
214
  element.focus();
169
215
  }
170
216
  });
@@ -108,6 +108,7 @@ EuiDataGridBody.propTypes = {
108
108
  * This can be used to display a readable column name in column hiding/sorting, where `display` won't be used.
109
109
  * This will also be used as a `title` attribute that will display on mouseover (useful if the display text is being truncated by the column width).
110
110
  * If not passed, `id` will be shown as the column name.
111
+ * Passing this together with `display` is useful to ensure an accessible label is added to the column.
111
112
  */
112
113
  displayAsText: _propTypes.default.string,
113
114
  /**
@@ -257,6 +257,7 @@ EuiDataGridBodyCustomRender.propTypes = {
257
257
  * This can be used to display a readable column name in column hiding/sorting, where `display` won't be used.
258
258
  * This will also be used as a `title` attribute that will display on mouseover (useful if the display text is being truncated by the column width).
259
259
  * If not passed, `id` will be shown as the column name.
260
+ * Passing this together with `display` is useful to ensure an accessible label is added to the column.
260
261
  */
261
262
  displayAsText: _propTypes.default.string,
262
263
  /**
@@ -397,6 +397,7 @@ EuiDataGridBodyVirtualized.propTypes = {
397
397
  * This can be used to display a readable column name in column hiding/sorting, where `display` won't be used.
398
398
  * This will also be used as a `title` attribute that will display on mouseover (useful if the display text is being truncated by the column width).
399
399
  * If not passed, `id` will be shown as the column name.
400
+ * Passing this together with `display` is useful to ensure an accessible label is added to the column.
400
401
  */
401
402
  displayAsText: _propTypes.default.string,
402
403
  /**
@@ -11,20 +11,27 @@ var _react = _interopRequireWildcard(require("react"));
11
11
  var _tabbable = require("tabbable");
12
12
  var _services = require("../../../../services");
13
13
  var _accessibility = require("../../../../services/accessibility");
14
- var _accessibility2 = require("../../../accessibility");
15
14
  var _i18n = require("../../../i18n");
16
15
  var _icon = require("../../../icon");
17
16
  var _list_group = require("../../../list_group");
18
17
  var _popover = require("../../../popover");
18
+ var _button_icon = require("../../../button/button_icon/button_icon.styles");
19
19
  var _focus = require("../../utils/focus");
20
20
  var _column_actions = require("./column_actions");
21
21
  var _data_grid_column_resizer = require("./data_grid_column_resizer");
22
22
  var _data_grid_header_cell_wrapper = require("./data_grid_header_cell_wrapper");
23
23
  var _react2 = require("@emotion/react");
24
+ var _excluded = ["children", "title", "arrow"];
25
+ /*
26
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
27
+ * or more contributor license agreements. Licensed under the Elastic License
28
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
29
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
30
+ * Side Public License, v 1.
31
+ */
24
32
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
25
33
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
26
34
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
27
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
28
35
  function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
29
36
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
30
37
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
@@ -34,21 +41,19 @@ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructur
34
41
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
35
42
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
36
43
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
37
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } /*
38
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
39
- * or more contributor license agreements. Licensed under the Elastic License
40
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
41
- * in compliance with, at your election, the Elastic License 2.0 or the Server
42
- * Side Public License, v 1.
43
- */
44
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
45
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
46
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o) >= 0 || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
47
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
44
48
  var CellContent = function CellContent(_ref) {
45
49
  var children = _ref.children,
46
50
  title = _ref.title,
47
- arrow = _ref.arrow;
48
- return (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)("div", {
51
+ arrow = _ref.arrow,
52
+ rest = _objectWithoutProperties(_ref, _excluded);
53
+ return (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)("div", _extends({}, rest, {
49
54
  title: title,
50
55
  className: "euiDataGridHeaderCell__content"
51
- }, children), arrow);
56
+ }), children), arrow);
52
57
  };
53
58
  CellContent.propTypes = {
54
59
  title: _propTypes.default.string.isRequired,
@@ -78,15 +83,29 @@ var EuiDataGridHeaderCell = exports.EuiDataGridHeaderCell = /*#__PURE__*/(0, _re
78
83
  display = column.display,
79
84
  displayAsText = column.displayAsText,
80
85
  displayHeaderCellProps = column.displayHeaderCellProps;
86
+ var title = displayAsText || id;
87
+ var children = display || displayAsText || id;
81
88
  var width = columnWidths[id] || defaultColumnWidth;
82
89
  var columnType = schema[id] ? schema[id].columnType : null;
83
90
  var _useContext = (0, _react.useContext)(_focus.DataGridFocusContext),
84
91
  setFocusedCell = _useContext.setFocusedCell,
85
92
  focusFirstVisibleInteractiveCell = _useContext.focusFirstVisibleInteractiveCell;
93
+
94
+ /*
95
+ * Column actions
96
+ */
86
97
  var _useState = (0, _react.useState)(false),
87
98
  _useState2 = _slicedToArray(_useState, 2),
88
99
  isPopoverOpen = _useState2[0],
89
100
  setIsPopoverOpen = _useState2[1];
101
+ var togglePopover = (0, _react.useCallback)(function () {
102
+ setIsPopoverOpen(function (isOpen) {
103
+ return !isOpen;
104
+ });
105
+ }, []);
106
+ var closePopover = (0, _react.useCallback)(function () {
107
+ return setIsPopoverOpen(false);
108
+ }, []);
90
109
  var popoverArrowNavigationProps = usePopoverArrowNavigation();
91
110
  var columnActions = (0, _react.useMemo)(function () {
92
111
  return (0, _column_actions.getColumnActions)({
@@ -105,14 +124,22 @@ var EuiDataGridHeaderCell = exports.EuiDataGridHeaderCell = /*#__PURE__*/(0, _re
105
124
  }, [column, columns, schema, schemaDetectors, setVisibleColumns, focusFirstVisibleInteractiveCell, setIsPopoverOpen, sorting, switchColumnPos, setFocusedCell, index]);
106
125
  var showColumnActions = columnActions && columnActions.length > 0;
107
126
  var actionsButtonRef = (0, _react.useRef)(null);
108
- var focusActionsButton = (0, _react.useCallback)(function () {
127
+ var clickActionsButton = (0, _react.useCallback)(function () {
109
128
  var _actionsButtonRef$cur;
110
- (_actionsButtonRef$cur = actionsButtonRef.current) === null || _actionsButtonRef$cur === void 0 || _actionsButtonRef$cur.focus();
129
+ (_actionsButtonRef$cur = actionsButtonRef.current) === null || _actionsButtonRef$cur === void 0 || _actionsButtonRef$cur.click();
111
130
  }, []);
112
131
  var _useState3 = (0, _react.useState)(false),
113
132
  _useState4 = _slicedToArray(_useState3, 2),
114
133
  isActionsButtonFocused = _useState4[0],
115
134
  setIsActionsButtonFocused = _useState4[1];
135
+ var actionsButtonAriaLabel = (0, _i18n.useEuiI18n)('euiDataGridHeaderCell.actionsButtonAriaLabel', '{title}. Click to view column header actions.', {
136
+ title: title
137
+ });
138
+ var actionsEnterKeyInstructions = (0, _i18n.useEuiI18n)('euiDataGridHeaderCell.actionsEnterKeyInstructions', "Press the Enter key to view this column's actions");
139
+
140
+ /*
141
+ * Column sorting
142
+ */
116
143
  var _useSortingUtils = useSortingUtils({
117
144
  sorting: sorting,
118
145
  id: id,
@@ -125,13 +152,12 @@ var EuiDataGridHeaderCell = exports.EuiDataGridHeaderCell = /*#__PURE__*/(0, _re
125
152
  prefix: 'euiDataGridCellHeader',
126
153
  suffix: 'sorting'
127
154
  });
128
- var actionsAriaId = (0, _accessibility.useGeneratedHtmlId)({
129
- prefix: 'euiDataGridCellHeader',
130
- suffix: 'actions'
131
- });
155
+
156
+ /*
157
+ * Rendering
158
+ */
132
159
  var classes = (0, _classnames2.default)(_defineProperty(_defineProperty(_defineProperty({}, "euiDataGridHeaderCell--".concat(columnType), columnType), 'euiDataGridHeaderCell--hasColumnActions', showColumnActions), 'euiDataGridHeaderCell--isActionsPopoverOpen', isPopoverOpen), displayHeaderCellProps === null || displayHeaderCellProps === void 0 ? void 0 : displayHeaderCellProps.className);
133
- var title = displayAsText || id;
134
- var children = display || displayAsText || id;
160
+ var emptyHoverStyles = (0, _services.useEuiMemoizedStyles)(_button_icon._emptyHoverStyles);
135
161
  return (0, _react2.jsx)(_data_grid_header_cell_wrapper.EuiDataGridHeaderCellWrapper, _extends({}, displayHeaderCellProps, {
136
162
  className: classes,
137
163
  id: id,
@@ -139,75 +165,58 @@ var EuiDataGridHeaderCell = exports.EuiDataGridHeaderCell = /*#__PURE__*/(0, _re
139
165
  width: width,
140
166
  "aria-sort": ariaSort,
141
167
  hasActionsPopover: showColumnActions,
142
- isActionsButtonFocused: isActionsButtonFocused,
143
- focusActionsButton: focusActionsButton
144
- }), column.isResizable !== false && width != null ? (0, _react2.jsx)(_data_grid_column_resizer.EuiDataGridColumnResizer, {
145
- columnId: id,
146
- columnWidth: width,
147
- setColumnWidth: setColumnWidth
148
- }) : null, !showColumnActions ? (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(CellContent, {
149
- title: title,
150
- arrow: sortingArrow
151
- }, children), sortingScreenReaderText && (0, _react2.jsx)(_accessibility2.EuiScreenReaderOnly, null, (0, _react2.jsx)("p", null, sortingScreenReaderText))) : (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)("button", {
152
- className: "euiDataGridHeaderCell__button",
153
- onClick: function onClick() {
154
- return setIsPopoverOpen(function (isPopoverOpen) {
155
- return !isPopoverOpen;
156
- });
157
- },
158
- onFocus: function onFocus() {
159
- return setIsActionsButtonFocused(true);
160
- },
161
- onBlur: function onBlur() {
162
- return setIsActionsButtonFocused(false);
163
- },
164
- "aria-describedby": "".concat(sortingAriaId, " ").concat(actionsAriaId),
165
- ref: actionsButtonRef,
166
- "data-test-subj": "dataGridHeaderCellActionButton-".concat(id)
167
- }, (0, _react2.jsx)(CellContent, {
168
- title: title,
169
- arrow: sortingArrow
170
- }, children), (0, _react2.jsx)(_popover.EuiPopover, _extends({
171
- display: "block",
172
- panelPaddingSize: "none",
173
- offset: 7,
174
- anchorPosition: "downRight",
175
- css: _ref3 // Align to right
168
+ openActionsPopover: clickActionsButton,
169
+ "aria-label": displayAsText && "".concat(displayAsText, ", ") // ensure cell text content is read first, if available
176
170
  ,
177
- focusTrapProps: {
178
- // We need to override the default EuiPopover `onClickOutside` since the anchor is separate from the actual button
179
- onClickOutside: function onClickOutside(event) {
180
- var _actionsButtonRef$cur2;
181
- if (((_actionsButtonRef$cur2 = actionsButtonRef.current) === null || _actionsButtonRef$cur2 === void 0 ? void 0 : _actionsButtonRef$cur2.contains(event.target)) === false) {
182
- setIsPopoverOpen(false);
183
- }
184
- }
185
- },
186
- button: (0, _react2.jsx)("div", {
187
- className: "euiDataGridHeaderCell__icon"
188
- }, (0, _react2.jsx)(_icon.EuiIcon, {
189
- type: "boxesVertical",
190
- size: "s",
191
- color: "text"
192
- })),
193
- isOpen: isPopoverOpen,
194
- closePopover: function closePopover() {
195
- return setIsPopoverOpen(false);
196
- }
197
- }, popoverArrowNavigationProps), (0, _react2.jsx)(_list_group.EuiListGroup, {
198
- listItems: columnActions,
199
- gutterSize: "none",
200
- "data-test-subj": "dataGridHeaderCellActionGroup-".concat(id)
201
- }))), (0, _react2.jsx)("p", {
202
- id: sortingAriaId,
203
- hidden: true
204
- }, sortingScreenReaderText), (0, _react2.jsx)("p", {
205
- id: actionsAriaId,
206
- hidden: true
207
- }, (0, _react2.jsx)(_i18n.EuiI18n, {
208
- token: "euiDataGridHeaderCell.headerActions",
209
- default: "Click to view column header actions"
210
- }))));
171
+ "aria-describedby": sortingAriaId
172
+ }), function (hasFocusTrap) {
173
+ return (0, _react2.jsx)(_react.default.Fragment, null, column.isResizable !== false && width != null ? (0, _react2.jsx)(_data_grid_column_resizer.EuiDataGridColumnResizer, {
174
+ columnId: id,
175
+ columnWidth: width,
176
+ setColumnWidth: setColumnWidth
177
+ }) : null, (0, _react2.jsx)(CellContent, {
178
+ title: title,
179
+ arrow: sortingArrow
180
+ }, children), sortingScreenReaderText && (0, _react2.jsx)("p", {
181
+ id: sortingAriaId,
182
+ hidden: true
183
+ }, sortingScreenReaderText), showColumnActions && (0, _react2.jsx)(_popover.EuiPopover, _extends({
184
+ display: "block",
185
+ panelPaddingSize: "none",
186
+ offset: 7,
187
+ anchorPosition: "downRight",
188
+ css: _ref3 // Align to right
189
+ ,
190
+ button: (0, _react2.jsx)("button", {
191
+ ref: actionsButtonRef,
192
+ className: "euiDataGridHeaderCell__button",
193
+ css: emptyHoverStyles.text,
194
+ onClick: togglePopover,
195
+ onFocus: function onFocus() {
196
+ return setIsActionsButtonFocused(true);
197
+ },
198
+ onBlur: function onBlur() {
199
+ return setIsActionsButtonFocused(false);
200
+ },
201
+ "aria-hidden": hasFocusTrap && !isActionsButtonFocused ? 'true' // prevent the actions button from being read on cell focus
202
+ : undefined,
203
+ "aria-label": hasFocusTrap ? actionsButtonAriaLabel : actionsEnterKeyInstructions,
204
+ "data-test-subj": "dataGridHeaderCellActionButton-".concat(id)
205
+ }, (0, _react2.jsx)("div", {
206
+ className: "euiDataGridHeaderCell__icon"
207
+ }, (0, _react2.jsx)(_icon.EuiIcon, {
208
+ type: "boxesVertical",
209
+ size: "s",
210
+ color: "text"
211
+ }))),
212
+ isOpen: isPopoverOpen,
213
+ closePopover: closePopover
214
+ }, popoverArrowNavigationProps), (0, _react2.jsx)(_list_group.EuiListGroup, {
215
+ listItems: columnActions,
216
+ gutterSize: "none",
217
+ "data-test-subj": "dataGridHeaderCellActionGroup-".concat(id)
218
+ })));
219
+ });
211
220
  });
212
221
  EuiDataGridHeaderCell.propTypes = {
213
222
  column: _propTypes.default.shape({
@@ -224,6 +233,7 @@ EuiDataGridHeaderCell.propTypes = {
224
233
  * This can be used to display a readable column name in column hiding/sorting, where `display` won't be used.
225
234
  * This will also be used as a `title` attribute that will display on mouseover (useful if the display text is being truncated by the column width).
226
235
  * If not passed, `id` will be shown as the column name.
236
+ * Passing this together with `display` is useful to ensure an accessible label is added to the column.
227
237
  */
228
238
  displayAsText: _propTypes.default.string,
229
239
  /**
@@ -5,13 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.EuiDataGridHeaderCellWrapper = void 0;
8
- var _classnames = _interopRequireDefault(require("classnames"));
9
- var _propTypes = _interopRequireDefault(require("prop-types"));
10
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ var _classnames = _interopRequireDefault(require("classnames"));
11
+ var _services = require("../../../../services");
11
12
  var _focus = require("../../utils/focus");
12
13
  var _focus_utils = require("../cell/focus_utils");
13
14
  var _react2 = require("@emotion/react");
14
- var _excluded = ["id", "index", "width", "className", "children", "hasActionsPopover", "isActionsButtonFocused", "focusActionsButton"];
15
+ var _excluded = ["id", "index", "width", "className", "children", "hasActionsPopover", "openActionsPopover", "aria-label"];
15
16
  /*
16
17
  * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
17
18
  * or more contributor license agreements. Licensed under the Elastic License
@@ -24,9 +25,9 @@ var _excluded = ["id", "index", "width", "className", "children", "hasActionsPop
24
25
  * standard header cells. Most of its shared logic is around focus state/UX,
25
26
  * but it also DRY's out certain class/data-test-subj/style attributes
26
27
  */
28
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
27
29
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
28
30
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
29
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
30
31
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
31
32
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
32
33
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -43,8 +44,8 @@ var EuiDataGridHeaderCellWrapper = exports.EuiDataGridHeaderCellWrapper = functi
43
44
  className = _ref.className,
44
45
  children = _ref.children,
45
46
  hasActionsPopover = _ref.hasActionsPopover,
46
- isActionsButtonFocused = _ref.isActionsButtonFocused,
47
- focusActionsButton = _ref.focusActionsButton,
47
+ openActionsPopover = _ref.openActionsPopover,
48
+ ariaLabel = _ref['aria-label'],
48
49
  rest = _objectWithoutProperties(_ref, _excluded);
49
50
  var classes = (0, _classnames.default)('euiDataGridHeaderCell', className);
50
51
 
@@ -53,16 +54,28 @@ var EuiDataGridHeaderCellWrapper = exports.EuiDataGridHeaderCellWrapper = functi
53
54
  _useState2 = _slicedToArray(_useState, 2),
54
55
  headerEl = _useState2[0],
55
56
  setHeaderEl = _useState2[1];
57
+ var _useState3 = (0, _react.useState)(false),
58
+ _useState4 = _slicedToArray(_useState3, 2),
59
+ renderFocusTrap = _useState4[0],
60
+ setRenderFocusTrap = _useState4[1];
61
+ var _useState5 = (0, _react.useState)([]),
62
+ _useState6 = _slicedToArray(_useState5, 2),
63
+ interactiveChildren = _useState6[0],
64
+ setInteractiveChildren = _useState6[1];
65
+ (0, _react.useEffect)(function () {
66
+ // We're checking for interactive children outside of the default actions button
67
+ setRenderFocusTrap(interactiveChildren.length > (hasActionsPopover ? 1 : 0));
68
+ }, [hasActionsPopover, interactiveChildren]);
56
69
  var _useContext = (0, _react.useContext)(_focus.DataGridFocusContext),
57
70
  setFocusedCell = _useContext.setFocusedCell,
58
71
  onFocusUpdate = _useContext.onFocusUpdate;
59
72
  var updateCellFocusContext = (0, _react.useCallback)(function () {
60
73
  setFocusedCell([index, -1]);
61
74
  }, [index, setFocusedCell]);
62
- var _useState3 = (0, _react.useState)(false),
63
- _useState4 = _slicedToArray(_useState3, 2),
64
- isFocused = _useState4[0],
65
- setIsFocused = _useState4[1];
75
+ var _useState7 = (0, _react.useState)(false),
76
+ _useState8 = _slicedToArray(_useState7, 2),
77
+ isFocused = _useState8[0],
78
+ setIsFocused = _useState8[1];
66
79
  (0, _react.useEffect)(function () {
67
80
  onFocusUpdate([index, -1], function (isFocused) {
68
81
  setIsFocused(isFocused);
@@ -75,18 +88,17 @@ var EuiDataGridHeaderCellWrapper = exports.EuiDataGridHeaderCellWrapper = functi
75
88
  });
76
89
  }, [index, onFocusUpdate, headerEl]);
77
90
 
78
- // For cell headers with actions, auto-focus into the button instead of the cell wrapper div
79
- // The button text is significantly more useful to screen readers (e.g. contains sort order & hints)
80
- var onFocus = (0, _react.useCallback)(function (e) {
81
- if (hasActionsPopover && e.target === headerEl) {
82
- focusActionsButton === null || focusActionsButton === void 0 || focusActionsButton();
91
+ // For cell headers with only actions, auto-open the actions popover on enter keypress
92
+ var onKeyDown = (0, _react.useCallback)(function (e) {
93
+ if (e.key === _services.keys.ENTER && hasActionsPopover && !renderFocusTrap && e.target === headerEl) {
94
+ openActionsPopover === null || openActionsPopover === void 0 || openActionsPopover();
83
95
  }
84
- }, [hasActionsPopover, focusActionsButton, headerEl]);
96
+ }, [hasActionsPopover, openActionsPopover, renderFocusTrap, headerEl]);
85
97
  return (0, _react2.jsx)("div", _extends({
86
98
  role: "columnheader",
87
99
  ref: setHeaderEl,
88
- tabIndex: isFocused && !isActionsButtonFocused ? 0 : -1,
89
- onFocus: onFocus,
100
+ tabIndex: isFocused ? 0 : -1,
101
+ onKeyDown: onKeyDown,
90
102
  className: classes,
91
103
  "data-test-subj": "dataGridHeaderCell-".concat(id),
92
104
  "data-gridcell-column-id": id,
@@ -95,19 +107,22 @@ var EuiDataGridHeaderCellWrapper = exports.EuiDataGridHeaderCellWrapper = functi
95
107
  "data-gridcell-visible-row-index": "-1",
96
108
  style: width != null ? {
97
109
  width: "".concat(width, "px")
98
- } : {}
110
+ } : {},
111
+ "aria-label": renderFocusTrap ? ariaLabel : undefined
99
112
  }, rest), (0, _react2.jsx)(_focus_utils.HandleInteractiveChildren, {
100
113
  cellEl: headerEl,
101
114
  updateCellFocusContext: updateCellFocusContext,
102
- renderFocusTrap: !hasActionsPopover
103
- }, children));
115
+ renderFocusTrap: renderFocusTrap,
116
+ onInteractiveChildrenFound: setInteractiveChildren
117
+ }, typeof children === 'function' ? children(renderFocusTrap) : children));
104
118
  };
105
119
  EuiDataGridHeaderCellWrapper.propTypes = {
120
+ children: _propTypes.default.oneOfType([_propTypes.default.node.isRequired, _propTypes.default.func.isRequired]).isRequired,
106
121
  id: _propTypes.default.string.isRequired,
107
122
  index: _propTypes.default.number.isRequired,
108
123
  width: _propTypes.default.oneOfType([_propTypes.default.number.isRequired, _propTypes.default.oneOf([null])]),
109
124
  className: _propTypes.default.string,
125
+ "aria-label": _propTypes.default.any,
110
126
  hasActionsPopover: _propTypes.default.bool,
111
- isActionsButtonFocused: _propTypes.default.bool,
112
- focusActionsButton: _propTypes.default.func
127
+ openActionsPopover: _propTypes.default.func
113
128
  };
@@ -283,6 +283,7 @@ DataGridSortingControl.propTypes = {
283
283
  * This can be used to display a readable column name in column hiding/sorting, where `display` won't be used.
284
284
  * This will also be used as a `title` attribute that will display on mouseover (useful if the display text is being truncated by the column width).
285
285
  * If not passed, `id` will be shown as the column name.
286
+ * Passing this together with `display` is useful to ensure an accessible label is added to the column.
286
287
  */
287
288
  displayAsText: _propTypes.default.string,
288
289
  /**
@@ -213,6 +213,7 @@ describe('EuiDataGrid', function () {
213
213
  cy.checkAxe();
214
214
  });
215
215
  it('has zero violations when the column actions menu is open', function () {
216
+ cy.get('.euiDataGridHeaderCell').first().realHover();
216
217
  cy.get('button.euiDataGridHeaderCell__button').first().realClick();
217
218
  cy.checkAxe();
218
219
  });
@@ -222,6 +223,7 @@ describe('EuiDataGrid', function () {
222
223
  cy.checkAxe();
223
224
  });
224
225
  it('has zero violations on sort and when the columns sorting menu is open', function () {
226
+ cy.get('.euiDataGridHeaderCell').last().realHover();
225
227
  cy.get('button.euiDataGridHeaderCell__button').last().realClick();
226
228
  cy.get('button.euiListGroupItem__button').contains('Sort Alma to Debian').should('exist').realClick();
227
229
  cy.get('div[data-test-subj="dataGridColumnSortingPopover"] button').realClick();
@@ -213,6 +213,7 @@ EuiDataGridInMemoryRenderer.propTypes = {
213
213
  * This can be used to display a readable column name in column hiding/sorting, where `display` won't be used.
214
214
  * This will also be used as a `title` attribute that will display on mouseover (useful if the display text is being truncated by the column width).
215
215
  * If not passed, `id` will be shown as the column name.
216
+ * Passing this together with `display` is useful to ensure an accessible label is added to the column.
216
217
  */
217
218
  displayAsText: _propTypes.default.string,
218
219
  /**