@atlaskit/editor-plugin-block-menu 0.0.5 → 0.0.7

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 (38) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/afm-dev-agents/tsconfig.json +3 -0
  4. package/afm-jira/tsconfig.json +3 -0
  5. package/afm-passionfruit/tsconfig.json +3 -0
  6. package/afm-post-office/tsconfig.json +3 -0
  7. package/afm-rovo-extension/tsconfig.json +3 -0
  8. package/afm-townsquare/tsconfig.json +3 -0
  9. package/dist/cjs/blockMenuPlugin.js +1 -1
  10. package/dist/cjs/ui/block-menu-components.js +65 -37
  11. package/dist/cjs/ui/block-menu.js +25 -10
  12. package/dist/cjs/ui/copy-block.js +82 -0
  13. package/dist/cjs/ui/move-down.js +50 -0
  14. package/dist/cjs/ui/move-up.js +50 -0
  15. package/dist/es2019/blockMenuPlugin.js +1 -1
  16. package/dist/es2019/ui/block-menu-components.js +60 -36
  17. package/dist/es2019/ui/block-menu.js +27 -11
  18. package/dist/es2019/ui/copy-block.js +75 -0
  19. package/dist/es2019/ui/move-down.js +48 -0
  20. package/dist/es2019/ui/move-up.js +48 -0
  21. package/dist/esm/blockMenuPlugin.js +1 -1
  22. package/dist/esm/ui/block-menu-components.js +65 -37
  23. package/dist/esm/ui/block-menu.js +26 -11
  24. package/dist/esm/ui/copy-block.js +75 -0
  25. package/dist/esm/ui/move-down.js +43 -0
  26. package/dist/esm/ui/move-up.js +43 -0
  27. package/dist/types/blockMenuPluginType.d.ts +6 -1
  28. package/dist/types/ui/block-menu-components.d.ts +3 -1
  29. package/dist/types/ui/copy-block.d.ts +11 -0
  30. package/dist/types/ui/move-down.d.ts +11 -0
  31. package/dist/types/ui/move-up.d.ts +11 -0
  32. package/dist/types-ts4.5/blockMenuPluginType.d.ts +3 -1
  33. package/dist/types-ts4.5/ui/block-menu-components.d.ts +3 -1
  34. package/dist/types-ts4.5/ui/copy-block.d.ts +11 -0
  35. package/dist/types-ts4.5/ui/move-down.d.ts +11 -0
  36. package/dist/types-ts4.5/ui/move-up.d.ts +11 -0
  37. package/package.json +5 -4
  38. package/tsconfig.json +1 -4
@@ -1,10 +1,11 @@
1
1
  /* block-menu.tsx generated by @compiled/babel-plugin v0.36.1 */
2
2
  import "./block-menu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
- import React, { useContext } from 'react';
4
+ import React, { useContext, useEffect } from 'react';
5
5
  import { injectIntl } from 'react-intl-next';
6
6
  import { cx } from '@atlaskit/css';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
+ import { DRAG_HANDLE_SELECTOR, DRAG_HANDLE_WIDTH } from '@atlaskit/editor-common/styles';
8
9
  import { Popup } from '@atlaskit/editor-common/ui';
9
10
  import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners } from '@atlaskit/editor-common/ui-react';
10
11
  import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
@@ -14,9 +15,7 @@ import { BlockMenuRenderer } from './block-menu-renderer';
14
15
  const styles = {
15
16
  base: "_2rkoglpi _bfhk1bhr _16qs1cd0"
16
17
  };
17
- const DRAG_HANDLE_SELECTOR = '[data-editor-block-ctrl-drag-handle=true]';
18
- const DRAG_HANDLE_WIDTH = 12;
19
- const DRAG_HANDLE_PADDING = 5;
18
+ const DRAG_HANDLE_OFFSET_PADDING = 5;
20
19
  const PopupWithListeners = withReactEditorViewOuterListeners(Popup);
