@atlaskit/editor-plugin-table 7.18.1 → 7.18.3
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 +14 -0
- package/dist/cjs/commands/index.js +6 -0
- package/dist/cjs/commands/misc.js +15 -1
- package/dist/cjs/plugin.js +7 -4
- package/dist/cjs/pm-plugins/keymap.js +3 -0
- package/dist/cjs/reducer.js +1 -0
- package/dist/cjs/ui/FloatingContextualButton/index.js +18 -2
- package/dist/cjs/ui/FloatingContextualMenu/ContextualMenu.js +170 -35
- package/dist/cjs/ui/FloatingContextualMenu/index.js +4 -2
- package/dist/es2019/commands/index.js +1 -1
- package/dist/es2019/commands/misc.js +9 -1
- package/dist/es2019/plugin.js +7 -4
- package/dist/es2019/pm-plugins/keymap.js +5 -2
- package/dist/es2019/reducer.js +1 -0
- package/dist/es2019/ui/FloatingContextualButton/index.js +17 -2
- package/dist/es2019/ui/FloatingContextualMenu/ContextualMenu.js +159 -24
- package/dist/es2019/ui/FloatingContextualMenu/index.js +4 -2
- package/dist/esm/commands/index.js +1 -1
- package/dist/esm/commands/misc.js +14 -0
- package/dist/esm/plugin.js +7 -4
- package/dist/esm/pm-plugins/keymap.js +5 -2
- package/dist/esm/reducer.js +1 -0
- package/dist/esm/ui/FloatingContextualButton/index.js +15 -2
- package/dist/esm/ui/FloatingContextualMenu/ContextualMenu.js +171 -40
- package/dist/esm/ui/FloatingContextualMenu/index.js +4 -2
- package/dist/types/commands/index.d.ts +1 -1
- package/dist/types/commands/misc.d.ts +1 -0
- package/dist/types/types.d.ts +6 -0
- package/dist/types/ui/FloatingContextualButton/index.d.ts +1 -0
- package/dist/types/ui/FloatingContextualMenu/ContextualMenu.d.ts +7 -3
- package/dist/types/ui/FloatingContextualMenu/index.d.ts +2 -1
- package/dist/types-ts4.5/commands/index.d.ts +1 -1
- package/dist/types-ts4.5/commands/misc.d.ts +1 -0
- package/dist/types-ts4.5/types.d.ts +6 -0
- package/dist/types-ts4.5/ui/FloatingContextualButton/index.d.ts +1 -0
- package/dist/types-ts4.5/ui/FloatingContextualMenu/ContextualMenu.d.ts +7 -3
- package/dist/types-ts4.5/ui/FloatingContextualMenu/index.d.ts +2 -1
- package/package.json +6 -3
- package/src/commands/index.ts +1 -0
- package/src/commands/misc.ts +13 -0
- package/src/plugin.tsx +6 -1
- package/src/pm-plugins/keymap.ts +6 -1
- package/src/reducer.ts +1 -0
- package/src/types.ts +27 -20
- package/src/ui/FloatingContextualButton/index.tsx +19 -1
- package/src/ui/FloatingContextualMenu/ContextualMenu.tsx +209 -30
- package/src/ui/FloatingContextualMenu/index.tsx +3 -0
package/dist/es2019/reducer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useEffect } 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';
|
|
@@ -12,6 +12,7 @@ import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
|
12
12
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
13
13
|
import { akEditorSmallZIndex } from '@atlaskit/editor-shared-styles';
|
|
14
14
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
15
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
15
16
|
import { toggleContextualMenu } from '../../commands';
|
|
16
17
|
import { TableCssClassName as ClassName } from '../../types';
|
|
17
18
|
import FixedButton from './FixedButton';
|
|
@@ -26,6 +27,7 @@ const FloatingContextualButtonInner = /*#__PURE__*/React.memo(props => {
|
|
|
26
27
|
stickyHeader,
|
|
27
28
|
tableWrapper,
|
|
28
29
|
targetCellPosition,
|
|
30
|
+
isCellMenuOpenByKeyboard,
|
|
29
31
|
intl: {
|
|
30
32
|
formatMessage
|
|
31
33
|
}
|
|
@@ -48,6 +50,18 @@ const FloatingContextualButtonInner = /*#__PURE__*/React.memo(props => {
|
|
|
48
50
|
const domAtPos = editorView.domAtPos.bind(editorView);
|
|
49
51
|
let targetCellRef;
|
|
50
52
|
targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
55
|
+
if (isCellMenuOpenByKeyboard && !isContextualMenuOpen) {
|
|
56
|
+
const {
|
|
57
|
+
state,
|
|
58
|
+
dispatch
|
|
59
|
+
} = editorView;
|
|
60
|
+
// open the menu when the keyboard shortcut is pressed
|
|
61
|
+
toggleContextualMenu()(state, dispatch);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, [isCellMenuOpenByKeyboard, isContextualMenuOpen, editorView]);
|
|
51
65
|
if (!targetCellRef || !(targetCellRef instanceof HTMLElement)) {
|
|
52
66
|
return null;
|
|
53
67
|
}
|
|
@@ -68,7 +82,8 @@ const FloatingContextualButtonInner = /*#__PURE__*/React.memo(props => {
|
|
|
68
82
|
iconBefore: jsx(ExpandIcon, {
|
|
69
83
|
label: ""
|
|
70
84
|
}),
|
|
71
|
-
"aria-label": labelCellOptions
|
|
85
|
+
"aria-label": labelCellOptions,
|
|
86
|
+
"aria-expanded": getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') ? isContextualMenuOpen : undefined
|
|
72
87
|
}));
|
|
73
88
|
const parentSticky = targetCellRef.parentElement && targetCellRef.parentElement.className.indexOf('sticky') > -1;
|
|
74
89
|
if (stickyHeader && parentSticky && tableWrapper) {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
3
3
|
/** @jsx jsx */
|
|
4
|
-
import { Component } from 'react';
|
|
5
|
-
|
|
4
|
+
import React, { Component } from 'react';
|
|
6
5
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
7
6
|
import { jsx } from '@emotion/react';
|
|
8
7
|
import { injectIntl } from 'react-intl-next';
|
|
@@ -11,8 +10,8 @@ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
|
11
10
|
import { addColumnAfter, addRowAfter, backspace, tooltip } from '@atlaskit/editor-common/keymaps';
|
|
12
11
|
import { tableMessages as messages } from '@atlaskit/editor-common/messages';
|
|
13
12
|
import { DropdownMenuSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
14
|
-
import { backgroundPaletteTooltipMessages, cellBackgroundColorPalette, ColorPalette } from '@atlaskit/editor-common/ui-color';
|
|
15
|
-
import { ArrowKeyNavigationType, DropdownMenu } from '@atlaskit/editor-common/ui-menu';
|
|
13
|
+
import { backgroundPaletteTooltipMessages, cellBackgroundColorPalette, ColorPalette, getSelectedRowAndColumnFromPalette } from '@atlaskit/editor-common/ui-color';
|
|
14
|
+
import { ArrowKeyNavigationProvider, ArrowKeyNavigationType, DropdownMenu } from '@atlaskit/editor-common/ui-menu';
|
|
16
15
|
import { closestElement } from '@atlaskit/editor-common/utils';
|
|
17
16
|
import { hexToEditorBackgroundPaletteColor } from '@atlaskit/editor-palette';
|
|
18
17
|
import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
|
|
@@ -21,22 +20,26 @@ import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
|
|
|
21
20
|
import EditorBackgroundColorIcon from '@atlaskit/icon/glyph/editor/background-color';
|
|
22
21
|
import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
|
|
23
22
|
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
24
|
-
import { clearHoverSelection, hoverColumns, hoverMergedCells, hoverRows, toggleContextualMenu } from '../../commands';
|
|
23
|
+
import { clearHoverSelection, hoverColumns, hoverMergedCells, hoverRows, setFocusToCellMenu, toggleContextualMenu } from '../../commands';
|
|
25
24
|
import { deleteColumnsWithAnalytics, deleteRowsWithAnalytics, distributeColumnsWidthsWithAnalytics, emptyMultipleCellsWithAnalytics, insertColumnWithAnalytics, insertRowWithAnalytics, mergeCellsWithAnalytics, setColorWithAnalytics, sortColumnWithAnalytics, splitCellWithAnalytics } from '../../commands-with-analytics';
|
|
26
25
|
import { getPluginState } from '../../pm-plugins/plugin-factory';
|
|
26
|
+
import { pluginKey as tablePluginKey } from '../../pm-plugins/plugin-key';
|
|
27
27
|
import { getNewResizeStateFromSelectedColumns } from '../../pm-plugins/table-resizing/utils/resize-state';
|
|
28
28
|
import { canMergeCells } from '../../transforms';
|
|
29
29
|
import { TableCssClassName as ClassName } from '../../types';
|
|
30
30
|
import { getMergedCellsPositions, getSelectedColumnIndexes, getSelectedRowIndexes } from '../../utils';
|
|
31
|
-
import { contextualMenuDropdownWidth, contextualMenuDropdownWidthDnD } from '../consts';
|
|
31
|
+
import { colorPalletteColumns, contextualMenuDropdownWidth, contextualMenuDropdownWidthDnD } from '../consts';
|
|
32
32
|
import { AddColRightIcon, AddRowBelowIcon, MergeCellsIcon, SplitCellIcon } from '../icons';
|
|
33
33
|
import { cellColourPreviewStyles, elementBeforeIconStyles } from './styles';
|
|
34
|
+
const arrowsList = new Set(['ArrowRight', 'ArrowLeft']);
|
|
34
35
|
export class ContextualMenu extends Component {
|
|
35
36
|
constructor(...args) {
|
|
36
37
|
super(...args);
|
|
37
38
|
_defineProperty(this, "state", {
|
|
38
|
-
isSubmenuOpen: false
|
|
39
|
+
isSubmenuOpen: false,
|
|
40
|
+
isOpenAllowed: false
|
|
39
41
|
});
|
|
42
|
+
_defineProperty(this, "dropdownMenuRef", /*#__PURE__*/React.createRef());
|
|
40
43
|
_defineProperty(this, "handleSubMenuRef", ref => {
|
|
41
44
|
const parent = closestElement(this.props.editorView.dom, '.fabric-editor-popup-scroll-parent');
|
|
42
45
|
if (!(parent && ref)) {
|
|
@@ -58,7 +61,8 @@ export class ContextualMenu extends Component {
|
|
|
58
61
|
intl: {
|
|
59
62
|
formatMessage
|
|
60
63
|
},
|
|
61
|
-
editorView
|
|
64
|
+
editorView,
|
|
65
|
+
isCellMenuOpenByKeyboard
|
|
62
66
|
} = this.props;
|
|
63
67
|
const {
|
|
64
68
|
isSubmenuOpen
|
|
@@ -68,9 +72,16 @@ export class ContextualMenu extends Component {
|
|
|
68
72
|
isDragAndDropEnabled
|
|
69
73
|
} = getPluginState(editorView.state);
|
|
70
74
|
if (allowBackgroundColor) {
|
|
71
|
-
var _node$attrs, _node$attrs2;
|
|
75
|
+
var _node$attrs, _node$attrs2, _node$attrs3;
|
|
72
76
|
const node = isOpen && targetCellPosition ? state.doc.nodeAt(targetCellPosition) : null;
|
|
73
77
|
const background = hexToEditorBackgroundPaletteColor((node === null || node === void 0 ? void 0 : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.background) || '#ffffff');
|
|
78
|
+
let selectedRowIndex;
|
|
79
|
+
let selectedColumnIndex;
|
|
80
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
81
|
+
const selectedRowAndColumnFromPalette = getSelectedRowAndColumnFromPalette(cellBackgroundColorPalette, background, colorPalletteColumns);
|
|
82
|
+
selectedRowIndex = selectedRowAndColumnFromPalette.selectedRowIndex;
|
|
83
|
+
selectedColumnIndex = selectedRowAndColumnFromPalette.selectedColumnIndex;
|
|
84
|
+
}
|
|
74
85
|
return {
|
|
75
86
|
content: isDragAndDropEnabled ? formatMessage(messages.backgroundColor) : formatMessage(messages.cellBackground),
|
|
76
87
|
value: {
|
|
@@ -94,10 +105,27 @@ export class ContextualMenu extends Component {
|
|
|
94
105
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
95
106
|
,
|
|
96
107
|
className: isDragAndDropEnabled ? ClassName.CONTEXTUAL_MENU_ICON_SMALL : ClassName.CONTEXTUAL_MENU_ICON
|
|
97
|
-
}), isSubmenuOpen && jsx("div", {
|
|
108
|
+
}), getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') ? isSubmenuOpen && jsx("div", {
|
|
98
109
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
99
110
|
className: ClassName.CONTEXTUAL_SUBMENU,
|
|
100
111
|
ref: this.handleSubMenuRef
|
|
112
|
+
}, jsx(ArrowKeyNavigationProvider, {
|
|
113
|
+
type: ArrowKeyNavigationType.COLOR,
|
|
114
|
+
selectedRowIndex: selectedRowIndex || 0,
|
|
115
|
+
selectedColumnIndex: selectedColumnIndex || 0,
|
|
116
|
+
handleClose: () => {
|
|
117
|
+
this.setState({
|
|
118
|
+
isSubmenuOpen: false
|
|
119
|
+
});
|
|
120
|
+
if (this.dropdownMenuRef && this.dropdownMenuRef.current) {
|
|
121
|
+
const focusableItems = this.dropdownMenuRef.current.querySelectorAll('div[tabindex="-1"]:not([disabled])');
|
|
122
|
+
if (focusableItems && focusableItems.length) {
|
|
123
|
+
focusableItems[0].focus();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
isPopupPositioned: true,
|
|
128
|
+
isOpenedByKeyboard: isCellMenuOpenByKeyboard
|
|
101
129
|
}, jsx(ColorPalette, {
|
|
102
130
|
cols: 7,
|
|
103
131
|
onClick: this.setColor,
|
|
@@ -107,7 +135,22 @@ export class ContextualMenu extends Component {
|
|
|
107
135
|
paletteColorTooltipMessages: backgroundPaletteTooltipMessages,
|
|
108
136
|
hexToPaletteColor: hexToEditorBackgroundPaletteColor
|
|
109
137
|
}
|
|
110
|
-
})))
|
|
138
|
+
}))) : isSubmenuOpen &&
|
|
139
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
140
|
+
jsx("div", {
|
|
141
|
+
className: ClassName.CONTEXTUAL_SUBMENU,
|
|
142
|
+
ref: this.handleSubMenuRef
|
|
143
|
+
}, jsx(ColorPalette, {
|
|
144
|
+
cols: 7,
|
|
145
|
+
onClick: this.setColor,
|
|
146
|
+
selectedColor: (node === null || node === void 0 ? void 0 : (_node$attrs3 = node.attrs) === null || _node$attrs3 === void 0 ? void 0 : _node$attrs3.background) || '#ffffff',
|
|
147
|
+
paletteOptions: {
|
|
148
|
+
palette: cellBackgroundColorPalette,
|
|
149
|
+
paletteColorTooltipMessages: backgroundPaletteTooltipMessages,
|
|
150
|
+
hexToPaletteColor: hexToEditorBackgroundPaletteColor
|
|
151
|
+
}
|
|
152
|
+
}))),
|
|
153
|
+
'aria-expanded': getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') ? isSubmenuOpen : undefined
|
|
111
154
|
};
|
|
112
155
|
}
|
|
113
156
|
});
|
|
@@ -439,7 +482,8 @@ export class ContextualMenu extends Component {
|
|
|
439
482
|
selectionRect,
|
|
440
483
|
editorAnalyticsAPI,
|
|
441
484
|
getEditorContainerWidth,
|
|
442
|
-
getEditorFeatureFlags
|
|
485
|
+
getEditorFeatureFlags,
|
|
486
|
+
isCellMenuOpenByKeyboard
|
|
443
487
|
} = this.props;
|
|
444
488
|
// TargetCellPosition could be outdated: https://product-fabric.atlassian.net/browse/ED-8129
|
|
445
489
|
const {
|
|
@@ -454,6 +498,21 @@ export class ContextualMenu extends Component {
|
|
|
454
498
|
tableDuplicateCellColouring = false,
|
|
455
499
|
tableWithFixedColumnWidthsOption = false
|
|
456
500
|
} = getEditorFeatureFlags ? getEditorFeatureFlags() : {};
|
|
501
|
+
// context menu opened by keyboard and any item except 'background' activated
|
|
502
|
+
// or color has been chosen from color palette
|
|
503
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') && isCellMenuOpenByKeyboard && (item.value.name !== 'background' || item.value.name === 'background' && this.state.isSubmenuOpen)) {
|
|
504
|
+
const {
|
|
505
|
+
tr
|
|
506
|
+
} = state;
|
|
507
|
+
tr.setMeta(tablePluginKey, {
|
|
508
|
+
type: 'SET_CELL_MENU_OPEN',
|
|
509
|
+
data: {
|
|
510
|
+
isCellMenuOpenByKeyboard: false
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
dispatch(tr);
|
|
514
|
+
editorView.dom.focus(); // otherwise cursor disappears from cell
|
|
515
|
+
}
|
|
457
516
|
const shouldUseIncreasedScalingPercent = isTableScalingEnabled && tableWithFixedColumnWidthsOption && getBooleanFF('platform.editor.table.use-increased-scaling-percent');
|
|
458
517
|
switch (item.value.name) {
|
|
459
518
|
case 'sort_column_desc':
|
|
@@ -507,6 +566,19 @@ export class ContextualMenu extends Component {
|
|
|
507
566
|
deleteRowsWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, selectionRect, !!isHeaderRowRequired)(state, dispatch);
|
|
508
567
|
this.toggleOpen();
|
|
509
568
|
break;
|
|
569
|
+
case 'background':
|
|
570
|
+
{
|
|
571
|
+
// This is called twice.
|
|
572
|
+
// 1st time when user chooses the background color item.
|
|
573
|
+
// 2nd when color has been chosen from color palette.
|
|
574
|
+
// here we are handling the 1st call relying on the isSubmenuOpen state value
|
|
575
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') && isCellMenuOpenByKeyboard && !this.state.isSubmenuOpen) {
|
|
576
|
+
this.setState({
|
|
577
|
+
isSubmenuOpen: true
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
510
582
|
}
|
|
511
583
|
});
|
|
512
584
|
_defineProperty(this, "toggleOpen", () => {
|
|
@@ -524,17 +596,51 @@ export class ContextualMenu extends Component {
|
|
|
524
596
|
});
|
|
525
597
|
}
|
|
526
598
|
});
|
|
527
|
-
_defineProperty(this, "handleOpenChange",
|
|
599
|
+
_defineProperty(this, "handleOpenChange", payload => {
|
|
528
600
|
const {
|
|
529
601
|
editorView: {
|
|
530
602
|
state,
|
|
531
|
-
dispatch
|
|
532
|
-
|
|
603
|
+
dispatch,
|
|
604
|
+
dom
|
|
605
|
+
},
|
|
606
|
+
isCellMenuOpenByKeyboard
|
|
533
607
|
} = this.props;
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
608
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
609
|
+
if (payload) {
|
|
610
|
+
const {
|
|
611
|
+
event
|
|
612
|
+
} = payload;
|
|
613
|
+
if (event && event instanceof KeyboardEvent) {
|
|
614
|
+
if (!this.state.isSubmenuOpen) {
|
|
615
|
+
if (arrowsList.has(event.key)) {
|
|
616
|
+
// preventing default behavior for avoiding cursor jump to next/previous table column
|
|
617
|
+
// when left/right arrow pressed.
|
|
618
|
+
event.preventDefault();
|
|
619
|
+
}
|
|
620
|
+
toggleContextualMenu()(state, dispatch);
|
|
621
|
+
this.setState({
|
|
622
|
+
isSubmenuOpen: false
|
|
623
|
+
});
|
|
624
|
+
setFocusToCellMenu(false)(state, dispatch);
|
|
625
|
+
dom.focus();
|
|
626
|
+
}
|
|
627
|
+
} else {
|
|
628
|
+
// mouse click outside
|
|
629
|
+
toggleContextualMenu()(state, dispatch);
|
|
630
|
+
this.setState({
|
|
631
|
+
isSubmenuOpen: false
|
|
632
|
+
});
|
|
633
|
+
if (isCellMenuOpenByKeyboard) {
|
|
634
|
+
setFocusToCellMenu(false)(state, dispatch);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
} else {
|
|
639
|
+
toggleContextualMenu()(state, dispatch);
|
|
640
|
+
this.setState({
|
|
641
|
+
isSubmenuOpen: false
|
|
642
|
+
});
|
|
643
|
+
}
|
|
538
644
|
});
|
|
539
645
|
_defineProperty(this, "handleItemMouseEnter", ({
|
|
540
646
|
item
|
|
@@ -601,21 +707,46 @@ export class ContextualMenu extends Component {
|
|
|
601
707
|
this.toggleOpen();
|
|
602
708
|
});
|
|
603
709
|
}
|
|
710
|
+
componentDidMount() {
|
|
711
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
712
|
+
// ArrowKeyNavigationProvider in DropdownMenu expects that menu handle will stay focused
|
|
713
|
+
// until user pressed ArrowDown.
|
|
714
|
+
// Behavior above fails the A11Y requirement about first item in menu should be focused immediately.
|
|
715
|
+
// so here is triggering componentDidUpdate inside dropdown to set focus on first element
|
|
716
|
+
const {
|
|
717
|
+
isCellMenuOpenByKeyboard
|
|
718
|
+
} = this.props;
|
|
719
|
+
if (isCellMenuOpenByKeyboard) {
|
|
720
|
+
this.setState({
|
|
721
|
+
...this.state,
|
|
722
|
+
isOpenAllowed: isCellMenuOpenByKeyboard
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|
|
604
727
|
render() {
|
|
605
728
|
const {
|
|
606
729
|
isOpen,
|
|
607
730
|
mountPoint,
|
|
608
731
|
offset,
|
|
609
732
|
boundariesElement,
|
|
610
|
-
editorView
|
|
733
|
+
editorView,
|
|
734
|
+
isCellMenuOpenByKeyboard
|
|
611
735
|
} = this.props;
|
|
612
736
|
const {
|
|
613
737
|
isDragAndDropEnabled
|
|
614
738
|
} = getPluginState(editorView.state);
|
|
615
739
|
const items = isDragAndDropEnabled ? this.createNewContextMenuItems() : this.createOriginalContextMenuItems();
|
|
740
|
+
let isOpenAllowed = false;
|
|
741
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
742
|
+
isOpenAllowed = isCellMenuOpenByKeyboard ? this.state.isOpenAllowed : isOpen;
|
|
743
|
+
} else {
|
|
744
|
+
isOpenAllowed = isOpen;
|
|
745
|
+
}
|
|
616
746
|
return jsx("div", {
|
|
617
747
|
"data-testid": "table-cell-contextual-menu",
|
|
618
|
-
onMouseLeave: this.closeSubmenu
|
|
748
|
+
onMouseLeave: this.closeSubmenu,
|
|
749
|
+
ref: this.dropdownMenuRef
|
|
619
750
|
}, jsx(DropdownMenu, {
|
|
620
751
|
mountTo: mountPoint
|
|
621
752
|
//This needs be removed when the a11y is completely handled
|
|
@@ -623,21 +754,25 @@ export class ContextualMenu extends Component {
|
|
|
623
754
|
,
|
|
624
755
|
arrowKeyNavigationProviderOptions: {
|
|
625
756
|
type: ArrowKeyNavigationType.MENU,
|
|
626
|
-
disableArrowKeyNavigation: true
|
|
757
|
+
disableArrowKeyNavigation: getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') && isCellMenuOpenByKeyboard && !this.state.isSubmenuOpen ? false : true
|
|
627
758
|
},
|
|
628
759
|
items: items,
|
|
629
|
-
isOpen:
|
|
760
|
+
isOpen: isOpenAllowed,
|
|
630
761
|
onOpenChange: this.handleOpenChange,
|
|
631
762
|
onItemActivated: this.onMenuItemActivated,
|
|
632
763
|
onMouseEnter: this.handleItemMouseEnter,
|
|
633
764
|
onMouseLeave: this.handleItemMouseLeave,
|
|
634
765
|
fitHeight: 188,
|
|
635
766
|
fitWidth: isDragAndDropEnabled ? contextualMenuDropdownWidthDnD : contextualMenuDropdownWidth,
|
|
767
|
+
shouldFocusFirstItem: getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') ? () => {
|
|
768
|
+
return Boolean(isCellMenuOpenByKeyboard);
|
|
769
|
+
} : undefined,
|
|
636
770
|
boundariesElement: boundariesElement,
|
|
637
771
|
offset: offset,
|
|
638
772
|
section: isDragAndDropEnabled ? {
|
|
639
773
|
hasSeparator: true
|
|
640
|
-
} : undefined
|
|
774
|
+
} : undefined,
|
|
775
|
+
isAllowEnterDefaultBehavior: getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') ? this.state.isSubmenuOpen : false
|
|
641
776
|
}));
|
|
642
777
|
}
|
|
643
778
|
}
|
|
@@ -18,7 +18,8 @@ const FloatingContextualMenu = ({
|
|
|
18
18
|
pluginConfig,
|
|
19
19
|
editorAnalyticsAPI,
|
|
20
20
|
getEditorContainerWidth,
|
|
21
|
-
getEditorFeatureFlags
|
|
21
|
+
getEditorFeatureFlags,
|
|
22
|
+
isCellMenuOpenByKeyboard
|
|
22
23
|
}) => {
|
|
23
24
|
// TargetCellPosition could be outdated: https://product-fabric.atlassian.net/browse/ED-8129
|
|
24
25
|
const {
|
|
@@ -71,7 +72,8 @@ const FloatingContextualMenu = ({
|
|
|
71
72
|
boundariesElement: boundariesElement,
|
|
72
73
|
editorAnalyticsAPI: editorAnalyticsAPI,
|
|
73
74
|
getEditorContainerWidth: getEditorContainerWidth,
|
|
74
|
-
getEditorFeatureFlags: getEditorFeatureFlags
|
|
75
|
+
getEditorFeatureFlags: getEditorFeatureFlags,
|
|
76
|
+
isCellMenuOpenByKeyboard: isCellMenuOpenByKeyboard
|
|
75
77
|
})));
|
|
76
78
|
};
|
|
77
79
|
FloatingContextualMenu.displayName = 'FloatingContextualMenu';
|
|
@@ -2,7 +2,7 @@ export { hoverColumns, hoverRows, hoverTable, hoverCell, hoverMergedCells, clear
|
|
|
2
2
|
export { insertColumn, insertRow, createTable } from './insert';
|
|
3
3
|
export { getNextLayout, toggleContextualMenu, toggleHeaderColumn, toggleHeaderRow, toggleNumberColumn, toggleTableLayout } from './toggle';
|
|
4
4
|
export { clearMultipleCells } from './clear';
|
|
5
|
-
export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectColumns, selectRow, selectRows, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations, updateWidthToWidest } from './misc';
|
|
5
|
+
export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectColumns, selectRow, selectRows, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations, updateWidthToWidest, setFocusToCellMenu } from './misc';
|
|
6
6
|
export { sortByColumn } from './sort';
|
|
7
7
|
export { goToNextCell } from './go-to-next-cell';
|
|
8
8
|
export { removeDescendantNodes } from './referentiality';
|
|
@@ -619,4 +619,18 @@ export var setTableAlignmentWithTableContentWithPos = function setTableAlignment
|
|
|
619
619
|
tr.setNodeMarkup(tableNodeWithPos.pos, undefined, nextTableAttrs).setMeta('scrollIntoView', false);
|
|
620
620
|
return tr;
|
|
621
621
|
};
|
|
622
|
+
};
|
|
623
|
+
export var setFocusToCellMenu = function setFocusToCellMenu() {
|
|
624
|
+
var isCellMenuOpenByKeyboard = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
625
|
+
var originalTr = arguments.length > 1 ? arguments[1] : undefined;
|
|
626
|
+
return createCommand(function () {
|
|
627
|
+
return {
|
|
628
|
+
type: 'SET_CELL_MENU_OPEN',
|
|
629
|
+
data: {
|
|
630
|
+
isCellMenuOpenByKeyboard: isCellMenuOpenByKeyboard
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
}, function (tr) {
|
|
634
|
+
return (originalTr || tr).setMeta('addToHistory', false);
|
|
635
|
+
});
|
|
622
636
|
};
|
package/dist/esm/plugin.js
CHANGED
|
@@ -349,10 +349,11 @@ var tablesPlugin = function tablesPlugin(_ref) {
|
|
|
349
349
|
isHeaderColumnEnabled = _ref18.isHeaderColumnEnabled,
|
|
350
350
|
isHeaderRowEnabled = _ref18.isHeaderRowEnabled,
|
|
351
351
|
isDragAndDropEnabled = _ref18.isDragAndDropEnabled,
|
|
352
|
-
tableWrapperTarget = _ref18.tableWrapperTarget
|
|
352
|
+
tableWrapperTarget = _ref18.tableWrapperTarget,
|
|
353
|
+
isCellMenuOpenByKeyboard = _ref18.isCellMenuOpenByKeyboard;
|
|
353
354
|
var allowControls = pluginConfig.allowControls;
|
|
354
355
|
var stickyHeader = stickyHeadersState ? findStickyHeaderForTable(stickyHeadersState, tablePos) : undefined;
|
|
355
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, targetCellPosition && tableRef && !isResizing && options && options.allowContextualMenu && /*#__PURE__*/React.createElement(FloatingContextualButton, {
|
|
356
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, targetCellPosition && (tableRef || getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') && isCellMenuOpenByKeyboard) && !isResizing && options && options.allowContextualMenu && /*#__PURE__*/React.createElement(FloatingContextualButton, {
|
|
356
357
|
isNumberColumnEnabled: tableNode && tableNode.attrs.isNumberColumnEnabled,
|
|
357
358
|
editorView: editorView,
|
|
358
359
|
tableNode: tableNode,
|
|
@@ -362,7 +363,8 @@ var tablesPlugin = function tablesPlugin(_ref) {
|
|
|
362
363
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
363
364
|
isContextualMenuOpen: isContextualMenuOpen,
|
|
364
365
|
stickyHeader: stickyHeader,
|
|
365
|
-
tableWrapper: tableWrapperTarget
|
|
366
|
+
tableWrapper: tableWrapperTarget,
|
|
367
|
+
isCellMenuOpenByKeyboard: isCellMenuOpenByKeyboard
|
|
366
368
|
}), allowControls && /*#__PURE__*/React.createElement(FloatingInsertButton, {
|
|
367
369
|
tableNode: tableNode,
|
|
368
370
|
tableRef: tableRef,
|
|
@@ -390,7 +392,8 @@ var tablesPlugin = function tablesPlugin(_ref) {
|
|
|
390
392
|
pluginConfig: pluginConfig,
|
|
391
393
|
editorAnalyticsAPI: editorAnalyticsAPI,
|
|
392
394
|
getEditorContainerWidth: defaultGetEditorContainerWidth,
|
|
393
|
-
getEditorFeatureFlags: (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags
|
|
395
|
+
getEditorFeatureFlags: (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags,
|
|
396
|
+
isCellMenuOpenByKeyboard: isCellMenuOpenByKeyboard
|
|
394
397
|
}), isDragAndDropEnabled && /*#__PURE__*/React.createElement(FloatingDragMenu, {
|
|
395
398
|
editorView: editorView,
|
|
396
399
|
mountPoint: popupsMountPoint,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
-
import { addColumnAfter, addColumnAfterVO, addColumnBefore, addColumnBeforeVO, addRowAfter, addRowAfterVO, addRowBefore, addRowBeforeVO, backspace, bindKeymapWithCommand, decreaseMediaSize, deleteColumn, deleteRow, escape, increaseMediaSize, moveColumnLeft, moveColumnRight, moveLeft, moveRight, moveRowDown, moveRowUp, nextCell, previousCell, startColumnResizing, toggleTable } from '@atlaskit/editor-common/keymaps';
|
|
2
|
+
import { addColumnAfter, addColumnAfterVO, addColumnBefore, addColumnBeforeVO, addRowAfter, addRowAfterVO, addRowBefore, addRowBeforeVO, backspace, bindKeymapWithCommand, decreaseMediaSize, deleteColumn, deleteRow, escape, focusToContextMenuTrigger, increaseMediaSize, moveColumnLeft, moveColumnRight, moveLeft, moveRight, moveRowDown, moveRowUp, nextCell, previousCell, startColumnResizing, toggleTable } from '@atlaskit/editor-common/keymaps';
|
|
3
3
|
import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
|
4
4
|
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
5
5
|
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
6
|
-
import { goToNextCell, moveCursorBackward } from '../commands';
|
|
6
|
+
import { goToNextCell, moveCursorBackward, setFocusToCellMenu } from '../commands';
|
|
7
7
|
import { addRowAroundSelection, changeColumnWidthByStepWithAnalytics, deleteSelectedRowsOrColumnsWithAnalyticsViaShortcut, deleteTableIfSelectedWithAnalytics, emptyMultipleCellsWithAnalytics } from '../commands-with-analytics';
|
|
8
8
|
import { activateNextResizeArea, initiateKeyboardColumnResizing, stopKeyboardColumnResizing } from '../commands/column-resize';
|
|
9
9
|
import { addColumnAfter as addColumnAfterCommand, addColumnBefore as addColumnBeforeCommand, createTable } from '../commands/insert';
|
|
@@ -77,6 +77,9 @@ export function keymapPlugin(getEditorContainerWidth, editorAnalyticsAPI, dragAn
|
|
|
77
77
|
getIntl: getIntl
|
|
78
78
|
}), list);
|
|
79
79
|
}
|
|
80
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
81
|
+
bindKeymapWithCommand(focusToContextMenuTrigger.common, setFocusToCellMenu(), list);
|
|
82
|
+
}
|
|
80
83
|
return keymap(list);
|
|
81
84
|
}
|
|
82
85
|
export default keymapPlugin;
|
package/dist/esm/reducer.js
CHANGED
|
@@ -95,6 +95,7 @@ export default (function (pluginState, action) {
|
|
|
95
95
|
case 'HOVER_CELL':
|
|
96
96
|
case 'SHOW_RESIZE_HANDLE_LINE':
|
|
97
97
|
case 'SET_EDITOR_FOCUS':
|
|
98
|
+
case 'SET_CELL_MENU_OPEN':
|
|
98
99
|
return _objectSpread(_objectSpread({}, pluginState), action.data);
|
|
99
100
|
default:
|
|
100
101
|
return pluginState;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useEffect } 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';
|
|
@@ -12,6 +12,7 @@ import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
|
12
12
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
13
13
|
import { akEditorSmallZIndex } from '@atlaskit/editor-shared-styles';
|
|
14
14
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
15
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
15
16
|
import { toggleContextualMenu } from '../../commands';
|
|
16
17
|
import { TableCssClassName as ClassName } from '../../types';
|
|
17
18
|
import FixedButton from './FixedButton';
|
|
@@ -25,6 +26,7 @@ var FloatingContextualButtonInner = /*#__PURE__*/React.memo(function (props) {
|
|
|
25
26
|
stickyHeader = props.stickyHeader,
|
|
26
27
|
tableWrapper = props.tableWrapper,
|
|
27
28
|
targetCellPosition = props.targetCellPosition,
|
|
29
|
+
isCellMenuOpenByKeyboard = props.isCellMenuOpenByKeyboard,
|
|
28
30
|
formatMessage = props.intl.formatMessage; // : Props & WrappedComponentProps
|
|
29
31
|
|
|
30
32
|
var handleClick = function handleClick() {
|
|
@@ -42,6 +44,16 @@ var FloatingContextualButtonInner = /*#__PURE__*/React.memo(function (props) {
|
|
|
42
44
|
var domAtPos = editorView.domAtPos.bind(editorView);
|
|
43
45
|
var targetCellRef;
|
|
44
46
|
targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
|
|
47
|
+
useEffect(function () {
|
|
48
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
49
|
+
if (isCellMenuOpenByKeyboard && !isContextualMenuOpen) {
|
|
50
|
+
var state = editorView.state,
|
|
51
|
+
dispatch = editorView.dispatch;
|
|
52
|
+
// open the menu when the keyboard shortcut is pressed
|
|
53
|
+
toggleContextualMenu()(state, dispatch);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, [isCellMenuOpenByKeyboard, isContextualMenuOpen, editorView]);
|
|
45
57
|
if (!targetCellRef || !(targetCellRef instanceof HTMLElement)) {
|
|
46
58
|
return null;
|
|
47
59
|
}
|
|
@@ -62,7 +74,8 @@ var FloatingContextualButtonInner = /*#__PURE__*/React.memo(function (props) {
|
|
|
62
74
|
iconBefore: jsx(ExpandIcon, {
|
|
63
75
|
label: ""
|
|
64
76
|
}),
|
|
65
|
-
"aria-label": labelCellOptions
|
|
77
|
+
"aria-label": labelCellOptions,
|
|
78
|
+
"aria-expanded": getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c') ? isContextualMenuOpen : undefined
|
|
66
79
|
}));
|
|
67
80
|
var parentSticky = targetCellRef.parentElement && targetCellRef.parentElement.className.indexOf('sticky') > -1;
|
|
68
81
|
if (stickyHeader && parentSticky && tableWrapper) {
|