@atlaskit/editor-plugin-insert-block 4.3.2 → 4.3.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/insertBlockPlugin.js +8 -2
  3. package/dist/cjs/ui/toolbar-components/EmojiButton.js +25 -83
  4. package/dist/cjs/ui/toolbar-components/InsertButton.js +250 -0
  5. package/dist/cjs/ui/toolbar-components/TableSizePicker.js +25 -48
  6. package/dist/cjs/ui/toolbar-components/hooks/useEmojiPickerPopup.js +52 -0
  7. package/dist/cjs/ui/toolbar-components/hooks/useInsertButtonState.js +89 -0
  8. package/dist/cjs/ui/toolbar-components/hooks/usePopupManager.js +65 -0
  9. package/dist/cjs/ui/toolbar-components/hooks/useTableSelectorPopup.js +35 -0
  10. package/dist/cjs/ui/toolbar-components/popups/EmojiPickerPopup.js +53 -0
  11. package/dist/cjs/ui/toolbar-components/popups/TableSelectorPopupWrapper.js +36 -0
  12. package/dist/cjs/ui/toolbar-components/shared/constants.js +18 -0
  13. package/dist/cjs/ui/toolbar-components/shared/types.js +5 -0
  14. package/dist/cjs/ui/toolbar-components.js +66 -2
  15. package/dist/es2019/insertBlockPlugin.js +8 -2
  16. package/dist/es2019/ui/toolbar-components/EmojiButton.js +24 -77
  17. package/dist/es2019/ui/toolbar-components/InsertButton.js +243 -0
  18. package/dist/es2019/ui/toolbar-components/TableSizePicker.js +26 -41
  19. package/dist/es2019/ui/toolbar-components/hooks/useEmojiPickerPopup.js +42 -0
  20. package/dist/es2019/ui/toolbar-components/hooks/useInsertButtonState.js +81 -0
  21. package/dist/es2019/ui/toolbar-components/hooks/usePopupManager.js +50 -0
  22. package/dist/es2019/ui/toolbar-components/hooks/useTableSelectorPopup.js +27 -0
  23. package/dist/es2019/ui/toolbar-components/popups/EmojiPickerPopup.js +47 -0
  24. package/dist/es2019/ui/toolbar-components/popups/TableSelectorPopupWrapper.js +30 -0
  25. package/dist/es2019/ui/toolbar-components/shared/constants.js +12 -0
  26. package/dist/es2019/ui/toolbar-components/shared/types.js +1 -0
  27. package/dist/es2019/ui/toolbar-components.js +63 -3
  28. package/dist/esm/insertBlockPlugin.js +8 -2
  29. package/dist/esm/ui/toolbar-components/EmojiButton.js +26 -83
  30. package/dist/esm/ui/toolbar-components/InsertButton.js +242 -0
  31. package/dist/esm/ui/toolbar-components/TableSizePicker.js +26 -48
  32. package/dist/esm/ui/toolbar-components/hooks/useEmojiPickerPopup.js +45 -0
  33. package/dist/esm/ui/toolbar-components/hooks/useInsertButtonState.js +82 -0
  34. package/dist/esm/ui/toolbar-components/hooks/usePopupManager.js +58 -0
  35. package/dist/esm/ui/toolbar-components/hooks/useTableSelectorPopup.js +28 -0
  36. package/dist/esm/ui/toolbar-components/popups/EmojiPickerPopup.js +46 -0
  37. package/dist/esm/ui/toolbar-components/popups/TableSelectorPopupWrapper.js +29 -0
  38. package/dist/esm/ui/toolbar-components/shared/constants.js +12 -0
  39. package/dist/esm/ui/toolbar-components/shared/types.js +1 -0
  40. package/dist/esm/ui/toolbar-components.js +67 -3
  41. package/dist/types/insertBlockPluginType.d.ts +2 -2
  42. package/dist/types/types/index.d.ts +3 -3
  43. package/dist/types/ui/ElementBrowser/types.d.ts +3 -3
  44. package/dist/types/ui/ToolbarInsertBlock/block-insert-element-browser.d.ts +8 -8
  45. package/dist/types/ui/ToolbarInsertBlock/block-insert-menu.d.ts +12 -12
  46. package/dist/types/ui/ToolbarInsertBlock/create-items.d.ts +24 -24
  47. package/dist/types/ui/ToolbarInsertBlock/dropdown-button.d.ts +4 -4
  48. package/dist/types/ui/ToolbarInsertBlock/index.d.ts +1 -1
  49. package/dist/types/ui/ToolbarInsertBlock/item.d.ts +2 -2
  50. package/dist/types/ui/ToolbarInsertBlock/types.d.ts +36 -36
  51. package/dist/types/ui/toolbar-components/EmojiButton.d.ts +2 -7
  52. package/dist/types/ui/toolbar-components/InsertButton.d.ts +18 -0
  53. package/dist/types/ui/toolbar-components/TableSizePicker.d.ts +3 -5
  54. package/dist/types/ui/toolbar-components/hooks/useEmojiPickerPopup.d.ts +20 -0
  55. package/dist/types/ui/toolbar-components/hooks/useInsertButtonState.d.ts +24 -0
  56. package/dist/types/ui/toolbar-components/hooks/usePopupManager.d.ts +21 -0
  57. package/dist/types/ui/toolbar-components/hooks/useTableSelectorPopup.d.ts +19 -0
  58. package/dist/types/ui/toolbar-components/popups/EmojiPickerPopup.d.ts +16 -0
  59. package/dist/types/ui/toolbar-components/popups/TableSelectorPopupWrapper.d.ts +15 -0
  60. package/dist/types/ui/toolbar-components/shared/constants.d.ts +12 -0
  61. package/dist/types/ui/toolbar-components/shared/types.d.ts +8 -0
  62. package/dist/types/ui/toolbar-components.d.ts +9 -2
  63. package/dist/types-ts4.5/insertBlockPluginType.d.ts +2 -2
  64. package/dist/types-ts4.5/types/index.d.ts +3 -3
  65. package/dist/types-ts4.5/ui/ElementBrowser/types.d.ts +3 -3
  66. package/dist/types-ts4.5/ui/ToolbarInsertBlock/block-insert-element-browser.d.ts +8 -8
  67. package/dist/types-ts4.5/ui/ToolbarInsertBlock/block-insert-menu.d.ts +12 -12
  68. package/dist/types-ts4.5/ui/ToolbarInsertBlock/create-items.d.ts +24 -24
  69. package/dist/types-ts4.5/ui/ToolbarInsertBlock/dropdown-button.d.ts +4 -4
  70. package/dist/types-ts4.5/ui/ToolbarInsertBlock/index.d.ts +1 -1
  71. package/dist/types-ts4.5/ui/ToolbarInsertBlock/item.d.ts +2 -2
  72. package/dist/types-ts4.5/ui/ToolbarInsertBlock/types.d.ts +36 -36
  73. package/dist/types-ts4.5/ui/toolbar-components/EmojiButton.d.ts +2 -7
  74. package/dist/types-ts4.5/ui/toolbar-components/InsertButton.d.ts +18 -0
  75. package/dist/types-ts4.5/ui/toolbar-components/TableSizePicker.d.ts +3 -5
  76. package/dist/types-ts4.5/ui/toolbar-components/hooks/useEmojiPickerPopup.d.ts +20 -0
  77. package/dist/types-ts4.5/ui/toolbar-components/hooks/useInsertButtonState.d.ts +24 -0
  78. package/dist/types-ts4.5/ui/toolbar-components/hooks/usePopupManager.d.ts +21 -0
  79. package/dist/types-ts4.5/ui/toolbar-components/hooks/useTableSelectorPopup.d.ts +19 -0
  80. package/dist/types-ts4.5/ui/toolbar-components/popups/EmojiPickerPopup.d.ts +16 -0
  81. package/dist/types-ts4.5/ui/toolbar-components/popups/TableSelectorPopupWrapper.d.ts +15 -0
  82. package/dist/types-ts4.5/ui/toolbar-components/shared/constants.d.ts +15 -0
  83. package/dist/types-ts4.5/ui/toolbar-components/shared/types.d.ts +8 -0
  84. package/dist/types-ts4.5/ui/toolbar-components.d.ts +9 -2
  85. package/package.json +8 -9
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
- import { INSERT_BLOCK_SECTION, TASK_LIST_GROUP, MEDIA_GROUP, INSERT_BLOCK_SECTION_RANK, TASK_LIST_BUTTON, TASK_LIST_GROUP_RANK, MEDIA_BUTTON, MENTION_GROUP, MEDIA_GROUP_RANK, MENTION_BUTTON, MENTION_GROUP_RANK, EMOJI_GROUP, EMOJI_BUTTON, EMOJI_GROUP_RANK, LAYOUT_GROUP, LAYOUT_BUTTON, LAYOUT_GROUP_RANK, TABLE_GROUP_RANK, TABLE_BUTTON, TABLE_GROUP, TABLE_SIZE_PICKER } from '@atlaskit/editor-common/toolbar';
2
+ import { INSERT_BLOCK_SECTION, TASK_LIST_GROUP, MEDIA_GROUP, INSERT_BLOCK_SECTION_RANK, TASK_LIST_BUTTON, TASK_LIST_GROUP_RANK, MEDIA_BUTTON, MENTION_GROUP, MEDIA_GROUP_RANK, MENTION_BUTTON, MENTION_GROUP_RANK, EMOJI_GROUP, EMOJI_BUTTON, EMOJI_GROUP_RANK, LAYOUT_GROUP, LAYOUT_BUTTON, LAYOUT_GROUP_RANK, TABLE_GROUP_RANK, TABLE_BUTTON, TABLE_GROUP, TABLE_SIZE_PICKER, INSERT_GROUP, INSERT_BUTTON, INSERT_GROUP_RANK } from '@atlaskit/editor-common/toolbar';
3
3
  import { EmojiButton } from './toolbar-components/EmojiButton';
