@atlaskit/editor-core 185.12.0 → 185.12.2

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 (44) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/plugins/block-type/commands/block-type.js +79 -44
  3. package/dist/cjs/plugins/card/ui/EditLinkToolbar.js +4 -3
  4. package/dist/cjs/plugins/card/ui/EditorSmartCardEventsNext.js +15 -36
  5. package/dist/cjs/plugins/code-block/index.js +7 -3
  6. package/dist/cjs/plugins/expand/commands.js +6 -2
  7. package/dist/cjs/plugins/expand/index.js +5 -1
  8. package/dist/cjs/plugins/hyperlink/Toolbar.js +1 -0
  9. package/dist/cjs/plugins/panel/index.js +81 -43
  10. package/dist/cjs/plugins/quick-insert/commands.js +2 -0
  11. package/dist/cjs/ui/ElementBrowser/InsertMenu.js +10 -0
  12. package/dist/cjs/version-wrapper.js +1 -1
  13. package/dist/cjs/version.json +1 -1
  14. package/dist/es2019/plugins/block-type/commands/block-type.js +86 -51
  15. package/dist/es2019/plugins/card/ui/EditLinkToolbar.js +4 -3
  16. package/dist/es2019/plugins/card/ui/EditorSmartCardEventsNext.js +21 -35
  17. package/dist/es2019/plugins/code-block/index.js +7 -2
  18. package/dist/es2019/plugins/expand/commands.js +6 -2
  19. package/dist/es2019/plugins/expand/index.js +5 -1
  20. package/dist/es2019/plugins/hyperlink/Toolbar.js +1 -0
  21. package/dist/es2019/plugins/panel/index.js +82 -41
  22. package/dist/es2019/plugins/quick-insert/commands.js +2 -0
  23. package/dist/es2019/ui/ElementBrowser/InsertMenu.js +10 -0
  24. package/dist/es2019/version-wrapper.js +1 -1
  25. package/dist/es2019/version.json +1 -1
  26. package/dist/esm/plugins/block-type/commands/block-type.js +76 -43
  27. package/dist/esm/plugins/card/ui/EditLinkToolbar.js +4 -3
  28. package/dist/esm/plugins/card/ui/EditorSmartCardEventsNext.js +15 -36
  29. package/dist/esm/plugins/code-block/index.js +7 -2
  30. package/dist/esm/plugins/expand/commands.js +6 -2
  31. package/dist/esm/plugins/expand/index.js +5 -1
  32. package/dist/esm/plugins/hyperlink/Toolbar.js +1 -0
  33. package/dist/esm/plugins/panel/index.js +81 -43
  34. package/dist/esm/plugins/quick-insert/commands.js +2 -0
  35. package/dist/esm/ui/ElementBrowser/InsertMenu.js +10 -0
  36. package/dist/esm/version-wrapper.js +1 -1
  37. package/dist/esm/version.json +1 -1
  38. package/dist/types/plugins/block-type/commands/block-type.d.ts +25 -0
  39. package/dist/types/plugins/card/types.d.ts +2 -3
  40. package/dist/types/plugins/card/ui/EditLinkToolbar.d.ts +2 -2
  41. package/dist/types-ts4.5/plugins/block-type/commands/block-type.d.ts +25 -0
  42. package/dist/types-ts4.5/plugins/card/types.d.ts +2 -3
  43. package/dist/types-ts4.5/plugins/card/ui/EditLinkToolbar.d.ts +2 -2
  44. package/package.json +2 -2
@@ -207,6 +207,45 @@ export const insertBlockTypesWithAnalytics = (name, inputMethod, editorAnalytics
207
207
  }
208
208
  };
209
209
 