21
20
  const BlockMenuContent = ({
22
21
  api
@@ -64,20 +63,37 @@ const BlockMenu = ({
64
63
  });
65
64
  const hasFocus = (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
66
65
  const hasSelection = !!editorView && !editorView.state.selection.empty;
66
+ useEffect(() => {
67
+ var _api$userIntent;
68
+ if (!isMenuOpen || !menuTriggerBy || !isSelectedViaDragHandle || !hasFocus || !hasSelection || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
69
+ return;
70
+ }
71
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('blockMenuOpen'));
72
+ }, [api, isMenuOpen, menuTriggerBy, isSelectedViaDragHandle, hasFocus, hasSelection, currentUserIntent]);
67
73
  if (!isMenuOpen) {
68
74
  return null;
69
75
  }
70
76
  const closeMenu = () => {
71
- var _api$blockControls;
72
- api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.toggleBlockMenu({
73
- closeMenu: true
74
- }));
77
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(({
78
+ tr
79
+ }) => {
80
+ var _api$blockControls, _api$userIntent2;
81
+ api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.toggleBlockMenu({
82
+ closeMenu: true
83
+ })({
84
+ tr
85
+ });
86
+ api === null || api === void 0 ? void 0 : (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent(currentUserIntent === 'blockMenuOpen' ? 'default' : currentUserIntent || 'default')({
87
+ tr
88
+ });
89
+ return tr;
90
+ });
75
91
  };
76
- if (!menuTriggerBy || !isSelectedViaDragHandle || !hasFocus || !hasSelection || currentUserIntent === 'dragging') {
92
+ if (!menuTriggerBy || !isSelectedViaDragHandle || !hasFocus || !hasSelection || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
77
93
  closeMenu();
78
94
  return null;
79
95
  }
80
- const targetHandleRef = (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
96
+ const targetHandleRef = editorView === null || editorView === void 0 ? void 0 : (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
81
97
  if (targetHandleRef instanceof HTMLElement) {
82
98
  return /*#__PURE__*/React.createElement(PopupWithListeners, {
83
99
  alignX: 'left',
@@ -91,7 +107,7 @@ const BlockMenu = ({
91
107
  zIndex: akEditorFloatingOverlapPanelZIndex,
92
108
  forcePlacement: true,
93
109
  stick: true,
94
- offset: [DRAG_HANDLE_WIDTH + DRAG_HANDLE_PADDING, 0]
110
+ offset: [DRAG_HANDLE_WIDTH + DRAG_HANDLE_OFFSET_PADDING, 0]
95
111
  }, /*#__PURE__*/React.createElement(BlockMenuContent, {
96
112
  api: api
97
113
  }));
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { injectIntl, useIntl } from 'react-intl-next';
3
+ import { messages } from '@atlaskit/editor-common/block-menu';
4
+ import { copyHTMLToClipboard } from '@atlaskit/editor-common/clipboard';
5
+ import { toDOM, copyDomNode } from '@atlaskit/editor-common/copy-button';
6
+ import { Fragment, DOMSerializer } from '@atlaskit/editor-prosemirror/model';
7
+ import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
8
+ import { isTableSelected } from '@atlaskit/editor-tables/utils';
9
+ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
10
+ import CopyIcon from '@atlaskit/icon/core/copy';
11
+ const toDOMFromFragment = (fragment, schema) => {
12
+ return DOMSerializer.fromSchema(schema).serializeFragment(fragment);
13
+ };
14
+ const CopyBlockMenuItem = ({
15
+ api
16
+ }) => {
17
+ const {
18
+ formatMessage
19
+ } = useIntl();
20
+ const copyHandler = event => {
21
+ var _api$selection, _api$selection$shared, _api$selection$shared2;
22
+ // prevent click event from bubbling up to the ancestor elements
23
+ event.stopPropagation();
24
+ // get the current selection
25
+ const selection = api === null || api === void 0 ? void 0 : (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : (_api$selection$shared = _api$selection.sharedState) === null || _api$selection$shared === void 0 ? void 0 : (_api$selection$shared2 = _api$selection$shared.currentState()) === null || _api$selection$shared2 === void 0 ? void 0 : _api$selection$shared2.selection;
26
+ if (selection) {
27
+ const schema = selection.$from.doc.type.schema;
28
+ // for texts and inline nodes
29
+ if (selection instanceof TextSelection) {
30
+ var _fragment;
31
+ let fragment = selection === null || selection === void 0 ? void 0 : selection.content().content;
32
+ if (!fragment) {
33
+ return;
34
+ }
35
+ // if text is inside of a layout column, the selection contains the layoutSection and layoutColumn for some reason
36
+ // But the layoutSection only contains the layoutColumn that the selected text is in, hence we can use the .firstChild
37
+ if ((_fragment = fragment) !== null && _fragment !== void 0 && _fragment.firstChild && fragment.firstChild.type.name === 'layoutSection') {
38
+ const layoutSectionNode = fragment.firstChild;
39
+ const layoutColumnNode = layoutSectionNode.firstChild;
40
+ const layoutContent = layoutColumnNode === null || layoutColumnNode === void 0 ? void 0 : layoutColumnNode.firstChild;
41
+ fragment = (layoutContent === null || layoutContent === void 0 ? void 0 : layoutContent.content) || Fragment.empty;
42
+ }
43
+ const domNode = toDOMFromFragment(fragment, schema);
44
+ const div = document.createElement('div');
45
+ div.appendChild(domNode);
46
+ copyHTMLToClipboard(div);
47
+ }
48
+
49
+ // for table
50
+ if (isTableSelected(selection)) {
51
+ const nodeType = schema.nodes.table;
52
+ const tableNode = selection.$anchorCell.node(-1);
53
+ if (!tableNode) {
54
+ return;
55
+ }
56
+ const domNode = toDOM(tableNode, schema);
57
+ copyDomNode(domNode, nodeType, selection);
58
+ }
59
+
60
+ // for other nodes
61
+ if (selection instanceof NodeSelection) {
62
+ const nodeType = selection.node.type;
63
+ const domNode = toDOM(selection.node, schema);
64
+ copyDomNode(domNode, nodeType, selection);
65
+ }
66
+ }
67
+ };
68
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
69
+ elemBefore: /*#__PURE__*/React.createElement(CopyIcon, {
70
+ label: ""
71
+ }),
72
+ onClick: e => copyHandler(e)
73
+ }, formatMessage(messages.copyBlock));
74
+ };
75
+ export default injectIntl(CopyBlockMenuItem);
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { useIntl, injectIntl } from 'react-intl-next';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
+ import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { DIRECTION } from '@atlaskit/editor-common/types';
6
+ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
7
+ import ArrowDownIcon from '@atlaskit/icon/core/arrow-down';
8
+ const MoveDownDropdownItemContent = ({
9
+ api
10
+ }) => {
11
+ const {
12
+ formatMessage
13
+ } = useIntl();
14
+ const {
15
+ canMoveDown
16
+ } = useSharedPluginStateWithSelector(api, ['blockControls'], ({
17
+ blockControlsState
18
+ }) => {
19
+ var _blockControlsState$b;
20
+ return {
21
+ canMoveDown: blockControlsState === null || blockControlsState === void 0 ? void 0 : (_blockControlsState$b = blockControlsState.blockMenuOptions) === null || _blockControlsState$b === void 0 ? void 0 : _blockControlsState$b.canMoveDown
22
+ };
23
+ });
24
+ const handleClick = () => {
25
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(({
26
+ tr
27
+ }) => {
28
+ var _api$blockControls, _api$blockControls$co, _api$blockControls2, _api$blockControls2$c;
29
+ api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$co = _api$blockControls.commands) === null || _api$blockControls$co === void 0 ? void 0 : _api$blockControls$co.moveNodeWithBlockMenu(DIRECTION.DOWN)({
30
+ tr
31
+ });
32
+ api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
33
+ closeMenu: true
34
+ })({
35
+ tr
36
+ });
37
+ return tr;
38
+ });
39
+ };
40
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
41
+ onClick: handleClick,
42
+ elemBefore: /*#__PURE__*/React.createElement(ArrowDownIcon, {
43
+ label: ""
44
+ }),
45
+ isDisabled: !canMoveDown
46
+ }, formatMessage(messages.moveDownBlock));
47
+ };
48
+ export const MoveDownDropdownItem = injectIntl(MoveDownDropdownItemContent);
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { useIntl, injectIntl } from 'react-intl-next';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
+ import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { DIRECTION } from '@atlaskit/editor-common/types';
6
+ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
7
+ import ArrowUpIcon from '@atlaskit/icon/core/arrow-up';
8
+ const MoveUpDropdownItemContent = ({
9
+ api
10
+ }) => {
11
+ const {
12
+ formatMessage
13
+ } = useIntl();
14
+ const {
15
+ canMoveUp
16
+ } = useSharedPluginStateWithSelector(api, ['blockControls'], ({
17
+ blockControlsState
18
+ }) => {
19
+ var _blockControlsState$b;
20
+ return {
21
+ canMoveUp: blockControlsState === null || blockControlsState === void 0 ? void 0 : (_blockControlsState$b = blockControlsState.blockMenuOptions) === null || _blockControlsState$b === void 0 ? void 0 : _blockControlsState$b.canMoveUp
22
+ };
23
+ });
24
+ const handleClick = () => {
25
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(({
26
+ tr
27
+ }) => {
28
+ var _api$blockControls, _api$blockControls$co, _api$blockControls2, _api$blockControls2$c;
29
+ api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$co = _api$blockControls.commands) === null || _api$blockControls$co === void 0 ? void 0 : _api$blockControls$co.moveNodeWithBlockMenu(DIRECTION.UP)({
30
+ tr
31
+ });
32
+ api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
33
+ closeMenu: true
34
+ })({
35
+ tr
36
+ });
37
+ return tr;
38
+ });
39
+ };
40
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
41
+ onClick: handleClick,
42
+ elemBefore: /*#__PURE__*/React.createElement(ArrowUpIcon, {
43
+ label: ""
44
+ }),
45
+ isDisabled: !canMoveUp
46
+ }, formatMessage(messages.moveUpBlock));
47
+ };
48
+ export const MoveUpDropdownItem = injectIntl(MoveUpDropdownItemContent);
@@ -6,7 +6,7 @@ import { getBlockMenuComponents } from './ui/block-menu-components';
6
6
  export var blockMenuPlugin = function blockMenuPlugin(_ref) {
7
7
  var api = _ref.api;
8
8
  var registry = createBlockMenuRegistry();
9
- registry.register(getBlockMenuComponents());
9
+ registry.register(getBlockMenuComponents(api));
10
10
  return {
11
11
  name: 'blockMenu',
12
12
  pmPlugins: function pmPlugins() {
@@ -1,14 +1,49 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
1
2
  import React from 'react';
2
3
  import { ToolbarDropdownItem, ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
3
4
  import JiraIcon from '@atlaskit/icon-lab/core/jira';
4
- import ArrowDownIcon from '@atlaskit/icon/core/arrow-down';
5
- import ArrowUpIcon from '@atlaskit/icon/core/arrow-up';
6
5
  import ChangesIcon from '@atlaskit/icon/core/changes';
7
6
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
8
7
  import DeleteIcon from '@atlaskit/icon/core/delete';
9
8
  import ListBulletedIcon from '@atlaskit/icon/core/list-bulleted';
10
9
  import TaskIcon from '@atlaskit/icon/core/task';
11
- export var getBlockMenuComponents = function getBlockMenuComponents() {
10
+ import CopyBlockMenuItem from './copy-block';
11
+ import { MoveDownDropdownItem } from './move-down';
12
+ import { MoveUpDropdownItem } from './move-up';
13
+ var getMoveUpMoveDownMenuComponents = function getMoveUpMoveDownMenuComponents(api) {
14
+ var _api$blockControls;
15
+ if (!(api !== null && api !== void 0 && (_api$blockControls = api.blockControls) !== null && _api$blockControls !== void 0 && _api$blockControls.commands.moveNode)) {
16
+ return [];
17
+ }
18
+ return [{
19
+ type: 'block-menu-item',
20
+ key: 'block-menu-item-move-up',
21
+ parent: {
22
+ type: 'block-menu-section',
23
+ key: 'block-menu-section-move-up-down',
24
+ rank: 100
25
+ },
26
+ component: function component() {
27
+ return /*#__PURE__*/React.createElement(MoveUpDropdownItem, {
28
+ api: api
29
+ });
30
+ }
31
+ }, {
32
+ type: 'block-menu-item',
33
+ key: 'block-menu-item-move-down',
34
+ parent: {
35
+ type: 'block-menu-section',
36
+ key: 'block-menu-section-move-up-down',
37
+ rank: 200
38
+ },
39
+ component: function component() {
40
+ return /*#__PURE__*/React.createElement(MoveDownDropdownItem, {
41
+ api: api
42
+ });
43
+ }
44
+ }];
45
+ };
46
+ export var getBlockMenuComponents = function getBlockMenuComponents(api) {
12
47
  return [{
13
48
  type: 'block-menu-section',
14
49
  key: 'block-menu-section-format',
@@ -19,7 +54,7 @@ export var getBlockMenuComponents = function getBlockMenuComponents() {
19
54
  }
20
55
  }, {
21
56
  type: 'block-menu-section',
22
- key: 'block-menu-section-move-up-down',
57
+ key: 'block-menu-section-copy',
23
58
  rank: 200,
24
59
  component: function component(_ref2) {
25
60
  var children = _ref2.children;
@@ -27,9 +62,22 @@ export var getBlockMenuComponents = function getBlockMenuComponents() {
27
62
  hasSeparator: true
28
63
  }, children);
29
64
  }
65
+ }, {
66
+ type: 'block-menu-item',
67
+ key: 'block-menu-copy-block',
68
+ parent: {
69
+ type: 'block-menu-section',
70
+ key: 'block-menu-section-copy',
71
+ rank: 200
72
+ },
73
+ component: function component() {
74
+ return /*#__PURE__*/React.createElement(CopyBlockMenuItem, {
75
+ api: api
76
+ });
77
+ }
30
78
  }, {
31
79
  type: 'block-menu-section',
32
- key: 'block-menu-section-delete',
80
+ key: 'block-menu-section-move-up-down',
33
81
  rank: 300,
34
82
  component: function component(_ref3) {
35
83
  var children = _ref3.children;
@@ -37,6 +85,16 @@ export var getBlockMenuComponents = function getBlockMenuComponents() {
37
85
  hasSeparator: true
38
86
  }, children);
39
87
  }
88
+ }, {
89
+ type: 'block-menu-section',
90
+ key: 'block-menu-section-delete',
91
+ rank: 400,
92
+ component: function component(_ref4) {
93
+ var children = _ref4.children;
94
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
95
+ hasSeparator: true
96
+ }, children);
97
+ }
40
98
  }, {
41
99
  type: 'block-menu-nested',
42
100
  key: 'nested-menu',
@@ -79,37 +137,7 @@ export var getBlockMenuComponents = function getBlockMenuComponents() {
79
137
  })
80
138
  }, "Create Jira work item");
81
139
  }
