@atlaskit/editor-plugin-block-menu 6.0.21 → 6.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/afm-jira/tsconfig.json +1 -1
  3. package/dist/cjs/blockMenuPlugin.js +6 -0
  4. package/dist/cjs/pm-plugins/keymap.js +61 -0
  5. package/dist/cjs/pm-plugins/main.js +3 -8
  6. package/dist/cjs/pm-plugins/utils/shouldSuppressKeyboardEvent.js +37 -0
  7. package/dist/cjs/ui/MenuSection.js +21 -0
  8. package/dist/cjs/ui/block-menu-components.js +8 -6
  9. package/dist/cjs/ui/copy-link.js +7 -1
  10. package/dist/cjs/ui/suggested-items-menu-section.js +5 -1
  11. package/dist/es2019/blockMenuPlugin.js +4 -0
  12. package/dist/es2019/pm-plugins/keymap.js +56 -0
  13. package/dist/es2019/pm-plugins/main.js +3 -8
  14. package/dist/es2019/pm-plugins/utils/shouldSuppressKeyboardEvent.js +31 -0
  15. package/dist/es2019/ui/MenuSection.js +16 -0
  16. package/dist/es2019/ui/block-menu-components.js +8 -6
  17. package/dist/es2019/ui/copy-link.js +8 -2
  18. package/dist/es2019/ui/suggested-items-menu-section.js +6 -1
  19. package/dist/esm/blockMenuPlugin.js +6 -0
  20. package/dist/esm/pm-plugins/keymap.js +55 -0
  21. package/dist/esm/pm-plugins/main.js +3 -8
  22. package/dist/esm/pm-plugins/utils/shouldSuppressKeyboardEvent.js +31 -0
  23. package/dist/esm/ui/MenuSection.js +14 -0
  24. package/dist/esm/ui/block-menu-components.js +8 -6
  25. package/dist/esm/ui/copy-link.js +8 -2
  26. package/dist/esm/ui/suggested-items-menu-section.js +5 -1
  27. package/dist/types/pm-plugins/keymap.d.ts +4 -0
  28. package/dist/types/pm-plugins/utils/shouldSuppressKeyboardEvent.d.ts +14 -0
  29. package/dist/types/ui/MenuSection.d.ts +9 -0
  30. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
  31. package/dist/types-ts4.5/pm-plugins/utils/shouldSuppressKeyboardEvent.d.ts +14 -0
  32. package/dist/types-ts4.5/ui/MenuSection.d.ts +9 -0
  33. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 6.0.23
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0d8216e610e34`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0d8216e610e34) -
8
+ [ux] Add cmd-option-a shortcut for copylink to block from block menu
9
+ - Updated dependencies
10
+
11
+ ## 6.0.22
12
+
13
+ ### Patch Changes
14
+
15
+ - [`33f11753a7104`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/33f11753a7104) -
16
+ [ux] Added i18n for sections' titles in the Turn into menu.
17
+ - Updated dependencies
18
+
3
19
  ## 6.0.21
4
20
 
5
21
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../../../tsconfig.entry-points.jira.json",
2
+ "extends": "../../../../tsconfig.local-consumption.json",
3
3
  "compilerOptions": {
4
4
  "target": "es5",
5
5
  "outDir": "../../../../../jira/tsDist/@atlaskit__editor-plugin-block-menu/app",
@@ -10,6 +10,7 @@ var _editorActions = require("./editor-actions");
10
10
  var _isTransformToTargetDisabled = require("./editor-actions/isTransformToTargetDisabled");
11
11
  var _formatNode2 = require("./editor-commands/formatNode");
12
12
  var _transformNode2 = require("./editor-commands/transformNode");
13
+ var _keymap = require("./pm-plugins/keymap");
13
14
  var _main = require("./pm-plugins/main");
14
15
  var _blockMenu = _interopRequireDefault(require("./ui/block-menu"));
15
16
  var _blockMenuComponents = require("./ui/block-menu-components");
@@ -31,6 +32,11 @@ var blockMenuPlugin = exports.blockMenuPlugin = function blockMenuPlugin(_ref) {
31
32
  plugin: function plugin() {
32
33
  return (0, _main.createPlugin)(api);
33
34
  }
35
+ }, {
36
+ name: 'blockMenuKeymap',
37
+ plugin: function plugin() {
38
+ return (0, _keymap.keymapPlugin)(api, config);
39
+ }
34
40
  }];
35
41
  },
36
42
  actions: {
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.keymapPlugin = keymapPlugin;
7
+ var _keymaps = require("@atlaskit/editor-common/keymaps");
8
+ var _selection = require("@atlaskit/editor-common/selection");
9
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
+ var _blockMenuPluginType = require("../blockMenuPluginType");
11
+ var _main = require("../pm-plugins/main");
12
+ var _copyLink = require("../ui/utils/copyLink");
13
+ function keymapPlugin(api, config) {
14
+ var list = {};
15
+ var copyLinkToBlockCommand = function copyLinkToBlockCommand(state, dispatch) {
16
+ var _api$blockControls, _node$attrs;
17
+ // Check if feature flag is enabled
18
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid')) {
19
+ return false;
20
+ }
21
+
22
+ // Get the preserved selection (only works when block menu is open and selection is preserved)
23
+ var selection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
24
+ if (!selection) {
25
+ return false;
26
+ }
27
+
28
+ // Check if the selection has a valid block range with localId
29
+ var blockRange = (0, _selection.expandSelectionToBlockRange)(selection);
30
+ if (!blockRange) {
31
+ return false;
32
+ }
33
+ var node = blockRange.$from.nodeAfter;
34
+ if (!(node !== null && node !== void 0 && (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.localId)) {
35
+ return false;
36
+ }
37
+
38
+ // Execute the copy link action
39
+ var _ref = config || {},
40
+ getLinkPath = _ref.getLinkPath,
41
+ blockLinkHashPrefix = _ref.blockLinkHashPrefix;
42
+ (0, _copyLink.copyLink)({
43
+ getLinkPath: getLinkPath,
44
+ blockLinkHashPrefix: blockLinkHashPrefix,
45
+ selection: selection
46
+ }).then(function (success) {
47
+ if (success && dispatch) {
48
+ dispatch(state.tr.setMeta(_main.blockMenuPluginKey, {
49
+ showFlag: _blockMenuPluginType.FLAG_ID.LINK_COPIED_TO_CLIPBOARD
50
+ }));
51
+ }
52
+ });
53
+ return true;
54
+ };
55
+
56
+ // Ignored via go/ees005
57
+ (0, _keymaps.bindKeymapWithCommand)(
58
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
59
+ _keymaps.copyLinkToBlock.common, copyLinkToBlockCommand, list);
60
+ return (0, _keymaps.keymap)(list);
61
+ }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createPlugin = exports.blockMenuPluginKey = void 0;
7
7
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
8
8
  var _state = require("@atlaskit/editor-prosemirror/state");
9
+ var _shouldSuppressKeyboardEvent = require("./utils/shouldSuppressKeyboardEvent");
9
10
  var blockMenuPluginKey = exports.blockMenuPluginKey = new _state.PluginKey('blockMenuPlugin');
10
11
  var createPlugin = exports.createPlugin = function createPlugin(api) {
11
12
  return new _safePlugin.SafePlugin({
@@ -35,14 +36,8 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
35
36
  }
36
37
 
37
38
  // Block further handling of key events when block menu is open
38
- // Except for backspace/delete/copy/cut/paste/undo/redo which should be handled by the selection preservation plugin
39
- var key = event.key.toLowerCase();
40
- var isMetaCtrl = event.metaKey || event.ctrlKey;
41
- var isBackspaceDelete = ['backspace', 'delete'].includes(key);
42
- var isCopyCutPaste = isMetaCtrl && ['c', 'x', 'v'].includes(key);
43
- var isUndoRedo = isMetaCtrl && ['z', 'y'].includes(key);
44
- var suppressNativeHandling = !isCopyCutPaste && !isBackspaceDelete && !isUndoRedo;
45
- return suppressNativeHandling;
39
+ // Except for backspace/delete/copy/cut/paste/undo/redo/copy-link-to-block which should be handled by the selection preservation plugin
40
+ return (0, _shouldSuppressKeyboardEvent.shouldSuppressKeyboardEvent)(event);
46
41
  }
47
42
  }
48
43
  });
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldSuppressKeyboardEvent = void 0;
7
+ /**
8
+ * Determines whether keyboard events should be suppressed when the block menu is open.
9
+ *
10
+ * When the block menu is open, we want to block most keyboard events to prevent
11
+ * unintended interactions. However, certain actions should still be allowed:
12
+ * - Backspace/Delete: Allow deleting selected content
13
+ * - Copy/Cut/Paste: Allow clipboard operations (Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V)
14
+ * - Undo/Redo: Allow undo/redo operations (Cmd/Ctrl+Z, Cmd/Ctrl+Y)
15
+ * - Copy Link to Block: Allow the keyboard shortcut (Cmd/Ctrl+Alt+A)
16
+ *
17
+ * @param event - The keyboard event to check
18
+ * @returns true if the event should be suppressed, false if it should be allowed
19
+ */
20
+ var shouldSuppressKeyboardEvent = exports.shouldSuppressKeyboardEvent = function shouldSuppressKeyboardEvent(event) {
21
+ var key = event.key.toLowerCase();
22
+ var code = event.code.toLowerCase();
23
+ var isMetaCtrl = event.metaKey || event.ctrlKey;
24
+ var isAlt = event.altKey;
25
+
26
+ // Check for allowed keyboard shortcuts
27
+ var isBackspaceDelete = ['backspace', 'delete'].includes(key);
28
+ var isCopyCutPaste = isMetaCtrl && ['c', 'x', 'v'].includes(key);
29
+ var isUndoRedo = isMetaCtrl && ['z', 'y'].includes(key);
30
+
31
+ // Use event.code to detect physical key 'A' because on macOS Option+A produces 'å'
32
+ var isCopyLinkToBlock = isMetaCtrl && isAlt && code === 'keya';
33
+
34
+ // Suppress all events except the allowed ones
35
+ var suppressNativeHandling = !isCopyCutPaste && !isBackspaceDelete && !isUndoRedo && !isCopyLinkToBlock;
36
+ return suppressNativeHandling;
37
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.MenuSection = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _reactIntlNext = require("react-intl-next");
10
+ var _editorToolbar = require("@atlaskit/editor-toolbar");
11
+ var MenuSection = exports.MenuSection = function MenuSection(_ref) {
12
+ var children = _ref.children,
13
+ title = _ref.title,
14
+ hasSeparator = _ref.hasSeparator;
15
+ var _useIntl = (0, _reactIntlNext.useIntl)(),
16
+ formatMessage = _useIntl.formatMessage;
17
+ return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
18
+ title: formatMessage(title),
19
+ hasSeparator: hasSeparator
20
+ }, children);
21
+ };
@@ -8,6 +8,7 @@ exports.getBlockMenuComponents = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
10
  var _blockMenu = require("@atlaskit/editor-common/block-menu");
11
+ var _messages = require("@atlaskit/editor-common/messages");
11
12
  var _editorToolbar = require("@atlaskit/editor-toolbar");
12
13
  var _utils = require("./block-menu-renderer/utils");
13
14
  var _copyLink = require("./copy-link");
@@ -16,6 +17,7 @@ var _deleteButton = require("./delete-button");
16
17
  var _deleteSection = require("./delete-section");
17
18
  var _formatMenuNested = require("./format-menu-nested");
18
19
  var _formatMenuSection = require("./format-menu-section");
20
+ var _MenuSection = require("./MenuSection");
19
21
  var _moveDown = require("./move-down");
20
22
  var _moveUp = require("./move-up");
21
23
  var _suggestedItemsMenuSection = require("./suggested-items-menu-section");
@@ -139,8 +141,8 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
139
141
  children: null
140
142
  },
141
143
  children = _ref3.children;
142
- return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
143
- title: "Create"
144
+ return /*#__PURE__*/_react.default.createElement(_MenuSection.MenuSection, {
145
+ title: _messages.blockMenuMessages.create
144
146
  }, children);
145
147
  }
146
148
  }, {
@@ -156,8 +158,8 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
156
158
  children: null
157
159
  },
158
160
  children = _ref4.children;
159
- return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
160
- title: "Structure"
161
+ return /*#__PURE__*/_react.default.createElement(_MenuSection.MenuSection, {
162
+ title: _messages.blockMenuMessages.structure
161
163
  }, children);
162
164
  }
163
165
  }, {
@@ -173,8 +175,8 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
173
175
  children: null
174
176
  },
175
177
  children = _ref5.children;
176
- return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
177
- title: "Headings",
178
+ return /*#__PURE__*/_react.default.createElement(_MenuSection.MenuSection, {
179
+ title: _messages.blockMenuMessages.headings,
178
180
  hasSeparator: true
179
181
  }, children);
180
182
  }
@@ -10,6 +10,7 @@ var _react = _interopRequireWildcard(require("react"));
10
10
  var _reactIntlNext = require("react-intl-next");
11
11
  var _analytics = require("@atlaskit/editor-common/analytics");
12
12
  var _hooks = require("@atlaskit/editor-common/hooks");
13
+ var _keymaps = require("@atlaskit/editor-common/keymaps");
13
14
  var _messages = require("@atlaskit/editor-common/messages");
14
15
  var _editorToolbar = require("@atlaskit/editor-toolbar");
15
16
  var _link = _interopRequireDefault(require("@atlaskit/icon/core/link"));
@@ -30,6 +31,7 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
30
31
  var _ref2 = config || {},
31
32
  getLinkPath = _ref2.getLinkPath,
32
33
  blockLinkHashPrefix = _ref2.blockLinkHashPrefix;
34
+ var shortcut = (0, _keymaps.formatShortcut)(_keymaps.copyLinkToBlock);
33
35
  var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls', 'selection'], function (_ref3) {
34
36
  var blockControlsState = _ref3.blockControlsState,
35
37
  selectionState = _ref3.selectionState;
@@ -90,7 +92,11 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
90
92
  onClick: handleClick,
91
93
  elemBefore: /*#__PURE__*/_react.default.createElement(_link.default, {
92
94
  label: ""
93
- })
95
+ }),
96
+ elemAfter: shortcut ? /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarKeyboardShortcutHint, {
97
+ shortcut: shortcut
98
+ }) : undefined,
99
+ ariaKeyshortcuts: shortcut
94
100
  }, formatMessage(_messages.blockMenuMessages.copyLinkToBlock));
95
101
  };
96
102
  var CopyLinkDropdownItem = exports.CopyLinkDropdownItem = (0, _reactIntlNext.injectIntl)(CopyLinkDropdownItemContent);
@@ -6,16 +6,20 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.SuggestedItemsMenuSection = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
+ var _reactIntlNext = require("react-intl-next");
10
+ var _messages = require("@atlaskit/editor-common/messages");
9
11
  var _editorToolbar = require("@atlaskit/editor-toolbar");
10
12
  var _useSuggestedItems = require("./hooks/useSuggestedItems");
11
13
  var SuggestedItemsMenuSection = exports.SuggestedItemsMenuSection = /*#__PURE__*/_react.default.memo(function (_ref) {
12
14
  var api = _ref.api,
13
15
  children = _ref.children;
14
16
  var suggestedItems = (0, _useSuggestedItems.useSuggestedItems)(api);
17
+ var _useIntl = (0, _reactIntlNext.useIntl)(),
18
+ formatMessage = _useIntl.formatMessage;
15
19
  if (suggestedItems.length === 0) {
16
20
  return null;
17
21
  }
18
22
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
19
- title: "Suggested"
23
+ title: formatMessage(_messages.blockMenuMessages.suggested)
20
24
  }, children);
21
25
  });
@@ -3,6 +3,7 @@ import { createBlockMenuRegistry } from './editor-actions';
3
3
  import { isTransformToTargetDisabled } from './editor-actions/isTransformToTargetDisabled';
4
4
  import { formatNode } from './editor-commands/formatNode';
5
5
  import { transformNode } from './editor-commands/transformNode';
6
+ import { keymapPlugin } from './pm-plugins/keymap';
6
7
  import { blockMenuPluginKey, createPlugin } from './pm-plugins/main';
7
8
  import BlockMenu from './ui/block-menu';
8
9
  import { getBlockMenuComponents } from './ui/block-menu-components';
@@ -23,6 +24,9 @@ export const blockMenuPlugin = ({
23
24
  return [{
24
25
  name: 'blockMenuPlugin',
25
26
  plugin: () => createPlugin(api)
27
+ }, {
28
+ name: 'blockMenuKeymap',
29
+ plugin: () => keymapPlugin(api, config)
26
30
  }];
27
31
  },
28
32
  actions: {
@@ -0,0 +1,56 @@
1
+ import { bindKeymapWithCommand, copyLinkToBlock, keymap } from '@atlaskit/editor-common/keymaps';
2
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { FLAG_ID } from '../blockMenuPluginType';
5
+ import { blockMenuPluginKey } from '../pm-plugins/main';
6
+ import { copyLink } from '../ui/utils/copyLink';
7
+ export function keymapPlugin(api, config) {
8
+ const list = {};
9
+ const copyLinkToBlockCommand = (state, dispatch) => {
10
+ var _api$blockControls, _api$blockControls$sh, _node$attrs;
11
+ // Check if feature flag is enabled
12
+ if (!fg('platform_editor_adf_with_localid')) {
13
+ return false;
14
+ }
15
+
16
+ // Get the preserved selection (only works when block menu is open and selection is preserved)
17
+ const selection = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.preservedSelection;
18
+ if (!selection) {
19
+ return false;
20
+ }
21
+
22
+ // Check if the selection has a valid block range with localId
23
+ const blockRange = expandSelectionToBlockRange(selection);
24
+ if (!blockRange) {
25
+ return false;
26
+ }
27
+ const node = blockRange.$from.nodeAfter;
28
+ if (!(node !== null && node !== void 0 && (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.localId)) {
29
+ return false;
30
+ }
31
+
32
+ // Execute the copy link action
33
+ const {
34
+ getLinkPath,
35
+ blockLinkHashPrefix
36
+ } = config || {};
37
+ copyLink({
38
+ getLinkPath,
39
+ blockLinkHashPrefix,
40
+ selection
41
+ }).then(success => {
42
+ if (success && dispatch) {
43
+ dispatch(state.tr.setMeta(blockMenuPluginKey, {
44
+ showFlag: FLAG_ID.LINK_COPIED_TO_CLIPBOARD
45
+ }));
46
+ }
47
+ });
48
+ return true;
49
+ };
50
+
51
+ // Ignored via go/ees005
52
+ bindKeymapWithCommand(
53
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
54
+ copyLinkToBlock.common, copyLinkToBlockCommand, list);
55
+ return keymap(list);
56
+ }
@@ -1,5 +1,6 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { shouldSuppressKeyboardEvent } from './utils/shouldSuppressKeyboardEvent';
3
4
  export const blockMenuPluginKey = new PluginKey('blockMenuPlugin');
4
5
  export const createPlugin = api => {
5
6
  return new SafePlugin({
@@ -29,14 +30,8 @@ export const createPlugin = api => {
29
30
  }
30
31
 
31
32
  // Block further handling of key events when block menu is open
32
- // Except for backspace/delete/copy/cut/paste/undo/redo which should be handled by the selection preservation plugin
33
- const key = event.key.toLowerCase();
34
- const isMetaCtrl = event.metaKey || event.ctrlKey;
35
- const isBackspaceDelete = ['backspace', 'delete'].includes(key);
36
- const isCopyCutPaste = isMetaCtrl && ['c', 'x', 'v'].includes(key);
37
- const isUndoRedo = isMetaCtrl && ['z', 'y'].includes(key);
38
- const suppressNativeHandling = !isCopyCutPaste && !isBackspaceDelete && !isUndoRedo;
39
- return suppressNativeHandling;
33
+ // Except for backspace/delete/copy/cut/paste/undo/redo/copy-link-to-block which should be handled by the selection preservation plugin
34
+ return shouldSuppressKeyboardEvent(event);
40
35
  }
41
36
  }
42
37
  });
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Determines whether keyboard events should be suppressed when the block menu is open.
3
+ *
4
+ * When the block menu is open, we want to block most keyboard events to prevent
5
+ * unintended interactions. However, certain actions should still be allowed:
6
+ * - Backspace/Delete: Allow deleting selected content
7
+ * - Copy/Cut/Paste: Allow clipboard operations (Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V)
8
+ * - Undo/Redo: Allow undo/redo operations (Cmd/Ctrl+Z, Cmd/Ctrl+Y)
9
+ * - Copy Link to Block: Allow the keyboard shortcut (Cmd/Ctrl+Alt+A)
10
+ *
11
+ * @param event - The keyboard event to check
12
+ * @returns true if the event should be suppressed, false if it should be allowed
13
+ */
14
+ export const shouldSuppressKeyboardEvent = event => {
15
+ const key = event.key.toLowerCase();
16
+ const code = event.code.toLowerCase();
17
+ const isMetaCtrl = event.metaKey || event.ctrlKey;
18
+ const isAlt = event.altKey;
19
+
20
+ // Check for allowed keyboard shortcuts
21
+ const isBackspaceDelete = ['backspace', 'delete'].includes(key);
22
+ const isCopyCutPaste = isMetaCtrl && ['c', 'x', 'v'].includes(key);
23
+ const isUndoRedo = isMetaCtrl && ['z', 'y'].includes(key);
24
+
25
+ // Use event.code to detect physical key 'A' because on macOS Option+A produces 'å'
26
+ const isCopyLinkToBlock = isMetaCtrl && isAlt && code === 'keya';
27
+
28
+ // Suppress all events except the allowed ones
29
+ const suppressNativeHandling = !isCopyCutPaste && !isBackspaceDelete && !isUndoRedo && !isCopyLinkToBlock;
30
+ return suppressNativeHandling;
31
+ };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
4
+ export const MenuSection = ({
5
+ children,
6
+ title,
7
+ hasSeparator
8
+ }) => {
9
+ const {
10
+ formatMessage
11
+ } = useIntl();
12
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
13
+ title: formatMessage(title),
14
+ hasSeparator: hasSeparator
15
+ }, children);
16
+ };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { BLOCK_ACTIONS_COPY_LINK_TO_BLOCK_MENU_ITEM, BLOCK_ACTIONS_MENU_SECTION, BLOCK_ACTIONS_MENU_SECTION_RANK, DELETE_MENU_SECTION, DELETE_MENU_SECTION_RANK, DELETE_MENU_ITEM, POSITION_MENU_SECTION, POSITION_MENU_SECTION_RANK, POSITION_MOVE_DOWN_MENU_ITEM, POSITION_MOVE_UP_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_MENU_ITEM_RANK, TRANSFORM_MENU_SECTION, TRANSFORM_MENU_SECTION_RANK, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_HEADINGS_MENU_SECTION, MAIN_BLOCK_MENU_SECTION_RANK, TRANSFORM_SUGGESTED_MENU_SECTION_RANK, TRANSFORM_SUGGESTED_MENU_ITEM } from '@atlaskit/editor-common/block-menu';
3
+ import { blockMenuMessages } from '@atlaskit/editor-common/messages';
3
4
  import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
4
5
  import { buildChildrenMap, getChildrenMapKey, willComponentRender } from './block-menu-renderer/utils';
5
6
  import { CopyLinkDropdownItem } from './copy-link';
@@ -8,6 +9,7 @@ import { DeleteDropdownItem } from './delete-button';
8
9
  import { DeleteSection } from './delete-section';
9
10
  import { FormatMenuComponent } from './format-menu-nested';
10
11
  import { FormatMenuSection } from './format-menu-section';
12
+ import { MenuSection } from './MenuSection';
11
13
  import { MoveDownDropdownItem } from './move-down';
12
14
  import { MoveUpDropdownItem } from './move-up';
13
15
  import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
@@ -121,8 +123,8 @@ const getTurnIntoMenuComponents = api => {
121
123
  } = {
122
124
  children: null
123
125
  }) => {
124
- return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
125
- title: "Create"
126
+ return /*#__PURE__*/React.createElement(MenuSection, {
127
+ title: blockMenuMessages.create
126
128
  }, children);
127
129
  }
128
130
  }, {
@@ -138,8 +140,8 @@ const getTurnIntoMenuComponents = api => {
138
140
  } = {
139
141
  children: null
140
142
  }) => {
141
- return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
142
- title: "Structure"
143
+ return /*#__PURE__*/React.createElement(MenuSection, {
144
+ title: blockMenuMessages.structure
143
145
  }, children);
144
146
  }
145
147
  }, {
@@ -155,8 +157,8 @@ const getTurnIntoMenuComponents = api => {
155
157
  } = {
156
158
  children: null
157
159
  }) => {
158
- return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
159
- title: "Headings",
160
+ return /*#__PURE__*/React.createElement(MenuSection, {
161
+ title: blockMenuMessages.headings,
160
162
  hasSeparator: true
161
163
  }, children);
162
164
  }
@@ -2,8 +2,9 @@ import React, { useCallback } from 'react';
2
2
  import { injectIntl, useIntl } from 'react-intl-next';
3
3
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
4
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
+ import { copyLinkToBlock, formatShortcut } from '@atlaskit/editor-common/keymaps';
5
6
  import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
6
- import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
7
+ import { ToolbarDropdownItem, ToolbarKeyboardShortcutHint } from '@atlaskit/editor-toolbar';
7
8
  import LinkIcon from '@atlaskit/icon/core/link';
8
9
  import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import { FLAG_ID } from '../blockMenuPluginType';
@@ -25,6 +26,7 @@ const CopyLinkDropdownItemContent = ({
25
26
  getLinkPath,
26
27
  blockLinkHashPrefix
27
28
  } = config || {};
29
+ const shortcut = formatShortcut(copyLinkToBlock);
28
30
  const {
29
31
  preservedSelection,
30
32
  defaultSelection
@@ -89,7 +91,11 @@ const CopyLinkDropdownItemContent = ({
89
91
  onClick: handleClick,
90
92
  elemBefore: /*#__PURE__*/React.createElement(LinkIcon, {
91
93
  label: ""
92
- })
94
+ }),
95
+ elemAfter: shortcut ? /*#__PURE__*/React.createElement(ToolbarKeyboardShortcutHint, {
96
+ shortcut: shortcut
97
+ }) : undefined,
98
+ ariaKeyshortcuts: shortcut
93
99
  }, formatMessage(messages.copyLinkToBlock));
94
100
  };
95
101
  export const CopyLinkDropdownItem = injectIntl(CopyLinkDropdownItemContent);
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { blockMenuMessages } from '@atlaskit/editor-common/messages';
2
4
  import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
3
5
  import { useSuggestedItems } from './hooks/useSuggestedItems';
4
6
  export const SuggestedItemsMenuSection = /*#__PURE__*/React.memo(({
@@ -6,10 +8,13 @@ export const SuggestedItemsMenuSection = /*#__PURE__*/React.memo(({
6
8
  children
7
9
  }) => {
8
10
  const suggestedItems = useSuggestedItems(api);
11
+ const {
12
+ formatMessage
13
+ } = useIntl();
9
14
  if (suggestedItems.length === 0) {
10
15
  return null;
11
16
  }
12
17
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
13
- title: "Suggested"
18
+ title: formatMessage(blockMenuMessages.suggested)
14
19
  }, children);
15
20
  });
@@ -3,6 +3,7 @@ import { createBlockMenuRegistry } from './editor-actions';
3
3
  import { isTransformToTargetDisabled } from './editor-actions/isTransformToTargetDisabled';
4
4
  import { formatNode as _formatNode } from './editor-commands/formatNode';
5
5
  import { transformNode as _transformNode } from './editor-commands/transformNode';
6
+ import { keymapPlugin } from './pm-plugins/keymap';
6
7
  import { blockMenuPluginKey, createPlugin } from './pm-plugins/main';
7
8
  import BlockMenu from './ui/block-menu';
8
9
  import { getBlockMenuComponents } from './ui/block-menu-components';
@@ -24,6 +25,11 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
24
25
  plugin: function plugin() {
25
26
  return createPlugin(api);
26
27
  }
28
+ }, {
29
+ name: 'blockMenuKeymap',
30
+ plugin: function plugin() {
31
+ return keymapPlugin(api, config);
32
+ }
27
33
  }];
28
34
  },
29
35
  actions: {
@@ -0,0 +1,55 @@
1
+ import { bindKeymapWithCommand, copyLinkToBlock, keymap } from '@atlaskit/editor-common/keymaps';
2
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { FLAG_ID } from '../blockMenuPluginType';
5
+ import { blockMenuPluginKey } from '../pm-plugins/main';
6
+ import { copyLink } from '../ui/utils/copyLink';
7
+ export function keymapPlugin(api, config) {
8
+ var list = {};
9
+ var copyLinkToBlockCommand = function copyLinkToBlockCommand(state, dispatch) {
10
+ var _api$blockControls, _node$attrs;
11
+ // Check if feature flag is enabled
12
+ if (!fg('platform_editor_adf_with_localid')) {
13
+ return false;
14
+ }
15
+
16
+ // Get the preserved selection (only works when block menu is open and selection is preserved)
17
+ var selection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
18
+ if (!selection) {
19
+ return false;
20
+ }
21
+
22
+ // Check if the selection has a valid block range with localId
23
+ var blockRange = expandSelectionToBlockRange(selection);
24
+ if (!blockRange) {
25
+ return false;
26
+ }
27
+ var node = blockRange.$from.nodeAfter;
28
+ if (!(node !== null && node !== void 0 && (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.localId)) {
29
+ return false;
30
+ }
31
+
32
+ // Execute the copy link action
33
+ var _ref = config || {},
34
+ getLinkPath = _ref.getLinkPath,
35
+ blockLinkHashPrefix = _ref.blockLinkHashPrefix;
36
+ copyLink({
37
+ getLinkPath: getLinkPath,
38
+ blockLinkHashPrefix: blockLinkHashPrefix,
39
+ selection: selection
40
+ }).then(function (success) {
41
+ if (success && dispatch) {
42
+ dispatch(state.tr.setMeta(blockMenuPluginKey, {
43
+ showFlag: FLAG_ID.LINK_COPIED_TO_CLIPBOARD
44
+ }));
45
+ }
46
+ });
47
+ return true;
48
+ };
49
+
50
+ // Ignored via go/ees005
51
+ bindKeymapWithCommand(
52
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
53
+ copyLinkToBlock.common, copyLinkToBlockCommand, list);
54
+ return keymap(list);
55
+ }
@@ -1,5 +1,6 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { shouldSuppressKeyboardEvent } from './utils/shouldSuppressKeyboardEvent';
3
4
  export var blockMenuPluginKey = new PluginKey('blockMenuPlugin');
4
5
  export var createPlugin = function createPlugin(api) {
5
6
  return new SafePlugin({
@@ -29,14 +30,8 @@ export var createPlugin = function createPlugin(api) {
29
30
  }
30
31
 
31
32
  // Block further handling of key events when block menu is open
32
- // Except for backspace/delete/copy/cut/paste/undo/redo which should be handled by the selection preservation plugin
33
- var key = event.key.toLowerCase();
34
- var isMetaCtrl = event.metaKey || event.ctrlKey;
35
- var isBackspaceDelete = ['backspace', 'delete'].includes(key);
36
- var isCopyCutPaste = isMetaCtrl && ['c', 'x', 'v'].includes(key);
37
- var isUndoRedo = isMetaCtrl && ['z', 'y'].includes(key);
38
- var suppressNativeHandling = !isCopyCutPaste && !isBackspaceDelete && !isUndoRedo;
39
- return suppressNativeHandling;
33
+ // Except for backspace/delete/copy/cut/paste/undo/redo/copy-link-to-block which should be handled by the selection preservation plugin
34
+ return shouldSuppressKeyboardEvent(event);
40
35
  }
41
36
  }
42
37
  });
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Determines whether keyboard events should be suppressed when the block menu is open.
3
+ *
4
+ * When the block menu is open, we want to block most keyboard events to prevent
5
+ * unintended interactions. However, certain actions should still be allowed:
6
+ * - Backspace/Delete: Allow deleting selected content
7
+ * - Copy/Cut/Paste: Allow clipboard operations (Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V)
8
+ * - Undo/Redo: Allow undo/redo operations (Cmd/Ctrl+Z, Cmd/Ctrl+Y)
9
+ * - Copy Link to Block: Allow the keyboard shortcut (Cmd/Ctrl+Alt+A)
10
+ *
11
+ * @param event - The keyboard event to check
12
+ * @returns true if the event should be suppressed, false if it should be allowed
13
+ */
14
+ export var shouldSuppressKeyboardEvent = function shouldSuppressKeyboardEvent(event) {
15
+ var key = event.key.toLowerCase();
16
+ var code = event.code.toLowerCase();
17
+ var isMetaCtrl = event.metaKey || event.ctrlKey;
18
+ var isAlt = event.altKey;
19
+
20
+ // Check for allowed keyboard shortcuts
21
+ var isBackspaceDelete = ['backspace', 'delete'].includes(key);
22
+ var isCopyCutPaste = isMetaCtrl && ['c', 'x', 'v'].includes(key);
23
+ var isUndoRedo = isMetaCtrl && ['z', 'y'].includes(key);
24
+
25
+ // Use event.code to detect physical key 'A' because on macOS Option+A produces 'å'
26
+ var isCopyLinkToBlock = isMetaCtrl && isAlt && code === 'keya';
27
+
28
+ // Suppress all events except the allowed ones
29
+ var suppressNativeHandling = !isCopyCutPaste && !isBackspaceDelete && !isUndoRedo && !isCopyLinkToBlock;
30
+ return suppressNativeHandling;
31
+ };
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
4
+ export var MenuSection = function MenuSection(_ref) {
5
+ var children = _ref.children,
6
+ title = _ref.title,
7
+ hasSeparator = _ref.hasSeparator;
8
+ var _useIntl = useIntl(),
9
+ formatMessage = _useIntl.formatMessage;
10
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
11
+ title: formatMessage(title),
12
+ hasSeparator: hasSeparator
13
+ }, children);
14
+ };
@@ -1,6 +1,7 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import React from 'react';
3
3
  import { BLOCK_ACTIONS_COPY_LINK_TO_BLOCK_MENU_ITEM, BLOCK_ACTIONS_MENU_SECTION, BLOCK_ACTIONS_MENU_SECTION_RANK, DELETE_MENU_SECTION, DELETE_MENU_SECTION_RANK, DELETE_MENU_ITEM, POSITION_MENU_SECTION, POSITION_MENU_SECTION_RANK, POSITION_MOVE_DOWN_MENU_ITEM, POSITION_MOVE_UP_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_MENU_ITEM_RANK, TRANSFORM_MENU_SECTION, TRANSFORM_MENU_SECTION_RANK, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_HEADINGS_MENU_SECTION, MAIN_BLOCK_MENU_SECTION_RANK, TRANSFORM_SUGGESTED_MENU_SECTION_RANK, TRANSFORM_SUGGESTED_MENU_ITEM } from '@atlaskit/editor-common/block-menu';
4
+ import { blockMenuMessages } from '@atlaskit/editor-common/messages';
4
5
  import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
5
6
  import { buildChildrenMap, getChildrenMapKey, willComponentRender } from './block-menu-renderer/utils';
6
7
  import { CopyLinkDropdownItem } from './copy-link';
@@ -9,6 +10,7 @@ import { DeleteDropdownItem } from './delete-button';
9
10
  import { DeleteSection } from './delete-section';
10
11
  import { FormatMenuComponent } from './format-menu-nested';
11
12
  import { FormatMenuSection } from './format-menu-section';
13
+ import { MenuSection } from './MenuSection';
12
14
  import { MoveDownDropdownItem } from './move-down';
13
15
  import { MoveUpDropdownItem } from './move-up';
14
16
  import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
@@ -132,8 +134,8 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
132
134
  children: null
133
135
  },
134
136
  children = _ref3.children;
135
- return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
136
- title: "Create"
137
+ return /*#__PURE__*/React.createElement(MenuSection, {
138
+ title: blockMenuMessages.create
137
139
  }, children);
138
140
  }
139
141
  }, {
@@ -149,8 +151,8 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
149
151
  children: null
150
152
  },
151
153
  children = _ref4.children;
152
- return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
153
- title: "Structure"
154
+ return /*#__PURE__*/React.createElement(MenuSection, {
155
+ title: blockMenuMessages.structure
154
156
  }, children);
155
157
  }
156
158
  }, {
@@ -166,8 +168,8 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
166
168
  children: null
167
169
  },
168
170
  children = _ref5.children;
169
- return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
170
- title: "Headings",
171
+ return /*#__PURE__*/React.createElement(MenuSection, {
172
+ title: blockMenuMessages.headings,
171
173
  hasSeparator: true
172
174
  }, children);
173
175
  }
@@ -2,8 +2,9 @@ import React, { useCallback } from 'react';
2
2
  import { injectIntl, useIntl } from 'react-intl-next';
3
3
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
4
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
+ import { copyLinkToBlock, formatShortcut } from '@atlaskit/editor-common/keymaps';
5
6
  import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
6
- import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
7
+ import { ToolbarDropdownItem, ToolbarKeyboardShortcutHint } from '@atlaskit/editor-toolbar';
7
8
  import LinkIcon from '@atlaskit/icon/core/link';
8
9
  import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import { FLAG_ID } from '../blockMenuPluginType';
@@ -21,6 +22,7 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
21
22
  var _ref2 = config || {},
22
23
  getLinkPath = _ref2.getLinkPath,
23
24
  blockLinkHashPrefix = _ref2.blockLinkHashPrefix;
25
+ var shortcut = formatShortcut(copyLinkToBlock);
24
26
  var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'selection'], function (_ref3) {
25
27
  var blockControlsState = _ref3.blockControlsState,
26
28
  selectionState = _ref3.selectionState;
@@ -81,7 +83,11 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
81
83
  onClick: handleClick,
82
84
  elemBefore: /*#__PURE__*/React.createElement(LinkIcon, {
83
85
  label: ""
84
- })
86
+ }),
87
+ elemAfter: shortcut ? /*#__PURE__*/React.createElement(ToolbarKeyboardShortcutHint, {
88
+ shortcut: shortcut
89
+ }) : undefined,
90
+ ariaKeyshortcuts: shortcut
85
91
  }, formatMessage(messages.copyLinkToBlock));
86
92
  };
87
93
  export var CopyLinkDropdownItem = injectIntl(CopyLinkDropdownItemContent);
@@ -1,14 +1,18 @@
1
1
  import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { blockMenuMessages } from '@atlaskit/editor-common/messages';
2
4
  import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
3
5
  import { useSuggestedItems } from './hooks/useSuggestedItems';
4
6
  export var SuggestedItemsMenuSection = /*#__PURE__*/React.memo(function (_ref) {
5
7
  var api = _ref.api,
6
8
  children = _ref.children;
7
9
  var suggestedItems = useSuggestedItems(api);
10
+ var _useIntl = useIntl(),
11
+ formatMessage = _useIntl.formatMessage;
8
12
  if (suggestedItems.length === 0) {
9
13
  return null;
10
14
  }
11
15
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
12
- title: "Suggested"
16
+ title: formatMessage(blockMenuMessages.suggested)
13
17
  }, children);
14
18
  });
@@ -0,0 +1,4 @@
1
+ import type { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { BlockMenuPlugin, BlockMenuPluginOptions } from '../blockMenuPluginType';
4
+ export declare function keymapPlugin(api: ExtractInjectionAPI<BlockMenuPlugin> | undefined, config: BlockMenuPluginOptions | undefined): SafePlugin;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Determines whether keyboard events should be suppressed when the block menu is open.
3
+ *
4
+ * When the block menu is open, we want to block most keyboard events to prevent
5
+ * unintended interactions. However, certain actions should still be allowed:
6
+ * - Backspace/Delete: Allow deleting selected content
7
+ * - Copy/Cut/Paste: Allow clipboard operations (Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V)
8
+ * - Undo/Redo: Allow undo/redo operations (Cmd/Ctrl+Z, Cmd/Ctrl+Y)
9
+ * - Copy Link to Block: Allow the keyboard shortcut (Cmd/Ctrl+Alt+A)
10
+ *
11
+ * @param event - The keyboard event to check
12
+ * @returns true if the event should be suppressed, false if it should be allowed
13
+ */
14
+ export declare const shouldSuppressKeyboardEvent: (event: KeyboardEvent) => boolean;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { type MessageDescriptor } from 'react-intl-next';
3
+ type MenuSectionProps = {
4
+ children?: React.ReactNode;
5
+ hasSeparator?: boolean;
6
+ title: MessageDescriptor;
7
+ };
8
+ export declare const MenuSection: ({ children, title, hasSeparator, }: MenuSectionProps) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { BlockMenuPlugin, BlockMenuPluginOptions } from '../blockMenuPluginType';
4
+ export declare function keymapPlugin(api: ExtractInjectionAPI<BlockMenuPlugin> | undefined, config: BlockMenuPluginOptions | undefined): SafePlugin;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Determines whether keyboard events should be suppressed when the block menu is open.
3
+ *
4
+ * When the block menu is open, we want to block most keyboard events to prevent
5
+ * unintended interactions. However, certain actions should still be allowed:
6
+ * - Backspace/Delete: Allow deleting selected content
7
+ * - Copy/Cut/Paste: Allow clipboard operations (Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V)
8
+ * - Undo/Redo: Allow undo/redo operations (Cmd/Ctrl+Z, Cmd/Ctrl+Y)
9
+ * - Copy Link to Block: Allow the keyboard shortcut (Cmd/Ctrl+Alt+A)
10
+ *
11
+ * @param event - The keyboard event to check
12
+ * @returns true if the event should be suppressed, false if it should be allowed
13
+ */
14
+ export declare const shouldSuppressKeyboardEvent: (event: KeyboardEvent) => boolean;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { type MessageDescriptor } from 'react-intl-next';
3
+ type MenuSectionProps = {
4
+ children?: React.ReactNode;
5
+ hasSeparator?: boolean;
6
+ title: MessageDescriptor;
7
+ };
8
+ export declare const MenuSection: ({ children, title, hasSeparator, }: MenuSectionProps) => React.JSX.Element;
9
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "6.0.21",
3
+ "version": "6.0.23",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -46,7 +46,7 @@
46
46
  "@atlaskit/platform-feature-flags-react": "^0.4.0",
47
47
  "@atlaskit/primitives": "^17.1.0",
48
48
  "@atlaskit/prosemirror-history": "^0.2.0",
49
- "@atlaskit/tmp-editor-statsig": "^16.27.0",
49
+ "@atlaskit/tmp-editor-statsig": "^16.30.0",
50
50
  "@atlaskit/tokens": "^10.1.0",
51
51
  "@babel/runtime": "^7.0.0"
52
52
  },