210
+ /**
211
+ * This function creates a new transaction that wraps the current selection
212
+ * in the specified node type if it results in a valid transaction.
213
+ * If not valid, it performs a safe insert operation.
214
+ *
215
+ * Example of when wrapping might not be valid is when attempting to wrap
216
+ * content that is already inside a panel with another panel
217
+ */
218
+ export function createWrapSelectionTransaction({
219
+ state,
220
+ type,
221
+ nodeAttributes
222
+ }) {
223
+ let {
224
+ tr
225
+ } = state;
226
+ const {
227
+ $from,
228
+ $to
229
+ } = state.selection;
230
+ const {
231
+ alignment,
232
+ indentation
233
+ } = state.schema.marks;
234
+
235
+ /** Alignment or Indentation is not valid inside block types */
236
+ const removeAlignTr = removeBlockMarks(state, [alignment, indentation]);
237
+ tr = removeAlignTr || tr;
238
+ const range = $from.blockRange($to);
239
+ const wrapping = range && findWrapping(range, type, nodeAttributes);
240
+ if (range && wrapping) {
241
+ tr.wrap(range, wrapping).scrollIntoView();
242
+ } else {
243
+ /** We always want to append a block type */
244
+ safeInsert(type.createAndFill())(tr).scrollIntoView();
245
+ }
246
+ return tr;
247
+ }
248
+
210
249
  /**
211
250
  * Function will add wrapping node.
212
251
  * 1. If currently selected blocks can be wrapped in the wrapper type it will wrap them.
@@ -215,29 +254,10 @@ export const insertBlockTypesWithAnalytics = (name, inputMethod, editorAnalytics
215
254
  */