82
- }, {
83
- type: 'block-menu-item',
84
- key: 'block-menu-item-move-up',
85
- parent: {
86
- type: 'block-menu-section',
87
- key: 'block-menu-section-move-up-down',
88
- rank: 100
89
- },
90
- component: function component() {
91
- return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
92
- elemBefore: /*#__PURE__*/React.createElement(ArrowUpIcon, {
93
- label: ""
94
- })
95
- }, "Move up");
96
- }
97
- }, {
98
- type: 'block-menu-item',
99
- key: 'block-menu-item-move-down',
100
- parent: {
101
- type: 'block-menu-section',
102
- key: 'block-menu-section-move-up-down',
103
- rank: 200
104
- },
105
- component: function component() {
106
- return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
107
- elemBefore: /*#__PURE__*/React.createElement(ArrowDownIcon, {
108
- label: ""
109
- })
110
- }, "Move down");
111
- }
112
- }, {
140
+ }].concat(_toConsumableArray(getMoveUpMoveDownMenuComponents(api)), [{
113
141
  type: 'block-menu-item',
114
142
  key: 'block-menu-item-delete',
115
143
  parent: {
@@ -124,5 +152,5 @@ export var getBlockMenuComponents = function getBlockMenuComponents() {
124
152
  })
125
153
  }, "Delete");
126
154
  }