4
4
  import { ImageButton } from './toolbar-components/ImageButton';
5
+ import { InsertButton } from './toolbar-components/InsertButton';
5
6
  import { LayoutButton } from './toolbar-components/LayoutButton';
6
7
  import { MediaButton } from './toolbar-components/MediaButton';
7
8
  import { MentionButton } from './toolbar-components/MentionButton';
@@ -11,9 +12,41 @@ import { TaskListButton } from './toolbar-components/TaskListButton';
11
12
  export const getToolbarComponents = ({
12
13
  api,
13
14
  tableSelectorSupported,
14
- toolbarShowPlusInsertOnly
15
+ toolbarShowPlusInsertOnly,
16
+ showElementBrowserLink,
17
+ onInsertBlockType,
18
+ nativeStatusSupported,
19
+ horizontalRuleEnabled,
20
+ expandEnabled,
21
+ insertMenuItems
15
22
  }) => {
16
- return [...(toolbarShowPlusInsertOnly ? [] : [{
23
+ return [...(toolbarShowPlusInsertOnly ? [{
24
+ type: INSERT_GROUP.type,
25
+ key: INSERT_GROUP.key,
26
+ parents: [{
27
+ type: INSERT_BLOCK_SECTION.type,
28
+ key: INSERT_BLOCK_SECTION.key,
29
+ rank: INSERT_BLOCK_SECTION_RANK[INSERT_GROUP.key]
30
+ }]
31
+ }, {
32
+ type: INSERT_BUTTON.type,
33
+ key: INSERT_BUTTON.key,
34
+ parents: [{
35
+ type: INSERT_GROUP.type,
36
+ key: INSERT_GROUP.key,
37
+ rank: INSERT_GROUP_RANK[INSERT_BUTTON.key]
38
+ }],
39
+ component: () => /*#__PURE__*/React.createElement(InsertButton, {
40
+ api: api,
41
+ showElementBrowserLink: showElementBrowserLink,
42
+ tableSelectorSupported: tableSelectorSupported,
43
+ onInsertBlockType: onInsertBlockType,
44
+ nativeStatusSupported: nativeStatusSupported,
45
+ horizontalRuleEnabled: horizontalRuleEnabled,
46
+ expandEnabled: expandEnabled,
47
+ insertMenuItems: insertMenuItems
48
+ })
49
+ }] : [{
17
50
  type: TASK_LIST_GROUP.type,
18
51
  key: TASK_LIST_GROUP.key,
19
52
  parents: [{
@@ -141,5 +174,32 @@ export const getToolbarComponents = ({
141
174
  api: api,
142
175
  tableSelectorSupported: tableSelectorSupported
143
176
  })
177
+ }, {
178
+ type: INSERT_GROUP.type,
179
+ key: INSERT_GROUP.key,
180
+ parents: [{
181
+ type: INSERT_BLOCK_SECTION.type,
182
+ key: INSERT_BLOCK_SECTION.key,
183
+ rank: INSERT_BLOCK_SECTION_RANK[INSERT_GROUP.key]
184
+ }]
185
+ }, {
186
+ type: INSERT_BUTTON.type,
187
+ key: INSERT_BUTTON.key,
188
+ parents: [{
189
+ type: INSERT_GROUP.type,
190
+ key: INSERT_GROUP.key,
191
+ rank: INSERT_GROUP_RANK[INSERT_BUTTON.key]
192
+ }],
193
+ component: () => /*#__PURE__*/React.createElement(InsertButton, {
194
+ api: api,
195
+ showElementBrowserLink: showElementBrowserLink,
196
+ tableSelectorSupported: tableSelectorSupported,
197
+ onInsertBlockType: onInsertBlockType,
198
+ nativeStatusSupported: nativeStatusSupported,
199
+ horizontalRuleEnabled: horizontalRuleEnabled,
200
+ expandEnabled: expandEnabled,
201
+ insertMenuItems: insertMenuItems,
202
+ numberOfButtons: 7 // TODO: ED-28759 - Default to 7 buttons - Remove this once we have a proper way to do toolbar responsiveness
203
+ })
144
204
  }])];
145
205
  };
@@ -153,11 +153,17 @@ export var insertBlockPlugin = function insertBlockPlugin(_ref) {
153
153
  });
154
154
  };
155
155
  if (expValEquals('platform_editor_toolbar_aifc', 'isEnabled', true)) {
156
- var _api$toolbar;
156
+ var _api$toolbar, _api$codeBlock, _api$panel, _api$blockType;
157
157
  api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 || _api$toolbar.actions.registerComponents(getToolbarComponents({
158
158
  api: api,
159
159
  tableSelectorSupported: options.tableSelectorSupported,
160
- toolbarShowPlusInsertOnly: options.toolbarShowPlusInsertOnly
160
+ toolbarShowPlusInsertOnly: options.toolbarShowPlusInsertOnly,
161
+ showElementBrowserLink: options.showElementBrowserLink,
162
+ onInsertBlockType: handleInsertBlockType(api === null || api === void 0 || (_api$codeBlock = api.codeBlock) === null || _api$codeBlock === void 0 ? void 0 : _api$codeBlock.actions.insertCodeBlock, api === null || api === void 0 || (_api$panel = api.panel) === null || _api$panel === void 0 ? void 0 : _api$panel.actions.insertPanel, api === null || api === void 0 || (_api$blockType = api.blockType) === null || _api$blockType === void 0 ? void 0 : _api$blockType.actions.insertBlockQuote),
163
+ nativeStatusSupported: options.nativeStatusSupported,
164
+ horizontalRuleEnabled: options.horizontalRuleEnabled,
165
+ expandEnabled: options.allowExpand,
166
+ insertMenuItems: options.insertMenuItems
161
167
  }));
162
168
  } else {
163
169
  var _api$primaryToolbar;
@@ -1,33 +1,18 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { useRef, useState } from 'react';
1
+ import React, { useRef } from 'react';
3
2
  import { useIntl } from 'react-intl-next';
4
- import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
5
3
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
6
4
  import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
7
- import { Popup } from '@atlaskit/editor-common/ui';
8
- import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners as withOuterListeners } from '@atlaskit/editor-common/ui-react';
9
- import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
10
5
  import { ToolbarButton, ToolbarTooltip, EmojiIcon } from '@atlaskit/editor-toolbar';
11
- import { EmojiPicker as AkEmojiPicker } from '@atlaskit/emoji/picker';
12
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
- import { isDetachedElement } from './utils/utils';
14
- var EmojiPicker = function EmojiPicker(props) {
15
- var setOutsideClickTargetRef = React.useContext(OutsideClickTargetRefContext);
16
- return /*#__PURE__*/React.createElement(AkEmojiPicker, {
17
- onPickerRef: setOutsideClickTargetRef,
18
- emojiProvider: props.emojiProvider,
19
- onSelection: props.onSelection
20
- });
21
- };
22
- var EmojiPickerWithListeners = withOuterListeners(EmojiPicker);
7
+ import { useEmojiPickerPopup } from './hooks/useEmojiPickerPopup';
8
+ import { EmojiPickerPopup } from './popups/EmojiPickerPopup';
23
9
  export var EmojiButton = function EmojiButton(_ref) {
24
- var api = _ref.api;
10
+ var api = _ref.api,
11
+ popupsMountPoint = _ref.popupsMountPoint,
12
+ popupsBoundariesElement = _ref.popupsBoundariesElement,
13
+ popupsScrollableElement = _ref.popupsScrollableElement;
25
14
  var _useIntl = useIntl(),
26
15
  formatMessage = _useIntl.formatMessage;
27
- var _useState = useState(false),
28
- _useState2 = _slicedToArray(_useState, 2),
29
- emojiPickerOpen = _useState2[0],
30
- setEmojiPickerOpen = _useState2[1];
31
16
  var emojiButtonRef = useRef(null);
32
17
  var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['emoji', 'typeAhead'], function (states) {
33
18
  var _states$emojiState, _states$emojiState2, _states$typeAheadStat;
@@ -40,75 +25,31 @@ export var EmojiButton = function EmojiButton(_ref) {
40
25
  emojiProviderSelector = _useSharedPluginState.emojiProviderSelector,
41
26
  emojiProviderPromise = _useSharedPluginState.emojiProviderPromise,
42
27
  isTypeAheadAllowed = _useSharedPluginState.isTypeAheadAllowed;
28
+ var emojiPickerPopup = useEmojiPickerPopup({
29
+ api: api,
30
+ buttonRef: emojiButtonRef
31
+ });
43
32
  if (!(api !== null && api !== void 0 && api.emoji)) {
44
33
  return null;
45
34
  }
46
- var toggleEmojiPickerOpen = function toggleEmojiPickerOpen(newState) {
47
- var oldState = emojiPickerOpen;
48
- if (newState === true && oldState === false) {
49
- var _api$analytics;
50
- api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
51
- action: ACTION.OPENED,
52
- actionSubject: ACTION_SUBJECT.PICKER,
53
- actionSubjectId: ACTION_SUBJECT_ID.PICKER_EMOJI,
54
- attributes: {
55
- inputMethod: INPUT_METHOD.TOOLBAR
56
- },
57
- eventType: EVENT_TYPE.UI
58
- });
59
- }
60
- setEmojiPickerOpen(newState);
61
- };
62
35
  var getEmojiProvider = function getEmojiProvider() {
63
36
  if (emojiProviderSelector) {
64
37
  return Promise.resolve(emojiProviderSelector);
65
38
  }
66
39
  };
67
40
  var emojiProvider = expValEquals('platform_editor_prevent_toolbar_layout_shifts', 'isEnabled', true) ? emojiProviderPromise : getEmojiProvider();
68
- var onPopupUnmount = function onPopupUnmount() {
69
- requestAnimationFrame(function () {
70
- return api === null || api === void 0 ? void 0 : api.core.actions.focus();
71
- });
72
- };
73
- var handleSelectedEmoji = function handleSelectedEmoji(emojiId) {
74
- var _api$emoji;
75
- api === null || api === void 0 || api.core.actions.focus();
76
- api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$emoji = api.emoji) === null || _api$emoji === void 0 ? void 0 : _api$emoji.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER));
77
- toggleEmojiPickerOpen(false);
78
- return true;
79
- };
80
- var handleEmojiClickOutside = function handleEmojiClickOutside(e) {
81
- // Ignore click events for detached elements.
82
- // Workaround for FS-1322 - where two onClicks fire - one when the upload button is
83
- // still in the document, and one once it's detached. Does not always occur, and
84
- // may be a side effect of a react render optimisation
85
- if (e.target instanceof HTMLElement && !isDetachedElement(e.target)) {
86
- toggleEmojiPickerOpen(false);
87
- }
88
- };
89
- var handleEmojiPressEscape = function handleEmojiPressEscape() {
90
- var _emojiButtonRef$curre;
91
- toggleEmojiPickerOpen(false);
92
- emojiButtonRef === null || emojiButtonRef === void 0 || (_emojiButtonRef$curre = emojiButtonRef.current) === null || _emojiButtonRef$curre === void 0 || _emojiButtonRef$curre.focus();
93
- };
94
- var onClick = function onClick() {
95
- toggleEmojiPickerOpen(!emojiPickerOpen);
96
- };
97
- return /*#__PURE__*/React.createElement(React.Fragment, null, emojiPickerOpen && emojiButtonRef.current && emojiProvider && /*#__PURE__*/React.createElement(Popup, {
98
- target: emojiButtonRef.current,
99
- fitHeight: 350,
100
- fitWidth: 350,
101
- offset: [0, 3],
102
- mountTo: emojiButtonRef.current,
103
- onUnmount: onPopupUnmount,
104
- focusTrap: true,
105
- zIndex: akEditorMenuZIndex
106
- }, /*#__PURE__*/React.createElement(EmojiPickerWithListeners, {
41
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EmojiPickerPopup, {
42
+ isOpen: emojiPickerPopup.isOpen,
43
+ targetRef: emojiButtonRef,
107
44
  emojiProvider: emojiProvider,
108
- onSelection: handleSelectedEmoji,
109
- handleClickOutside: handleEmojiClickOutside,
110
- handleEscapeKeydown: handleEmojiPressEscape
111
- })), /*#__PURE__*/React.createElement(ToolbarTooltip, {
45
+ onSelection: emojiPickerPopup.handleSelectedEmoji,
46
+ onClickOutside: emojiPickerPopup.handleClickOutside,
47
+ onEscapeKeydown: emojiPickerPopup.handleEscapeKeydown,
48
+ onUnmount: emojiPickerPopup.onPopupUnmount,
49
+ popupsMountPoint: popupsMountPoint,
50
+ popupsBoundariesElement: popupsBoundariesElement,
51
+ popupsScrollableElement: popupsScrollableElement
52
+ }), /*#__PURE__*/React.createElement(ToolbarTooltip, {
112
53
  content: formatMessage(messages.emoji)
113
54
  }, /*#__PURE__*/React.createElement(ToolbarButton, {
114
55
  iconBefore: /*#__PURE__*/React.createElement(EmojiIcon, {
@@ -117,8 +58,10 @@ export var EmojiButton = function EmojiButton(_ref) {
117
58
  }),
118
59
  ariaKeyshortcuts: "Shift+;",
119
60
  ref: emojiButtonRef,
120
- onClick: onClick,
121
- isSelected: emojiPickerOpen,
61
+ onClick: function onClick() {
62
+ return emojiPickerPopup.toggle();
63
+ },
64
+ isSelected: emojiPickerPopup.isOpen,
122
65
  isDisabled: !isTypeAheadAllowed || !emojiProvider
123
66
  })));
124
67
  };
@@ -0,0 +1,242 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import React, { useRef, useState } from 'react';
3
+ import { useIntl } from 'react-intl-next';
4
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
5
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
+ import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
7
+ import { Popup } from '@atlaskit/editor-common/ui';
8
+ import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
9
+ import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
10
+ import { ToolbarButton, ToolbarTooltip, AddIcon, useToolbarUI } from '@atlaskit/editor-toolbar';
11
+ import { fg } from '@atlaskit/platform-feature-flags';
12
+ import InsertMenu, { DEFAULT_HEIGHT } from '../ElementBrowser/InsertMenu';
13
+ import { useEmojiPickerPopup } from './hooks/useEmojiPickerPopup';
14
+ import { useInsertButtonState } from './hooks/useInsertButtonState';
15
+ import { useTableSelectorPopup } from './hooks/useTableSelectorPopup';
16
+ import { EmojiPickerPopup } from './popups/EmojiPickerPopup';
17
+
18
+ // This determines how the popup should fit. We prefer the insert menu
19
+ // opening on the bottom as we have a search bar and should only open on
20
+ // top if there is more than sufficient room.
21
+ var FIT_HEIGHT_BUFFER = 100;
22
+ export var InsertButton = function InsertButton(_ref) {
23
+ var api = _ref.api,
24
+ _ref$showElementBrows = _ref.showElementBrowserLink,
25
+ showElementBrowserLink = _ref$showElementBrows === void 0 ? false : _ref$showElementBrows,
26
+ _ref$isFullPageAppear = _ref.isFullPageAppearance,
27
+ isFullPageAppearance = _ref$isFullPageAppear === void 0 ? false : _ref$isFullPageAppear,
28
+ tableSelectorSupported = _ref.tableSelectorSupported,
29
+ nativeStatusSupported = _ref.nativeStatusSupported,
30
+ horizontalRuleEnabled = _ref.horizontalRuleEnabled,
31
+ expandEnabled = _ref.expandEnabled,
32
+ insertMenuItems = _ref.insertMenuItems,
33
+ numberOfButtons = _ref.numberOfButtons,
34
+ onInsertBlockType = _ref.onInsertBlockType;
35
+ var _useEditorToolbar = useEditorToolbar(),
36
+ editorView = _useEditorToolbar.editorView;
37
+ var _useToolbarUI = useToolbarUI(),
38
+ isDisabled = _useToolbarUI.isDisabled,
39
+ popupsMountPoint = _useToolbarUI.popupsMountPoint,
40
+ popupsBoundariesElement = _useToolbarUI.popupsBoundariesElement,
41
+ popupsScrollableElement = _useToolbarUI.popupsScrollableElement;
42
+ var _useIntl = useIntl(),
43
+ formatMessage = _useIntl.formatMessage;
44
+ var _useState = useState(false),
45
+ _useState2 = _slicedToArray(_useState, 2),
46
+ insertMenuOpen = _useState2[0],
47
+ setInsertMenuOpen = _useState2[1];
48
+ var insertButtonRef = useRef(null);
49
+ var emojiPickerPopup = useEmojiPickerPopup({
50
+ api: api,
51
+ buttonRef: insertButtonRef
52
+ });
53
+ var tableSelectorPopup = useTableSelectorPopup({
54
+ api: api,
55
+ buttonRef: insertButtonRef
56
+ });
57
+ var showMediaPicker = useSharedPluginStateSelector(api, 'media.showMediaPicker');
58
+ var _useInsertButtonState = useInsertButtonState({
59
+ api: api,
60
+ editorView: editorView || undefined,
61
+ horizontalRuleEnabled: horizontalRuleEnabled,
62
+ insertMenuItems: insertMenuItems,
63
+ nativeStatusSupported: nativeStatusSupported,
64
+ numberOfButtons: numberOfButtons,
65
+ tableSelectorSupported: tableSelectorSupported,
66
+ expandEnabled: expandEnabled,
67
+ showElementBrowserLink: showElementBrowserLink
68
+ }),
69
+ dropdownItems = _useInsertButtonState.dropdownItems,
70
+ emojiProvider = _useInsertButtonState.emojiProvider,
71
+ isTypeAheadAllowed = _useInsertButtonState.isTypeAheadAllowed;
72
+ if (!(api !== null && api !== void 0 && api.insertBlock)) {
73
+ return null;
74
+ }
75
+ var toggleInsertMenuOpen = function toggleInsertMenuOpen(newState) {
76
+ setInsertMenuOpen(newState);
77
+ };
78
+ var onPopupUnmount = function onPopupUnmount() {
79
+ requestAnimationFrame(function () {
80
+ return api === null || api === void 0 ? void 0 : api.core.actions.focus();
81
+ });
82
+ };
83
+ var onClick = function onClick() {
84
+ toggleInsertMenuOpen(!insertMenuOpen);
85
+ };
86
+ var onItemActivated = function onItemActivated(_ref2) {
87
+ var _api$core, _api$hyperlink, _api$imageUpload, _api$mention, _api$taskDecision, _api$rule, _api$core4, _api$date, _api$placeholderText, _api$layout, _api$core5, _api$status, _api$expand;
88
+ var item = _ref2.item,
89
+ inputMethod = _ref2.inputMethod;
90
+ if (!editorView) {
91
+ return;
92
+ }
93
+ var state = editorView.state,
94
+ dispatch = editorView.dispatch;
95
+
96
+ // need to do this before inserting nodes so scrollIntoView works properly
97
+ if (!editorView.hasFocus()) {
98
+ editorView.focus();
99
+ }
100
+ switch (item.value.name) {
101
+ case 'link':
102
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$hyperlink = api.hyperlink) === null || _api$hyperlink === void 0 ? void 0 : _api$hyperlink.commands.showLinkToolbar(inputMethod));
103
+ break;
104
+ case 'table':
105
+ // workaround to solve race condition where cursor is not placed correctly inside table
106
+ queueMicrotask(function () {
107
+ var _api$table, _api$table$actions$in, _api$table$actions;
108
+ api === null || api === void 0 || (_api$table = api.table) === null || _api$table === void 0 || (_api$table$actions$in = (_api$table$actions = _api$table.actions).insertTable) === null || _api$table$actions$in === void 0 || _api$table$actions$in.call(_api$table$actions, {
109
+ action: ACTION.INSERTED,
110
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
111
+ actionSubjectId: ACTION_SUBJECT_ID.TABLE,
112
+ attributes: {
113
+ inputMethod: inputMethod
114
+ },
115
+ eventType: EVENT_TYPE.TRACK
116
+ })(state, dispatch);
117
+ });
118
+ break;
119
+ case 'table selector':
120
+ tableSelectorPopup.toggle(inputMethod);
121
+ break;
122
+ case 'image upload':
123
+ if (api !== null && api !== void 0 && (_api$imageUpload = api.imageUpload) !== null && _api$imageUpload !== void 0 && _api$imageUpload.actions.startUpload) {
124
+ api.imageUpload.actions.startUpload()(state, dispatch);
125
+ }
126
+ break;
127
+ case 'media':
128
+ if (showMediaPicker) {
129
+ if (fg('platform_editor_add_media_from_url_rollout')) {
130
+ var _api$core2, _api$mediaInsert;
131
+ api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(api === null || api === void 0 || (_api$mediaInsert = api.mediaInsert) === null || _api$mediaInsert === void 0 ? void 0 : _api$mediaInsert.commands.showMediaInsertPopup());
132
+ } else {
133
+ showMediaPicker();
134
+ }
135
+ }
136
+ break;
137
+ case 'mention':
138
+ api === null || api === void 0 || (_api$mention = api.mention) === null || _api$mention === void 0 || (_api$mention = _api$mention.actions) === null || _api$mention === void 0 || _api$mention.openTypeAhead(inputMethod);
139
+ break;
140
+ case 'emoji':
141
+ emojiPickerPopup.toggle(inputMethod);
142
+ break;
143
+ case 'codeblock':
144
+ case 'blockquote':
145
+ case 'panel':
146
+ onInsertBlockType === null || onInsertBlockType === void 0 || onInsertBlockType(item.value.name)(state, dispatch);
147
+ break;
148
+ case 'action':
149
+ case 'decision':
150
+ var listType = item.value.name === 'action' ? 'taskList' : 'decisionList';
151
+ api === null || api === void 0 || (_api$taskDecision = api.taskDecision) === null || _api$taskDecision === void 0 || _api$taskDecision.actions.insertTaskDecision(listType, inputMethod)(state, dispatch);
152
+ break;
153
+ case 'horizontalrule':
154
+ api === null || api === void 0 || (_api$rule = api.rule) === null || _api$rule === void 0 || _api$rule.actions.insertHorizontalRule(inputMethod)(state, dispatch);
155
+ break;
156
+ case 'macro':
157
+ if (!fg('platform_editor_refactor_view_more')) {
158
+ var _api$core3, _api$quickInsert;
159
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.commands.openElementBrowserModal);
160
+ }
161
+ break;
162
+ case 'date':
163
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(api === null || api === void 0 || (_api$date = api.date) === null || _api$date === void 0 || (_api$date = _api$date.commands) === null || _api$date === void 0 ? void 0 : _api$date.insertDate({
164
+ inputMethod: inputMethod
165
+ }));
166
+ break;
167
+ case 'placeholder text':
168
+ api === null || api === void 0 || (_api$placeholderText = api.placeholderText) === null || _api$placeholderText === void 0 || _api$placeholderText.actions.showPlaceholderFloatingToolbar(state, dispatch);
169
+ break;
170
+ case 'layout':
171
+ api === null || api === void 0 || (_api$layout = api.layout) === null || _api$layout === void 0 || _api$layout.actions.insertLayoutColumns(inputMethod)(state, dispatch);
172
+ break;
173
+ case 'status':
174
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(api === null || api === void 0 || (_api$status = api.status) === null || _api$status === void 0 || (_api$status = _api$status.commands) === null || _api$status === void 0 ? void 0 : _api$status.insertStatus(inputMethod));
175
+ break;
176
+ case 'expand':
177
+ api === null || api === void 0 || (_api$expand = api.expand) === null || _api$expand === void 0 || _api$expand.actions.insertExpand(state, dispatch);
178
+ break;
179
+ default:
180
+ if (item && item.onClick) {
181
+ item.onClick();
182
+ }
183
+ break;
184
+ }
185
+ toggleInsertMenuOpen(false);
186
+ };
187
+ var onInsert = function onInsert(_ref3) {
188
+ var item = _ref3.item;
189
+ onItemActivated({
190
+ item: item,
191
+ inputMethod: INPUT_METHOD.INSERT_MENU
192
+ });
193
+ };
194
+ var toggleVisibility = function toggleVisibility() {
195
+ toggleInsertMenuOpen(!insertMenuOpen);
196
+ };
197
+ return /*#__PURE__*/React.createElement(React.Fragment, null, insertMenuOpen && insertButtonRef.current && editorView && /*#__PURE__*/React.createElement(Popup, {
198
+ target: insertButtonRef.current,
199
+ fitHeight: DEFAULT_HEIGHT + FIT_HEIGHT_BUFFER,
200
+ fitWidth: 350,
201
+ offset: [0, 3],
202
+ mountTo: popupsMountPoint,
203
+ boundariesElement: popupsBoundariesElement,
204
+ scrollableElement: popupsScrollableElement,
205
+ onUnmount: onPopupUnmount,
206
+ focusTrap: true,
207
+ zIndex: akEditorMenuZIndex,
208
+ preventOverflow: true,
209
+ alignX: "right"
210
+ }, /*#__PURE__*/React.createElement(InsertMenu, {
211
+ editorView: editorView,
212
+ dropdownItems: dropdownItems,
213
+ onInsert: onInsert,
214
+ toggleVisiblity: toggleVisibility,
215
+ showElementBrowserLink: showElementBrowserLink,
216
+ pluginInjectionApi: api,
217
+ isFullPageAppearance: isFullPageAppearance
218
+ })), emojiProvider && /*#__PURE__*/React.createElement(EmojiPickerPopup, {
219
+ isOpen: emojiPickerPopup.isOpen,
220
+ targetRef: insertButtonRef,
221
+ emojiProvider: Promise.resolve(emojiProvider),
222
+ onSelection: emojiPickerPopup.handleSelectedEmoji,
223
+ onClickOutside: emojiPickerPopup.handleClickOutside,
224
+ onEscapeKeydown: emojiPickerPopup.handleEscapeKeydown,
225
+ onUnmount: emojiPickerPopup.onPopupUnmount,
226
+ popupsMountPoint: popupsMountPoint,
227
+ popupsBoundariesElement: popupsBoundariesElement,
228
+ popupsScrollableElement: popupsScrollableElement
229
+ }), /*#__PURE__*/React.createElement(ToolbarTooltip, {
230
+ content: formatMessage(messages.insertMenu)
231
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
232
+ iconBefore: /*#__PURE__*/React.createElement(AddIcon, {
233
+ size: "small",
234
+ label: formatMessage(messages.insertMenu)
235
+ }),
236
+ ariaKeyshortcuts: "/",
237
+ ref: insertButtonRef,
238
+ onClick: onClick,
239
+ isSelected: insertMenuOpen,
240
+ isDisabled: !isTypeAheadAllowed || isDisabled
241
+ })));
242
+ };
@@ -1,12 +1,10 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { useRef, useState } from 'react';
1
+ import React, { useRef } from 'react';
3
2
  import { useIntl } from 'react-intl-next';
