@atlaskit/editor-plugin-insert-block 4.1.7 → 4.2.0

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 (57) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/insertBlockPlugin.js +15 -5
  3. package/dist/cjs/ui/toolbar-components/EmojiButton.js +132 -0
  4. package/dist/cjs/ui/toolbar-components/ImageButton.js +47 -0
  5. package/dist/cjs/ui/toolbar-components/LayoutButton.js +39 -0
  6. package/dist/cjs/ui/toolbar-components/MediaButton.js +71 -0
  7. package/dist/cjs/ui/toolbar-components/MentionButton.js +46 -0
  8. package/dist/cjs/ui/toolbar-components/TableButton.js +52 -0
  9. package/dist/cjs/ui/toolbar-components/TableSizePicker.js +83 -0
  10. package/dist/cjs/ui/toolbar-components/TaskListButton.js +40 -0
  11. package/dist/cjs/ui/toolbar-components/utils/utils.js +12 -0
  12. package/dist/cjs/ui/toolbar-components.js +172 -0
  13. package/dist/es2019/insertBlockPlugin.js +15 -5
  14. package/dist/es2019/ui/toolbar-components/EmojiButton.js +120 -0
  15. package/dist/es2019/ui/toolbar-components/ImageButton.js +46 -0
  16. package/dist/es2019/ui/toolbar-components/LayoutButton.js +37 -0
  17. package/dist/es2019/ui/toolbar-components/MediaButton.js +66 -0
  18. package/dist/es2019/ui/toolbar-components/MentionButton.js +42 -0
  19. package/dist/es2019/ui/toolbar-components/TableButton.js +50 -0
  20. package/dist/es2019/ui/toolbar-components/TableSizePicker.js +70 -0
  21. package/dist/es2019/ui/toolbar-components/TaskListButton.js +38 -0
  22. package/dist/es2019/ui/toolbar-components/utils/utils.js +4 -0
  23. package/dist/es2019/ui/toolbar-components.js +152 -0
  24. package/dist/esm/insertBlockPlugin.js +15 -5
  25. package/dist/esm/ui/toolbar-components/EmojiButton.js +123 -0
  26. package/dist/esm/ui/toolbar-components/ImageButton.js +40 -0
  27. package/dist/esm/ui/toolbar-components/LayoutButton.js +32 -0
  28. package/dist/esm/ui/toolbar-components/MediaButton.js +63 -0
  29. package/dist/esm/ui/toolbar-components/MentionButton.js +39 -0
  30. package/dist/esm/ui/toolbar-components/TableButton.js +45 -0
  31. package/dist/esm/ui/toolbar-components/TableSizePicker.js +74 -0
  32. package/dist/esm/ui/toolbar-components/TaskListButton.js +33 -0
  33. package/dist/esm/ui/toolbar-components/utils/utils.js +6 -0
  34. package/dist/esm/ui/toolbar-components.js +165 -0
  35. package/dist/types/types/index.d.ts +3 -1
  36. package/dist/types/ui/toolbar-components/EmojiButton.d.ts +8 -0
  37. package/dist/types/ui/toolbar-components/ImageButton.d.ts +8 -0
  38. package/dist/types/ui/toolbar-components/LayoutButton.d.ts +8 -0
  39. package/dist/types/ui/toolbar-components/MediaButton.d.ts +8 -0
  40. package/dist/types/ui/toolbar-components/MentionButton.d.ts +8 -0
  41. package/dist/types/ui/toolbar-components/TableButton.d.ts +8 -0
  42. package/dist/types/ui/toolbar-components/TableSizePicker.d.ts +9 -0
  43. package/dist/types/ui/toolbar-components/TaskListButton.d.ts +8 -0
  44. package/dist/types/ui/toolbar-components/utils/utils.d.ts +4 -0
  45. package/dist/types/ui/toolbar-components.d.ts +9 -0
  46. package/dist/types-ts4.5/types/index.d.ts +3 -1
  47. package/dist/types-ts4.5/ui/toolbar-components/EmojiButton.d.ts +8 -0
  48. package/dist/types-ts4.5/ui/toolbar-components/ImageButton.d.ts +8 -0
  49. package/dist/types-ts4.5/ui/toolbar-components/LayoutButton.d.ts +8 -0
  50. package/dist/types-ts4.5/ui/toolbar-components/MediaButton.d.ts +8 -0
  51. package/dist/types-ts4.5/ui/toolbar-components/MentionButton.d.ts +8 -0
  52. package/dist/types-ts4.5/ui/toolbar-components/TableButton.d.ts +8 -0
  53. package/dist/types-ts4.5/ui/toolbar-components/TableSizePicker.d.ts +9 -0
  54. package/dist/types-ts4.5/ui/toolbar-components/TaskListButton.d.ts +8 -0
  55. package/dist/types-ts4.5/ui/toolbar-components/utils/utils.d.ts +4 -0
  56. package/dist/types-ts4.5/ui/toolbar-components.d.ts +9 -0
  57. package/package.json +6 -3
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getToolbarComponents = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _toolbar = require("@atlaskit/editor-common/toolbar");
10
+ var _EmojiButton = require("./toolbar-components/EmojiButton");
11
+ var _ImageButton = require("./toolbar-components/ImageButton");
12
+ var _LayoutButton = require("./toolbar-components/LayoutButton");
13
+ var _MediaButton = require("./toolbar-components/MediaButton");
14
+ var _MentionButton = require("./toolbar-components/MentionButton");
15
+ var _TableButton = require("./toolbar-components/TableButton");
16
+ var _TableSizePicker = require("./toolbar-components/TableSizePicker");
17
+ var _TaskListButton = require("./toolbar-components/TaskListButton");
18
+ var getToolbarComponents = exports.getToolbarComponents = function getToolbarComponents(_ref) {
19
+ var api = _ref.api,
20
+ tableSelectorSupported = _ref.tableSelectorSupported;
21
+ return [{
22
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
23
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
24
+ parents: [{
25
+ type: 'toolbar',
26
+ key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
27
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.INSERT_BLOCK_SECTION.key]
28
+ }]
29
+ }, {
30
+ type: _toolbar.TASK_LIST_GROUP.type,
31
+ key: _toolbar.TASK_LIST_GROUP.key,
32
+ parents: [{
33
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
34
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
35
+ rank: _toolbar.INSERT_BLOCK_SECTION_RANK[_toolbar.TASK_LIST_GROUP.key]
36
+ }]
37
+ }, {
38
+ type: _toolbar.TASK_LIST_BUTTON.type,
39
+ key: _toolbar.TASK_LIST_BUTTON.key,
40
+ parents: [{
41
+ type: _toolbar.TASK_LIST_GROUP.type,
42
+ key: _toolbar.TASK_LIST_GROUP.key,
43
+ rank: _toolbar.TASK_LIST_GROUP_RANK[_toolbar.TASK_LIST_BUTTON.key]
44
+ }],
45
+ component: function component() {
46
+ return /*#__PURE__*/_react.default.createElement(_TaskListButton.TaskListButton, {
47
+ api: api
48
+ });
49
+ }
50
+ }, {
51
+ type: _toolbar.MEDIA_GROUP.type,
52
+ key: _toolbar.MEDIA_GROUP.key,
53
+ parents: [{
54
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
55
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
56
+ rank: _toolbar.INSERT_BLOCK_SECTION_RANK[_toolbar.MEDIA_GROUP.key]
57
+ }]
58
+ }, {
59
+ type: _toolbar.MEDIA_BUTTON.type,
60
+ key: _toolbar.MEDIA_BUTTON.key,
61
+ parents: [{
62
+ type: _toolbar.MEDIA_GROUP.type,
63
+ key: _toolbar.MEDIA_GROUP.key,
64
+ rank: _toolbar.MEDIA_GROUP_RANK[_toolbar.MEDIA_BUTTON.key]
65
+ }],
66
+ component: function component() {
67
+ return !!(api !== null && api !== void 0 && api.imageUpload) ? /*#__PURE__*/_react.default.createElement(_ImageButton.ImageButton, {
68
+ api: api
69
+ }) : /*#__PURE__*/_react.default.createElement(_MediaButton.MediaButton, {
70
+ api: api
71
+ });
72
+ }
73
+ }, {
74
+ type: _toolbar.MENTION_GROUP.type,
75
+ key: _toolbar.MENTION_GROUP.key,
76
+ parents: [{
77
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
78
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
79
+ rank: _toolbar.INSERT_BLOCK_SECTION_RANK[_toolbar.MENTION_GROUP.key]
80
+ }]
81
+ }, {
82
+ type: _toolbar.MENTION_BUTTON.type,
83
+ key: _toolbar.MENTION_BUTTON.key,
84
+ parents: [{
85
+ type: _toolbar.MENTION_GROUP.type,
86
+ key: _toolbar.MENTION_GROUP.key,
87
+ rank: _toolbar.MENTION_GROUP_RANK[_toolbar.MENTION_BUTTON.key]
88
+ }],
89
+ component: function component() {
90
+ return /*#__PURE__*/_react.default.createElement(_MentionButton.MentionButton, {
91
+ api: api
92
+ });
93
+ }
94
+ }, {
95
+ type: _toolbar.EMOJI_GROUP.type,
96
+ key: _toolbar.EMOJI_GROUP.key,
97
+ parents: [{
98
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
99
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
100
+ rank: _toolbar.INSERT_BLOCK_SECTION_RANK[_toolbar.EMOJI_GROUP.key]
101
+ }]
102
+ }, {
103
+ type: _toolbar.EMOJI_BUTTON.type,
104
+ key: _toolbar.EMOJI_BUTTON.key,
105
+ parents: [{
106
+ type: _toolbar.EMOJI_GROUP.type,
107
+ key: _toolbar.EMOJI_GROUP.key,
108
+ rank: _toolbar.EMOJI_GROUP_RANK[_toolbar.EMOJI_BUTTON.key]
109
+ }],
110
+ component: function component() {
111
+ return /*#__PURE__*/_react.default.createElement(_EmojiButton.EmojiButton, {
112
+ api: api
113
+ });
114
+ }
115
+ }, {
116
+ type: _toolbar.LAYOUT_GROUP.type,
117
+ key: _toolbar.LAYOUT_GROUP.key,
118
+ parents: [{
119
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
120
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
121
+ rank: _toolbar.INSERT_BLOCK_SECTION_RANK[_toolbar.LAYOUT_GROUP.key]
122
+ }]
123
+ }, {
124
+ type: _toolbar.LAYOUT_BUTTON.type,
125
+ key: _toolbar.LAYOUT_BUTTON.key,
126
+ parents: [{
127
+ type: _toolbar.LAYOUT_GROUP.type,
128
+ key: _toolbar.LAYOUT_GROUP.key,
129
+ rank: _toolbar.LAYOUT_GROUP_RANK[_toolbar.LAYOUT_BUTTON.key]
130
+ }],
131
+ component: function component() {
132
+ return /*#__PURE__*/_react.default.createElement(_LayoutButton.LayoutButton, {
133
+ api: api
134
+ });
135
+ }
136
+ }, {
137
+ type: _toolbar.TABLE_GROUP.type,
138
+ key: _toolbar.TABLE_GROUP.key,
139
+ parents: [{
140
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
141
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
142
+ rank: _toolbar.INSERT_BLOCK_SECTION_RANK[_toolbar.TABLE_GROUP.key]
143
+ }]
144
+ }, {
145
+ type: _toolbar.TABLE_BUTTON.type,
146
+ key: _toolbar.TABLE_BUTTON.key,
147
+ parents: [{
148
+ type: _toolbar.TABLE_GROUP.type,
149
+ key: _toolbar.TABLE_GROUP.key,
150
+ rank: _toolbar.TABLE_GROUP_RANK[_toolbar.TABLE_BUTTON.key]
151
+ }],
152
+ component: function component() {
153
+ return /*#__PURE__*/_react.default.createElement(_TableButton.TableButton, {
154
+ api: api
155
+ });
156
+ }
157
+ }, {
158
+ type: _toolbar.TABLE_SIZE_PICKER.type,
159
+ key: _toolbar.TABLE_SIZE_PICKER.key,
160
+ parents: [{
161
+ type: _toolbar.TABLE_GROUP.type,
162
+ key: _toolbar.TABLE_GROUP.key,
163
+ rank: _toolbar.TABLE_GROUP_RANK[_toolbar.TABLE_SIZE_PICKER.key]
164
+ }],
165
+ component: function component() {
166
+ return /*#__PURE__*/_react.default.createElement(_TableSizePicker.TableSizePicker, {
167
+ api: api,
168
+ tableSelectorSupported: tableSelectorSupported
169
+ });
170
+ }
171
+ }];
172
+ };
@@ -7,8 +7,10 @@ import { ToolbarSize } from '@atlaskit/editor-common/types';
7
7
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
8
8
  import { BLOCK_QUOTE, CODE_BLOCK, PANEL } from '@atlaskit/editor-plugin-block-type/consts';