127
- }];
155
+ }]);
128
156
  };
@@ -1,10 +1,11 @@
1
1
  /* block-menu.tsx generated by @compiled/babel-plugin v0.36.1 */
2
2
  import "./block-menu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
- import React, { useContext } from 'react';
4
+ import React, { useContext, useEffect } from 'react';
5
5
  import { injectIntl } from 'react-intl-next';
6
6
  import { cx } from '@atlaskit/css';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
+ import { DRAG_HANDLE_SELECTOR, DRAG_HANDLE_WIDTH } from '@atlaskit/editor-common/styles';
8
9
  import { Popup } from '@atlaskit/editor-common/ui';
9
10
  import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners } from '@atlaskit/editor-common/ui-react';
10
11
  import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
@@ -14,9 +15,7 @@ import { BlockMenuRenderer } from './block-menu-renderer';
14
15
  var styles = {
15
16
  base: "_2rkoglpi _bfhk1bhr _16qs1cd0"
16
17
  };
17
- var DRAG_HANDLE_SELECTOR = '[data-editor-block-ctrl-drag-handle=true]';
18
- var DRAG_HANDLE_WIDTH = 12;
19
- var DRAG_HANDLE_PADDING = 5;
18
+ var DRAG_HANDLE_OFFSET_PADDING = 5;
20
19
  var PopupWithListeners = withReactEditorViewOuterListeners(Popup);
