@atlaskit/editor-plugin-toolbar 2.1.4 → 3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/editor-plugin-toolbar
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 2.1.5
10
+
11
+ ### Patch Changes
12
+
13
+ - [`bb498825fca37`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bb498825fca37) -
14
+ [ux] [ED-29266] add ToolbarKeyboardNavigationProvider to selection toolbar with Alt+F10 shortcut
15
+ to focus
16
+ - Updated dependencies
17
+
3
18
  ## 2.1.4
4
19
 
5
20
  ### Patch Changes
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-cc/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-cc/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-dev-agents/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-dev-agents/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-jira/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-jira/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-passionfruit/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-passionfruit/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-post-office/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-post-office/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-rovo-extension/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-rovo-extension/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-townsquare/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../editor-plugin-analytics/afm-townsquare/tsconfig.json"
22
25
  },
@@ -6,8 +6,11 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.SelectionToolbar = void 0;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _reactIntlNext = require("react-intl-next");
10
+ var _browserApis = require("@atlaskit/browser-apis");
9
11
  var _coreUtils = require("@atlaskit/editor-common/core-utils");
10
12
  var _hooks = require("@atlaskit/editor-common/hooks");
13
+ var _messages = require("@atlaskit/editor-common/messages");
11
14
  var _toolbar = require("@atlaskit/editor-common/toolbar");
12
15
  var _ui = require("@atlaskit/editor-common/ui");
13
16
  var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
@@ -20,6 +23,7 @@ var _platformFeatureFlagsReact = require("@atlaskit/platform-feature-flags-react
20
23
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
21
24
  var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
22
25
  var _consts = require("../consts");
26
+ var _toolbar2 = require("../utils/toolbar");
23
27
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
24
28
  var isToolbarComponent = function isToolbarComponent(component) {
25
29
  return component.type === 'toolbar' && component.key === 'inline-text-toolbar';
@@ -76,10 +80,14 @@ var SelectionToolbar = exports.SelectionToolbar = function SelectionToolbar(_ref
76
80
  shouldShowToolbar = _usePluginState.shouldShowToolbar,
77
81
  editorViewMode = _usePluginState.editorViewMode,
78
82
  selection = _usePluginState.selection;
83
+ var intl = (0, _reactIntlNext.useIntl)();
79
84
  var components = api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : _api$toolbar.actions.getComponents();
80
85
  var toolbar = components === null || components === void 0 ? void 0 : components.find(function (component) {
81
86
  return isToolbarComponent(component);
82
87
  });
88
+ var keyboardNavigation = (0, _react.useMemo)(function () {
89
+ return getKeyboardNavigationConfig(editorView, intl, api);
90
+ }, [editorView, intl, api]);
83
91
  var isOffline = connectivityStateMode === 'offline';
84
92
  var isTextSelection = !editorView.state.selection.empty && editorView.state.selection instanceof _state.TextSelection;
85
93
  var isAllSelection = !editorView.state.selection.empty && editorView.state.selection instanceof _state.AllSelection && (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_2', 'isEnabled', true);
@@ -118,7 +126,8 @@ var SelectionToolbar = exports.SelectionToolbar = function SelectionToolbar(_ref
118
126
  fireAnalyticsEvent: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_toolbar_analytic', 'isEnabled', true) ? function (payload) {
119
127
  var _api$analytics;
120
128
  api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent(payload);
121
- } : undefined
129
+ } : undefined,
130
+ keyboardNavigation: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? keyboardNavigation : undefined
122
131
  }, /*#__PURE__*/_react.default.createElement(_editorToolbarModel.ToolbarModelRenderer, {
123
132
  toolbar: toolbar,
124
133
  components: components,
@@ -160,4 +169,47 @@ var getDomRefFromSelection = function getDomRefFromSelection(view
160
169
  // dispatchAnalyticsEvent(payload);
161
170
  // }
162
171
  }
172
+ };
173
+ var getKeyboardNavigationConfig = function getKeyboardNavigationConfig(editorView, intl, api) {
174
+ if (!(editorView.dom instanceof HTMLElement)) {
175
+ return;
176
+ }
177
+ var toolbarSelector = "[data-testid='editor-floating-toolbar']";
178
+ return {
179
+ childComponentSelector: toolbarSelector,
180
+ dom: editorView.dom,
181
+ isShortcutToFocusToolbar: _toolbar2.isShortcutToFocusToolbar,
182
+ handleFocus: function handleFocus(event) {
183
+ var _getDocument, _filteredFocusableEle, _filteredFocusableEle2, _filteredFocusableEle3;
184
+ var toolbar = (_getDocument = (0, _browserApis.getDocument)()) === null || _getDocument === void 0 ? void 0 : _getDocument.querySelector(toolbarSelector);
185
+ if (!(toolbar instanceof HTMLElement)) {
186
+ return;
187
+ }
188
+ var filteredFocusableElements = (0, _toolbar2.getFocusableElements)(toolbar);
189
+ (_filteredFocusableEle = filteredFocusableElements[0]) === null || _filteredFocusableEle === void 0 || _filteredFocusableEle.focus();
190
+
191
+ // the button element removes the focus ring so this class adds it back
192
+ if (((_filteredFocusableEle2 = filteredFocusableElements[0]) === null || _filteredFocusableEle2 === void 0 ? void 0 : _filteredFocusableEle2.tagName) === 'BUTTON') {
193
+ filteredFocusableElements[0].classList.add('first-floating-toolbar-button');
194
+ }
195
+ (_filteredFocusableEle3 = filteredFocusableElements[0]) === null || _filteredFocusableEle3 === void 0 || _filteredFocusableEle3.scrollIntoView({
196
+ behavior: 'smooth',
197
+ block: 'center',
198
+ inline: 'nearest'
199
+ });
200
+ event.preventDefault();
201
+ event.stopPropagation();
202
+ },
203
+ handleEscape: function handleEscape(event) {
204
+ var isDropdownOpen = !!document.querySelector('[data-toolbar-component="menu-section"]');
205
+ if (isDropdownOpen) {
206
+ return;
207
+ }
208
+ api === null || api === void 0 || api.core.actions.focus();
209
+ event.preventDefault();
210
+ event.stopPropagation();
211
+ },
212
+ ariaControls: _ui.EDIT_AREA_ID,
213
+ ariaLabel: intl.formatMessage(_messages.fullPageMessages.toolbarLabel)
214
+ };
163
215
  };
@@ -25,7 +25,8 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
25
25
  var children = _ref.children;
26
26
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.Toolbar, {
27
27
  label: _consts.SELECTION_TOOLBAR_LABEL,
28
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.SELECTION_TOOLBAR
28
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.SELECTION_TOOLBAR,
29
+ testId: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
29
30
  }, children);
30
31
  }
31
32
  }, {
@@ -40,7 +41,11 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
40
41
  }, {
41
42
  type: _toolbar.TEXT_SECTION.type,
42
43
  key: _toolbar.TEXT_SECTION.key,
43
- parents: [{
44
+ parents: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsiveness_update', 'isEnabled', true) ? [{
45
+ type: 'toolbar',
46
+ key: _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR,
47
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.TEXT_SECTION.key]
48
+ }] : [{
44
49
  type: 'toolbar',
45
50
  key: _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR,
46
51
  rank: _toolbar.TOOLBAR_RANK[_toolbar.TEXT_SECTION.key]
@@ -69,7 +74,35 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
69
74
  testId: "text-section"
70
75
  }, children);