4
- import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
5
3
  import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
4
  import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
7
- import { TableSelectorPopup } from '@atlaskit/editor-common/ui';
8
5
  import { MoreItemsIcon, ToolbarButton, ToolbarTooltip, useToolbarUI } from '@atlaskit/editor-toolbar';
9
- import { isDetachedElement } from './utils/utils';
6
+ import { useTableSelectorPopup } from './hooks/useTableSelectorPopup';
7
+ import { TableSelectorPopupWrapper } from './popups/TableSelectorPopupWrapper';
10
8
  export var TableSizePicker = function TableSizePicker(_ref) {
11
9
  var api = _ref.api,
12
10
  tableSelectorSupported = _ref.tableSelectorSupported;
@@ -14,55 +12,35 @@ export var TableSizePicker = function TableSizePicker(_ref) {
14
12
  formatMessage = _useIntl.formatMessage;
15
13
  var _useEditorToolbar = useEditorToolbar(),
16
14
  editorView = _useEditorToolbar.editorView;
17
- var _useToolbarUI = useToolbarUI(),
18
- popupsMountPoint = _useToolbarUI.popupsMountPoint;
19
- var _useState = useState(false),
20
- _useState2 = _slicedToArray(_useState, 2),
21
- tableSizePickerOpen = _useState2[0],
22
- setTableSizePickerOpen = _useState2[1];
23
- var _useState3 = useState(false),
24
- _useState4 = _slicedToArray(_useState3, 2),
25
- isOpenedByKeyboard = _useState4[0],
26
- setIsOpenedByKeyboard = _useState4[1];
27
15
  var tableSizePickerRef = useRef(null);
16
+ var _useToolbarUI = useToolbarUI(),
17
+ popupsMountPoint = _useToolbarUI.popupsMountPoint,
18
+ popupsBoundariesElement = _useToolbarUI.popupsBoundariesElement,
19
+ popupsScrollableElement = _useToolbarUI.popupsScrollableElement;
20
+ var tableSelectorPopup = useTableSelectorPopup({
21
+ api: api,
22
+ buttonRef: tableSizePickerRef
23
+ });
28
24
  if (!(editorView !== null && editorView !== void 0 && editorView.state.schema.nodes.table) || !tableSelectorSupported) {
29
25
  return null;
30
26
  }
31
- var handleSelectedTableSize = function handleSelectedTableSize(rowsCount, colsCount) {
32
- // workaround to solve race condition where cursor is not placed correctly inside table
33
- queueMicrotask(function () {
34
- var _api$core, _api$table;
35
- api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$table = api.table) === null || _api$table === void 0 ? void 0 : _api$table.commands.insertTableWithSize(rowsCount, colsCount, INPUT_METHOD.PICKER));
36
- });
37
- setTableSizePickerOpen(false);
38
- };
39
- var handleTableSelectorClickOutside = function handleTableSelectorClickOutside(e) {
40
- // Ignore click events for detached elements.
41
- if (e.target instanceof HTMLElement && !isDetachedElement(e.target)) {
42
- setTableSizePickerOpen(false);
43
- }
44
- };
45
- var handleTableSelectorPressEscape = function handleTableSelectorPressEscape() {
46
- var _tableSizePickerRef$c;
47
- setTableSizePickerOpen(false);
48
- (_tableSizePickerRef$c = tableSizePickerRef.current) === null || _tableSizePickerRef$c === void 0 || _tableSizePickerRef$c.focus();
49
- };
50
- var onUnmount = function onUnmount() {
51
- api === null || api === void 0 || api.core.actions.focus();
52
- };
53
27
  var onClick = function onClick(event) {
54
- setIsOpenedByKeyboard(event.detail === 0 ? true : false);
55
- setTableSizePickerOpen(!tableSizePickerOpen);
28
+ if (event.detail === 0) {
29
+ tableSelectorPopup.handleKeyboardOpen(event);
30
+ }
31
+ tableSelectorPopup.toggle();
56
32
  };