21
20
  var BlockMenuContent = function BlockMenuContent(_ref) {
22
21
  var _api$blockMenu;
@@ -67,20 +66,36 @@ var BlockMenu = function BlockMenu(_ref2) {
67
66
  currentUserIntent = _useSharedPluginState.currentUserIntent;
68
67
  var hasFocus = (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
69
68
  var hasSelection = !!editorView && !editorView.state.selection.empty;
69
+ useEffect(function () {
70
+ var _api$userIntent;
71
+ if (!isMenuOpen || !menuTriggerBy || !isSelectedViaDragHandle || !hasFocus || !hasSelection || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
72
+ return;
73
+ }
74
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('blockMenuOpen'));
75
+ }, [api, isMenuOpen, menuTriggerBy, isSelectedViaDragHandle, hasFocus, hasSelection, currentUserIntent]);
70
76
  if (!isMenuOpen) {
71
77
  return null;
72
78
  }
73
79
  var closeMenu = function closeMenu() {
74
- var _api$blockControls;
75
- api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.toggleBlockMenu({
76
- closeMenu: true
77
- }));
80
+ api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
81
+ var _api$blockControls, _api$userIntent2;
82
+ var tr = _ref3.tr;
83
+ api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu({
84
+ closeMenu: true
85
+ })({
86
+ tr: tr
87
+ });
88
+ api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent(currentUserIntent === 'blockMenuOpen' ? 'default' : currentUserIntent || 'default')({
89
+ tr: tr
90
+ });
91
+ return tr;
92
+ });
78
93
  };