216
255
  function wrapSelectionIn(type) {
217
256
  return function (state, dispatch) {
218
- let {
219
- tr
220
- } = state;
221
- const {
222
- $from,
223
- $to
224
- } = state.selection;
225
- const {
226
- alignment,
227
- indentation
228
- } = state.schema.marks;
229
-
230
- /** Alignment or Indentation is not valid inside block types */
231
- const removeAlignTr = removeBlockMarks(state, [alignment, indentation]);
232
- tr = removeAlignTr || tr;
233
- const range = $from.blockRange($to);
234
- const wrapping = range && findWrapping(range, type);
235
- if (range && wrapping) {
236
- tr.wrap(range, wrapping).scrollIntoView();
237
- } else {
238
- /** We always want to append a block type */
239
- safeInsert(type.createAndFill())(tr).scrollIntoView();
240
- }
257
+ let tr = createWrapSelectionTransaction({
258
+ state,
259
+ type
260
+ });
241
261
  if (dispatch) {
242
262
  dispatch(tr);
243
263
  }
@@ -245,45 +265,60 @@ function wrapSelectionIn(type) {
245
265
  };
246
266
  }
247
267
 
268
+ /**
269
+ * This function creates a new transaction that inserts a code block,
270
+ * if there is text selected it will wrap the current selection if not it will
271
+ * append the codeblock to the end of the document.
272
+ */
273
+ export function createInsertCodeBlockTransaction({
274
+ state
275
+ }) {
276
+ var _state$selection$$fro;
277
+ let {
278
+ tr
279
+ } = state;
280
+ const {
281
+ from
282
+ } = state.selection;
283
+ const {
284
+ codeBlock
285
+ } = state.schema.nodes;
286
+ const grandParentNodeType = (_state$selection$$fro = state.selection.$from.node(-1)) === null || _state$selection$$fro === void 0 ? void 0 : _state$selection$$fro.type;
287
+ const parentNodeType = state.selection.$from.parent.type;
288
+
289
+ /** We always want to append a codeBlock unless we're inserting into a paragraph
290
+ * AND it's a valid child of the grandparent node.
291
+ * Insert the current selection as codeBlock content unless it contains nodes other
292
+ * than paragraphs and inline.
293
+ */
294
+ const canInsertCodeBlock = shouldSplitSelectedNodeOnNodeInsertion({
295
+ parentNodeType,
296
+ grandParentNodeType,
297
+ content: codeBlock.createAndFill()
298
+ }) && contentAllowedInCodeBlock(state);
299
+ if (canInsertCodeBlock) {
300
+ tr = transformToCodeBlockAction(state, from);
301
+ } else {
302
+ safeInsert(codeBlock.createAndFill())(tr).scrollIntoView();
303
+ }
304
+ return tr;
305
+ }
306
+
248
307
  /**
249
308
  * Function will insert code block at current selection if block is empty or below current selection and set focus on it.
250
309
  */
251
310
  function insertCodeBlock() {
252
311
  return function (state, dispatch) {
253
- var _state$selection$$fro;
254
- let {
255
- tr
256
- } = state;
257
- const {
258
- from
259
- } = state.selection;
260
- const {
261
- codeBlock
262
- } = state.schema.nodes;
263
- const grandParentNodeType = (_state$selection$$fro = state.selection.$from.node(-1)) === null || _state$selection$$fro === void 0 ? void 0 : _state$selection$$fro.type;
264
- const parentNodeType = state.selection.$from.parent.type;
265
-
266
- /** We always want to append a codeBlock unless we're inserting into a paragraph
267
- * AND it's a valid child of the grandparent node.
268
- * Insert the current selection as codeBlock content unless it contains nodes other
269
- * than paragraphs and inline.
270
- */
271
- const canInsertCodeBlock = shouldSplitSelectedNodeOnNodeInsertion({
272
- parentNodeType,
273
- grandParentNodeType,
274
- content: codeBlock.createAndFill()
275
- }) && contentAllowedInCodeBlock(state);
276
- if (canInsertCodeBlock) {
277
- tr = transformToCodeBlockAction(state, from);
278
- } else {
279
- safeInsert(codeBlock.createAndFill())(tr).scrollIntoView();
280
- }
312
+ let tr = createInsertCodeBlockTransaction({
313
+ state
314
+ });
281
315
  if (dispatch) {
282
316
  dispatch(tr);
283
317
  }
284
318
  return true;
285
319
  };
286
320
  }
321
+
287
322
  /**
288
323
  * Check if the current selection contains any nodes that are not permitted
289
324
  * as codeBlock child nodes. Note that this allows paragraphs and inline nodes
@@ -59,10 +59,10 @@ export class EditLinkToolbar extends React.Component {
59
59
  ,
60
60
  invokeMethod: INPUT_METHOD.FLOATING_TB,
61
61
  featureFlags: featureFlags,
62
- onSubmit: (href, title, displayText, _, analytic) => {
62
+ onSubmit: (href, title, displayText, inputMethod, analytic) => {
63
63
  this.hideLinkToolbar();
64
64
  if (onSubmit) {
65
- onSubmit(href, displayText || title, analytic);
65
+ onSubmit(href, displayText || title, inputMethod, analytic);
66
66
  }
67
67
  }
68
68
  });
@@ -111,7 +111,7 @@ export const buildEditLinkToolbar = ({
111
111
  node: node,
112
112
  featureFlags: featureFlags,
113
113
  forceFocusSelector: pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d = pluginInjectionApi.dependencies.floatingToolbar.actions) === null || _pluginInjectionApi$d === void 0 ? void 0 : _pluginInjectionApi$d.forceFocusSelector,
114
- onSubmit: (newHref, newText, analytic) => {
114
+ onSubmit: (newHref, newText, inputMethod, analytic) => {
115
115
  const urlChanged = newHref !== displayInfo.url;
116
116
  const titleChanged = newText !== displayInfo.title;
117
117
 
@@ -121,6 +121,7 @@ export const buildEditLinkToolbar = ({
121
121
  var _pluginInjectionApi$d2;
122
122
  return commandWithMetadata(changeSelectedCardToLink(newText, newHref, undefined, undefined, undefined, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d2 = pluginInjectionApi.dependencies.analytics) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.actions), {
123
123
  action: ACTION.UPDATED,
124
+ inputMethod,
124
125
  sourceEvent: analytic
125
126
  })(view.state, view.dispatch);
126
127
  }
@@ -29,15 +29,8 @@ const withHistoryMethod = fn => {
29
29
  };
30
30
  };
31
31
  const getMethod = withHistoryMethod(({
32
- inputMethod,
33
- sourceEvent
32
+ inputMethod
34
33
  }) => {
35
- /**
36
- * If sourceEvent is present, don't provide a custom method
37
- */
38
- if (sourceEvent) {
39
- return;
40
- }
41
34
  switch (inputMethod) {
42
35
  case INPUT_METHOD.CLIPBOARD:
43
36
  return 'editor_paste';
@@ -51,15 +44,8 @@ const getMethod = withHistoryMethod(({
51
44
  }
52
45
  });
53
46
  const getUpdateType = withHistoryMethod(({
54
- action,
55
- sourceEvent
47
+ action
56
48
  }) => {
57
- /**
58
- * If sourceEvent is present, don't provide a custom method
59
- */
60
- if (sourceEvent) {
61
- return;
62
- }
63
49
  switch (action) {
64
50
  case ACTION.CHANGED_TYPE:
65
51
  return 'display_update';
@@ -111,12 +97,12 @@ export const EventsBinding = ({
111
97
  } = useSmartLinkLifecycleAnalytics();
112
98
  const events = useMemo(() => {
113
99
  return {
114
- created: ({
115
- url,
116
- display,
117
- nodeContext,
118
- ...metadata
119
- }) => {
100
+ created: metadata => {
101
+ const {
102
+ url,
103
+ display,
104
+ nodeContext
105
+ } = metadata;
120
106
  const displayCategory = displayCategoryFromDisplay(display);
121
107
  const sourceEvent = getSourceEventFromMetadata(metadata);
122
108
  const creationMethod = getMethod(metadata);
@@ -129,13 +115,13 @@ export const EventsBinding = ({
129
115
  creationMethod
130
116
  });
131
117
  },
132
- updated: ({
133
- url,
134
- display,
135
- previousDisplay,
136
- nodeContext,
137
- ...metadata
138
- }) => {
118
+ updated: metadata => {
119
+ const {
120
+ url,
121
+ display,
122
+ previousDisplay,
123
+ nodeContext
124
+ } = metadata;
139
125
  const displayCategory = displayCategoryFromDisplay(display);
140
126
  const sourceEvent = getSourceEventFromMetadata(metadata);
141
127
  const updateMethod = getMethod(metadata);
@@ -151,12 +137,12 @@ export const EventsBinding = ({
151
137
  updateType
152
138
  });
153
139
  },
154
- deleted: ({
155
- url,
156
- display,
157
- nodeContext,
158
- ...metadata
159
- }) => {
140
+ deleted: metadata => {
141
+ const {
142
+ url,
143
+ display,
144
+ nodeContext
145
+ } = metadata;
160
146
  const displayCategory = displayCategoryFromDisplay(display);
161
147
  const sourceEvent = getSourceEventFromMetadata(metadata);
162
148
  const deleteMethod = getMethod(metadata);
@@ -9,6 +9,10 @@ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD, EVENT_TYPE } f
9
9
  import { IconCode } from '../quick-insert/assets';
10
10
  import { messages } from '../block-type/messages';
11
11
  import refreshBrowserSelectionOnChange from './refresh-browser-selection';
12
+ // Theres an existing interelationship between these files, where the imported function is being called for code-block
13
+ // Insertions via the drop down menu
14
+ // tslint-ignore-next-line
15
+ import { createInsertCodeBlockTransaction } from '../block-type/commands/block-type';
12
16
  const codeBlockPlugin = (options, api) => ({
13
17
  name: 'codeBlock',
14
18
  nodes() {
@@ -58,8 +62,9 @@ const codeBlockPlugin = (options, api) => ({
58
62
  icon: () => /*#__PURE__*/React.createElement(IconCode, null),
59
63
  action(insert, state) {
60
64
  var _api$dependencies$ana;
61
- const schema = state.schema;
62
- const tr = insert(schema.nodes.codeBlock.createChecked());
65
+ const tr = createInsertCodeBlockTransaction({
66
+ state
67
+ });
63
68
  api === null || api === void 0 ? void 0 : (_api$dependencies$ana = api.dependencies.analytics) === null || _api$dependencies$ana === void 0 ? void 0 : _api$dependencies$ana.actions.attachAnalyticsEvent({
64
69
  action: ACTION.INSERTED,
65
70
  actionSubject: ACTION_SUBJECT.DOCUMENT,
@@ -1,10 +1,10 @@
1
1
  import { TextSelection } from 'prosemirror-state';
2
- import { safeInsert } from 'prosemirror-utils';
3
2
  import { findTable } from '@atlaskit/editor-tables/utils';
4
3
  import { addAnalytics, ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD, EVENT_TYPE, PLATFORMS, MODE } from '../analytics';
5
4
  import { GapCursorSelection, Side } from '../selection/gap-cursor-selection';
6
5
  import { findExpand } from './utils';
7
6
  import { createCommand } from './pm-plugins/plugin-factory';
7
+ import { createWrapSelectionTransaction } from '../block-type/commands/block-type';
8
8
  export const setExpandRef = ref => createCommand({
9
9
  type: 'SET_EXPAND_REF',
10
10
  data: {
@@ -97,6 +97,10 @@ export const createExpandNode = state => {
97
97
  };
98
98
  export const insertExpand = (state, dispatch) => {
99
99
  const expandNode = createExpandNode(state);
100
+ const tr = createWrapSelectionTransaction({
101
+ state,
102
+ type: state.schema.nodes.expand
103
+ });
100
104
  const payload = {
101
105
  action: ACTION.INSERTED,
102
106
  actionSubject: ACTION_SUBJECT.DOCUMENT,
@@ -107,7 +111,7 @@ export const insertExpand = (state, dispatch) => {
107
111
  eventType: EVENT_TYPE.TRACK
108
112
  };
109
113
  if (dispatch && expandNode) {
110
- dispatch(addAnalytics(state, safeInsert(expandNode)(state.tr).scrollIntoView(), payload));
114
+ dispatch(addAnalytics(state, tr, payload));
111
115
  }
112
116
  return true;
113
117
  };
@@ -7,6 +7,7 @@ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, EVENT_TYPE, IN
7
7
  import { getToolbarConfig } from './toolbar';
8
8
  import { createExpandNode } from './commands';
9
9
  import { messages } from '../insert-block/ui/ToolbarInsertBlock/messages';
10
+ import { createWrapSelectionTransaction } from '../block-type/commands/block-type';
10
11
  const expandPlugin = (options = {}, api) => {
11
12
  var _api$dependencies, _api$dependencies$fea;
12
13
  const featureFlags = (api === null || api === void 0 ? void 0 : (_api$dependencies = api.dependencies) === null || _api$dependencies === void 0 ? void 0 : (_api$dependencies$fea = _api$dependencies.featureFlags) === null || _api$dependencies$fea === void 0 ? void 0 : _api$dependencies$fea.sharedState.currentState()) || {};
@@ -55,7 +56,10 @@ const expandPlugin = (options = {}, api) => {
55
56
  if (!node) {
56
57
  return false;
57
58
  }
58
- const tr = insert(node);
59
+ const tr = createWrapSelectionTransaction({
60
+ state,
61
+ type: state.schema.nodes.expand
62
+ });
59
63
  return addAnalytics(state, tr, {
60
64
  action: ACTION.INSERTED,
61
65
  actionSubject: ACTION_SUBJECT.DOCUMENT,
@@ -204,6 +204,7 @@ export const getToolbarConfig = (options, featureFlags, pluginInjectionApi) => (
204
204
  const action = isEdit ? ACTION.UPDATED : ACTION.INSERTED;
205
205
  const command = isEdit ? commandWithMetadata(updateLink(href, displayText || title, activeLinkMark.pos), {
206
206
  action,
207
+ inputMethod,
207
208
  sourceEvent: analytic
208
209
  }) : insertLinkWithAnalytics(inputMethod, activeLinkMark.from, activeLinkMark.to, href, title, displayText, !!(options !== null && options !== void 0 && (_options$cardOptions = options.cardOptions) !== null && _options$cardOptions !== void 0 && _options$cardOptions.provider), analytic);
209
210
  command(view.state, view.dispatch, view);
@@ -8,23 +8,10 @@ import { IconPanel, IconPanelNote, IconPanelSuccess, IconPanelWarning, IconPanel
8
8
  import { messages } from '../block-type/messages';
9
9
  import IconCustomPanel from '../quick-insert/assets/custom-panel';
10
10
  import { T50 } from '@atlaskit/theme/colors';
11
- const insertPanelTypeWithAnalytics = (panelAttributes, state, insert) => {
12
- const tr = insert(insertPanelType(panelAttributes, state));
13
- if (tr) {
14
- addAnalytics(state, tr, {
15
- action: ACTION.INSERTED,
16
- actionSubject: ACTION_SUBJECT.DOCUMENT,
17
- actionSubjectId: ACTION_SUBJECT_ID.PANEL,
18
- attributes: {
19
- inputMethod: INPUT_METHOD.QUICK_INSERT,
20
- panelType: panelAttributes.panelType
21
- },
22
- eventType: EVENT_TYPE.TRACK
23
- });
24
- }
25
- return tr;
26
- };
27
- const insertPanelType = (panelAttributes, state) => state.schema.nodes.panel.createChecked(panelAttributes, state.schema.nodes.paragraph.createChecked());
11
+ // Theres an existing interelationship between these files, where the imported function is being called for panel
12
+ // Insertions via the drop down menu
13
+ // tslint-ignore-next-line
14
+ import { createWrapSelectionTransaction } from '../block-type/commands/block-type';
28
15
  const panelPlugin = (options = {}, api) => ({
29
16
  name: 'panel',
30
17
  nodes() {
@@ -58,9 +45,12 @@ const panelPlugin = (options = {}, api) => ({
58
45
  priority: 800,
59
46
  icon: () => /*#__PURE__*/React.createElement(IconPanel, null),
60
47
  action(insert, state) {
61
- return insertPanelTypeWithAnalytics({
62
- panelType: PanelType.INFO
63
- }, state, insert);
48
+ return createPanelAction({
49
+ state,
50
+ attributes: {
51
+ panelType: PanelType.INFO
52
+ }
53
+ });
64
54
  }
65
55
  }, {
66
56
  id: 'notepanel',
@@ -69,9 +59,12 @@ const panelPlugin = (options = {}, api) => ({
69
59
  priority: 1000,
70
60
  icon: () => /*#__PURE__*/React.createElement(IconPanelNote, null),
71
61
  action(insert, state) {
72
- return insertPanelTypeWithAnalytics({
73
- panelType: PanelType.NOTE
74
- }, state, insert);
62
+ return createPanelAction({
63
+ state,
64
+ attributes: {
65
+ panelType: PanelType.NOTE
66
+ }
67
+ });
75
68
  }
76
69
  }, {
77
70
  id: 'successpanel',
@@ -81,9 +74,12 @@ const panelPlugin = (options = {}, api) => ({
81
74
  priority: 1000,
82
75
  icon: () => /*#__PURE__*/React.createElement(IconPanelSuccess, null),
83
76
  action(insert, state) {
84
- return insertPanelTypeWithAnalytics({
85
- panelType: PanelType.SUCCESS
86
- }, state, insert);
77
+ return createPanelAction({
78
+ state,
79
+ attributes: {
80
+ panelType: PanelType.SUCCESS
81
+ }
82
+ });
87
83
  }
88
84
  }, {
89
85
  id: 'warningpanel',
@@ -92,9 +88,12 @@ const panelPlugin = (options = {}, api) => ({
92
88
  priority: 1000,
93
89
  icon: () => /*#__PURE__*/React.createElement(IconPanelWarning, null),
94
90
  action(insert, state) {
95
- return insertPanelTypeWithAnalytics({
96
- panelType: PanelType.WARNING
97
- }, state, insert);
91
+ return createPanelAction({
92
+ state,
93
+ attributes: {
94
+ panelType: PanelType.WARNING
95
+ }
96
+ });
98
97
  }
99
98
  }, {
100
99
  id: 'errorpanel',
@@ -103,9 +102,12 @@ const panelPlugin = (options = {}, api) => ({
103
102
  priority: 1000,
104
103
  icon: () => /*#__PURE__*/React.createElement(IconPanelError, null),
105
104
  action(insert, state) {
106
- return insertPanelTypeWithAnalytics({
107
- panelType: PanelType.ERROR
108
- }, state, insert);
105
+ return createPanelAction({
106
+ state,
107
+ attributes: {
108
+ panelType: PanelType.ERROR
109
+ }
110
+ });
109
111
  }
110
112
  }];
111
113
  if (options.allowCustomPanel && options.allowCustomPanelEdit) {
@@ -116,15 +118,18 @@ const panelPlugin = (options = {}, api) => ({
116
118
  priority: 1000,
117
119
  icon: () => /*#__PURE__*/React.createElement(IconCustomPanel, null),
118
120
  action(insert, state) {
119
- return insertPanelTypeWithAnalytics({
120
- panelType: PanelType.CUSTOM,
121
- panelIcon: ':rainbow:',
122
- panelIconId: '1f308',
123
- panelIconText: '🌈',
124
- // TODO: https://product-fabric.atlassian.net/browse/DSP-7268
125
- // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
126
- panelColor: T50
127
- }, state, insert);
121
+ return createPanelAction({
122
+ state,
123
+ attributes: {
124
+ panelType: PanelType.CUSTOM,
125
+ panelIcon: ':rainbow:',
126
+ panelIconId: '1f308',
127
+ panelIconText: '🌈',
128
+ // TODO: https://product-fabric.atlassian.net/browse/DSP-7268
129
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
130
+ panelColor: T50
131
+ }
132
+ });
128
133
  }
129
134
  });
130
135
  }
@@ -133,4 +138,40 @@ const panelPlugin = (options = {}, api) => ({
133
138
  floatingToolbar: (state, intl, providerFactory) => getToolbarConfig(state, intl, options, providerFactory, api === null || api === void 0 ? void 0 : api.dependencies.decorations.actions.hoverDecoration)
134
139
  }
135
140
  });
141
+
142
+ /**
143
+ * Creates panel action and wrap selection transaction with analytics for the panel insertion.
144
+ *
145
+ * @example
146
+ * const tr = createPanelAction({
147
+ * state: editorState,
148
+ * attributes: { panelType: 'info' },
149
+ * });
150
+ * if (tr) {
151
+ * applyTransaction(tr);
152
+ * }
153
+ */
154
+ function createPanelAction({
155
+ state,
156
+ attributes
157
+ }) {
158
+ const tr = createWrapSelectionTransaction({
159
+ state,
160
+ type: state.schema.nodes.panel,
161
+ nodeAttributes: attributes
162
+ });
163
+ if (tr) {
164
+ addAnalytics(state, tr, {
165
+ action: ACTION.INSERTED,
166
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
167
+ actionSubjectId: ACTION_SUBJECT_ID.PANEL,
168
+ attributes: {
169
+ inputMethod: INPUT_METHOD.QUICK_INSERT,
170
+ panelType: attributes.panelType
171
+ },
172
+ eventType: EVENT_TYPE.TRACK
173
+ });
174
+ }
175
+ return tr;
176
+ }
136
177
  export default panelPlugin;
@@ -25,6 +25,8 @@ export const insertItem = item => (state, dispatch) => {
25
25
  return insertSelectedItem(maybeNode, opts)(state, state.tr, state.selection.head);
26
26
  };
27
27
  const tr = item.action(insert, state);
28
+
29
+ /** @note There is no transaction when called without a search currently (different insert) */
28
30
  if (tr && dispatch) {
29
31
  dispatch(tr);
30
32
  }
@@ -30,6 +30,10 @@ const InsertMenu = ({
30
30
  icon: () => getSvgIconForItem({
31
31
  name: item.value.name
32
32
  }) || item.elemBefore,
33
+ /**
34
+ * @note This transformed items action is only used when a quick insert item has been
35
+ * called from the quick insert menu and a search has not been performed.
36
+ */
33
37
  action: () => onInsert({
34
38
  item
35
39
  }),
@@ -48,6 +52,12 @@ const InsertMenu = ({
48
52
  }, [editorView, toggleVisiblity]);
49
53
  const getItems = useCallback(quickInsertState => (query, category) => {
50
54
  let result;
55
+ /**
56
+ * @warning The results if there is a query are not the same as the results if there is no query.
57
+ * For example: If you have a typed panel and then select the panel item then it will call a different action
58
+ * than is specified on the editor plugins quick insert
59
+ * @see above transform function for more details.
60
+ */
51
61
  if (query) {
52
62
  result = searchQuickInsertItems(quickInsertState, {})(query, category);
53
63
  } else {
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/editor-core";
2
- export const version = "185.12.0";
2
+ export const version = "185.12.2";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-core",
3
- "version": "185.12.0",
3
+ "version": "185.12.2",
4
4
  "sideEffects": false
5
5
  }