@elastic/eui 72.2.0 → 73.0.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 (53) hide show
  1. package/CHANGELOG.md +6185 -0
  2. package/dist/eui_theme_dark.css +15 -12
  3. package/dist/eui_theme_dark.min.css +1 -1
  4. package/dist/eui_theme_light.css +15 -12
  5. package/dist/eui_theme_light.min.css +1 -1
  6. package/es/components/datagrid/controls/column_selector.js +23 -7
  7. package/es/components/datagrid/controls/column_sorting_draggable.js +17 -8
  8. package/es/components/datagrid/data_grid.a11y.js +3 -2
  9. package/es/components/notification/notification_event.a11y.js +113 -0
  10. package/es/components/page/page_header/page_header.a11y.js +32 -0
  11. package/es/components/portal/portal.a11y.js +70 -0
  12. package/es/components/tool_tip/tool_tip.js +10 -5
  13. package/es/components/tool_tip/tool_tip_manager.js +42 -0
  14. package/eui.d.ts +11 -0
  15. package/i18ntokens.json +36 -20
  16. package/lib/components/datagrid/controls/column_selector.js +21 -6
  17. package/lib/components/datagrid/controls/column_sorting_draggable.js +17 -8
  18. package/lib/components/datagrid/data_grid.a11y.js +3 -2
  19. package/lib/components/notification/notification_event.a11y.js +117 -0
  20. package/lib/components/page/page_header/page_header.a11y.js +40 -0
  21. package/lib/components/portal/portal.a11y.js +73 -0
  22. package/lib/components/tool_tip/tool_tip.js +13 -7
  23. package/lib/components/tool_tip/tool_tip_manager.js +50 -0
  24. package/optimize/es/components/datagrid/controls/column_selector.js +22 -7
  25. package/optimize/es/components/datagrid/controls/column_sorting_draggable.js +17 -8
  26. package/optimize/es/components/datagrid/data_grid.a11y.js +3 -2
  27. package/optimize/es/components/notification/notification_event.a11y.js +103 -0
  28. package/optimize/es/components/page/page_header/page_header.a11y.js +32 -0
  29. package/optimize/es/components/portal/portal.a11y.js +60 -0
  30. package/optimize/es/components/tool_tip/tool_tip.js +10 -5
  31. package/optimize/es/components/tool_tip/tool_tip_manager.js +41 -0
  32. package/optimize/lib/components/datagrid/controls/column_selector.js +21 -6
  33. package/optimize/lib/components/datagrid/controls/column_sorting_draggable.js +17 -8
  34. package/optimize/lib/components/datagrid/data_grid.a11y.js +3 -2
  35. package/optimize/lib/components/notification/notification_event.a11y.js +117 -0
  36. package/optimize/lib/components/page/page_header/page_header.a11y.js +40 -0
  37. package/optimize/lib/components/portal/portal.a11y.js +73 -0
  38. package/optimize/lib/components/tool_tip/tool_tip.js +13 -7
  39. package/optimize/lib/components/tool_tip/tool_tip_manager.js +49 -0
  40. package/package.json +1 -1
  41. package/src/components/datagrid/controls/_data_grid_column_sorting.scss +14 -13
  42. package/src/components/date_picker/react-datepicker/LICENSE +21 -0
  43. package/src/components/date_picker/react-datepicker/README.md +168 -0
  44. package/src/services/theme/README.md +153 -0
  45. package/src/test/README.md +59 -0
  46. package/test-env/components/datagrid/controls/column_selector.js +21 -6
  47. package/test-env/components/datagrid/controls/column_sorting_draggable.js +17 -8
  48. package/test-env/components/datagrid/data_grid.a11y.js +3 -2
  49. package/test-env/components/notification/notification_event.a11y.js +117 -0
  50. package/test-env/components/page/page_header/page_header.a11y.js +40 -0
  51. package/test-env/components/portal/portal.a11y.js +73 -0
  52. package/test-env/components/tool_tip/tool_tip.js +13 -7
  53. package/test-env/components/tool_tip/tool_tip_manager.js +49 -0