57
- return /*#__PURE__*/React.createElement(React.Fragment, null, tableSizePickerRef.current && tableSizePickerOpen && /*#__PURE__*/React.createElement(TableSelectorPopup, {
58
- allowOutsideSelection: true,
59
- target: tableSizePickerRef.current,
60
- onUnmount: onUnmount,
61
- onSelection: handleSelectedTableSize,
33
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TableSelectorPopupWrapper, {
34
+ isOpen: tableSelectorPopup.isOpen,
35
+ targetRef: tableSizePickerRef,
36
+ isOpenedByKeyboard: tableSelectorPopup.isOpenedByKeyboard,
37
+ onSelection: tableSelectorPopup.handleSelectedTableSize,
38
+ onClickOutside: tableSelectorPopup.handleClickOutside,
39
+ onEscapeKeydown: tableSelectorPopup.handleEscapeKeydown,
40
+ onUnmount: tableSelectorPopup.onPopupUnmount,
62
41
  popupsMountPoint: popupsMountPoint,
63
- handleClickOutside: handleTableSelectorClickOutside,
64
- handleEscapeKeydown: handleTableSelectorPressEscape,
65
- isOpenedByKeyboard: isOpenedByKeyboard
42
+ popupsBoundariesElement: popupsBoundariesElement,
43
+ popupsScrollableElement: popupsScrollableElement
66
44
  }), /*#__PURE__*/React.createElement(ToolbarTooltip, {
67
45
  content: formatMessage(messages.tableSelector)
68
46
  }, /*#__PURE__*/React.createElement(ToolbarButton, {
@@ -70,7 +48,7 @@ export var TableSizePicker = function TableSizePicker(_ref) {
70
48
  label: formatMessage(messages.tableSelector)
71
49
  }),
72
50
  onClick: onClick,
73
- isSelected: tableSizePickerOpen,
51
+ isSelected: tableSelectorPopup.isOpen,
74
52
  ref: tableSizePickerRef
75
53
  })));
