@atlaskit/editor-plugin-media 1.24.0 → 1.24.2

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,22 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 1.24.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 1.24.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [#120417](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/120417)
14
+ [`26e76bb38b63f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/26e76bb38b63f) -
15
+ [ux] ECA11Y-175: This changes improves the floating toolbar a11y by making the image border
16
+ options menu accessible for keyboard-only users, and is behind the feature gate
17
+ `platform-editor-a11y-image-border-options-dropdown`.
18
+ - Updated dependencies
19
+
3
20
  ## 1.24.0
4
21
 
5
22
  ### Minor Changes
@@ -16,6 +16,7 @@ var _uiColor = require("@atlaskit/editor-common/ui-color");
16
16
  var _uiMenu = require("@atlaskit/editor-common/ui-menu");
17
17
  var _editorPalette = require("@atlaskit/editor-palette");
18
18
  var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/glyph/chevron-down"));
19
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
19
20
  var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
20
21
  var _styles2 = require("./styles");
21
22
  /** @jsx jsx */
@@ -28,6 +29,11 @@ var ImageBorder = function ImageBorder(_ref) {
28
29
  borderMark = _ref.borderMark,
29
30
  setBorder = _ref.setBorder;
30
31
  var popupTarget = (0, _react.useRef)(null);
32
+ var dropDownColorOptionButton = (0, _react.useRef)(null);
33
+ var dropDownSizeOptionButton = (0, _react.useRef)(null);
34
+ var colorSubmenuRef = (0, _react.useRef)(null);
35
+ var sizeSubmenuRef = (0, _react.useRef)(null);
36
+ var openDropdownButtonRef = (0, _react.useRef)(null);
31
37
  var enabled = !!borderMark;
32
38
  var color = borderMark === null || borderMark === void 0 ? void 0 : borderMark.color;
33
39
  var size = borderMark === null || borderMark === void 0 ? void 0 : borderMark.size;
@@ -37,12 +43,28 @@ var ImageBorder = function ImageBorder(_ref) {
37
43
  setIsOpen = _useState2[1];
38
44
  var _useState3 = (0, _react.useState)(false),
39
45
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
40
- isColorSubmenuOpen = _useState4[0],
41
- setIsColorSubmenuOpen = _useState4[1];
46
+ isOpenByKeyboard = _useState4[0],
47
+ setIsOpenedByKeyboard = _useState4[1];
42
48
  var _useState5 = (0, _react.useState)(false),
43
49
  _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
44
- isSizeSubmenuOpen = _useState6[0],
45
- setIsSizeSubmenuOpen = _useState6[1];
50
+ isColorSubmenuOpen = _useState6[0],
51
+ setIsColorSubmenuOpen = _useState6[1];
52
+ var _useState7 = (0, _react.useState)(false),
53
+ _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
54
+ isSizeSubmenuOpen = _useState8[0],
55
+ setIsSizeSubmenuOpen = _useState8[1];
56
+ var handleColorSubmenuEsc = (0, _react.useCallback)(function () {
57
+ var _dropDownColorOptionB;
58
+ setIsOpenedByKeyboard(false);
59
+ setIsColorSubmenuOpen(false);
60
+ dropDownColorOptionButton === null || dropDownColorOptionButton === void 0 || (_dropDownColorOptionB = dropDownColorOptionButton.current) === null || _dropDownColorOptionB === void 0 || _dropDownColorOptionB.focus();
61
+ }, []);
62
+ var handleSizeSubmenuEsc = (0, _react.useCallback)(function () {
63
+ var _dropDownSizeOptionBu;
64
+ setIsOpenedByKeyboard(false);
65
+ setIsSizeSubmenuOpen(false);
66
+ dropDownSizeOptionButton === null || dropDownSizeOptionButton === void 0 || (_dropDownSizeOptionBu = dropDownSizeOptionButton.current) === null || _dropDownSizeOptionBu === void 0 || _dropDownSizeOptionBu.focus();
67
+ }, []);
46
68
  var handleSubMenuRef = function handleSubMenuRef(ref) {
47
69
  if (!ref) {
48
70
  return;
@@ -52,6 +74,38 @@ var ImageBorder = function ImageBorder(_ref) {
52
74
  ref.style.left = "-".concat(rect.width, "px");
53
75
  }
54
76
  };
77
+ var handleTriggerByKeyboard = function handleTriggerByKeyboard(event, callback) {
78
+ if ((0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown')) {
79
+ if (event.key === 'Enter' || event.key === ' ') {
80
+ event.preventDefault();
81
+ callback();
82
+ setIsOpenedByKeyboard(true);
83
+ }
84
+ }
85
+ };
86
+ (0, _react.useEffect)(function () {
87
+ if ((0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown')) {
88
+ var focusFirstOption = function focusFirstOption(submenuRef, isOpen) {
89
+ if (!isOpenByKeyboard) {
90
+ return;
91
+ }
92
+ if (isOpen && submenuRef.current) {
93
+ var firstOption = submenuRef.current.querySelector('button');
94
+ if (!firstOption) {
95
+ return;
96
+ }
97
+ firstOption.focus();
98
+ var keyboardEvent = new KeyboardEvent('keydown', {
99
+ key: 'ArrowDown',
100
+ bubbles: true
101
+ });
102
+ firstOption.dispatchEvent(keyboardEvent);
103
+ }
104
+ };
105
+ focusFirstOption(colorSubmenuRef, isColorSubmenuOpen);
106
+ focusFirstOption(sizeSubmenuRef, isSizeSubmenuOpen);
107
+ }
108
+ }, [isColorSubmenuOpen, isSizeSubmenuOpen, isOpenByKeyboard]);
55
109
  var borderSizeOptions = [{
56
110
  name: formatMessage(_media.imageBorderMessages.borderSizeSubtle),
57
111
  value: 1
@@ -62,7 +116,153 @@ var ImageBorder = function ImageBorder(_ref) {
62
116
  name: formatMessage(_media.imageBorderMessages.borderSizeBold),
63
117
  value: 3
64
118
  }];
65
- var items = [{
119
+ var items = (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? [{
120
+ content: (0, _react2.jsx)("div", null, (0, _react2.jsx)("button", {
121
+ ref: dropDownColorOptionButton,
122
+ type: "button",
123
+ "aria-label": "Image border options Color dropdown button",
124
+ "data-testid": "image-border-dropdown-button-color"
125
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
126
+ ,
127
+ css: [_styles2.dropdownOptionButton],
128
+ "aria-expanded": isColorSubmenuOpen,
129
+ onKeyDown: function onKeyDown(e) {
130
+ return handleTriggerByKeyboard(e, function () {
131
+ return setIsColorSubmenuOpen(!isColorSubmenuOpen);
132
+ });
133
+ }
134
+ }, (0, _react2.jsx)("span", null, formatMessage(_media.imageBorderMessages.borderColor)), (0, _react2.jsx)("div", {
135
+ css: (0, _styles2.contextualMenuColorIcon)(color && (0, _editorPalette.hexToEditorBorderPaletteColor)(color))
136
+ })), (0, _react2.jsx)("div", {
137
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
138
+ className: _styles.DropdownMenuSharedCssClassName.SUBMENU,
139
+ ref: colorSubmenuRef
140
+ }, isColorSubmenuOpen &&
141
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
142
+ (0, _react2.jsx)("div", {
143
+ css: (0, _styles2.contextualSubMenu)(0),
144
+ ref: handleSubMenuRef
145
+ }, (0, _react2.jsx)(_uiMenu.ArrowKeyNavigationProvider, {
146
+ type: _uiMenu.ArrowKeyNavigationType.MENU,
147
+ handleClose: function handleClose(e) {
148
+ e.preventDefault();
149
+ e.stopPropagation();
150
+ handleColorSubmenuEsc();
151
+ },
152
+ disableCloseOnArrowClick: true
153
+ }, (0, _react2.jsx)(_uiColor.ColorPalette, {
154
+ onClick: function onClick(color) {
155
+ setBorder({
156
+ color: color
157
+ });
158
+ setIsOpen(!isOpen);
159
+ },
160
+ onKeyDown: function onKeyDown(color, _, event) {
161
+ if (event.key === 'Enter' || event.key === ' ') {
162
+ var _openDropdownButtonRe;
163
+ setBorder({
164
+ color: color
165
+ });
166
+ setIsOpen(!isOpen);
167
+ setIsColorSubmenuOpen(false);
168
+ setIsSizeSubmenuOpen(false);
169
+ (_openDropdownButtonRe = openDropdownButtonRef.current) === null || _openDropdownButtonRe === void 0 || _openDropdownButtonRe.focus();
170
+ }
171
+ },
172
+ selectedColor: color !== null && color !== void 0 ? color : null,
173
+ paletteOptions: {
174
+ palette: _uiColor.borderColorPalette,
175
+ paletteColorTooltipMessages: _uiColor.borderPaletteTooltipMessages,
176
+ hexToPaletteColor: _editorPalette.hexToEditorBorderPaletteColor
177
+ }
178
+ }))))),
179
+ 'data-testid': 'dropdown-item__Color',
180
+ key: 'dropdown-menu-image-border-color-button',
181
+ value: {
182
+ name: 'color'
183
+ },
184
+ 'aria-label': '',
185
+ wrapperTabIndex: null
186
+ }, {
187
+ content: (0, _react2.jsx)("div", null, (0, _react2.jsx)("button", {
188
+ type: "button",
189
+ "aria-label": "Image border options Size dropdown button",
190
+ "data-testid": "image-border-dropdown-button-size"
191
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
192
+ ,
193
+ css: [_styles2.dropdownOptionButton],
194
+ "aria-expanded": isSizeSubmenuOpen,
195
+ ref: dropDownSizeOptionButton,
196
+ onKeyDown: function onKeyDown(e) {
197
+ return handleTriggerByKeyboard(e, function () {
198
+ return setIsSizeSubmenuOpen(!isSizeSubmenuOpen);
199
+ });
200
+ }
201
+ }, (0, _react2.jsx)("span", null, formatMessage(_media.imageBorderMessages.borderSize)), (0, _react2.jsx)("div", {
202
+ css: _styles2.contextualMenuArrow
203
+ })), (0, _react2.jsx)("div", {
204
+ //eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
205
+ className: _styles.DropdownMenuSharedCssClassName.SUBMENU,
206
+ ref: sizeSubmenuRef
207
+ }, isSizeSubmenuOpen && (0, _react2.jsx)(_uiMenu.ArrowKeyNavigationProvider, {
208
+ type: _uiMenu.ArrowKeyNavigationType.MENU,
209
+ handleClose: function handleClose(e) {
210
+ e.preventDefault();
211
+ handleSizeSubmenuEsc();
212
+ },
213
+ disableCloseOnArrowClick: true
214
+ }, (0, _react2.jsx)("div", {
215
+ css: (0, _styles2.contextualSubMenu)(1),
216
+ ref: handleSubMenuRef
217
+ }, borderSizeOptions.map(function (_ref2, idx) {
218
+ var name = _ref2.name,
219
+ value = _ref2.value;
220
+ return (0, _react2.jsx)(_tooltip.default, {
221
+ key: idx,
222
+ content: name
223
+ }, (0, _react2.jsx)("span", {
224
+ css: _styles2.buttonWrapperStyle
225
+ }, (0, _react2.jsx)("button", {
226
+ type: "button"
227
+ /* eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */,
228
+ css: (0, _styles2.buttonStyle)(value === size),
229
+ "aria-label": name,
230
+ role: "radio",
231
+ "aria-checked": value === size,
232
+ onClick: function onClick() {
233
+ setBorder({
234
+ size: value
235
+ });
236
+ setIsOpen(false);
237
+ },
238
+ onKeyDown: function onKeyDown(event) {
239
+ if (event.key === 'Enter' || event.key === ' ') {
240
+ var _openDropdownButtonRe2;
241
+ setBorder({
242
+ size: value
243
+ });
244
+ setIsOpen(false);
245
+ setIsColorSubmenuOpen(false);
246
+ setIsSizeSubmenuOpen(false);
247
+ (_openDropdownButtonRe2 = openDropdownButtonRef.current) === null || _openDropdownButtonRe2 === void 0 || _openDropdownButtonRe2.focus();
248
+ }
249
+ },
250
+ onMouseDown: function onMouseDown(e) {
251
+ e.preventDefault();
252
+ }
253
+ }, (0, _react2.jsx)("div", {
254
+ css: (0, _styles2.line)(value, value === size),
255
+ role: "presentation"
256
+ }))));
257
+ }))))),
258
+ 'data-testid': 'dropdown-item__Size',
259
+ key: 'dropdown-menu-image-border-size-button',
260
+ value: {
261
+ name: 'size'
262
+ },
263
+ 'aria-label': '',
264
+ wrapperTabIndex: null
265
+ }] : [{
66
266
  content: formatMessage(_media.imageBorderMessages.borderColor),
67
267
  value: {
68
268
  name: 'color'
@@ -108,9 +308,9 @@ var ImageBorder = function ImageBorder(_ref) {
108
308
  (0, _react2.jsx)("div", {
109
309
  css: (0, _styles2.contextualSubMenu)(1),
110
310
  ref: handleSubMenuRef
111
- }, borderSizeOptions.map(function (_ref2, idx) {
112
- var name = _ref2.name,
113
- value = _ref2.value;
311
+ }, borderSizeOptions.map(function (_ref3, idx) {
312
+ var name = _ref3.name,
313
+ value = _ref3.value;
114
314
  return (0, _react2.jsx)(_tooltip.default, {
115
315
  key: idx,
116
316
  content: name
@@ -139,7 +339,6 @@ var ImageBorder = function ImageBorder(_ref) {
139
339
  }))));
140
340
  })))
141
341
  }];
142
-
143
342
  /**
144
343
  * We want to change direction of our dropdowns a bit early,
145
344
  * not exactly when it hits the boundary.
@@ -147,6 +346,7 @@ var ImageBorder = function ImageBorder(_ref) {
147
346
  var fitTolerance = 10;
148
347
  var fitWidth = _styles2.menuItemDimensions.width;
149
348
  var fitHeight = items.length * (_styles2.menuItemDimensions.height + _styles2.itemSpacing);
349
+ var isAnySubMenuOpen = isSizeSubmenuOpen || isColorSubmenuOpen;
150
350
  return (0, _react2.jsx)("div", null, (0, _react2.jsx)("div", {
151
351
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
152
352
  css: (0, _styles2.toolbarButtonWrapper)({
@@ -171,7 +371,9 @@ var ImageBorder = function ImageBorder(_ref) {
171
371
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
172
372
  , {
173
373
  className: "image-border-toolbar-dropdown",
374
+ ref: openDropdownButtonRef,
174
375
  selected: enabled || isOpen,
376
+ "aria-expanded": (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? isOpen : undefined,
175
377
  "aria-label": formatMessage(_media.imageBorderMessages.borderOptions),
176
378
  title: formatMessage(_media.imageBorderMessages.borderOptions),
177
379
  spacing: "compact",
@@ -180,7 +382,15 @@ var ImageBorder = function ImageBorder(_ref) {
180
382
  }),
181
383
  onClick: function onClick() {
182
384
  setIsOpen(!isOpen);
183
- }
385
+ if ((0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown')) {
386
+ setIsOpenedByKeyboard(false);
387
+ }
388
+ },
389
+ onKeyDown: (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? function (e) {
390
+ return handleTriggerByKeyboard(e, function () {
391
+ return setIsOpen(!isOpen);
392
+ });
393
+ } : undefined
184
394
  }))), (0, _react2.jsx)(_ui.Popup, {
185
395
  target: popupTarget.current ? popupTarget.current : undefined,
186
396
  fitWidth: fitWidth + fitTolerance,
@@ -191,7 +401,9 @@ var ImageBorder = function ImageBorder(_ref) {
191
401
  onMouseLeave: function onMouseLeave() {
192
402
  setIsColorSubmenuOpen(false);
193
403
  setIsSizeSubmenuOpen(false);
194
- }
404
+ },
405
+ css: (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? /* eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
406
+ _styles2.dropdownWrapper : undefined
195
407
  }, (0, _react2.jsx)(_uiMenu.DropdownMenu
196
408
  //This needs be removed when the a11y is completely handled
197
409
  //Disabling key navigation now as it works only partially
@@ -199,19 +411,32 @@ var ImageBorder = function ImageBorder(_ref) {
199
411
  , {
200
412
  arrowKeyNavigationProviderOptions: {
201
413
  type: _uiMenu.ArrowKeyNavigationType.MENU,
202
- disableArrowKeyNavigation: true
414
+ disableArrowKeyNavigation: (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? true : false : true
203
415
  },
416
+ allowEnterDefaultBehavior: (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? true : false : undefined,
417
+ handleEscapeKeydown: (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? function () {
418
+ return;
419
+ } : function () {
420
+ var _openDropdownButtonRe3;
421
+ (_openDropdownButtonRe3 = openDropdownButtonRef.current) === null || _openDropdownButtonRe3 === void 0 || _openDropdownButtonRe3.focus();
422
+ } : undefined,
204
423
  items: [{
205
424
  items: items
206
425
  }],
207
426
  isOpen: isOpen,
427
+ shouldFocusFirstItem: (0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown') ? function () {
428
+ return isOpenByKeyboard;
429
+ } : undefined,
208
430
  onOpenChange: function onOpenChange() {
209
431
  setIsOpen(false);
210
432
  setIsColorSubmenuOpen(false);
211
433
  setIsSizeSubmenuOpen(false);
434
+ if ((0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown')) {
435
+ setIsOpenedByKeyboard(false);
436
+ }
212
437
  },
213
- onItemActivated: function onItemActivated(_ref3) {
214
- var item = _ref3.item;
438
+ onItemActivated: function onItemActivated(_ref4) {
439
+ var item = _ref4.item;
215
440
  if (item.value.name === 'color') {
216
441
  setIsColorSubmenuOpen(!isColorSubmenuOpen);
217
442
  }
@@ -219,17 +444,23 @@ var ImageBorder = function ImageBorder(_ref) {
219
444
  setIsSizeSubmenuOpen(!isSizeSubmenuOpen);
220
445
  }
221
446
  },
222
- onMouseEnter: function onMouseEnter(_ref4) {
223
- var item = _ref4.item;
447
+ onMouseEnter: function onMouseEnter(_ref5) {
448
+ var item = _ref5.item;
224
449
  if (item.value.name === 'color') {
225
450
  setIsColorSubmenuOpen(true);
451
+ if ((0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown')) {
452
+ setIsOpenedByKeyboard(false);
453
+ }
226
454
  }
227
455
  if (item.value.name === 'size') {
228
456
  setIsSizeSubmenuOpen(true);
457
+ if ((0, _platformFeatureFlags.fg)('platform-editor-a11y-image-border-options-dropdown')) {
458
+ setIsOpenedByKeyboard(false);
459
+ }
229
460
  }
230
461
  },
231
- onMouseLeave: function onMouseLeave(_ref5) {
232
- var item = _ref5.item;
462
+ onMouseLeave: function onMouseLeave(_ref6) {
463
+ var item = _ref6.item;
233
464
  if (item.value.name === 'color') {
234
465
  setIsColorSubmenuOpen(false);
235
466
  }
@@ -5,14 +5,14 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.toolbarButtonWrapper = exports.menuItemDimensions = exports.line = exports.itemSpacing = exports.contextualSubMenu = exports.contextualMenuColorIcon = exports.contextualMenuArrow = exports.buttonWrapperStyle = exports.buttonStyle = void 0;
8
+ exports.toolbarButtonWrapper = exports.menuItemDimensions = exports.line = exports.itemSpacing = exports.dropdownWrapper = exports.dropdownOptionButton = exports.contextualSubMenu = exports.contextualMenuColorIcon = exports.contextualMenuArrow = exports.buttonWrapperStyle = exports.buttonStyle = void 0;
9
9
  var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
10
10
  var _react = require("@emotion/react");
11
11
  var _uiColor = require("@atlaskit/editor-common/ui-color");
12
12
  var _colors = _interopRequireWildcard(require("@atlaskit/theme/colors"));
13
13
  var colors = _colors;
14
14
  var _constants = require("@atlaskit/theme/constants");
15
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
15
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9;
16
16
  /* eslint-disable @atlaskit/design-system/no-css-tagged-template-expression -- Needs manual remediation*/
17
17
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
18
18
  // eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
@@ -55,4 +55,10 @@ var toolbarButtonWrapper = exports.toolbarButtonWrapper = function toolbarButton
55
55
  var enabled = _ref.enabled,
56
56
  isOpen = _ref.isOpen;
57
57
  return (0, _react.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n\tdisplay: flex;\n\t.image-border-toolbar-btn {\n\t\tborder-top-right-radius: 0;\n\t\tborder-bottom-right-radius: 0;\n\t\tpadding: 0;\n\t\t& > span {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n\t.image-border-toolbar-dropdown {\n\t\tpadding: 0;\n\t\t& > span {\n\t\t\tmargin: 0;\n\t\t}\n\t\twidth: 16px !important;\n\t\tborder-top-left-radius: 0 !important;\n\t\tborder-bottom-left-radius: 0 !important;\n\t\tmargin-left: ", ";\n\t}\n\n\t", "\n\t", "\n"])), "var(--ds-space-025, 2px)", !enabled && getHoverStyles('.image-border-toolbar-btn'), !isOpen && !enabled && getHoverStyles('.image-border-toolbar-dropdown'));
58
- };
58
+ };
59
+
60
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
61
+ var dropdownOptionButton = exports.dropdownOptionButton = (0, _react.css)(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2.default)(["\n\tbackground: transparent;\n\tborder: 2px solid transparent;\n\tdisplay: flex;\n\twidth: 100%;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 8px 16px;\n\n\t&:focus {\n\t\tbackground-color: ", ";\n\t\tborder: 2px solid ", ";\n\t}\n"])), "var(--ds-background-neutral-subtle-hovered, rgb(244, 245, 247))", "var(--ds-border-focused, #2684FF)");
62
+
63
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
64
+ var dropdownWrapper = exports.dropdownWrapper = (0, _react.css)(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2.default)(["\n\tspan[role='menuitem'] {\n\t\tpadding: 0;\n\t}\n"])));
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
- import { useRef, useState } from 'react';
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
3
 
4
4
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
5
5
  import { jsx } from '@emotion/react';
@@ -8,11 +8,12 @@ import { imageBorderMessages as messages } from '@atlaskit/editor-common/media';
8
8
  import { DropdownMenuSharedCssClassName } from '@atlaskit/editor-common/styles';
9
9
  import { Popup } from '@atlaskit/editor-common/ui';
10
10
  import { borderColorPalette, borderPaletteTooltipMessages, ColorPalette } from '@atlaskit/editor-common/ui-color';
11
- import { ArrowKeyNavigationType, DropdownMenu, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
11
+ import { ArrowKeyNavigationProvider, ArrowKeyNavigationType, DropdownMenu, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
12
12
  import { hexToEditorBorderPaletteColor } from '@atlaskit/editor-palette';
13
13
  import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
14
+ import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import Tooltip from '@atlaskit/tooltip';
15
- import { buttonStyle, buttonWrapperStyle, contextualMenuArrow, contextualMenuColorIcon, contextualSubMenu, itemSpacing, line, menuItemDimensions, toolbarButtonWrapper } from './styles';
16
+ import { buttonStyle, buttonWrapperStyle, contextualMenuArrow, contextualMenuColorIcon, contextualSubMenu, dropdownOptionButton, dropdownWrapper, itemSpacing, line, menuItemDimensions, toolbarButtonWrapper } from './styles';
16
17
  const ImageBorder = ({
17
18
  intl: {
18
19
  formatMessage
@@ -22,12 +23,30 @@ const ImageBorder = ({
22
23
  setBorder
23
24
  }) => {
24
25
  const popupTarget = useRef(null);
26
+ const dropDownColorOptionButton = useRef(null);
27
+ const dropDownSizeOptionButton = useRef(null);
28
+ const colorSubmenuRef = useRef(null);
29
+ const sizeSubmenuRef = useRef(null);
30
+ const openDropdownButtonRef = useRef(null);
25
31
  const enabled = !!borderMark;
26
32
  const color = borderMark === null || borderMark === void 0 ? void 0 : borderMark.color;
27
33
  const size = borderMark === null || borderMark === void 0 ? void 0 : borderMark.size;
28
34
  const [isOpen, setIsOpen] = useState(false);
35
+ const [isOpenByKeyboard, setIsOpenedByKeyboard] = useState(false);
29
36
  const [isColorSubmenuOpen, setIsColorSubmenuOpen] = useState(false);
30
37
  const [isSizeSubmenuOpen, setIsSizeSubmenuOpen] = useState(false);
38
+ const handleColorSubmenuEsc = useCallback(() => {
39
+ var _dropDownColorOptionB;
40
+ setIsOpenedByKeyboard(false);
41
+ setIsColorSubmenuOpen(false);
42
+ dropDownColorOptionButton === null || dropDownColorOptionButton === void 0 ? void 0 : (_dropDownColorOptionB = dropDownColorOptionButton.current) === null || _dropDownColorOptionB === void 0 ? void 0 : _dropDownColorOptionB.focus();
43
+ }, []);
44
+ const handleSizeSubmenuEsc = useCallback(() => {
45
+ var _dropDownSizeOptionBu;
46
+ setIsOpenedByKeyboard(false);
47
+ setIsSizeSubmenuOpen(false);
48
+ dropDownSizeOptionButton === null || dropDownSizeOptionButton === void 0 ? void 0 : (_dropDownSizeOptionBu = dropDownSizeOptionButton.current) === null || _dropDownSizeOptionBu === void 0 ? void 0 : _dropDownSizeOptionBu.focus();
49
+ }, []);
31
50
  const handleSubMenuRef = ref => {
32
51
  if (!ref) {
33
52
  return;
@@ -37,6 +56,38 @@ const ImageBorder = ({
37
56
  ref.style.left = `-${rect.width}px`;
38
57
  }
39
58
  };
59
+ const handleTriggerByKeyboard = (event, callback) => {
60
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
61
+ if (event.key === 'Enter' || event.key === ' ') {
62
+ event.preventDefault();
63
+ callback();
64
+ setIsOpenedByKeyboard(true);
65
+ }
66
+ }
67
+ };
68
+ useEffect(() => {
69
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
70
+ const focusFirstOption = (submenuRef, isOpen) => {
71
+ if (!isOpenByKeyboard) {
72
+ return;
73
+ }
74
+ if (isOpen && submenuRef.current) {
75
+ const firstOption = submenuRef.current.querySelector('button');
76
+ if (!firstOption) {
77
+ return;
78
+ }
79
+ firstOption.focus();
80
+ const keyboardEvent = new KeyboardEvent('keydown', {
81
+ key: 'ArrowDown',
82
+ bubbles: true
83
+ });
84
+ firstOption.dispatchEvent(keyboardEvent);
85
+ }
86
+ };
87
+ focusFirstOption(colorSubmenuRef, isColorSubmenuOpen);
88
+ focusFirstOption(sizeSubmenuRef, isSizeSubmenuOpen);
89
+ }
90
+ }, [isColorSubmenuOpen, isSizeSubmenuOpen, isOpenByKeyboard]);
40
91
  const borderSizeOptions = [{
41
92
  name: formatMessage(messages.borderSizeSubtle),
42
93
  value: 1
@@ -47,7 +98,144 @@ const ImageBorder = ({
47
98
  name: formatMessage(messages.borderSizeBold),
48
99
  value: 3
49
100
  }];
50
- const items = [{
101
+ const items = fg('platform-editor-a11y-image-border-options-dropdown') ? [{
102
+ content: jsx("div", null, jsx("button", {
103
+ ref: dropDownColorOptionButton,
104
+ type: "button",
105
+ "aria-label": "Image border options Color dropdown button",
106
+ "data-testid": "image-border-dropdown-button-color"
107
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
108
+ ,
109
+ css: [dropdownOptionButton],
110
+ "aria-expanded": isColorSubmenuOpen,
111
+ onKeyDown: e => handleTriggerByKeyboard(e, () => setIsColorSubmenuOpen(!isColorSubmenuOpen))
112
+ }, jsx("span", null, formatMessage(messages.borderColor)), jsx("div", {
113
+ css: contextualMenuColorIcon(color && hexToEditorBorderPaletteColor(color))
114
+ })), jsx("div", {
115
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
116
+ className: DropdownMenuSharedCssClassName.SUBMENU,
117
+ ref: colorSubmenuRef
118
+ }, isColorSubmenuOpen &&
119
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
120
+ jsx("div", {
121
+ css: contextualSubMenu(0),
122
+ ref: handleSubMenuRef
123
+ }, jsx(ArrowKeyNavigationProvider, {
124
+ type: ArrowKeyNavigationType.MENU,
125
+ handleClose: e => {
126
+ e.preventDefault();
127
+ e.stopPropagation();
128
+ handleColorSubmenuEsc();
129
+ },
130
+ disableCloseOnArrowClick: true
131
+ }, jsx(ColorPalette, {
132
+ onClick: color => {
133
+ setBorder({
134
+ color
135
+ });
136
+ setIsOpen(!isOpen);
137
+ },
138
+ onKeyDown: (color, _, event) => {
139
+ if (event.key === 'Enter' || event.key === ' ') {
140
+ var _openDropdownButtonRe;
141
+ setBorder({
142
+ color
143
+ });
144
+ setIsOpen(!isOpen);
145
+ setIsColorSubmenuOpen(false);
146
+ setIsSizeSubmenuOpen(false);
147
+ (_openDropdownButtonRe = openDropdownButtonRef.current) === null || _openDropdownButtonRe === void 0 ? void 0 : _openDropdownButtonRe.focus();
148
+ }
149
+ },
150
+ selectedColor: color !== null && color !== void 0 ? color : null,
151
+ paletteOptions: {
152
+ palette: borderColorPalette,
153
+ paletteColorTooltipMessages: borderPaletteTooltipMessages,
154
+ hexToPaletteColor: hexToEditorBorderPaletteColor
155
+ }
156
+ }))))),
157
+ 'data-testid': 'dropdown-item__Color',
158
+ key: 'dropdown-menu-image-border-color-button',
159
+ value: {
160
+ name: 'color'
161
+ },
162
+ 'aria-label': '',
163
+ wrapperTabIndex: null
164
+ }, {
165
+ content: jsx("div", null, jsx("button", {
166
+ type: "button",
167
+ "aria-label": "Image border options Size dropdown button",
168
+ "data-testid": "image-border-dropdown-button-size"
169
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
170
+ ,
171
+ css: [dropdownOptionButton],
172
+ "aria-expanded": isSizeSubmenuOpen,
173
+ ref: dropDownSizeOptionButton,
174
+ onKeyDown: e => handleTriggerByKeyboard(e, () => setIsSizeSubmenuOpen(!isSizeSubmenuOpen))
175
+ }, jsx("span", null, formatMessage(messages.borderSize)), jsx("div", {
176
+ css: contextualMenuArrow
177
+ })), jsx("div", {
178
+ //eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
179
+ className: DropdownMenuSharedCssClassName.SUBMENU,
180
+ ref: sizeSubmenuRef
181
+ }, isSizeSubmenuOpen && jsx(ArrowKeyNavigationProvider, {
182
+ type: ArrowKeyNavigationType.MENU,
183
+ handleClose: e => {
184
+ e.preventDefault();
185
+ handleSizeSubmenuEsc();
186
+ },
187
+ disableCloseOnArrowClick: true
188
+ }, jsx("div", {
189
+ css: contextualSubMenu(1),
190
+ ref: handleSubMenuRef
191
+ }, borderSizeOptions.map(({
192
+ name,
193
+ value
194
+ }, idx) => jsx(Tooltip, {
195
+ key: idx,
196
+ content: name
197
+ }, jsx("span", {
198
+ css: buttonWrapperStyle
199
+ }, jsx("button", {
200
+ type: "button"
201
+ /* eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */,
202
+ css: buttonStyle(value === size),
203
+ "aria-label": name,
204
+ role: "radio",
205
+ "aria-checked": value === size,
206
+ onClick: () => {
207
+ setBorder({
208
+ size: value
209
+ });
210
+ setIsOpen(false);
211
+ },
212
+ onKeyDown: event => {
213
+ if (event.key === 'Enter' || event.key === ' ') {
214
+ var _openDropdownButtonRe2;
215
+ setBorder({
216
+ size: value
217
+ });
218
+ setIsOpen(false);
219
+ setIsColorSubmenuOpen(false);
220
+ setIsSizeSubmenuOpen(false);
221
+ (_openDropdownButtonRe2 = openDropdownButtonRef.current) === null || _openDropdownButtonRe2 === void 0 ? void 0 : _openDropdownButtonRe2.focus();
222
+ }
223
+ },
224
+ onMouseDown: e => {
225
+ e.preventDefault();
226
+ }
227
+ }, jsx("div", {
228
+ css: line(value, value === size),
229
+ role: "presentation"
230
+ }))))))))),
231
+ 'data-testid': 'dropdown-item__Size',
232
+ key: 'dropdown-menu-image-border-size-button',
233
+ value: {
234
+ name: 'size'
235
+ },
236
+ 'aria-label': '',
237
+ wrapperTabIndex: null
238
+ }] : [{
51
239
  content: formatMessage(messages.borderColor),
52
240
  value: {
53
241
  name: 'color'
@@ -123,7 +311,6 @@ const ImageBorder = ({
123
311
  role: "presentation"
124
312
  })))))))
125
313
  }];
126
-
127
314
  /**
128
315
  * We want to change direction of our dropdowns a bit early,
129
316
  * not exactly when it hits the boundary.
@@ -131,6 +318,7 @@ const ImageBorder = ({
131
318
  const fitTolerance = 10;
132
319
  const fitWidth = menuItemDimensions.width;
133
320
  const fitHeight = items.length * (menuItemDimensions.height + itemSpacing);
321
+ const isAnySubMenuOpen = isSizeSubmenuOpen || isColorSubmenuOpen;
134
322
  return jsx("div", null, jsx("div", {
135
323
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
136
324
  css: toolbarButtonWrapper({
@@ -155,7 +343,9 @@ const ImageBorder = ({
155
343
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
156
344
  , {
157
345
  className: "image-border-toolbar-dropdown",
346
+ ref: openDropdownButtonRef,
158
347
  selected: enabled || isOpen,
348
+ "aria-expanded": fg('platform-editor-a11y-image-border-options-dropdown') ? isOpen : undefined,
159
349
  "aria-label": formatMessage(messages.borderOptions),
160
350
  title: formatMessage(messages.borderOptions),
161
351
  spacing: "compact",
@@ -164,7 +354,11 @@ const ImageBorder = ({
164
354
  }),
165
355
  onClick: () => {
166
356
  setIsOpen(!isOpen);
167
- }
357
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
358
+ setIsOpenedByKeyboard(false);
359
+ }
360
+ },
361
+ onKeyDown: fg('platform-editor-a11y-image-border-options-dropdown') ? e => handleTriggerByKeyboard(e, () => setIsOpen(!isOpen)) : undefined
168
362
  }))), jsx(Popup, {
169
363
  target: popupTarget.current ? popupTarget.current : undefined,
170
364
  fitWidth: fitWidth + fitTolerance,
@@ -175,7 +369,9 @@ const ImageBorder = ({
175
369
  onMouseLeave: () => {
176
370
  setIsColorSubmenuOpen(false);
177
371
  setIsSizeSubmenuOpen(false);
178
- }
372
+ },
373
+ css: fg('platform-editor-a11y-image-border-options-dropdown') ? /* eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
374
+ dropdownWrapper : undefined
179
375
  }, jsx(DropdownMenu
180
376
  //This needs be removed when the a11y is completely handled
181
377
  //Disabling key navigation now as it works only partially
@@ -183,16 +379,27 @@ const ImageBorder = ({
183
379
  , {
184
380
  arrowKeyNavigationProviderOptions: {
185
381
  type: ArrowKeyNavigationType.MENU,
186
- disableArrowKeyNavigation: true
382
+ disableArrowKeyNavigation: fg('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? true : false : true
187
383
  },
384
+ allowEnterDefaultBehavior: fg('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? true : false : undefined,
385
+ handleEscapeKeydown: fg('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? () => {
386
+ return;
387
+ } : () => {
388
+ var _openDropdownButtonRe3;
389
+ (_openDropdownButtonRe3 = openDropdownButtonRef.current) === null || _openDropdownButtonRe3 === void 0 ? void 0 : _openDropdownButtonRe3.focus();
390
+ } : undefined,
188
391
  items: [{
189
392
  items
190
393
  }],
191
394
  isOpen: isOpen,
395
+ shouldFocusFirstItem: fg('platform-editor-a11y-image-border-options-dropdown') ? () => isOpenByKeyboard : undefined,
192
396
  onOpenChange: () => {
193
397
  setIsOpen(false);
194
398
  setIsColorSubmenuOpen(false);
195
399
  setIsSizeSubmenuOpen(false);
400
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
401
+ setIsOpenedByKeyboard(false);
402
+ }
196
403
  },
197
404
  onItemActivated: ({
198
405
  item
@@ -209,9 +416,15 @@ const ImageBorder = ({
209
416
  }) => {
210
417
  if (item.value.name === 'color') {
211
418
  setIsColorSubmenuOpen(true);
419
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
420
+ setIsOpenedByKeyboard(false);
421
+ }
212
422
  }
213
423
  if (item.value.name === 'size') {
214
424
  setIsSizeSubmenuOpen(true);
425
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
426
+ setIsOpenedByKeyboard(false);
427
+ }
215
428
  }
216
429
  },
217
430
  onMouseLeave: ({
@@ -129,4 +129,27 @@ export const toolbarButtonWrapper = ({
129
129
 
130
130
  ${!enabled && getHoverStyles('.image-border-toolbar-btn')}
131
131
  ${!isOpen && !enabled && getHoverStyles('.image-border-toolbar-dropdown')}
132
+ `;
133
+
134
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
135
+ export const dropdownOptionButton = css`
136
+ background: transparent;
137
+ border: 2px solid transparent;
138
+ display: flex;
139
+ width: 100%;
140
+ align-items: center;
141
+ justify-content: space-between;
142
+ padding: 8px 16px;
143
+
144
+ &:focus {
145
+ background-color: ${"var(--ds-background-neutral-subtle-hovered, rgb(244, 245, 247))"};
146
+ border: 2px solid ${"var(--ds-border-focused, #2684FF)"};
147
+ }
148
+ `;
149
+
150
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
151
+ export const dropdownWrapper = css`
152
+ span[role='menuitem'] {
153
+ padding: 0;
154
+ }
132
155
  `;
@@ -1,6 +1,6 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  /** @jsx jsx */
3
- import { useRef, useState } from 'react';
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
4
 
5
5
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
6
6
  import { jsx } from '@emotion/react';
@@ -9,17 +9,23 @@ import { imageBorderMessages as messages } from '@atlaskit/editor-common/media';
9
9
  import { DropdownMenuSharedCssClassName } from '@atlaskit/editor-common/styles';
10
10
  import { Popup } from '@atlaskit/editor-common/ui';
11
11
  import { borderColorPalette, borderPaletteTooltipMessages, ColorPalette } from '@atlaskit/editor-common/ui-color';
12
- import { ArrowKeyNavigationType, DropdownMenu, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
12
+ import { ArrowKeyNavigationProvider, ArrowKeyNavigationType, DropdownMenu, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
13
13
  import { hexToEditorBorderPaletteColor } from '@atlaskit/editor-palette';
14
14
  import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
15
+ import { fg } from '@atlaskit/platform-feature-flags';
15
16
  import Tooltip from '@atlaskit/tooltip';
16
- import { buttonStyle, buttonWrapperStyle, contextualMenuArrow, contextualMenuColorIcon, contextualSubMenu, itemSpacing, line, menuItemDimensions, toolbarButtonWrapper } from './styles';
17
+ import { buttonStyle, buttonWrapperStyle, contextualMenuArrow, contextualMenuColorIcon, contextualSubMenu, dropdownOptionButton, dropdownWrapper, itemSpacing, line, menuItemDimensions, toolbarButtonWrapper } from './styles';
17
18
  var ImageBorder = function ImageBorder(_ref) {
18
19
  var formatMessage = _ref.intl.formatMessage,
19
20
  toggleBorder = _ref.toggleBorder,
20
21
  borderMark = _ref.borderMark,
21
22
  setBorder = _ref.setBorder;
22
23
  var popupTarget = useRef(null);
24
+ var dropDownColorOptionButton = useRef(null);
25
+ var dropDownSizeOptionButton = useRef(null);
26
+ var colorSubmenuRef = useRef(null);
27
+ var sizeSubmenuRef = useRef(null);
28
+ var openDropdownButtonRef = useRef(null);
23
29
  var enabled = !!borderMark;
24
30
  var color = borderMark === null || borderMark === void 0 ? void 0 : borderMark.color;
25
31
  var size = borderMark === null || borderMark === void 0 ? void 0 : borderMark.size;
@@ -29,12 +35,28 @@ var ImageBorder = function ImageBorder(_ref) {
29
35
  setIsOpen = _useState2[1];
30
36
  var _useState3 = useState(false),
31
37
  _useState4 = _slicedToArray(_useState3, 2),
32
- isColorSubmenuOpen = _useState4[0],
33
- setIsColorSubmenuOpen = _useState4[1];
38
+ isOpenByKeyboard = _useState4[0],
39
+ setIsOpenedByKeyboard = _useState4[1];
34
40
  var _useState5 = useState(false),
35
41
  _useState6 = _slicedToArray(_useState5, 2),
36
- isSizeSubmenuOpen = _useState6[0],
37
- setIsSizeSubmenuOpen = _useState6[1];
42
+ isColorSubmenuOpen = _useState6[0],
43
+ setIsColorSubmenuOpen = _useState6[1];
44
+ var _useState7 = useState(false),
45
+ _useState8 = _slicedToArray(_useState7, 2),
46
+ isSizeSubmenuOpen = _useState8[0],
47
+ setIsSizeSubmenuOpen = _useState8[1];
48
+ var handleColorSubmenuEsc = useCallback(function () {
49
+ var _dropDownColorOptionB;
50
+ setIsOpenedByKeyboard(false);
51
+ setIsColorSubmenuOpen(false);
52
+ dropDownColorOptionButton === null || dropDownColorOptionButton === void 0 || (_dropDownColorOptionB = dropDownColorOptionButton.current) === null || _dropDownColorOptionB === void 0 || _dropDownColorOptionB.focus();
53
+ }, []);
54
+ var handleSizeSubmenuEsc = useCallback(function () {
55
+ var _dropDownSizeOptionBu;
56
+ setIsOpenedByKeyboard(false);
57
+ setIsSizeSubmenuOpen(false);
58
+ dropDownSizeOptionButton === null || dropDownSizeOptionButton === void 0 || (_dropDownSizeOptionBu = dropDownSizeOptionButton.current) === null || _dropDownSizeOptionBu === void 0 || _dropDownSizeOptionBu.focus();
59
+ }, []);
38
60
  var handleSubMenuRef = function handleSubMenuRef(ref) {
39
61
  if (!ref) {
40
62
  return;
@@ -44,6 +66,38 @@ var ImageBorder = function ImageBorder(_ref) {
44
66
  ref.style.left = "-".concat(rect.width, "px");
45
67
  }
46
68
  };
69
+ var handleTriggerByKeyboard = function handleTriggerByKeyboard(event, callback) {
70
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
71
+ if (event.key === 'Enter' || event.key === ' ') {
72
+ event.preventDefault();
73
+ callback();
74
+ setIsOpenedByKeyboard(true);
75
+ }
76
+ }
77
+ };
78
+ useEffect(function () {
79
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
80
+ var focusFirstOption = function focusFirstOption(submenuRef, isOpen) {
81
+ if (!isOpenByKeyboard) {
82
+ return;
83
+ }
84
+ if (isOpen && submenuRef.current) {
85
+ var firstOption = submenuRef.current.querySelector('button');
86
+ if (!firstOption) {
87
+ return;
88
+ }
89
+ firstOption.focus();
90
+ var keyboardEvent = new KeyboardEvent('keydown', {
91
+ key: 'ArrowDown',
92
+ bubbles: true
93
+ });
94
+ firstOption.dispatchEvent(keyboardEvent);
95
+ }
96
+ };
97
+ focusFirstOption(colorSubmenuRef, isColorSubmenuOpen);
98
+ focusFirstOption(sizeSubmenuRef, isSizeSubmenuOpen);
99
+ }
100
+ }, [isColorSubmenuOpen, isSizeSubmenuOpen, isOpenByKeyboard]);
47
101
  var borderSizeOptions = [{
48
102
  name: formatMessage(messages.borderSizeSubtle),
49
103
  value: 1
@@ -54,7 +108,153 @@ var ImageBorder = function ImageBorder(_ref) {
54
108
  name: formatMessage(messages.borderSizeBold),
55
109
  value: 3
56
110
  }];
57
- var items = [{
111
+ var items = fg('platform-editor-a11y-image-border-options-dropdown') ? [{
112
+ content: jsx("div", null, jsx("button", {
113
+ ref: dropDownColorOptionButton,
114
+ type: "button",
115
+ "aria-label": "Image border options Color dropdown button",
116
+ "data-testid": "image-border-dropdown-button-color"
117
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
118
+ ,
119
+ css: [dropdownOptionButton],
120
+ "aria-expanded": isColorSubmenuOpen,
121
+ onKeyDown: function onKeyDown(e) {
122
+ return handleTriggerByKeyboard(e, function () {
123
+ return setIsColorSubmenuOpen(!isColorSubmenuOpen);
124
+ });
125
+ }
126
+ }, jsx("span", null, formatMessage(messages.borderColor)), jsx("div", {
127
+ css: contextualMenuColorIcon(color && hexToEditorBorderPaletteColor(color))
128
+ })), jsx("div", {
129
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
130
+ className: DropdownMenuSharedCssClassName.SUBMENU,
131
+ ref: colorSubmenuRef
132
+ }, isColorSubmenuOpen &&
133
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
134
+ jsx("div", {
135
+ css: contextualSubMenu(0),
136
+ ref: handleSubMenuRef
137
+ }, jsx(ArrowKeyNavigationProvider, {
138
+ type: ArrowKeyNavigationType.MENU,
139
+ handleClose: function handleClose(e) {
140
+ e.preventDefault();
141
+ e.stopPropagation();
142
+ handleColorSubmenuEsc();
143
+ },
144
+ disableCloseOnArrowClick: true
145
+ }, jsx(ColorPalette, {
146
+ onClick: function onClick(color) {
147
+ setBorder({
148
+ color: color
149
+ });
150
+ setIsOpen(!isOpen);
151
+ },
152
+ onKeyDown: function onKeyDown(color, _, event) {
153
+ if (event.key === 'Enter' || event.key === ' ') {
154
+ var _openDropdownButtonRe;
155
+ setBorder({
156
+ color: color
157
+ });
158
+ setIsOpen(!isOpen);
159
+ setIsColorSubmenuOpen(false);
160
+ setIsSizeSubmenuOpen(false);
161
+ (_openDropdownButtonRe = openDropdownButtonRef.current) === null || _openDropdownButtonRe === void 0 || _openDropdownButtonRe.focus();
162
+ }
163
+ },
164
+ selectedColor: color !== null && color !== void 0 ? color : null,
165
+ paletteOptions: {
166
+ palette: borderColorPalette,
167
+ paletteColorTooltipMessages: borderPaletteTooltipMessages,
168
+ hexToPaletteColor: hexToEditorBorderPaletteColor
169
+ }
170
+ }))))),
171
+ 'data-testid': 'dropdown-item__Color',
172
+ key: 'dropdown-menu-image-border-color-button',
173
+ value: {
174
+ name: 'color'
175
+ },
176
+ 'aria-label': '',
177
+ wrapperTabIndex: null
178
+ }, {
179
+ content: jsx("div", null, jsx("button", {
180
+ type: "button",
181
+ "aria-label": "Image border options Size dropdown button",
182
+ "data-testid": "image-border-dropdown-button-size"
183
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
184
+ ,
185
+ css: [dropdownOptionButton],
186
+ "aria-expanded": isSizeSubmenuOpen,
187
+ ref: dropDownSizeOptionButton,
188
+ onKeyDown: function onKeyDown(e) {
189
+ return handleTriggerByKeyboard(e, function () {
190
+ return setIsSizeSubmenuOpen(!isSizeSubmenuOpen);
191
+ });
192
+ }
193
+ }, jsx("span", null, formatMessage(messages.borderSize)), jsx("div", {
194
+ css: contextualMenuArrow
195
+ })), jsx("div", {
196
+ //eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
197
+ className: DropdownMenuSharedCssClassName.SUBMENU,
198
+ ref: sizeSubmenuRef
199
+ }, isSizeSubmenuOpen && jsx(ArrowKeyNavigationProvider, {
200
+ type: ArrowKeyNavigationType.MENU,
201
+ handleClose: function handleClose(e) {
202
+ e.preventDefault();
203
+ handleSizeSubmenuEsc();
204
+ },
205
+ disableCloseOnArrowClick: true
206
+ }, jsx("div", {
207
+ css: contextualSubMenu(1),
208
+ ref: handleSubMenuRef
209
+ }, borderSizeOptions.map(function (_ref2, idx) {
210
+ var name = _ref2.name,
211
+ value = _ref2.value;
212
+ return jsx(Tooltip, {
213
+ key: idx,
214
+ content: name
215
+ }, jsx("span", {
216
+ css: buttonWrapperStyle
217
+ }, jsx("button", {
218
+ type: "button"
219
+ /* eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */,
220
+ css: buttonStyle(value === size),
221
+ "aria-label": name,
222
+ role: "radio",
223
+ "aria-checked": value === size,
224
+ onClick: function onClick() {
225
+ setBorder({
226
+ size: value
227
+ });
228
+ setIsOpen(false);
229
+ },
230
+ onKeyDown: function onKeyDown(event) {
231
+ if (event.key === 'Enter' || event.key === ' ') {
232
+ var _openDropdownButtonRe2;
233
+ setBorder({
234
+ size: value
235
+ });
236
+ setIsOpen(false);
237
+ setIsColorSubmenuOpen(false);
238
+ setIsSizeSubmenuOpen(false);
239
+ (_openDropdownButtonRe2 = openDropdownButtonRef.current) === null || _openDropdownButtonRe2 === void 0 || _openDropdownButtonRe2.focus();
240
+ }
241
+ },
242
+ onMouseDown: function onMouseDown(e) {
243
+ e.preventDefault();
244
+ }
245
+ }, jsx("div", {
246
+ css: line(value, value === size),
247
+ role: "presentation"
248
+ }))));
249
+ }))))),
250
+ 'data-testid': 'dropdown-item__Size',
251
+ key: 'dropdown-menu-image-border-size-button',
252
+ value: {
253
+ name: 'size'
254
+ },
255
+ 'aria-label': '',
256
+ wrapperTabIndex: null
257
+ }] : [{
58
258
  content: formatMessage(messages.borderColor),
59
259
  value: {
60
260
  name: 'color'
@@ -100,9 +300,9 @@ var ImageBorder = function ImageBorder(_ref) {
100
300
  jsx("div", {
101
301
  css: contextualSubMenu(1),
102
302
  ref: handleSubMenuRef
103
- }, borderSizeOptions.map(function (_ref2, idx) {
104
- var name = _ref2.name,
105
- value = _ref2.value;
303
+ }, borderSizeOptions.map(function (_ref3, idx) {
304
+ var name = _ref3.name,
305
+ value = _ref3.value;
106
306
  return jsx(Tooltip, {
107
307
  key: idx,
108
308
  content: name
@@ -131,7 +331,6 @@ var ImageBorder = function ImageBorder(_ref) {
131
331
  }))));
132
332
  })))
133
333
  }];
134
-
135
334
  /**
136
335
  * We want to change direction of our dropdowns a bit early,
137
336
  * not exactly when it hits the boundary.
@@ -139,6 +338,7 @@ var ImageBorder = function ImageBorder(_ref) {
139
338
  var fitTolerance = 10;
140
339
  var fitWidth = menuItemDimensions.width;
141
340
  var fitHeight = items.length * (menuItemDimensions.height + itemSpacing);
341
+ var isAnySubMenuOpen = isSizeSubmenuOpen || isColorSubmenuOpen;
142
342
  return jsx("div", null, jsx("div", {
143
343
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
144
344
  css: toolbarButtonWrapper({
@@ -163,7 +363,9 @@ var ImageBorder = function ImageBorder(_ref) {
163
363
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
164
364
  , {
165
365
  className: "image-border-toolbar-dropdown",
366
+ ref: openDropdownButtonRef,
166
367
  selected: enabled || isOpen,
368
+ "aria-expanded": fg('platform-editor-a11y-image-border-options-dropdown') ? isOpen : undefined,
167
369
  "aria-label": formatMessage(messages.borderOptions),
168
370
  title: formatMessage(messages.borderOptions),
169
371
  spacing: "compact",
@@ -172,7 +374,15 @@ var ImageBorder = function ImageBorder(_ref) {
172
374
  }),
173
375
  onClick: function onClick() {
174
376
  setIsOpen(!isOpen);
175
- }
377
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
378
+ setIsOpenedByKeyboard(false);
379
+ }
380
+ },
381
+ onKeyDown: fg('platform-editor-a11y-image-border-options-dropdown') ? function (e) {
382
+ return handleTriggerByKeyboard(e, function () {
383
+ return setIsOpen(!isOpen);
384
+ });
385
+ } : undefined
176
386
  }))), jsx(Popup, {
177
387
  target: popupTarget.current ? popupTarget.current : undefined,
178
388
  fitWidth: fitWidth + fitTolerance,
@@ -183,7 +393,9 @@ var ImageBorder = function ImageBorder(_ref) {
183
393
  onMouseLeave: function onMouseLeave() {
184
394
  setIsColorSubmenuOpen(false);
185
395
  setIsSizeSubmenuOpen(false);
186
- }
396
+ },
397
+ css: fg('platform-editor-a11y-image-border-options-dropdown') ? /* eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
398
+ dropdownWrapper : undefined
187
399
  }, jsx(DropdownMenu
188
400
  //This needs be removed when the a11y is completely handled
189
401
  //Disabling key navigation now as it works only partially
@@ -191,19 +403,32 @@ var ImageBorder = function ImageBorder(_ref) {
191
403
  , {
192
404
  arrowKeyNavigationProviderOptions: {
193
405
  type: ArrowKeyNavigationType.MENU,
194
- disableArrowKeyNavigation: true
406
+ disableArrowKeyNavigation: fg('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? true : false : true
195
407
  },
408
+ allowEnterDefaultBehavior: fg('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? true : false : undefined,
409
+ handleEscapeKeydown: fg('platform-editor-a11y-image-border-options-dropdown') ? isAnySubMenuOpen ? function () {
410
+ return;
411
+ } : function () {
412
+ var _openDropdownButtonRe3;
413
+ (_openDropdownButtonRe3 = openDropdownButtonRef.current) === null || _openDropdownButtonRe3 === void 0 || _openDropdownButtonRe3.focus();
414
+ } : undefined,
196
415
  items: [{
197
416
  items: items
198
417
  }],
199
418
  isOpen: isOpen,
419
+ shouldFocusFirstItem: fg('platform-editor-a11y-image-border-options-dropdown') ? function () {
420
+ return isOpenByKeyboard;
421
+ } : undefined,
200
422
  onOpenChange: function onOpenChange() {
201
423
  setIsOpen(false);
202
424
  setIsColorSubmenuOpen(false);
203
425
  setIsSizeSubmenuOpen(false);
426
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
427
+ setIsOpenedByKeyboard(false);
428
+ }
204
429
  },
205
- onItemActivated: function onItemActivated(_ref3) {
206
- var item = _ref3.item;
430
+ onItemActivated: function onItemActivated(_ref4) {
431
+ var item = _ref4.item;
207
432
  if (item.value.name === 'color') {
208
433
  setIsColorSubmenuOpen(!isColorSubmenuOpen);
209
434
  }
@@ -211,17 +436,23 @@ var ImageBorder = function ImageBorder(_ref) {
211
436
  setIsSizeSubmenuOpen(!isSizeSubmenuOpen);
212
437
  }
213
438
  },
214
- onMouseEnter: function onMouseEnter(_ref4) {
215
- var item = _ref4.item;
439
+ onMouseEnter: function onMouseEnter(_ref5) {
440
+ var item = _ref5.item;
216
441
  if (item.value.name === 'color') {
217
442
  setIsColorSubmenuOpen(true);
443
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
444
+ setIsOpenedByKeyboard(false);
445
+ }
218
446
  }
219
447
  if (item.value.name === 'size') {
220
448
  setIsSizeSubmenuOpen(true);
449
+ if (fg('platform-editor-a11y-image-border-options-dropdown')) {
450
+ setIsOpenedByKeyboard(false);
451
+ }
221
452
  }
222
453
  },
223
- onMouseLeave: function onMouseLeave(_ref5) {
224
- var item = _ref5.item;
454
+ onMouseLeave: function onMouseLeave(_ref6) {
455
+ var item = _ref6.item;
225
456
  if (item.value.name === 'color') {
226
457
  setIsColorSubmenuOpen(false);
227
458
  }
@@ -1,5 +1,5 @@
1
1
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
2
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9;
3
3
  /* eslint-disable @atlaskit/design-system/no-css-tagged-template-expression -- Needs manual remediation*/
4
4
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
5
5
  import { css } from '@emotion/react';
@@ -45,4 +45,10 @@ export var toolbarButtonWrapper = function toolbarButtonWrapper(_ref) {
45
45
  var enabled = _ref.enabled,
46
46
  isOpen = _ref.isOpen;
47
47
  return css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n\tdisplay: flex;\n\t.image-border-toolbar-btn {\n\t\tborder-top-right-radius: 0;\n\t\tborder-bottom-right-radius: 0;\n\t\tpadding: 0;\n\t\t& > span {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n\t.image-border-toolbar-dropdown {\n\t\tpadding: 0;\n\t\t& > span {\n\t\t\tmargin: 0;\n\t\t}\n\t\twidth: 16px !important;\n\t\tborder-top-left-radius: 0 !important;\n\t\tborder-bottom-left-radius: 0 !important;\n\t\tmargin-left: ", ";\n\t}\n\n\t", "\n\t", "\n"])), "var(--ds-space-025, 2px)", !enabled && getHoverStyles('.image-border-toolbar-btn'), !isOpen && !enabled && getHoverStyles('.image-border-toolbar-dropdown'));
48
- };
48
+ };
49
+
50
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
51
+ export var dropdownOptionButton = css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n\tbackground: transparent;\n\tborder: 2px solid transparent;\n\tdisplay: flex;\n\twidth: 100%;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 8px 16px;\n\n\t&:focus {\n\t\tbackground-color: ", ";\n\t\tborder: 2px solid ", ";\n\t}\n"])), "var(--ds-background-neutral-subtle-hovered, rgb(244, 245, 247))", "var(--ds-border-focused, #2684FF)");
52
+
53
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
54
+ export var dropdownWrapper = css(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n\tspan[role='menuitem'] {\n\t\tpadding: 0;\n\t}\n"])));
@@ -13,3 +13,5 @@ export declare const toolbarButtonWrapper: ({ enabled, isOpen, }: {
13
13
  enabled: boolean;
14
14
  isOpen: boolean;
15
15
  }) => import("@emotion/react").SerializedStyles;
16
+ export declare const dropdownOptionButton: import("@emotion/react").SerializedStyles;
17
+ export declare const dropdownWrapper: import("@emotion/react").SerializedStyles;
@@ -13,3 +13,5 @@ export declare const toolbarButtonWrapper: ({ enabled, isOpen, }: {
13
13
  enabled: boolean;
14
14
  isOpen: boolean;
15
15
  }) => import("@emotion/react").SerializedStyles;
16
+ export declare const dropdownOptionButton: import("@emotion/react").SerializedStyles;
17
+ export declare const dropdownWrapper: import("@emotion/react").SerializedStyles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "1.24.0",
3
+ "version": "1.24.2",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -37,10 +37,10 @@
37
37
  "@atlaskit/analytics-namespaced-context": "^6.10.0",
38
38
  "@atlaskit/analytics-next": "^9.3.0",
39
39
  "@atlaskit/button": "^18.4.0",
40
- "@atlaskit/editor-common": "^85.0.0",
40
+ "@atlaskit/editor-common": "^86.0.0",
41
41
  "@atlaskit/editor-palette": "1.6.0",
42
42
  "@atlaskit/editor-plugin-analytics": "^1.4.0",
43
- "@atlaskit/editor-plugin-annotation": "1.15.0",
43
+ "@atlaskit/editor-plugin-annotation": "1.15.1",
44
44
  "@atlaskit/editor-plugin-decorations": "^1.1.0",
45
45
  "@atlaskit/editor-plugin-editor-disabled": "^1.1.0",
46
46
  "@atlaskit/editor-plugin-editor-viewmode": "^2.0.0",
@@ -67,7 +67,7 @@
67
67
  "@atlaskit/primitives": "^11.0.0",
68
68
  "@atlaskit/textfield": "^6.4.0",
69
69
  "@atlaskit/theme": "^12.11.0",
70
- "@atlaskit/tokens": "^1.54.0",
70
+ "@atlaskit/tokens": "^1.55.0",
71
71
  "@atlaskit/tooltip": "^18.5.0",
72
72
  "@babel/runtime": "^7.0.0",
73
73
  "@emotion/react": "^11.7.1",
@@ -146,6 +146,9 @@
146
146
  },
147
147
  "platform_editor_media_provider_from_plugin_config": {
148
148
  "type": "boolean"
149
+ },
150
+ "platform-editor-a11y-image-border-options-dropdown": {
151
+ "type": "boolean"
149
152
  }
150
153
  },
151
154
  "stricter": {