@@ -6,6 +6,8 @@ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symb
6
6
 
7
7
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
8
8
 
9
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
10
+
9
11
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
10
12
 
11
13
  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."); }
@@ -28,7 +30,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
28
30
  import React, { Fragment, useState, useMemo, useCallback } from 'react';
29
31
  import classNames from 'classnames';
30
32
  import { EuiPopover, EuiPopoverFooter, EuiPopoverTitle } from '../../popover';
31
- import { EuiI18n } from '../../i18n';
33
+ import { EuiI18n, useEuiI18n } from '../../i18n';
32
34
  import { EuiButtonEmpty } from '../../button';
33
35
  import { EuiFlexGroup, EuiFlexItem } from '../../flex';
34
36
  import { EuiSwitch, EuiFieldText } from '../../form';
@@ -96,6 +98,8 @@ export var useDataGridColumnSelector = function useDataGridColumnSelector(availa
96
98
  }, [sortedColumns, columnSearchText, displayValues]);
97
99
  var isDragEnabled = allowColumnReorder && columnSearchText.length === 0; // only allow drag-and-drop when not filtering columns
98
100
 
101
+ var dragHandleAriaLabel = useEuiI18n('euiColumnSelector.dragHandleAriaLabel', 'Drag handle');
102
+
99
103
  var buttonText = ___EmotionJSX(EuiI18n, {
100
104
  token: "euiColumnSelector.button",
101
105
  default: "Columns"
@@ -168,18 +172,23 @@ export var useDataGridColumnSelector = function useDataGridColumnSelector(availa
168
172
  key: id,
169
173
  draggableId: id,
170
174
  index: index,
171
- isDragDisabled: !isDragEnabled
175
+ isDragDisabled: !isDragEnabled,
176
+ hasInteractiveChildren: true,
177
+ customDragHandle: true
172
178
  }, function (provided, state) {
173
179
  return ___EmotionJSX("div", {
174
180
  className: "euiDataGridColumnSelector__item ".concat(state.isDragging && 'euiDataGridColumnSelector__item-isDragging'),
175
181
  "data-test-subj": "dataGridColumnSelectorColumnItem-".concat(id)
176
182
  }, ___EmotionJSX(EuiFlexGroup, {
177
183
  responsive: false,
178
- gutterSize: "m",
184
+ gutterSize: "s",
179
185
  alignItems: "center"
180
- }, ___EmotionJSX(EuiFlexItem, null, allowColumnHiding ? ___EmotionJSX(EuiSwitch, {
186
+ }, allowColumnHiding && ___EmotionJSX(EuiFlexItem, {
187
+ grow: false
188
+ }, ___EmotionJSX(EuiSwitch, {
181
189
  name: id,
182
190
  label: displayValues[id] || id,
191
+ showLabel: false,
183
192
  checked: visibleColumnIds.has(id),
184
193
  compressed: true,
185
194
  className: "euiSwitch--mini",
@@ -191,11 +200,18 @@ export var useDataGridColumnSelector = function useDataGridColumnSelector(availa
191
200
  setVisibleColumns(nextVisibleColumns);
192
201
  },
193
202
  "data-test-subj": "dataGridColumnSelectorToggleColumnVisibility-".concat(id)
194
- }) : ___EmotionJSX("span", {
203
+ })), ___EmotionJSX(EuiFlexItem // This extra column name flex item affords the column more grabbable real estate
204
+ // for mouse users, while hiding repetition for keyboard/screen reader users
205
+ , _extends({}, provided.dragHandleProps, {
206
+ "aria-hidden": true,
207
+ tabIndex: -1
208
+ }), ___EmotionJSX("span", {
195
209
  className: "euiDataGridColumnSelector__itemLabel"
196
- }, id)), isDragEnabled && ___EmotionJSX(EuiFlexItem, {
210
+ }, displayValues[id] || id)), isDragEnabled && ___EmotionJSX(EuiFlexItem, _extends({
197
211
  grow: false
198
- }, ___EmotionJSX(EuiIcon, {
212
+ }, provided.dragHandleProps, {
213
+ "aria-label": dragHandleAriaLabel
214
+ }), ___EmotionJSX(EuiIcon, {
199
215
  type: "grab",
200
216
  color: "subdued"
201
217
  }))));
@@ -72,7 +72,9 @@ export var EuiDataGridColumnSortingDraggable = function EuiDataGridColumnSorting
72
72
  var dragHandleAriaLabel = useEuiI18n('euiColumnSortingDraggable.dragHandleAriaLabel', 'Drag handle');
73
73
  return ___EmotionJSX(EuiDraggable, _extends({
74
74
  draggableId: id,
75
- index: index
75
+ index: index,
76
+ hasInteractiveChildren: true,
77
+ customDragHandle: true
76
78
  }, rest), function (provided, state) {
77
79
  return ___EmotionJSX("div", {
78
80
  className: "euiDataGridColumnSorting__item ".concat(state.isDragging && 'euiDataGridColumnSorting__item-isDragging')
@@ -114,18 +116,25 @@ export var EuiDataGridColumnSortingDraggable = function EuiDataGridColumnSorting
114
116
  sorting.onSort(nextColumns);
115
117
  }
116
118
  });
117
- })), ___EmotionJSX(EuiFlexItem, {
119
+ })), ___EmotionJSX(EuiFlexItem, _extends({
120
+ className: "euiDataGridColumnSorting__name" // This extra column name flex item affords the column more grabbable real estate
121
+ // for mouse users, while hiding repetition for keyboard/screen reader users
122
+
123
+ }, provided.dragHandleProps, {
124
+ tabIndex: -1,
125
+ "aria-hidden": true
126
+ }), ___EmotionJSX(EuiFlexGroup, {
127
+ gutterSize: "xs",
128
+ alignItems: "center",
129
+ responsive: false
130
+ }, ___EmotionJSX(EuiFlexItem, {
118
131
  grow: false
119
132
  }, ___EmotionJSX(EuiToken, {
120
133
  color: schemaDetails != null ? schemaDetails.color : undefined,
121
134
  iconType: schemaDetails != null ? schemaDetails.icon : 'tokenString'
122
- })), ___EmotionJSX(EuiFlexItem, {
123
- "aria-hidden": true
124
- }, ___EmotionJSX(EuiText, {
135
+ })), ___EmotionJSX(EuiFlexItem, null, ___EmotionJSX(EuiText, {
125
136
  size: "xs"
126
- }, ___EmotionJSX("p", null, display))), ___EmotionJSX(EuiFlexItem, {
127
- className: "euiDataGridColumnSorting__orderButtons"
128
- }, ___EmotionJSX(EuiI18n, {
137
+ }, ___EmotionJSX("p", null, display))))), ___EmotionJSX(EuiFlexItem, null, ___EmotionJSX(EuiI18n, {
129
138
  token: "euiColumnSortingDraggable.toggleLegend",
130
139
  default: "Select sorting method for {display}",
131
140
  values: {
@@ -184,7 +184,7 @@ describe('EuiDataGrid', function () {
184
184
  it('has zero violations on first render', function () {
185
185
  cy.checkAxe();
186
186
  });
187
- it('has zero violations when the columns reorder menu is open', function () {
187
+ it('has zero violations when the columns visibility menu is open', function () {
188
188
  cy.get('button[data-test-subj="dataGridColumnSelectorButton"]').realClick();
189
189
  cy.checkAxe();
190
190
  });
@@ -237,9 +237,10 @@ describe('EuiDataGrid', function () {
237
237
  cy.get('div[data-gridcell-visible-row-index="0"][data-gridcell-column-index="1"]').find('button.euiButtonIcon').last().realClick();
238
238
  cy.checkAxe();
239
239
  });
240
- it('has zero violations when the Favorite Distro column has been sorted', function () {
240
+ it('has zero violations on sort and when the columns sorting menu is open', function () {
241
241
  cy.get('button.euiDataGridHeaderCell__button').last().realClick();
242
242
  cy.get('button.euiListGroupItem__button').contains('Sort Alma to Debian').should('exist').realClick();
243
+ cy.get('button[data-test-subj="dataGridColumnSortingPopover"]').realClick();
243
244
  cy.checkAxe();
244
245
  });
245
246
  it('has zero violations when fullscreen is open', function () {
@@ -0,0 +1,113 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+
3
+ 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."); }
4
+
5
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
+
7
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
8
+
9
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
10
+
11
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
+
13
+ /*
14
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
15
+ * or more contributor license agreements. Licensed under the Elastic License
16
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
17
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
18
+ * Side Public License, v 1.
19
+ */
20
+ /// <reference types="../../../cypress/support"/>
21
+ import React, { useState } from 'react';
22
+ import { EuiContextMenuItem } from '../context_menu';
23
+ import { EuiNotificationEvent } from './notification_event';
24
+ import { EuiPanel } from '../panel';
25
+ import { jsx as ___EmotionJSX } from "@emotion/react";
26
+
27
+ var NotificationEvent = function NotificationEvent() {
28
+ var _useState = useState(false),
29
+ _useState2 = _slicedToArray(_useState, 2),
30
+ isRead = _useState2[0],
31
+ setIsRead = _useState2[1];
32
+
33
+ var onRead = function onRead(id, isRead) {
34
+ setIsRead(!isRead);
35
+ };
36
+
37
+ var onOpenContextMenu = function onOpenContextMenu(id) {
38
+ return [___EmotionJSX(EuiContextMenuItem, {
39
+ key: "contextMenuItemA",
40
+ onClick: function onClick() {
41
+ return onRead(id, isRead);
42
+ }
43
+ }, isRead ? 'Mark as unread' : 'Mark as read'), ___EmotionJSX(EuiContextMenuItem, {
44
+ key: "contextMenuItemB",
45
+ onClick: function onClick() {}
46
+ }, "View messages like this"), ___EmotionJSX(EuiContextMenuItem, {
47
+ key: "contextMenuItemC",
48
+ onClick: function onClick() {}
49
+ }, "Don\u2019t notify me about this")];
50
+ };
51
+
52
+ return ___EmotionJSX(EuiPanel, {
53
+ paddingSize: "none",
54
+ hasShadow: true,
55
+ style: {
56
+ maxWidth: '540px'
57
+ }
58
+ }, ___EmotionJSX(EuiNotificationEvent, {
59
+ id: "cy-eui-notification-1",
60
+ type: "Report",
61
+ iconType: "logoKibana",
62
+ iconAriaLabel: "Kibana",
63
+ time: "1 min ago",
64
+ title: "[Error Monitoring Report] is generated",
65
+ primaryAction: "Download",
66
+ primaryActionProps: {
67
+ iconType: 'download'
68
+ },
69
+ messages: ['The reported was generated at 17:12:16 GMT+4'],
70
+ isRead: isRead,
71
+ onRead: onRead,
72
+ onOpenContextMenu: onOpenContextMenu,
73
+ onClickPrimaryAction: function onClickPrimaryAction() {},
74
+ onClickTitle: function onClickTitle() {}
75
+ }));
76
+ };
77
+
78
+ describe('EuiNotificationEvent', function () {
79
+ beforeEach(function () {
80
+ cy.viewport(1024, 768); // medium breakpoint
81
+
82
+ cy.realMount(___EmotionJSX(NotificationEvent, null));
83
+ cy.get('article.euiNotificationEvent').should('exist');
84
+ });
85
+ describe('Automated accessibility check', function () {
86
+ it('has zero violations on first render', function () {
87
+ cy.checkAxe();
88
+ });
89
+ it('has zero violations when popover is open', function () {
90
+ cy.get('button[data-test-subj="cy-eui-notification-1-notificationEventMetaButton"]').realClick();
91
+ cy.get('div.euiPopover__panel').should('exist');
92
+ cy.checkAxe();
93
+ });
94
+ it('has zero violations after the Mark as read button is clicked', function () {
95
+ cy.get('button[data-test-subj="cy-eui-notification-1-notificationEventMetaButton"]').realClick();
96
+ cy.get('div.euiPopover__panel').should('exist');
97
+ cy.get('div.euiPopover__panel button').first().realClick();
98
+ cy.checkAxe();
99
+ });
100
+ });
101
+ describe('Keyboard accessibility', function () {
102
+ it('has zero violations when the popover is opened by keyboard', function () {
103
+ cy.repeatRealPress('Tab');
104
+ cy.get('button[data-test-subj="cy-eui-notification-1-notificationEventMetaButton"]').should('have.focus');
105
+ cy.realPress('Enter');
106
+ cy.get('div.euiPopover__panel').should('exist');
107
+ cy.checkAxe();
108
+ cy.realPress('Escape');
109
+ cy.get('div.euiPopover__panel').should('not.exist');
110
+ cy.checkAxe();
111
+ });
112
+ });
113
+ });
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ /// <reference types="../../../../cypress/support"/>
9
+ import React from 'react';
10
+ import { EuiButton } from '../../button';
11
+ import { EuiPageHeader } from './page_header';
12
+ import { jsx as ___EmotionJSX } from "@emotion/react";
13
+ describe('EuiPageHeader', function () {
14
+ beforeEach(function () {
15
+ cy.viewport(1024, 768); // medium breakpoint
16
+
17
+ cy.realMount(___EmotionJSX(EuiPageHeader, {
18
+ pageTitle: "Page title",
19
+ iconType: "logoKibana",
20
+ description: "This description should be describing the current page as depicted by the page title. It will never extend beneath the right side content.",
21
+ rightSideItems: [___EmotionJSX(EuiButton, {
22
+ fill: true
23
+ }, "Add something"), ___EmotionJSX(EuiButton, null, "Do something")]
24
+ }));
25
+ cy.get('h1.euiTitle').should('exist');
26
+ });
27
+ describe('Automated accessibility check', function () {
28
+ it('has zero violations on first render', function () {
29
+ cy.checkAxe();
30
+ });
31
+ });
32
+ });
@@ -0,0 +1,70 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+
3
+ 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."); }
4
+
5
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
+
7
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
8
+
9
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
10
+
11
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
+
13
+ /*
14
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
15
+ * or more contributor license agreements. Licensed under the Elastic License
16
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
17
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
18
+ * Side Public License, v 1.
19
+ */
20
+ /// <reference types="../../../cypress/support"/>
21
+ import React, { useState } from 'react';
22
+ import { EuiButton } from '../button';
23
+ import { EuiPortal } from './portal';
24
+ import { jsx as ___EmotionJSX } from "@emotion/react";
25
+
26
+ var Portal = function Portal() {
27
+ var _useState = useState(false),
28
+ _useState2 = _slicedToArray(_useState, 2),
29
+ isPortalVisible = _useState2[0],
30
+ setIsPortalVisible = _useState2[1];
31
+
32
+ var togglePortal = function togglePortal() {
33
+ setIsPortalVisible(!isPortalVisible);
34
+ };
35
+
36
+ var closePortal = function closePortal() {
37
+ setIsPortalVisible(false);
38
+ };
39
+
40
+ var customPortal;
41
+
42
+ if (isPortalVisible) {
43
+ customPortal = ___EmotionJSX(EuiPortal, null, ___EmotionJSX("div", null, "This is the portal. Click anywhere to close."), ___EmotionJSX(EuiButton, {
44
+ onClick: closePortal
45
+ }, "Close portal"));
46
+ }
47
+
48
+ return ___EmotionJSX("div", null, ___EmotionJSX(EuiButton, {
49
+ onClick: togglePortal
50
+ }, "View guide"), customPortal);
51
+ };
52
+
53
+ describe('EuiPortal', function () {
54
+ beforeEach(function () {
55
+ cy.viewport(1024, 768); // medium breakpoint
56
+
57
+ cy.realMount(___EmotionJSX(Portal, null));
58
+ cy.get('div[data-relative-to-header="above"]').should('not.exist');
59
+ });
60
+ describe('Automated accessibility check', function () {
61
+ it('has zero violations on first render', function () {
62
+ cy.checkAxe();
63
+ });
64
+ it('has zero violations after the portal is activated', function () {
65
+ cy.get('button[type="button"]').contains('View guide').realClick();
66
+ cy.get('div[data-euiportal="true"]').should('exist');
67
+ cy.checkAxe();
68
+ });
69
+ });
70
+ });
@@ -41,13 +41,14 @@ import React, { Component } from 'react';
41
41
  import PropTypes from "prop-types";
42
42
  import classNames from 'classnames';
43
43
  import { keysOf } from '../common';
44
+ import { findPopoverPosition, htmlIdGenerator } from '../../services';
45
+ import { enqueueStateChange } from '../../services/react';
46
+ import { EuiResizeObserver } from '../observer/resize_observer';
44
47
  import { EuiPortal } from '../portal';
48
+ import { EuiToolTipPopover } from './tool_tip_popover';
45
49
  import { EuiToolTipAnchor } from './tool_tip_anchor';
46
50
  import { EuiToolTipArrow } from './tool_tip_arrow';
47
- import { EuiToolTipPopover } from './tool_tip_popover';
48
- import { enqueueStateChange } from '../../services/react';
49
- import { findPopoverPosition, htmlIdGenerator } from '../../services';
50
- import { EuiResizeObserver } from '../observer/resize_observer';
51
+ import { toolTipManager } from './tool_tip_manager';
51
52
  import { jsx as ___EmotionJSX } from "@emotion/react";
52
53
  var positionsToClassNameMap = {
53
54
  top: 'euiToolTip--top',
@@ -142,9 +143,11 @@ export var EuiToolTip = /*#__PURE__*/function (_Component) {
142
143
  if (!_this.timeoutId) {
143
144
  _this.timeoutId = setTimeout(function () {
144
145
  enqueueStateChange(function () {
145
- return _this.setState({
146
+ _this.setState({
146
147
  visible: true
147
148
  });
149
+
150
+ toolTipManager.registerTooltip(_this.hideToolTip);
148
151
  });
149
152
  }, delayToMsMap[_this.props.delay]);
150
153
  }
@@ -205,6 +208,8 @@ export var EuiToolTip = /*#__PURE__*/function (_Component) {
205
208
  toolTipStyles: DEFAULT_TOOLTIP_STYLES,
206
209
  arrowStyles: undefined
207
210
  });
211
+
212
+ toolTipManager.deregisterToolTip(_this.hideToolTip);
208
213
  }
209
214
  });
210
215
  });
@@ -0,0 +1,42 @@
1
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
+
3
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
+
5
+ /*
6
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
7
+ * or more contributor license agreements. Licensed under the Elastic License
8
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
9
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
10
+ * Side Public License, v 1.
11
+ */
12
+
13
+ /**
14
+ * Manager utility that ensures only one tooltip is visible at a time
15
+ *
16
+ * UX rationale (primarily for mouse-only users):
17
+ * @see https://github.com/elastic/kibana/issues/144482
18
+ * @see https://github.com/elastic/eui/issues/5883
19
+ */
20
+ var ToolTipManager = function ToolTipManager() {
21
+ var _this = this;
22
+
23
+ _classCallCheck(this, ToolTipManager);
24
+
25
+ _defineProperty(this, "toolTipsToHide", new Set());
26
+
27
+ _defineProperty(this, "registerTooltip", function (hideCallback) {
28
+ _this.toolTipsToHide.forEach(function (hide) {
29
+ return hide();
30
+ });
31
+
32
+ _this.toolTipsToHide.clear();
33
+
34
+ _this.toolTipsToHide.add(hideCallback);
35
+ });
36
+
37
+ _defineProperty(this, "deregisterToolTip", function (hideCallback) {
38
+ _this.toolTipsToHide.delete(hideCallback);
39
+ });
40
+ };
41
+
42
+ export var toolTipManager = new ToolTipManager();
package/eui.d.ts CHANGED
@@ -5695,6 +5695,16 @@ declare module '@elastic/eui/src/components/tool_tip/tool_tip_arrow' {
5695
5695
  position: ToolTipPositions;
5696
5696
  } & HTMLAttributes<HTMLDivElement>>;
5697
5697
 
5698
+ }
5699
+ declare module '@elastic/eui/src/components/tool_tip/tool_tip_manager' {
5700
+ class ToolTipManager {
5701
+ toolTipsToHide: Set<Function>;
5702
+ registerTooltip: (hideCallback: Function) => void;
5703
+ deregisterToolTip: (hideCallback: Function) => void;
5704
+ }
5705
+ export const toolTipManager: ToolTipManager;
5706
+ export {};
5707
+
5698
5708
  }
5699
5709
  declare module '@elastic/eui/src/components/tool_tip/tool_tip' {
5700
5710
  import { Component, ReactElement, ReactNode, MouseEvent as ReactMouseEvent, HTMLAttributes } from 'react';
@@ -25755,6 +25765,7 @@ declare module '@elastic/eui' {
25755
25765
  "euiDataGridHeaderCell.sortedByAscendingMultiple": any;
25756
25766
  "euiDataGridHeaderCell.sortedByDescendingMultiple": any;
25757
25767
  "euiDataGridHeaderCell.actionsPopoverScreenReaderText": any;
25768
+ "euiColumnSelector.dragHandleAriaLabel": any;
25758
25769
  "euiColumnSelector.button": any;
25759
25770
  "euiColumnSelector.buttonActiveSingular": any;
25760
25771
  "euiColumnSelector.buttonActivePlural": any;
package/i18ntokens.json CHANGED
@@ -1071,17 +1071,33 @@
1071
1071
  },
1072
1072
  "filepath": "src/components/datagrid/body/header/data_grid_header_cell.tsx"
1073
1073
  },
1074
+ {
1075
+ "token": "euiColumnSelector.dragHandleAriaLabel",
1076
+ "defString": "Drag handle",
1077
+ "highlighting": "string",
1078
+ "loc": {
1079
+ "start": {
1080
+ "line": 119,
1081
+ "column": 30
1082
+ },
1083
+ "end": {
1084
+ "line": 122,
1085
+ "column": 3
1086
+ }
1087
+ },
1088
+ "filepath": "src/components/datagrid/controls/column_selector.tsx"
1089
+ },
1074
1090
  {
1075
1091
  "token": "euiColumnSelector.button",
1076
1092
  "defString": "Columns",
1077
1093
  "highlighting": "string",
1078
1094
  "loc": {
1079
1095
  "start": {
1080
- "line": 121,
1096
+ "line": 125,
1081
1097
  "column": 4
1082
1098
  },
1083
1099
  "end": {
1084
- "line": 121,
1100
+ "line": 125,
1085
1101
  "column": 66
1086
1102
  }
1087
1103
  },
@@ -1093,11 +1109,11 @@
1093
1109
  "highlighting": "string",
1094
1110
  "loc": {
1095
1111
  "start": {
1096
- "line": 126,
1112
+ "line": 130,
1097
1113
  "column": 6
1098
1114
  },
1099
1115
  "end": {
1100
- "line": 130,
1116
+ "line": 134,
1101
1117
  "column": 8
1102
1118
  }
1103
1119
  },
@@ -1109,11 +1125,11 @@
1109
1125
  "highlighting": "string",
1110
1126
  "loc": {
1111
1127
  "start": {
1112
- "line": 134,
1128
+ "line": 138,
1113
1129
  "column": 6
1114
1130
  },
1115
1131
  "end": {
1116
- "line": 138,
1132
+ "line": 142,
1117
1133
  "column": 8
1118
1134
  }
1119
1135
  },
@@ -1125,11 +1141,11 @@
1125
1141
  "highlighting": "string",
1126
1142
  "loc": {
1127
1143
  "start": {
1128
- "line": 167,
1144
+ "line": 171,
1129
1145
  "column": 14
1130
1146
  },
1131
1147
  "end": {
1132
- "line": 173,
1148
+ "line": 177,
1133
1149
  "column": 15
1134
1150
  }
1135
1151
  },
@@ -1141,11 +1157,11 @@
1141
1157
  "highlighting": "string",
1142
1158
  "loc": {
1143
1159
  "start": {
1144
- "line": 167,
1160
+ "line": 171,
1145
1161
  "column": 14
1146
1162
  },
1147
1163
  "end": {
1148
- "line": 173,
1164
+ "line": 177,
1149
1165
  "column": 15
1150
1166
  }
1151
1167
  },
@@ -1157,11 +1173,11 @@
1157
1173
  "highlighting": "string",
1158
1174
  "loc": {
1159
1175
  "start": {
1160
- "line": 275,
1176
+ "line": 293,
1161
1177
  "column": 18
1162
1178
  },
1163
1179
  "end": {
1164
- "line": 278,
1180
+ "line": 296,
1165
1181
  "column": 20
1166
1182
  }
1167
1183
  },
@@ -1173,11 +1189,11 @@
1173
1189
  "highlighting": "string",
1174
1190
  "loc": {
1175
1191
  "start": {
1176
- "line": 288,
1192
+ "line": 306,
1177
1193
  "column": 18
1178
1194
  },
1179
1195
  "end": {
1180
- "line": 291,
1196
+ "line": 309,
1181
1197
  "column": 20
1182
1198
  }
1183
1199
  },
@@ -1237,11 +1253,11 @@
1237
1253
  "highlighting": "string",
1238
1254
  "loc": {
1239
1255
  "start": {
1240
- "line": 79,
1256
+ "line": 85,
1241
1257
  "column": 14
1242
1258
  },
1243
1259
  "end": {
1244
- "line": 83,
1260
+ "line": 89,
1245
1261
  "column": 15
1246
1262
  }
1247
1263
  },
@@ -1253,11 +1269,11 @@
1253
1269
  "highlighting": "string",
1254
1270
  "loc": {
1255
1271
  "start": {
1256
- "line": 95,
1272
+ "line": 101,
1257
1273
  "column": 14
1258
1274
  },
1259
1275
  "end": {
1260
- "line": 99,
1276
+ "line": 105,
1261
1277
  "column": 15
1262
1278
  }
1263
1279
  },
@@ -1269,11 +1285,11 @@
1269
1285
  "highlighting": "string",
1270
1286
  "loc": {
1271
1287
  "start": {
1272
- "line": 133,
1288
+ "line": 157,
1273
1289
  "column": 14
1274
1290
  },
1275
1291
  "end": {
1276
- "line": 137,
1292
+ "line": 161,
1277
1293
  "column": 15
1278
1294
  }
1279
1295
  },