79
- if (!menuTriggerBy || !isSelectedViaDragHandle || !hasFocus || !hasSelection || currentUserIntent === 'dragging') {
94
+ if (!menuTriggerBy || !isSelectedViaDragHandle || !hasFocus || !hasSelection || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
80
95
  closeMenu();
81
96
  return null;
82
97
  }
83
- var targetHandleRef = (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
98
+ var targetHandleRef = editorView === null || editorView === void 0 || (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
84
99
  if (targetHandleRef instanceof HTMLElement) {
85
100
  return /*#__PURE__*/React.createElement(PopupWithListeners, {
86
101
  alignX: 'left',
@@ -94,7 +109,7 @@ var BlockMenu = function BlockMenu(_ref2) {
94
109
  zIndex: akEditorFloatingOverlapPanelZIndex,
95
110
  forcePlacement: true,
96
111
  stick: true,
97
- offset: [DRAG_HANDLE_WIDTH + DRAG_HANDLE_PADDING, 0]
112
+ offset: [DRAG_HANDLE_WIDTH + DRAG_HANDLE_OFFSET_PADDING, 0]
98
113
  }, /*#__PURE__*/React.createElement(BlockMenuContent, {
99
114
  api: api
100
115
  }));
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { injectIntl, useIntl } from 'react-intl-next';
3
+ import { messages } from '@atlaskit/editor-common/block-menu';
4
+ import { copyHTMLToClipboard } from '@atlaskit/editor-common/clipboard';
5
+ import { toDOM, copyDomNode } from '@atlaskit/editor-common/copy-button';
6
+ import { Fragment, DOMSerializer } from '@atlaskit/editor-prosemirror/model';
7
+ import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
8
+ import { isTableSelected } from '@atlaskit/editor-tables/utils';
9
+ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
10
+ import CopyIcon from '@atlaskit/icon/core/copy';
11
+ var toDOMFromFragment = function toDOMFromFragment(fragment, schema) {
12
+ return DOMSerializer.fromSchema(schema).serializeFragment(fragment);
13
+ };
14
+ var CopyBlockMenuItem = function CopyBlockMenuItem(_ref) {
15
+ var api = _ref.api;
16
+ var _useIntl = useIntl(),
17
+ formatMessage = _useIntl.formatMessage;
18
+ var copyHandler = function copyHandler(event) {
19
+ var _api$selection;
20
+ // prevent click event from bubbling up to the ancestor elements
21
+ event.stopPropagation();
22
+ // get the current selection
23
+ var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState) === null || _api$selection === void 0 || (_api$selection = _api$selection.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
24
+ if (selection) {
25
+ var schema = selection.$from.doc.type.schema;
26
+ // for texts and inline nodes
27
+ if (selection instanceof TextSelection) {
28
+ var _fragment;
29
+ var fragment = selection === null || selection === void 0 ? void 0 : selection.content().content;
30
+ if (!fragment) {
31
+ return;
32
+ }
33
+ // if text is inside of a layout column, the selection contains the layoutSection and layoutColumn for some reason
34
+ // But the layoutSection only contains the layoutColumn that the selected text is in, hence we can use the .firstChild
35
+ if ((_fragment = fragment) !== null && _fragment !== void 0 && _fragment.firstChild && fragment.firstChild.type.name === 'layoutSection') {
36
+ var layoutSectionNode = fragment.firstChild;
37
+ var layoutColumnNode = layoutSectionNode.firstChild;
38
+ var layoutContent = layoutColumnNode === null || layoutColumnNode === void 0 ? void 0 : layoutColumnNode.firstChild;
39
+ fragment = (layoutContent === null || layoutContent === void 0 ? void 0 : layoutContent.content) || Fragment.empty;
40
+ }
41
+ var domNode = toDOMFromFragment(fragment, schema);
42
+ var div = document.createElement('div');
43
+ div.appendChild(domNode);
44
+ copyHTMLToClipboard(div);
45
+ }
46
+
47
+ // for table
48
+ if (isTableSelected(selection)) {
49
+ var nodeType = schema.nodes.table;
50
+ var tableNode = selection.$anchorCell.node(-1);
51
+ if (!tableNode) {
52
+ return;
53
+ }
54
+ var _domNode = toDOM(tableNode, schema);
55
+ copyDomNode(_domNode, nodeType, selection);
56
+ }
57
+
58
+ // for other nodes
59
+ if (selection instanceof NodeSelection) {
60
+ var _nodeType = selection.node.type;
61
+ var _domNode2 = toDOM(selection.node, schema);
62
+ copyDomNode(_domNode2, _nodeType, selection);
63
+ }
64
+ }
65
+ };
66
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
67
+ elemBefore: /*#__PURE__*/React.createElement(CopyIcon, {
68
+ label: ""
69
+ }),
70
+ onClick: function onClick(e) {
71
+ return copyHandler(e);
72
+ }
73
+ }, formatMessage(messages.copyBlock));
74
+ };
75
+ export default injectIntl(CopyBlockMenuItem);
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { useIntl, injectIntl } from 'react-intl-next';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
+ import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { DIRECTION } from '@atlaskit/editor-common/types';
6
+ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
7
+ import ArrowDownIcon from '@atlaskit/icon/core/arrow-down';
8
+ var MoveDownDropdownItemContent = function MoveDownDropdownItemContent(_ref) {
9
+ var api = _ref.api;
10
+ var _useIntl = useIntl(),
11
+ formatMessage = _useIntl.formatMessage;
12
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls'], function (_ref2) {
13
+ var _blockControlsState$b;
14
+ var blockControlsState = _ref2.blockControlsState;
15
+ return {
16
+ canMoveDown: blockControlsState === null || blockControlsState === void 0 || (_blockControlsState$b = blockControlsState.blockMenuOptions) === null || _blockControlsState$b === void 0 ? void 0 : _blockControlsState$b.canMoveDown
17
+ };
18
+ }),
19
+ canMoveDown = _useSharedPluginState.canMoveDown;
20
+ var handleClick = function handleClick() {
21
+ api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
22
+ var _api$blockControls, _api$blockControls2;
23
+ var tr = _ref3.tr;
24
+ api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.commands) === null || _api$blockControls === void 0 || _api$blockControls.moveNodeWithBlockMenu(DIRECTION.DOWN)({
25
+ tr: tr
26
+ });
27
+ api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 || _api$blockControls2.toggleBlockMenu({
28
+ closeMenu: true
29
+ })({
30
+ tr: tr
31
+ });
32
+ return tr;
33
+ });
34
+ };
35
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
36
+ onClick: handleClick,
37
+ elemBefore: /*#__PURE__*/React.createElement(ArrowDownIcon, {
38
+ label: ""
39
+ }),
40
+ isDisabled: !canMoveDown
41
+ }, formatMessage(messages.moveDownBlock));
42
+ };
43
+ export var MoveDownDropdownItem = injectIntl(MoveDownDropdownItemContent);
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { useIntl, injectIntl } from 'react-intl-next';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
+ import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { DIRECTION } from '@atlaskit/editor-common/types';
6
+ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
7
+ import ArrowUpIcon from '@atlaskit/icon/core/arrow-up';
8
+ var MoveUpDropdownItemContent = function MoveUpDropdownItemContent(_ref) {
9
+ var api = _ref.api;
10
+ var _useIntl = useIntl(),
11
+ formatMessage = _useIntl.formatMessage;
12
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls'], function (_ref2) {
13
+ var _blockControlsState$b;
14
+ var blockControlsState = _ref2.blockControlsState;
15
+ return {
16
+ canMoveUp: blockControlsState === null || blockControlsState === void 0 || (_blockControlsState$b = blockControlsState.blockMenuOptions) === null || _blockControlsState$b === void 0 ? void 0 : _blockControlsState$b.canMoveUp
17
+ };
18
+ }),
19
+ canMoveUp = _useSharedPluginState.canMoveUp;
20
+ var handleClick = function handleClick() {
21
+ api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
22
+ var _api$blockControls, _api$blockControls2;
23
+ var tr = _ref3.tr;
24
+ api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.commands) === null || _api$blockControls === void 0 || _api$blockControls.moveNodeWithBlockMenu(DIRECTION.UP)({
25
+ tr: tr
26
+ });
27
+ api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 || _api$blockControls2.toggleBlockMenu({
28
+ closeMenu: true
29
+ })({
30
+ tr: tr
31
+ });
32
+ return tr;
33
+ });
34
+ };
35
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
36
+ onClick: handleClick,
37
+ elemBefore: /*#__PURE__*/React.createElement(ArrowUpIcon, {
38
+ label: ""
39
+ }),
40
+ isDisabled: !canMoveUp
41
+ }, formatMessage(messages.moveUpBlock));
42
+ };
43
+ export var MoveUpDropdownItem = injectIntl(MoveUpDropdownItemContent);
@@ -1,8 +1,13 @@
1
1
  import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
2
  import type { BlockControlsPlugin } from '@atlaskit/editor-plugin-block-controls';
3
+ import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
3
4
  import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent';
4
5
  export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
5
- dependencies: [OptionalPlugin<BlockControlsPlugin>, OptionalPlugin<UserIntentPlugin>];
6
+ dependencies: [
7
+ OptionalPlugin<BlockControlsPlugin>,
8
+ OptionalPlugin<UserIntentPlugin>,
9
+ OptionalPlugin<SelectionPlugin>
10
+ ];
6
11
  actions: {
7
12
  registerBlockMenuComponents: (blockMenuComponents: Array<RegisterBlockMenuComponent>) => void;
8
13
  getBlockMenuComponents: () => Array<RegisterBlockMenuComponent>;