76
54
  };
@@ -0,0 +1,45 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import { useCallback } from 'react';
5
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
6
+ import { usePopupManager } from './usePopupManager';
7
+ export var useEmojiPickerPopup = function useEmojiPickerPopup(_ref) {
8
+ var api = _ref.api,
9
+ buttonRef = _ref.buttonRef;
10
+ var popupManager = usePopupManager({
11
+ focusTarget: buttonRef,
12
+ analytics: {
13
+ onToggle: function onToggle(isOpen) {
14
+ if (isOpen) {
15
+ var _api$analytics;
16
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
17
+ action: ACTION.OPENED,
18
+ actionSubject: ACTION_SUBJECT.PICKER,
19
+ actionSubjectId: ACTION_SUBJECT_ID.PICKER_EMOJI,
20
+ attributes: {
21
+ inputMethod: INPUT_METHOD.TOOLBAR
22
+ },
23
+ eventType: EVENT_TYPE.UI
24
+ });
25
+ }
26
+ }
27
+ }
28
+ });
29
+ var handleSelectedEmoji = useCallback(function (emojiId) {
30
+ var _api$emoji;
31
+ api === null || api === void 0 || api.core.actions.focus();
32
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$emoji = api.emoji) === null || _api$emoji === void 0 ? void 0 : _api$emoji.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER));
33
+ popupManager.close();
34
+ return true;
35
+ }, [api, popupManager]);
36
+ var onPopupUnmount = useCallback(function () {
37
+ requestAnimationFrame(function () {
38
+ return api === null || api === void 0 ? void 0 : api.core.actions.focus();
39
+ });
40
+ }, [api]);
41
+ return _objectSpread(_objectSpread({}, popupManager), {}, {
42
+ handleSelectedEmoji: handleSelectedEmoji,
43
+ onPopupUnmount: onPopupUnmount
44
+ });
45
+ };