71
76
  }
72
- }].concat((0, _toConsumableArray2.default)((0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? [{
77
+ }].concat((0, _toConsumableArray2.default)((0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsiveness_update', 'isEnabled', true) ? [{
78
+ type: _toolbar.TEXT_SECTION_PRIMARY_TOOLBAR.type,
79
+ key: _toolbar.TEXT_SECTION_PRIMARY_TOOLBAR.key,
80
+ parents: [{
81
+ type: 'toolbar',
82
+ key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
83
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.TEXT_SECTION.key]
84
+ }],
85
+ component: function component(_ref4) {
86
+ var children = _ref4.children,
87
+ parents = _ref4.parents;
88
+ if ((0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsive', 'isEnabled', true)) {
89
+ return /*#__PURE__*/_react.default.createElement(_editorToolbar.Show, {
90
+ above: "md"
91
+ }, /*#__PURE__*/_react.default.createElement(_Section.Section, {
92
+ parents: parents,
93
+ api: api,
94
+ disableSelectionToolbar: disableSelectionToolbar,
95
+ testId: "text-section"
96
+ }, children));
97
+ }
98
+ return /*#__PURE__*/_react.default.createElement(_Section.Section, {
99
+ parents: parents,
100
+ api: api,
101
+ disableSelectionToolbar: disableSelectionToolbar,
102
+ testId: "text-section"
103
+ }, children);
104
+ }
105
+ }] : []), (0, _toConsumableArray2.default)((0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? [{
73
106
  type: _toolbar.TEXT_SECTION_COLLAPSED.type,
74
107
  key: _toolbar.TEXT_SECTION_COLLAPSED.key,
75
108
  parents: [{
@@ -81,9 +114,9 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
81
114
  key: _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR,
82
115
  rank: _toolbar.TOOLBAR_RANK[_toolbar.TEXT_SECTION_COLLAPSED.key]
83
116
  }],
84
- component: function component(_ref4) {
85
- var children = _ref4.children,
86
- parents = _ref4.parents;
117
+ component: function component(_ref5) {
118
+ var children = _ref5.children,
119
+ parents = _ref5.parents;
87
120
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.Show, {
88
121
  below: "md"
89
122
  }, /*#__PURE__*/_react.default.createElement(_Section.Section, {
@@ -118,9 +151,9 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
118
151
  key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
119
152
  rank: _toolbar.TOOLBAR_RANK[_toolbar.INSERT_BLOCK_SECTION.key]
120
153
  }],
121
- component: function component(_ref5) {
122
- var children = _ref5.children,
123
- parents = _ref5.parents;
154
+ component: function component(_ref6) {
155
+ var children = _ref6.children,
156
+ parents = _ref6.parents;
124
157
  return /*#__PURE__*/_react.default.createElement(_Section.Section, {
125
158
  testId: "insert-block-section",
126
159
  parents: parents,
@@ -141,9 +174,9 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
141
174
  key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
142
175
  rank: _toolbar.TOOLBAR_RANK[_toolbar.LINKING_SECTION.key]
143
176
  }],
144
- component: function component(_ref6) {
145
- var children = _ref6.children,
146
- parents = _ref6.parents;
177
+ component: function component(_ref7) {
178
+ var children = _ref7.children,
179
+ parents = _ref7.parents;
147
180
  return /*#__PURE__*/_react.default.createElement(_Section.Section, {
148
181
  testId: "link-section",
149
182
  parents: parents,
@@ -175,8 +208,8 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
175
208
  key: _toolbar.OVERFLOW_GROUP.key,
176
209
  rank: _toolbar.OVERFLOW_GROUP_RANK[_toolbar.OVERFLOW_MENU.key]
177
210
  }],
178
- component: function component(_ref7) {
179
- var children = _ref7.children;
211
+ component: function component(_ref8) {
212
+ var children = _ref8.children;
180
213
  return /*#__PURE__*/_react.default.createElement(_OverflowMenu.OverflowMenu, null, children);
181
214
  }
182
215
  }, {
@@ -197,8 +230,8 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
197
230
  key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
198
231
  rank: _toolbar.TOOLBAR_RANK[_toolbar.OVERFLOW_SECTION_PRIMARY_TOOLBAR.key]
199
232
  }],
200
- component: function component(_ref8) {
201
- var children = _ref8.children;
233
+ component: function component(_ref9) {
234
+ var children = _ref9.children;
202
235
  return /*#__PURE__*/_react.default.createElement(_OverflowSection.OverflowSection, null, children);
203
236
  }
204
237
  }, {
@@ -217,8 +250,8 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
217
250
  key: _toolbar.OVERFLOW_GROUP_PRIMARY_TOOLBAR.key,
218
251
  rank: _toolbar.OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK[_toolbar.OVERFLOW_MENU_PRIMARY_TOOLBAR.key]
219
252
  }],
220
- component: function component(_ref9) {
221
- var children = _ref9.children;
253
+ component: function component(_ref0) {
254
+ var children = _ref0.children;
222
255
  return /*#__PURE__*/_react.default.createElement(_OverflowMenu.OverflowMenu, null, children);
223
256
  }
224
257
  });
@@ -3,11 +3,29 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isEventInContainer = void 0;
6
+ exports.isShortcutToFocusToolbar = exports.isEventInContainer = exports.getFocusableElements = void 0;
7
7
  var isEventInContainer = exports.isEventInContainer = function isEventInContainer(event, containerSelector) {
8
8
  var target = event.target instanceof Element ? event.target : null;
9
9
  if (!target) {
10
10
  return false;
11
11
  }
12
12
  return !!target.closest(containerSelector);
13
+ };
14
+ var isShortcutToFocusToolbar = exports.isShortcutToFocusToolbar = function isShortcutToFocusToolbar(event) {
15
+ return event.altKey && event.key === 'F10';
16
+ };
17
+ var getFocusableElements = exports.getFocusableElements = function getFocusableElements(rootNode) {
18
+ if (!rootNode) {
19
+ return [];
20
+ }
21
+ var focusableElements = rootNode.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, div[tabindex="-1"], div[tabindex="0"]') || [];
22
+ var focusableElementsArray = Array.from(focusableElements);
23
+
24
+ // filter out focusable elements from child components such as dropdown menus / popups
25
+ return focusableElementsArray.filter(function (elm) {
26
+ var style = window.getComputedStyle(elm);
27
+
28
+ // filter out invisible elements
29
+ return style.visibility !== 'hidden' && style.display !== 'none';
30
+ });
13
31
  };
@@ -1,8 +1,11 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { getDocument } from '@atlaskit/browser-apis';
2
4
  import { isSSR } from '@atlaskit/editor-common/core-utils';
3
5
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
6
+ import { fullPageMessages } from '@atlaskit/editor-common/messages';
4
7
  import { EditorToolbarProvider, EditorToolbarUIProvider } from '@atlaskit/editor-common/toolbar';
5
- import { Popup } from '@atlaskit/editor-common/ui';
8
+ import { Popup, EDIT_AREA_ID } from '@atlaskit/editor-common/ui';
6
9
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
7
10
  import { calculateToolbarPositionTrackHead, calculateToolbarPositionOnCellSelection } from '@atlaskit/editor-common/utils';
8
11
  import { AllSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
@@ -13,6 +16,7 @@ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react'
13
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
17
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
15
18
  import { SELECTION_TOOLBAR_LABEL } from '../consts';
19
+ import { getFocusableElements, isShortcutToFocusToolbar } from '../utils/toolbar';
16
20
  const isToolbarComponent = component => {
17
21
  return component.type === 'toolbar' && component.key === 'inline-text-toolbar';
18
22
  };
@@ -70,8 +74,12 @@ export const SelectionToolbar = ({
70
74
  // @ts-expect-error
71
75
  selection
72
76
  } = usePluginState(api);
77
+ const intl = useIntl();
73
78
  const components = api === null || api === void 0 ? void 0 : (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : _api$toolbar.actions.getComponents();
74
79
  const toolbar = components === null || components === void 0 ? void 0 : components.find(component => isToolbarComponent(component));
80
+ const keyboardNavigation = useMemo(() => {
81
+ return getKeyboardNavigationConfig(editorView, intl, api);
82
+ }, [editorView, intl, api]);
75
83
  const isOffline = connectivityStateMode === 'offline';
76
84
  const isTextSelection = !editorView.state.selection.empty && editorView.state.selection instanceof TextSelection;
77
85
  const isAllSelection = !editorView.state.selection.empty && editorView.state.selection instanceof AllSelection && expValEquals('platform_editor_toolbar_aifc_patch_2', 'isEnabled', true);
@@ -110,7 +118,8 @@ export const SelectionToolbar = ({
110
118
  fireAnalyticsEvent: expValEquals('platform_editor_toolbar_aifc_toolbar_analytic', 'isEnabled', true) ? payload => {
111
119
  var _api$analytics;
112
120
  api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent(payload);
113
- } : undefined
121
+ } : undefined,
122
+ keyboardNavigation: expValEquals('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? keyboardNavigation : undefined
114
123
  }, /*#__PURE__*/React.createElement(ToolbarModelRenderer, {
115
124
  toolbar: toolbar,
116
125
  components: components,
@@ -152,4 +161,47 @@ const getDomRefFromSelection = (view
152
161
  // dispatchAnalyticsEvent(payload);
153
162
  // }
154
163
  }
164
+ };
165
+ const getKeyboardNavigationConfig = (editorView, intl, api) => {
166
+ if (!(editorView.dom instanceof HTMLElement)) {
167
+ return;
168
+ }
169
+ const toolbarSelector = "[data-testid='editor-floating-toolbar']";
170
+ return {
171
+ childComponentSelector: toolbarSelector,
172
+ dom: editorView.dom,
173
+ isShortcutToFocusToolbar: isShortcutToFocusToolbar,
174
+ handleFocus: event => {
175
+ var _getDocument, _filteredFocusableEle, _filteredFocusableEle2, _filteredFocusableEle3;
176
+ const toolbar = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.querySelector(toolbarSelector);
177
+ if (!(toolbar instanceof HTMLElement)) {
178
+ return;
179
+ }
180
+ const filteredFocusableElements = getFocusableElements(toolbar);
181
+ (_filteredFocusableEle = filteredFocusableElements[0]) === null || _filteredFocusableEle === void 0 ? void 0 : _filteredFocusableEle.focus();
182
+
183
+ // the button element removes the focus ring so this class adds it back
184
+ if (((_filteredFocusableEle2 = filteredFocusableElements[0]) === null || _filteredFocusableEle2 === void 0 ? void 0 : _filteredFocusableEle2.tagName) === 'BUTTON') {
185
+ filteredFocusableElements[0].classList.add('first-floating-toolbar-button');
186
+ }
187
+ (_filteredFocusableEle3 = filteredFocusableElements[0]) === null || _filteredFocusableEle3 === void 0 ? void 0 : _filteredFocusableEle3.scrollIntoView({
188
+ behavior: 'smooth',
189
+ block: 'center',
190
+ inline: 'nearest'
191
+ });
192
+ event.preventDefault();
193
+ event.stopPropagation();
194
+ },
195
+ handleEscape: event => {
196
+ const isDropdownOpen = !!document.querySelector('[data-toolbar-component="menu-section"]');
197
+ if (isDropdownOpen) {
198
+ return;
199
+ }
200
+ api === null || api === void 0 ? void 0 : api.core.actions.focus();
201
+ event.preventDefault();
202
+ event.stopPropagation();
203
+ },
204
+ ariaControls: EDIT_AREA_ID,
205
+ ariaLabel: intl.formatMessage(fullPageMessages.toolbarLabel)
206
+ };
155
207
  };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
3
- import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_PRIMARY_TOOLBAR, OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_MENU_PRIMARY_TOOLBAR, OVERFLOW_SECTION, OVERFLOW_SECTION_PRIMARY_TOOLBAR, OVERFLOW_SECTION_PRIMARY_TOOLBAR_RANK, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_COLLAPSED_GROUP, TEXT_SECTION, TEXT_SECTION_COLLAPSED, TEXT_COLLAPSED_MENU, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
3
+ import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_PRIMARY_TOOLBAR, OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_MENU_PRIMARY_TOOLBAR, OVERFLOW_SECTION, OVERFLOW_SECTION_PRIMARY_TOOLBAR, OVERFLOW_SECTION_PRIMARY_TOOLBAR_RANK, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_COLLAPSED_GROUP, TEXT_SECTION, TEXT_SECTION_PRIMARY_TOOLBAR, TEXT_SECTION_COLLAPSED, TEXT_COLLAPSED_MENU, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
4
4
  import { PrimaryToolbar as PrimaryToolbarBase, Show, Toolbar } from '@atlaskit/editor-toolbar';
5
5
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
6
  import { SELECTION_TOOLBAR_LABEL } from './consts';
@@ -18,7 +18,8 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
18
18
  }) => {
19
19
  return /*#__PURE__*/React.createElement(Toolbar, {
20
20
  label: SELECTION_TOOLBAR_LABEL,
21
- actionSubjectId: ACTION_SUBJECT_ID.SELECTION_TOOLBAR
21
+ actionSubjectId: ACTION_SUBJECT_ID.SELECTION_TOOLBAR,
22
+ testId: expValEquals('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
22
23
  }, children);
23
24
  }
24
25
  }, {
@@ -32,7 +33,11 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
32
33
  }, {
33
34
  type: TEXT_SECTION.type,
34
35
  key: TEXT_SECTION.key,
35
- parents: [{
36
+ parents: expValEquals('platform_editor_toolbar_aifc_responsiveness_update', 'isEnabled', true) ? [{
37
+ type: 'toolbar',
38
+ key: TOOLBARS.INLINE_TEXT_TOOLBAR,
39
+ rank: TOOLBAR_RANK[TEXT_SECTION.key]
40
+ }] : [{
36
41
  type: 'toolbar',
37
42
  key: TOOLBARS.INLINE_TEXT_TOOLBAR,
38
43
  rank: TOOLBAR_RANK[TEXT_SECTION.key]
@@ -62,7 +67,36 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
62
67
  testId: "text-section"
63
68
  }, children);
64
69
  }
65
- }, ...(expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? [{
70
+ }, ...(expValEquals('platform_editor_toolbar_aifc_responsiveness_update', 'isEnabled', true) ? [{
71
+ type: TEXT_SECTION_PRIMARY_TOOLBAR.type,
72
+ key: TEXT_SECTION_PRIMARY_TOOLBAR.key,
73
+ parents: [{
74
+ type: 'toolbar',
75
+ key: TOOLBARS.PRIMARY_TOOLBAR,
76
+ rank: TOOLBAR_RANK[TEXT_SECTION.key]
77
+ }],
78
+ component: ({
79
+ children,
80
+ parents
81
+ }) => {
82
+ if (expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true)) {
83
+ return /*#__PURE__*/React.createElement(Show, {
84
+ above: "md"
85
+ }, /*#__PURE__*/React.createElement(Section, {
86
+ parents: parents,
87
+ api: api,
88
+ disableSelectionToolbar: disableSelectionToolbar,
89
+ testId: "text-section"
90
+ }, children));
91
+ }
92
+ return /*#__PURE__*/React.createElement(Section, {
93
+ parents: parents,
94
+ api: api,
95
+ disableSelectionToolbar: disableSelectionToolbar,
96
+ testId: "text-section"
97
+ }, children);
98
+ }
99
+ }] : []), ...(expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? [{
66
100
  type: TEXT_SECTION_COLLAPSED.type,
67
101
  key: TEXT_SECTION_COLLAPSED.key,
68
102
  parents: [{
@@ -4,4 +4,22 @@ export const isEventInContainer = (event, containerSelector) => {
4
4
  return false;
5
5
  }
6
6
  return !!target.closest(containerSelector);
7
+ };
8
+ export const isShortcutToFocusToolbar = event => {
9
+ return event.altKey && event.key === 'F10';
10
+ };
11
+ export const getFocusableElements = rootNode => {
12
+ if (!rootNode) {
13
+ return [];
14
+ }
15
+ const focusableElements = rootNode.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, div[tabindex="-1"], div[tabindex="0"]') || [];
16
+ const focusableElementsArray = Array.from(focusableElements);
17
+
18
+ // filter out focusable elements from child components such as dropdown menus / popups
19
+ return focusableElementsArray.filter(elm => {
20
+ const style = window.getComputedStyle(elm);
21
+
22
+ // filter out invisible elements
23
+ return style.visibility !== 'hidden' && style.display !== 'none';
24
+ });
7
25
  };
@@ -1,8 +1,11 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { getDocument } from '@atlaskit/browser-apis';
2
4
  import { isSSR } from '@atlaskit/editor-common/core-utils';
3
5
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
6
+ import { fullPageMessages } from '@atlaskit/editor-common/messages';
4
7
  import { EditorToolbarProvider, EditorToolbarUIProvider } from '@atlaskit/editor-common/toolbar';
5
- import { Popup } from '@atlaskit/editor-common/ui';
8
+ import { Popup, EDIT_AREA_ID } from '@atlaskit/editor-common/ui';
6
9
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
7
10
  import { calculateToolbarPositionTrackHead, calculateToolbarPositionOnCellSelection } from '@atlaskit/editor-common/utils';
8
11
  import { AllSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
@@ -13,6 +16,7 @@ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react'
13
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
17
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
15
18
  import { SELECTION_TOOLBAR_LABEL } from '../consts';
19
+ import { getFocusableElements, isShortcutToFocusToolbar } from '../utils/toolbar';
16
20
  var isToolbarComponent = function isToolbarComponent(component) {
17
21
  return component.type === 'toolbar' && component.key === 'inline-text-toolbar';
18
22
  };
@@ -68,10 +72,14 @@ export var SelectionToolbar = function SelectionToolbar(_ref) {
68
72
  shouldShowToolbar = _usePluginState.shouldShowToolbar,
69
73
  editorViewMode = _usePluginState.editorViewMode,
70
74
  selection = _usePluginState.selection;
75
+ var intl = useIntl();
71
76
  var components = api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : _api$toolbar.actions.getComponents();
72
77
  var toolbar = components === null || components === void 0 ? void 0 : components.find(function (component) {
73
78
  return isToolbarComponent(component);
74
79
  });
80
+ var keyboardNavigation = useMemo(function () {
81
+ return getKeyboardNavigationConfig(editorView, intl, api);
82
+ }, [editorView, intl, api]);
75
83
  var isOffline = connectivityStateMode === 'offline';
76
84
  var isTextSelection = !editorView.state.selection.empty && editorView.state.selection instanceof TextSelection;
77
85
  var isAllSelection = !editorView.state.selection.empty && editorView.state.selection instanceof AllSelection && expValEquals('platform_editor_toolbar_aifc_patch_2', 'isEnabled', true);
@@ -110,7 +118,8 @@ export var SelectionToolbar = function SelectionToolbar(_ref) {
110
118
  fireAnalyticsEvent: expValEquals('platform_editor_toolbar_aifc_toolbar_analytic', 'isEnabled', true) ? function (payload) {
111
119
  var _api$analytics;
112
120
  api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent(payload);
113
- } : undefined
121
+ } : undefined,
122
+ keyboardNavigation: expValEquals('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? keyboardNavigation : undefined
114
123
  }, /*#__PURE__*/React.createElement(ToolbarModelRenderer, {
115
124
  toolbar: toolbar,
116
125
  components: components,
@@ -152,4 +161,47 @@ var getDomRefFromSelection = function getDomRefFromSelection(view
152
161
  // dispatchAnalyticsEvent(payload);
153
162
  // }
154
163
  }
164
+ };
165
+ var getKeyboardNavigationConfig = function getKeyboardNavigationConfig(editorView, intl, api) {
166
+ if (!(editorView.dom instanceof HTMLElement)) {
167
+ return;
168
+ }
169
+ var toolbarSelector = "[data-testid='editor-floating-toolbar']";
170
+ return {
171
+ childComponentSelector: toolbarSelector,
172
+ dom: editorView.dom,
173
+ isShortcutToFocusToolbar: isShortcutToFocusToolbar,
174
+ handleFocus: function handleFocus(event) {
175
+ var _getDocument, _filteredFocusableEle, _filteredFocusableEle2, _filteredFocusableEle3;
176
+ var toolbar = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.querySelector(toolbarSelector);
177
+ if (!(toolbar instanceof HTMLElement)) {
178
+ return;
179
+ }
180
+ var filteredFocusableElements = getFocusableElements(toolbar);
181
+ (_filteredFocusableEle = filteredFocusableElements[0]) === null || _filteredFocusableEle === void 0 || _filteredFocusableEle.focus();
182
+
183
+ // the button element removes the focus ring so this class adds it back
184
+ if (((_filteredFocusableEle2 = filteredFocusableElements[0]) === null || _filteredFocusableEle2 === void 0 ? void 0 : _filteredFocusableEle2.tagName) === 'BUTTON') {
185
+ filteredFocusableElements[0].classList.add('first-floating-toolbar-button');
186
+ }
187
+ (_filteredFocusableEle3 = filteredFocusableElements[0]) === null || _filteredFocusableEle3 === void 0 || _filteredFocusableEle3.scrollIntoView({
188
+ behavior: 'smooth',
189
+ block: 'center',
190
+ inline: 'nearest'
191
+ });
192
+ event.preventDefault();
193
+ event.stopPropagation();
194
+ },
195
+ handleEscape: function handleEscape(event) {
196
+ var isDropdownOpen = !!document.querySelector('[data-toolbar-component="menu-section"]');
197
+ if (isDropdownOpen) {
198
+ return;
199
+ }
200
+ api === null || api === void 0 || api.core.actions.focus();
201
+ event.preventDefault();
202
+ event.stopPropagation();
203
+ },
204
+ ariaControls: EDIT_AREA_ID,
205
+ ariaLabel: intl.formatMessage(fullPageMessages.toolbarLabel)
206
+ };
155
207
  };
@@ -1,7 +1,7 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import React from 'react';
3
3
  import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
4
- import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_PRIMARY_TOOLBAR, OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_MENU_PRIMARY_TOOLBAR, OVERFLOW_SECTION, OVERFLOW_SECTION_PRIMARY_TOOLBAR, OVERFLOW_SECTION_PRIMARY_TOOLBAR_RANK, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_COLLAPSED_GROUP, TEXT_SECTION, TEXT_SECTION_COLLAPSED, TEXT_COLLAPSED_MENU, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
4
+ import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_PRIMARY_TOOLBAR, OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_MENU_PRIMARY_TOOLBAR, OVERFLOW_SECTION, OVERFLOW_SECTION_PRIMARY_TOOLBAR, OVERFLOW_SECTION_PRIMARY_TOOLBAR_RANK, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_COLLAPSED_GROUP, TEXT_SECTION, TEXT_SECTION_PRIMARY_TOOLBAR, TEXT_SECTION_COLLAPSED, TEXT_COLLAPSED_MENU, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
5
5
  import { PrimaryToolbar as PrimaryToolbarBase, Show, Toolbar } from '@atlaskit/editor-toolbar';
6
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
7
  import { SELECTION_TOOLBAR_LABEL } from './consts';
@@ -18,7 +18,8 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
18
18
  var children = _ref.children;
19
19
  return /*#__PURE__*/React.createElement(Toolbar, {
20
20
  label: SELECTION_TOOLBAR_LABEL,
21
- actionSubjectId: ACTION_SUBJECT_ID.SELECTION_TOOLBAR
21
+ actionSubjectId: ACTION_SUBJECT_ID.SELECTION_TOOLBAR,
22
+ testId: expValEquals('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
22
23
  }, children);
23
24
  }
24
25
  }, {
@@ -33,7 +34,11 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
33
34
  }, {
34
35
  type: TEXT_SECTION.type,
35
36
  key: TEXT_SECTION.key,
36
- parents: [{
37
+ parents: expValEquals('platform_editor_toolbar_aifc_responsiveness_update', 'isEnabled', true) ? [{
38
+ type: 'toolbar',
39
+ key: TOOLBARS.INLINE_TEXT_TOOLBAR,
40
+ rank: TOOLBAR_RANK[TEXT_SECTION.key]
41
+ }] : [{
37
42
  type: 'toolbar',
38
43
  key: TOOLBARS.INLINE_TEXT_TOOLBAR,
39
44
  rank: TOOLBAR_RANK[TEXT_SECTION.key]
@@ -62,7 +67,35 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
62
67
  testId: "text-section"
63
68
  }, children);
64
69
  }
65
- }].concat(_toConsumableArray(expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? [{
70
+ }].concat(_toConsumableArray(expValEquals('platform_editor_toolbar_aifc_responsiveness_update', 'isEnabled', true) ? [{
71
+ type: TEXT_SECTION_PRIMARY_TOOLBAR.type,
72
+ key: TEXT_SECTION_PRIMARY_TOOLBAR.key,
73
+ parents: [{
74
+ type: 'toolbar',
75
+ key: TOOLBARS.PRIMARY_TOOLBAR,
76
+ rank: TOOLBAR_RANK[TEXT_SECTION.key]
77
+ }],
78
+ component: function component(_ref4) {
79
+ var children = _ref4.children,
80
+ parents = _ref4.parents;
81
+ if (expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true)) {
82
+ return /*#__PURE__*/React.createElement(Show, {
83
+ above: "md"
84
+ }, /*#__PURE__*/React.createElement(Section, {
85
+ parents: parents,
86
+ api: api,
87
+ disableSelectionToolbar: disableSelectionToolbar,
88
+ testId: "text-section"
89
+ }, children));
90
+ }
91
+ return /*#__PURE__*/React.createElement(Section, {
92
+ parents: parents,
93
+ api: api,
94
+ disableSelectionToolbar: disableSelectionToolbar,
95
+ testId: "text-section"
96
+ }, children);
97
+ }
98
+ }] : []), _toConsumableArray(expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? [{
66
99
  type: TEXT_SECTION_COLLAPSED.type,
67
100
  key: TEXT_SECTION_COLLAPSED.key,
68
101
  parents: [{
@@ -74,9 +107,9 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
74
107
  key: TOOLBARS.INLINE_TEXT_TOOLBAR,
75
108
  rank: TOOLBAR_RANK[TEXT_SECTION_COLLAPSED.key]
76
109
  }],
77
- component: function component(_ref4) {
78
- var children = _ref4.children,
79
- parents = _ref4.parents;
110
+ component: function component(_ref5) {
111
+ var children = _ref5.children,
112
+ parents = _ref5.parents;
80
113
  return /*#__PURE__*/React.createElement(Show, {
81
114
  below: "md"
82
115
  }, /*#__PURE__*/React.createElement(Section, {
@@ -111,9 +144,9 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
111
144
  key: TOOLBARS.PRIMARY_TOOLBAR,
112
145
  rank: TOOLBAR_RANK[INSERT_BLOCK_SECTION.key]
113
146
  }],
114
- component: function component(_ref5) {
115
- var children = _ref5.children,
116
- parents = _ref5.parents;
147
+ component: function component(_ref6) {
148
+ var children = _ref6.children,
149
+ parents = _ref6.parents;
117
150
  return /*#__PURE__*/React.createElement(Section, {
118
151
  testId: "insert-block-section",
119
152
  parents: parents,
@@ -134,9 +167,9 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
134
167
  key: TOOLBARS.PRIMARY_TOOLBAR,
135
168
  rank: TOOLBAR_RANK[LINKING_SECTION.key]
136
169
  }],
137
- component: function component(_ref6) {
138
- var children = _ref6.children,
139
- parents = _ref6.parents;
170
+ component: function component(_ref7) {
171
+ var children = _ref7.children,
172
+ parents = _ref7.parents;
140
173
  return /*#__PURE__*/React.createElement(Section, {
141
174
  testId: "link-section",
142
175
  parents: parents,
@@ -168,8 +201,8 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
168
201
  key: OVERFLOW_GROUP.key,
169
202
  rank: OVERFLOW_GROUP_RANK[OVERFLOW_MENU.key]
170
203
  }],
171
- component: function component(_ref7) {
172
- var children = _ref7.children;
204
+ component: function component(_ref8) {
205
+ var children = _ref8.children;
173
206
  return /*#__PURE__*/React.createElement(OverflowMenu, null, children);
174
207
  }
175
208
  }, {
@@ -190,8 +223,8 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
190
223
  key: TOOLBARS.PRIMARY_TOOLBAR,
191
224
  rank: TOOLBAR_RANK[OVERFLOW_SECTION_PRIMARY_TOOLBAR.key]
192
225
  }],
193
- component: function component(_ref8) {
194
- var children = _ref8.children;
226
+ component: function component(_ref9) {
227
+ var children = _ref9.children;
195
228
  return /*#__PURE__*/React.createElement(OverflowSection, null, children);
196
229
  }
197
230
  }, {
@@ -210,8 +243,8 @@ export var getToolbarComponents = function getToolbarComponents(api, disableSele
210
243
  key: OVERFLOW_GROUP_PRIMARY_TOOLBAR.key,
211
244
  rank: OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK[OVERFLOW_MENU_PRIMARY_TOOLBAR.key]
212
245
  }],
213
- component: function component(_ref9) {
214
- var children = _ref9.children;
246
+ component: function component(_ref0) {
247
+ var children = _ref0.children;
215
248
  return /*#__PURE__*/React.createElement(OverflowMenu, null, children);
216
249
  }
217
250
  });
@@ -4,4 +4,22 @@ export var isEventInContainer = function isEventInContainer(event, containerSele
4
4
  return false;
5
5
  }
6
6
  return !!target.closest(containerSelector);
7
+ };
8
+ export var isShortcutToFocusToolbar = function isShortcutToFocusToolbar(event) {
9
+ return event.altKey && event.key === 'F10';
10
+ };
11
+ export var getFocusableElements = function getFocusableElements(rootNode) {
12
+ if (!rootNode) {
13
+ return [];
14
+ }
15
+ var focusableElements = rootNode.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, div[tabindex="-1"], div[tabindex="0"]') || [];
16
+ var focusableElementsArray = Array.from(focusableElements);
17
+
18
+ // filter out focusable elements from child components such as dropdown menus / popups
19
+ return focusableElementsArray.filter(function (elm) {
20
+ var style = window.getComputedStyle(elm);
21
+
22
+ // filter out invisible elements
23
+ return style.visibility !== 'hidden' && style.display !== 'none';
24
+ });
7
25
  };
@@ -1 +1,3 @@
1
1
  export declare const isEventInContainer: (event: Event, containerSelector: string) => boolean;
2
+ export declare const isShortcutToFocusToolbar: (event: KeyboardEvent) => boolean;
3
+ export declare const getFocusableElements: (rootNode: HTMLElement | null) => Array<HTMLElement>;
@@ -1 +1,3 @@
1
1
  export declare const isEventInContainer: (event: Event, containerSelector: string) => boolean;
2
+ export declare const isShortcutToFocusToolbar: (event: KeyboardEvent) => boolean;
3
+ export declare const getFocusableElements: (rootNode: HTMLElement | null) => Array<HTMLElement>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-toolbar",
3
- "version": "2.1.4",
3
+ "version": "3.0.0",
4
4
  "description": "Toolbar plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -28,23 +28,24 @@
28
28
  "sideEffects": false,
29
29
  "atlaskit:src": "src/index.ts",
30
30
  "dependencies": {
31
- "@atlaskit/editor-plugin-analytics": "^5.2.0",
32
- "@atlaskit/editor-plugin-connectivity": "^5.0.0",
33
- "@atlaskit/editor-plugin-editor-viewmode": "^7.0.0",
34
- "@atlaskit/editor-plugin-selection": "^5.0.0",
35
- "@atlaskit/editor-plugin-user-intent": "^3.0.0",
36
- "@atlaskit/editor-plugin-user-preferences": "^3.0.0",
31
+ "@atlaskit/browser-apis": "^0.0.1",
32
+ "@atlaskit/editor-plugin-analytics": "^6.0.0",
33
+ "@atlaskit/editor-plugin-connectivity": "^6.0.0",
34
+ "@atlaskit/editor-plugin-editor-viewmode": "^8.0.0",
35
+ "@atlaskit/editor-plugin-selection": "^6.0.0",
36
+ "@atlaskit/editor-plugin-user-intent": "^4.0.0",
37
+ "@atlaskit/editor-plugin-user-preferences": "^4.0.0",
37
38
  "@atlaskit/editor-prosemirror": "7.0.0",
38
39
  "@atlaskit/editor-toolbar": "^0.9.0",
39
40
  "@atlaskit/editor-toolbar-model": "^0.2.0",
40
41
  "@atlaskit/platform-feature-flags-react": "^0.3.0",
41
- "@atlaskit/tmp-editor-statsig": "^12.24.0",
42
+ "@atlaskit/tmp-editor-statsig": "^12.31.0",
42
43
  "@babel/runtime": "^7.0.0",
43
44
  "bind-event-listener": "^3.0.0",
44
45
  "react-intl-next": "npm:react-intl@^5.18.1"
45
46
  },
46
47
  "peerDependencies": {
47
- "@atlaskit/editor-common": "^109.8.0",
48
+ "@atlaskit/editor-common": "^110.0.0",
48
49
  "react": "^18.2.0"
49
50
  },
50
51
  "techstack": {