@atlaskit/editor-plugin-table 7.18.2 → 7.18.4
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 +16 -0
- package/dist/cjs/commands/column-resize.js +0 -12
- package/dist/cjs/commands/go-to-next-cell.js +8 -11
- package/dist/cjs/commands/index.js +6 -0
- package/dist/cjs/commands/misc.js +15 -1
- package/dist/cjs/commands/selection.js +4 -11
- package/dist/cjs/event-handlers.js +7 -11
- package/dist/cjs/plugin.js +7 -4
- package/dist/cjs/pm-plugins/keymap.js +22 -21
- package/dist/cjs/pm-plugins/main.js +26 -30
- package/dist/cjs/pm-plugins/table-resizing/event-handlers.js +13 -21
- package/dist/cjs/pm-plugins/table-resizing/plugin.js +8 -11
- 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/column-resize.js +0 -12
- package/dist/es2019/commands/go-to-next-cell.js +8 -11
- package/dist/es2019/commands/index.js +1 -1
- package/dist/es2019/commands/misc.js +9 -1
- package/dist/es2019/commands/selection.js +4 -11
- package/dist/es2019/event-handlers.js +8 -12
- package/dist/es2019/plugin.js +7 -4
- package/dist/es2019/pm-plugins/keymap.js +24 -23
- package/dist/es2019/pm-plugins/main.js +27 -31
- package/dist/es2019/pm-plugins/table-resizing/event-handlers.js +13 -21
- package/dist/es2019/pm-plugins/table-resizing/plugin.js +9 -12
- 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/column-resize.js +0 -12
- package/dist/esm/commands/go-to-next-cell.js +8 -11
- package/dist/esm/commands/index.js +1 -1
- package/dist/esm/commands/misc.js +14 -0
- package/dist/esm/commands/selection.js +4 -11
- package/dist/esm/event-handlers.js +7 -11
- package/dist/esm/plugin.js +7 -4
- package/dist/esm/pm-plugins/keymap.js +24 -23
- package/dist/esm/pm-plugins/main.js +26 -30
- package/dist/esm/pm-plugins/table-resizing/event-handlers.js +13 -21
- package/dist/esm/pm-plugins/table-resizing/plugin.js +8 -11
- 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 +4 -4
- package/src/commands/column-resize.ts +0 -14
- package/src/commands/go-to-next-cell.ts +7 -10
- package/src/commands/index.ts +1 -0
- package/src/commands/misc.ts +13 -0
- package/src/commands/selection.ts +4 -11
- package/src/event-handlers.ts +6 -12
- package/src/plugin.tsx +6 -1
- package/src/pm-plugins/keymap.ts +65 -62
- package/src/pm-plugins/main.ts +27 -31
- package/src/pm-plugins/table-resizing/event-handlers.ts +11 -19
- package/src/pm-plugins/table-resizing/plugin.ts +7 -10
- package/src/reducer.ts +1 -0
- package/src/types.ts +8 -1
- package/src/ui/FloatingContextualButton/index.tsx +19 -1
- package/src/ui/FloatingContextualMenu/ContextualMenu.tsx +207 -30
- package/src/ui/FloatingContextualMenu/index.tsx +3 -0
|
@@ -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';
|
|
@@ -47,27 +47,28 @@ export function keymapPlugin(getEditorContainerWidth, editorAnalyticsAPI, dragAn
|
|
|
47
47
|
bindKeymapWithCommand(deleteColumn.common, deleteSelectedRowsOrColumnsWithAnalyticsViaShortcut(editorAnalyticsAPI, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent), list);
|
|
48
48
|
bindKeymapWithCommand(deleteRow.common, deleteSelectedRowsOrColumnsWithAnalyticsViaShortcut(editorAnalyticsAPI, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent), list);
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
50
|
+
bindKeymapWithCommand(startColumnResizing.common, initiateKeyboardColumnResizing({
|
|
51
|
+
ariaNotify: ariaNotifyPlugin,
|
|
52
|
+
getIntl: getIntl
|
|
53
|
+
}), list);
|
|
54
|
+
bindKeymapWithCommand(moveRight.common, activateNextResizeArea({
|
|
55
|
+
direction: 1,
|
|
56
|
+
ariaNotify: ariaNotifyPlugin,
|
|
57
|
+
getIntl: getIntl
|
|
58
|
+
}), list);
|
|
59
|
+
bindKeymapWithCommand(moveLeft.common, activateNextResizeArea({
|
|
60
|
+
direction: -1,
|
|
61
|
+
ariaNotify: ariaNotifyPlugin,
|
|
62
|
+
getIntl: getIntl
|
|
63
|
+
}), list);
|
|
64
|
+
bindKeymapWithCommand(decreaseMediaSize.common, changeColumnWidthByStepWithAnalytics(editorAnalyticsAPI)(-10, getEditorContainerWidth, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, INPUT_METHOD.SHORTCUT, ariaNotifyPlugin, getIntl), list);
|
|
65
|
+
bindKeymapWithCommand(increaseMediaSize.common, changeColumnWidthByStepWithAnalytics(editorAnalyticsAPI)(10, getEditorContainerWidth, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, INPUT_METHOD.SHORTCUT, ariaNotifyPlugin, getIntl), list);
|
|
66
|
+
bindKeymapWithCommand(escape.common, stopKeyboardColumnResizing({
|
|
67
|
+
ariaNotify: ariaNotifyPlugin,
|
|
68
|
+
getIntl: getIntl
|
|
69
|
+
}), list);
|
|
70
|
+
if (getBooleanFF('platform.editor.a11y-table-context-menu_y4c9c')) {
|
|
71
|
+
bindKeymapWithCommand(focusToContextMenuTrigger.common, setFocusToCellMenu(), list);
|
|
71
72
|
}
|
|
72
73
|
return keymap(list);
|
|
73
74
|
}
|
|
@@ -106,31 +106,29 @@ export const createPlugin = (dispatchAnalyticsEvent, dispatch, portalProviderAPI
|
|
|
106
106
|
tableRef = parent.querySelector('table') || undefined;
|
|
107
107
|
}
|
|
108
108
|
const tableNode = findTable(state.selection);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// Jump to another table
|
|
122
|
-
stopKeyboardColumnResizing({
|
|
123
|
-
ariaNotify: ariaNotifyPlugin,
|
|
124
|
-
getIntl: getIntl
|
|
125
|
-
})(state, dispatch);
|
|
126
|
-
}
|
|
127
|
-
} else if (!tableNode) {
|
|
128
|
-
// selection outside of table
|
|
109
|
+
// when keyboard cursor leaves the table we need to stop column resizing
|
|
110
|
+
const pluginPrevState = getPluginState(prevState);
|
|
111
|
+
const isStopKeyboardColumResizing = pluginPrevState.isResizeHandleWidgetAdded && pluginPrevState.isKeyboardResize;
|
|
112
|
+
if (isStopKeyboardColumResizing) {
|
|
113
|
+
const isTableNodesDifferent = (pluginPrevState === null || pluginPrevState === void 0 ? void 0 : pluginPrevState.tableNode) !== (tableNode === null || tableNode === void 0 ? void 0 : tableNode.node);
|
|
114
|
+
if (pluginPrevState !== null && pluginPrevState !== void 0 && pluginPrevState.tableNode && tableNode && isTableNodesDifferent) {
|
|
115
|
+
const oldRowsNumber = TableMap.get(pluginPrevState.tableNode).height;
|
|
116
|
+
const newRowsNumber = TableMap.get(tableNode.node).height;
|
|
117
|
+
if (oldRowsNumber !== newRowsNumber ||
|
|
118
|
+
// Add/delete row
|
|
119
|
+
tableNode.node.attrs.localId !== pluginPrevState.tableNode.attrs.localId) {
|
|
120
|
+
// Jump to another table
|
|
129
121
|
stopKeyboardColumnResizing({
|
|
130
122
|
ariaNotify: ariaNotifyPlugin,
|
|
131
123
|
getIntl: getIntl
|
|
132
124
|
})(state, dispatch);
|
|
133
125
|
}
|
|
126
|
+
} else if (!tableNode) {
|
|
127
|
+
// selection outside of table
|
|
128
|
+
stopKeyboardColumnResizing({
|
|
129
|
+
ariaNotify: ariaNotifyPlugin,
|
|
130
|
+
getIntl: getIntl
|
|
131
|
+
})(state, dispatch);
|
|
134
132
|
}
|
|
135
133
|
}
|
|
136
134
|
}
|
|
@@ -240,17 +238,15 @@ export const createPlugin = (dispatchAnalyticsEvent, dispatch, portalProviderAPI
|
|
|
240
238
|
state,
|
|
241
239
|
dispatch
|
|
242
240
|
} = view;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
241
|
+
const {
|
|
242
|
+
isKeyboardResize
|
|
243
|
+
} = getPluginState(state);
|
|
244
|
+
if (isKeyboardResize) {
|
|
245
|
+
stopKeyboardColumnResizing({
|
|
246
|
+
ariaNotify: ariaNotifyPlugin,
|
|
247
|
+
getIntl: getIntl
|
|
248
|
+
})(state, dispatch);
|
|
249
|
+
return false;
|
|
254
250
|
}
|
|
255
251
|
const tr = replaceSelectedTable(state, text, INPUT_METHOD.KEYBOARD, editorAnalyticsAPI);
|
|
256
252
|
if (tr.selectionSet) {
|
|
@@ -118,15 +118,11 @@ export const handleMouseDown = (view, event, localResizeHandlePos, getEditorCont
|
|
|
118
118
|
|
|
119
119
|
// If we let go in the same place we started, don't need to do anything.
|
|
120
120
|
if (dragging && clientX === dragging.startX) {
|
|
121
|
-
if (
|
|
122
|
-
if
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return stopKeyboardColumnResizing({})(state, dispatch, view);
|
|
127
|
-
} else {
|
|
128
|
-
return stopResizing()(state, dispatch);
|
|
129
|
-
}
|
|
121
|
+
if (isKeyboardResize || !isTableHovered) {
|
|
122
|
+
/** if column resize had started via keyboard but continued by mouse
|
|
123
|
+
* or mouse pointer leaves the table but mouse button still pressed
|
|
124
|
+
*/
|
|
125
|
+
return stopKeyboardColumnResizing({})(state, dispatch, view);
|
|
130
126
|
} else {
|
|
131
127
|
return stopResizing()(state, dispatch);
|
|
132
128
|
}
|
|
@@ -197,17 +193,13 @@ export const handleMouseDown = (view, event, localResizeHandlePos, getEditorCont
|
|
|
197
193
|
}
|
|
198
194
|
})(tr);
|
|
199
195
|
}
|
|
200
|
-
if (
|
|
201
|
-
if
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
})(state, dispatch, view);
|
|
208
|
-
} else {
|
|
209
|
-
return stopResizing(tr)(state, dispatch);
|
|
210
|
-
}
|
|
196
|
+
if (isKeyboardResize || !isTableHovered) {
|
|
197
|
+
/** if column resize had started via keyboard but continued by mouse
|
|
198
|
+
* or mouse pointer leaves the table but mouse button still pressed
|
|
199
|
+
*/
|
|
200
|
+
return stopKeyboardColumnResizing({
|
|
201
|
+
originalTr: tr
|
|
202
|
+
})(state, dispatch, view);
|
|
211
203
|
} else {
|
|
212
204
|
return stopResizing(tr)(state, dispatch);
|
|
213
205
|
}
|
|
@@ -228,7 +220,7 @@ export const handleMouseDown = (view, event, localResizeHandlePos, getEditorCont
|
|
|
228
220
|
const {
|
|
229
221
|
isTableHovered
|
|
230
222
|
} = getTablePluginState(state);
|
|
231
|
-
if (!which || !dragging || resizeHandlePos === null || !pointsAtCell(state.doc.resolve(resizeHandlePos)) || !isTableHovered
|
|
223
|
+
if (!which || !dragging || resizeHandlePos === null || !pointsAtCell(state.doc.resolve(resizeHandlePos)) || !isTableHovered) {
|
|
232
224
|
return finish(event);
|
|
233
225
|
}
|
|
234
226
|
const $cell = state.doc.resolve(resizeHandlePos);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import classnames from 'classnames';
|
|
2
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
-
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
4
3
|
import { TableCssClassName as ClassName } from '../../types';
|
|
5
4
|
import { getPluginState as getTablePluginState } from '../plugin-factory';
|
|
6
5
|
import { setResizeHandlePos } from './commands';
|
|
@@ -41,17 +40,15 @@ export function createPlugin(dispatch, {
|
|
|
41
40
|
dragging
|
|
42
41
|
} = getPluginState(state);
|
|
43
42
|
let isColumnKeyboardResizeStarted = false;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
isColumnKeyboardResizeStarted = isKeyboardResize;
|
|
54
|
-
}
|
|
43
|
+
/*
|
|
44
|
+
We need to start listening mouse events if column resize started from keyboard.
|
|
45
|
+
This will allow continue resizing via mouse
|
|
46
|
+
*/
|
|
47
|
+
const {
|
|
48
|
+
isKeyboardResize
|
|
49
|
+
} = getTablePluginState(state);
|
|
50
|
+
if (isKeyboardResize) {
|
|
51
|
+
isColumnKeyboardResizeStarted = isKeyboardResize;
|
|
55
52
|
}
|
|
56
53
|
if (resizeHandlePos !== null && (!dragging || isColumnKeyboardResizeStarted)) {
|
|
57
54
|
if (handleMouseDown(view, event, resizeHandlePos, getEditorContainerWidth, getEditorFeatureFlags, isTableScalingEnabled || false, editorAnalyticsAPI, isNewColumnResizingEnabled)) {
|
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';
|