9
9
  import { fg } from '@atlaskit/platform-feature-flags';
10
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
10
11
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
11
12
  import { toggleInsertBlockPmKey, toggleInsertBlockPmPlugin } from './pm-plugins/toggleInsertBlock';
13
+ import { getToolbarComponents } from './ui/toolbar-components';
12
14
  // Ignored via go/ees005
13
15
  // eslint-disable-next-line import/no-named-as-default
14
16
  import ToolbarInsertBlock from './ui/ToolbarInsertBlock';
@@ -89,7 +91,6 @@ export const insertBlockPlugin = ({
89
91
  config: options = {},
90
92
  api
91
93
  }) => {
92
- var _api$primaryToolbar;
93
94
  const primaryToolbarComponent = ({
94
95
  editorView,
95
96
  editorActions,
@@ -146,10 +147,19 @@ export const insertBlockPlugin = ({
146
147
  renderNode: renderNode
147
148
  });
148
149
  };
149
- api === null || api === void 0 ? void 0 : (_api$primaryToolbar = api.primaryToolbar) === null || _api$primaryToolbar === void 0 ? void 0 : _api$primaryToolbar.actions.registerComponent({
150
- name: 'insertBlock',
151
- component: primaryToolbarComponent
152
- });
150
+ if (expValEquals('platform_editor_toolbar_aifc', 'isEnabled', true)) {
151
+ var _api$toolbar;
152
+ api === null || api === void 0 ? void 0 : (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : _api$toolbar.actions.registerComponents(getToolbarComponents({
153
+ api,
154
+ tableSelectorSupported: options.tableSelectorSupported
155
+ }));
156
+ } else {
157
+ var _api$primaryToolbar;
158
+ api === null || api === void 0 ? void 0 : (_api$primaryToolbar = api.primaryToolbar) === null || _api$primaryToolbar === void 0 ? void 0 : _api$primaryToolbar.actions.registerComponent({
159
+ name: 'insertBlock',
160
+ component: primaryToolbarComponent
161
+ });
162
+ }
153
163
  const plugin = {
154
164
  name: 'insertBlock',
155
165
  actions: {
@@ -0,0 +1,120 @@
1
+ import React, { useRef, useState } from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
+ import { Popup } from '@atlaskit/editor-common/ui';
7
+ import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners as withOuterListeners } from '@atlaskit/editor-common/ui-react';
8
+ import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
9
+ import { ToolbarButton, ToolbarTooltip, EmojiIcon } from '@atlaskit/editor-toolbar';
10
+ import { EmojiPicker as AkEmojiPicker } from '@atlaskit/emoji/picker';
11
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
12
+ import { isDetachedElement } from './utils/utils';
13
+ const EmojiPicker = props => {
14
+ const setOutsideClickTargetRef = React.useContext(OutsideClickTargetRefContext);
15
+ return /*#__PURE__*/React.createElement(AkEmojiPicker, {
16
+ onPickerRef: setOutsideClickTargetRef,
17
+ emojiProvider: props.emojiProvider,
18
+ onSelection: props.onSelection
19
+ });
20
+ };
21
+ const EmojiPickerWithListeners = withOuterListeners(EmojiPicker);
22
+ export const EmojiButton = ({
23
+ api
24
+ }) => {
25
+ const {
26
+ formatMessage
27
+ } = useIntl();
28
+ const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
29
+ const emojiButtonRef = useRef(null);
30
+ const {
31
+ emojiProviderSelector,
32
+ emojiProviderPromise,
33
+ isTypeAheadAllowed
34
+ } = useSharedPluginStateWithSelector(api, ['emoji', 'typeAhead'], states => {
35
+ var _states$emojiState, _states$emojiState2, _states$typeAheadStat;
36
+ return {
37
+ emojiProviderSelector: (_states$emojiState = states.emojiState) === null || _states$emojiState === void 0 ? void 0 : _states$emojiState.emojiProvider,
38
+ emojiProviderPromise: (_states$emojiState2 = states.emojiState) === null || _states$emojiState2 === void 0 ? void 0 : _states$emojiState2.emojiProviderPromise,
39
+ isTypeAheadAllowed: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.isAllowed
40
+ };
41
+ });
42
+ if (!(api !== null && api !== void 0 && api.emoji)) {
43
+ return null;
44
+ }
45
+ const toggleEmojiPickerOpen = newState => {
46
+ const oldState = emojiPickerOpen;
47
+ if (newState === true && oldState === false) {
48
+ var _api$analytics;
49
+ api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent({
50
+ action: ACTION.OPENED,
51
+ actionSubject: ACTION_SUBJECT.PICKER,
52
+ actionSubjectId: ACTION_SUBJECT_ID.PICKER_EMOJI,
53
+ attributes: {
54
+ inputMethod: INPUT_METHOD.TOOLBAR
55
+ },
56
+ eventType: EVENT_TYPE.UI
57
+ });
58
+ }
59
+ setEmojiPickerOpen(newState);
60
+ };
61
+ const getEmojiProvider = () => {
62
+ if (emojiProviderSelector) {
63
+ return Promise.resolve(emojiProviderSelector);
64
+ }
65
+ };
66
+ const emojiProvider = expValEquals('platform_editor_prevent_toolbar_layout_shifts', 'isEnabled', true) ? emojiProviderPromise : getEmojiProvider();
67
+ const onPopupUnmount = () => {
68
+ requestAnimationFrame(() => api === null || api === void 0 ? void 0 : api.core.actions.focus());
69
+ };
70
+ const handleSelectedEmoji = emojiId => {
71
+ var _api$emoji;
72
+ api === null || api === void 0 ? void 0 : api.core.actions.focus();
73
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$emoji = api.emoji) === null || _api$emoji === void 0 ? void 0 : _api$emoji.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER));
74
+ toggleEmojiPickerOpen(false);
75
+ return true;
76
+ };
77
+ const handleEmojiClickOutside = e => {
78
+ // Ignore click events for detached elements.
79
+ // Workaround for FS-1322 - where two onClicks fire - one when the upload button is
80
+ // still in the document, and one once it's detached. Does not always occur, and
81
+ // may be a side effect of a react render optimisation
82
+ if (e.target instanceof HTMLElement && !isDetachedElement(e.target)) {
83
+ toggleEmojiPickerOpen(false);
84
+ }
85
+ };
86
+ const handleEmojiPressEscape = () => {
87
+ var _emojiButtonRef$curre;
88
+ toggleEmojiPickerOpen(false);
89
+ emojiButtonRef === null || emojiButtonRef === void 0 ? void 0 : (_emojiButtonRef$curre = emojiButtonRef.current) === null || _emojiButtonRef$curre === void 0 ? void 0 : _emojiButtonRef$curre.focus();
90
+ };
91
+ const onClick = () => {
92
+ toggleEmojiPickerOpen(!emojiPickerOpen);
93
+ };
94
+ return /*#__PURE__*/React.createElement(React.Fragment, null, emojiPickerOpen && emojiButtonRef.current && emojiProvider && /*#__PURE__*/React.createElement(Popup, {
95
+ target: emojiButtonRef.current,
96
+ fitHeight: 350,
97
+ fitWidth: 350,
98
+ offset: [0, 3],
99
+ mountTo: emojiButtonRef.current,
100
+ onUnmount: onPopupUnmount,
101
+ focusTrap: true,
102
+ zIndex: akEditorMenuZIndex
103
+ }, /*#__PURE__*/React.createElement(EmojiPickerWithListeners, {
104
+ emojiProvider: emojiProvider,
105
+ onSelection: handleSelectedEmoji,
106
+ handleClickOutside: handleEmojiClickOutside,
107
+ handleEscapeKeydown: handleEmojiPressEscape
108
+ })), /*#__PURE__*/React.createElement(ToolbarTooltip, {
109
+ content: formatMessage(messages.emoji)
110
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
111
+ iconBefore: /*#__PURE__*/React.createElement(EmojiIcon, {
112
+ label: formatMessage(messages.emoji)
113
+ }),
114
+ ariaKeyshortcuts: "Shift+;",
115
+ ref: emojiButtonRef,
116
+ onClick: onClick,
117
+ isSelected: emojiPickerOpen,
118
+ isDisabled: !isTypeAheadAllowed || !emojiProvider
119
+ })));
120
+ };
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
6
+ import { ToolbarButton, ToolbarTooltip, ImageIcon } from '@atlaskit/editor-toolbar';
7
+ export const ImageButton = ({
8
+ api
9
+ }) => {
10
+ const {
11
+ formatMessage
12
+ } = useIntl();
13
+ const {
14
+ connectivityMode,
15
+ imageUploadEnabled
16
+ } = useSharedPluginStateWithSelector(api, ['connectivity', 'imageUpload'], states => {
17
+ var _states$connectivityS, _states$imageUploadSt;
18
+ return {
19
+ connectivityMode: (_states$connectivityS = states.connectivityState) === null || _states$connectivityS === void 0 ? void 0 : _states$connectivityS.mode,
20
+ imageUploadEnabled: (_states$imageUploadSt = states.imageUploadState) === null || _states$imageUploadSt === void 0 ? void 0 : _states$imageUploadSt.enabled
21
+ };
22
+ });
23
+ const {
24
+ editorView
25
+ } = useEditorToolbar();
26
+ const isOffline = connectivityMode === 'offline';
27
+ const onClick = () => {
28
+ if (editorView) {
29
+ var _api$imageUpload;
30
+ const {
31
+ state,
32
+ dispatch
33
+ } = editorView;
34
+ api === null || api === void 0 ? void 0 : (_api$imageUpload = api.imageUpload) === null || _api$imageUpload === void 0 ? void 0 : _api$imageUpload.actions.startUpload()(state, dispatch);
35
+ }
36
+ };
37
+ return /*#__PURE__*/React.createElement(ToolbarTooltip, {
38
+ content: formatMessage(messages.image)
39
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
40
+ iconBefore: /*#__PURE__*/React.createElement(ImageIcon, {
41
+ label: formatMessage(messages.image)
42
+ }),
43
+ onClick: onClick,
44
+ isDisabled: !imageUploadEnabled || isOffline
45
+ }));
46
+ };
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
6
+ import { ToolbarButton, ToolbarTooltip, LayoutIcon } from '@atlaskit/editor-toolbar';
7
+ export const LayoutButton = ({
8
+ api
9
+ }) => {
10
+ const {
11
+ formatMessage
12
+ } = useIntl();
13
+ const {
14
+ editorView
15
+ } = useEditorToolbar();
16
+ if (!(api !== null && api !== void 0 && api.layout)) {
17
+ return null;
18
+ }
19
+ const onClick = () => {
20
+ if (editorView) {
21
+ var _api$layout;
22
+ const {
23
+ state,
24
+ dispatch
25
+ } = editorView;
26
+ api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.actions.insertLayoutColumns(INPUT_METHOD.TOOLBAR)(state, dispatch);
27
+ }
28
+ };
29
+ return /*#__PURE__*/React.createElement(ToolbarTooltip, {
30
+ content: formatMessage(messages.columns)
31
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
32
+ iconBefore: /*#__PURE__*/React.createElement(LayoutIcon, {
33
+ label: formatMessage(messages.columns)
34
+ }),
35
+ onClick: onClick
36
+ }));
37
+ };
@@ -0,0 +1,66 @@
1
+ import React, { useRef } from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
+ import { ToolbarButton, ToolbarTooltip, ImageIcon } from '@atlaskit/editor-toolbar';
7
+ import { fg } from '@atlaskit/platform-feature-flags';
8
+ export const MediaButton = ({
9
+ api
10
+ }) => {
11
+ const {
12
+ formatMessage
13
+ } = useIntl();
14
+ const {
15
+ showMediaPicker,
16
+ connectivityMode,
17
+ allowsUploads
18
+ } = useSharedPluginStateWithSelector(api, ['media', 'connectivity'], states => {
19
+ var _states$mediaState, _states$mediaState2, _states$connectivityS;
20
+ return {
21
+ showMediaPicker: (_states$mediaState = states.mediaState) === null || _states$mediaState === void 0 ? void 0 : _states$mediaState.showMediaPicker,
22
+ allowsUploads: (_states$mediaState2 = states.mediaState) === null || _states$mediaState2 === void 0 ? void 0 : _states$mediaState2.allowsUploads,
23
+ connectivityMode: (_states$connectivityS = states.connectivityState) === null || _states$connectivityS === void 0 ? void 0 : _states$connectivityS.mode
24
+ };
25
+ });
26
+ const mediaButtonRef = useRef(null);
27
+ if (!(api !== null && api !== void 0 && api.media)) {
28
+ return null;
29
+ }
30
+ const onClick = () => {
31
+ var _api$mediaInsert, _api$mediaInsert$comm, _api$analytics;
32
+ if (!showMediaPicker) {
33
+ return;
34
+ }
35
+ if (api !== null && api !== void 0 && (_api$mediaInsert = api.mediaInsert) !== null && _api$mediaInsert !== void 0 && (_api$mediaInsert$comm = _api$mediaInsert.commands) !== null && _api$mediaInsert$comm !== void 0 && _api$mediaInsert$comm.showMediaInsertPopup && fg('platform_editor_add_media_from_url_rollout')) {
36
+ var _api$core, _api$mediaInsert2;
37
+ const mountInfo = mediaButtonRef.current ? {
38
+ ref: mediaButtonRef.current,
39
+ mountPoint: mediaButtonRef.current
40
+ } : undefined;
41
+ api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$mediaInsert2 = api.mediaInsert) === null || _api$mediaInsert2 === void 0 ? void 0 : _api$mediaInsert2.commands.showMediaInsertPopup(mountInfo));
42
+ } else {
43
+ showMediaPicker();
44
+ }
45
+ api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent({
46
+ action: ACTION.OPENED,
47
+ actionSubject: ACTION_SUBJECT.PICKER,
48
+ actionSubjectId: fg('platform_editor_add_media_from_url_rollout') ? ACTION_SUBJECT_ID.PICKER_MEDIA : ACTION_SUBJECT_ID.PICKER_CLOUD,
49
+ attributes: {
50
+ inputMethod: INPUT_METHOD.TOOLBAR
51
+ },
52
+ eventType: EVENT_TYPE.UI
53
+ });
54
+ };
55
+ const isOffline = connectivityMode === 'offline';
56
+ return /*#__PURE__*/React.createElement(ToolbarTooltip, {
57
+ content: formatMessage(messages.addMediaFiles)
58
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
59
+ iconBefore: /*#__PURE__*/React.createElement(ImageIcon, {
60
+ label: formatMessage(messages.addMediaFiles)
61
+ }),
62
+ onClick: onClick,
63
+ ref: mediaButtonRef,
64
+ isDisabled: isOffline || !allowsUploads
65
+ }));
66
+ };
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
+ import { ToolbarButton, ToolbarTooltip, MentionIcon } from '@atlaskit/editor-toolbar';
7
+ export const MentionButton = ({
8
+ api
9
+ }) => {
10
+ const {
11
+ formatMessage
12
+ } = useIntl();
13
+ const {
14
+ canInsertMention,
15
+ mentionProvider,
16
+ isTypeAheadAllowed
17
+ } = useSharedPluginStateWithSelector(api, ['mention', 'typeAhead'], states => {
18
+ var _states$mentionState, _states$mentionState2, _states$typeAheadStat;
19
+ return {
20
+ canInsertMention: (_states$mentionState = states.mentionState) === null || _states$mentionState === void 0 ? void 0 : _states$mentionState.canInsertMention,
21
+ mentionProvider: (_states$mentionState2 = states.mentionState) === null || _states$mentionState2 === void 0 ? void 0 : _states$mentionState2.mentionProvider,
22
+ isTypeAheadAllowed: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.isAllowed
23
+ };
24
+ });
25
+ if (!(api !== null && api !== void 0 && api.mention)) {
26
+ return null;
27
+ }
28
+ const onClick = () => {
29
+ var _api$mention, _api$mention$actions;
30
+ api === null || api === void 0 ? void 0 : (_api$mention = api.mention) === null || _api$mention === void 0 ? void 0 : (_api$mention$actions = _api$mention.actions) === null || _api$mention$actions === void 0 ? void 0 : _api$mention$actions.openTypeAhead(INPUT_METHOD.TOOLBAR);
31
+ };
32
+ return /*#__PURE__*/React.createElement(ToolbarTooltip, {
33
+ content: formatMessage(messages.mention)
34
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
35
+ iconBefore: /*#__PURE__*/React.createElement(MentionIcon, {
36
+ label: formatMessage(messages.mention)
37
+ }),
38
+ onClick: onClick,
39
+ ariaKeyshortcuts: "Shift+2 Space",
40
+ isDisabled: !canInsertMention || !mentionProvider || !isTypeAheadAllowed
41
+ }));
42
+ };
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { formatShortcut, toggleTable } from '@atlaskit/editor-common/keymaps';
5
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
+ import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
7
+ import { ToolbarButton, ToolbarTooltip, TableIcon } from '@atlaskit/editor-toolbar';
8
+ export const TableButton = ({
9
+ api
10
+ }) => {
11
+ const {
12
+ formatMessage
13
+ } = useIntl();
14
+ const {
15
+ editorView
16
+ } = useEditorToolbar();
17
+ if (!(editorView !== null && editorView !== void 0 && editorView.state.schema.nodes.table)) {
18
+ return null;
19
+ }
20
+ const onClick = () => {
21
+ if (editorView) {
22
+ const {
23
+ state,
24
+ dispatch
25
+ } = editorView;
26
+ // workaround to solve race condition where cursor is not placed correctly inside table
27
+ queueMicrotask(() => {
28
+ var _api$table, _api$table$actions$in, _api$table$actions;
29
+ api === null || api === void 0 ? void 0 : (_api$table = api.table) === null || _api$table === void 0 ? void 0 : (_api$table$actions$in = (_api$table$actions = _api$table.actions).insertTable) === null || _api$table$actions$in === void 0 ? void 0 : _api$table$actions$in.call(_api$table$actions, {
30
+ action: ACTION.INSERTED,
31
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
32
+ actionSubjectId: ACTION_SUBJECT_ID.TABLE,
33
+ attributes: {
34
+ inputMethod: INPUT_METHOD.TOOLBAR
35
+ },
36
+ eventType: EVENT_TYPE.TRACK
37
+ })(state, dispatch);
38
+ });
39
+ }
40
+ };
41
+ return /*#__PURE__*/React.createElement(ToolbarTooltip, {
42
+ content: formatMessage(messages.table)
43
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
44
+ iconBefore: /*#__PURE__*/React.createElement(TableIcon, {
45
+ label: formatMessage(messages.table)
46
+ }),
47
+ onClick: onClick,
48
+ ariaKeyshortcuts: formatShortcut(toggleTable)
49
+ }));
50
+ };
@@ -0,0 +1,70 @@
1
+ import React, { useRef, useState } from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
6
+ import { TableSelectorPopup } from '@atlaskit/editor-common/ui';
7
+ import { MoreItemsIcon, ToolbarButton, ToolbarTooltip } from '@atlaskit/editor-toolbar';
8
+ import { isDetachedElement } from './utils/utils';
9
+ export const TableSizePicker = ({
10
+ api,
11
+ tableSelectorSupported
12
+ }) => {
13
+ const {
14
+ formatMessage
15
+ } = useIntl();
16
+ const {
17
+ editorView
18
+ } = useEditorToolbar();
19
+ const [tableSizePickerOpen, setTableSizePickerOpen] = useState(false);
20
+ const [isOpenedByKeyboard, setIsOpenedByKeyboard] = useState(false);
21
+ const tableSizePickerRef = useRef(null);
22
+ if (!(editorView !== null && editorView !== void 0 && editorView.state.schema.nodes.table) || !tableSelectorSupported) {
23
+ return null;
24
+ }
25
+ const handleSelectedTableSize = (rowsCount, colsCount) => {
26
+ // workaround to solve race condition where cursor is not placed correctly inside table
27
+ queueMicrotask(() => {
28
+ var _api$core, _api$table;
29
+ api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$table = api.table) === null || _api$table === void 0 ? void 0 : _api$table.commands.insertTableWithSize(rowsCount, colsCount, INPUT_METHOD.PICKER));
30
+ });
31
+ setTableSizePickerOpen(false);
32
+ };
33
+ const handleTableSelectorClickOutside = e => {
34
+ // Ignore click events for detached elements.
35
+ if (e.target instanceof HTMLElement && !isDetachedElement(e.target)) {
36
+ setTableSizePickerOpen(false);
37
+ }
38
+ };
39
+ const handleTableSelectorPressEscape = () => {
40
+ var _tableSizePickerRef$c;
41
+ setTableSizePickerOpen(false);
42
+ (_tableSizePickerRef$c = tableSizePickerRef.current) === null || _tableSizePickerRef$c === void 0 ? void 0 : _tableSizePickerRef$c.focus();
43
+ };
44
+ const onUnmount = () => {
45
+ api === null || api === void 0 ? void 0 : api.core.actions.focus();
46
+ };
47
+ const onClick = event => {
48
+ setIsOpenedByKeyboard(event.detail === 0 ? true : false);
49
+ setTableSizePickerOpen(!tableSizePickerOpen);
50
+ };
51
+ return /*#__PURE__*/React.createElement(React.Fragment, null, tableSizePickerRef.current && tableSizePickerOpen && /*#__PURE__*/React.createElement(TableSelectorPopup, {
52
+ allowOutsideSelection: true,
53
+ target: tableSizePickerRef.current,
54
+ onUnmount: onUnmount,
55
+ onSelection: handleSelectedTableSize,
56
+ popupsMountPoint: tableSizePickerRef.current,
57
+ handleClickOutside: handleTableSelectorClickOutside,
58
+ handleEscapeKeydown: handleTableSelectorPressEscape,
59
+ isOpenedByKeyboard: isOpenedByKeyboard
60
+ }), /*#__PURE__*/React.createElement(ToolbarTooltip, {
61
+ content: formatMessage(messages.tableSelector)
62
+ }, /*#__PURE__*/React.createElement(ToolbarButton, {
63
+ iconBefore: /*#__PURE__*/React.createElement(MoreItemsIcon, {
64
+ label: formatMessage(messages.tableSelector)
65
+ }),
66
+ onClick: onClick,
67
+ isSelected: tableSizePickerOpen,
68
+ ref: tableSizePickerRef
69
+ })));
70
+ };