@atlaskit/editor-core 187.34.2 → 187.35.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 (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/index.js +10 -42
  3. package/dist/cjs/plugins/block-type/commands/block-type.js +19 -211
  4. package/dist/cjs/plugins/block-type/commands/index.js +2 -28
  5. package/dist/cjs/plugins/block-type/index.js +21 -4
  6. package/dist/cjs/plugins/block-type/pm-plugins/input-rule.js +9 -64
  7. package/dist/cjs/plugins/block-type/pm-plugins/keymap.js +1 -1
  8. package/dist/cjs/plugins/code-block/actions.js +83 -6
  9. package/dist/cjs/plugins/code-block/index.js +27 -12
  10. package/dist/cjs/plugins/code-block/pm-plugins/input-rule.js +68 -0
  11. package/dist/cjs/plugins/date/ui/DatePicker/index.js +3 -2
  12. package/dist/cjs/plugins/expand/commands.js +3 -3
  13. package/dist/cjs/plugins/expand/index.js +2 -2
  14. package/dist/cjs/plugins/index.js +1 -7
  15. package/dist/cjs/plugins/insert-block/index.js +34 -29
  16. package/dist/cjs/plugins/panel/actions.js +26 -2
  17. package/dist/cjs/plugins/panel/index.js +9 -5
  18. package/dist/cjs/version-wrapper.js +1 -1
  19. package/dist/es2019/index.js +16 -2
  20. package/dist/es2019/plugins/block-type/commands/block-type.js +15 -217
  21. package/dist/es2019/plugins/block-type/commands/index.js +1 -3
  22. package/dist/es2019/plugins/block-type/index.js +21 -4
  23. package/dist/es2019/plugins/block-type/pm-plugins/input-rule.js +3 -56
  24. package/dist/es2019/plugins/block-type/pm-plugins/keymap.js +2 -2
  25. package/dist/es2019/plugins/code-block/actions.js +84 -3
  26. package/dist/es2019/plugins/code-block/index.js +22 -7
  27. package/dist/es2019/plugins/code-block/pm-plugins/input-rule.js +60 -0
  28. package/dist/es2019/plugins/date/ui/DatePicker/index.js +3 -2
  29. package/dist/es2019/plugins/expand/commands.js +1 -1
  30. package/dist/es2019/plugins/expand/index.js +1 -1
  31. package/dist/es2019/plugins/index.js +0 -1
  32. package/dist/es2019/plugins/insert-block/index.js +47 -42
  33. package/dist/es2019/plugins/panel/actions.js +26 -2
  34. package/dist/es2019/plugins/panel/index.js +8 -4
  35. package/dist/es2019/version-wrapper.js +1 -1
  36. package/dist/esm/index.js +16 -2
  37. package/dist/esm/plugins/block-type/commands/block-type.js +17 -205
  38. package/dist/esm/plugins/block-type/commands/index.js +1 -3
  39. package/dist/esm/plugins/block-type/index.js +21 -4
  40. package/dist/esm/plugins/block-type/pm-plugins/input-rule.js +3 -58
  41. package/dist/esm/plugins/block-type/pm-plugins/keymap.js +2 -2
  42. package/dist/esm/plugins/code-block/actions.js +76 -3
  43. package/dist/esm/plugins/code-block/index.js +25 -11
  44. package/dist/esm/plugins/code-block/pm-plugins/input-rule.js +62 -0
  45. package/dist/esm/plugins/date/ui/DatePicker/index.js +3 -2
  46. package/dist/esm/plugins/expand/commands.js +1 -1
  47. package/dist/esm/plugins/expand/index.js +1 -1
  48. package/dist/esm/plugins/index.js +0 -1
  49. package/dist/esm/plugins/insert-block/index.js +27 -22
  50. package/dist/esm/plugins/panel/actions.js +24 -2
  51. package/dist/esm/plugins/panel/index.js +8 -4
  52. package/dist/esm/version-wrapper.js +1 -1
  53. package/dist/types/index.d.ts +16 -3
  54. package/dist/types/labs/next/presets/default.d.ts +6 -0
  55. package/dist/types/plugins/block-type/commands/block-type.d.ts +1 -25
  56. package/dist/types/plugins/block-type/commands/index.d.ts +1 -3
  57. package/dist/types/plugins/block-type/index.d.ts +10 -2
  58. package/dist/types/plugins/code-block/actions.d.ts +11 -0
  59. package/dist/types/plugins/code-block/index.d.ts +6 -1
  60. package/dist/types/plugins/code-block/pm-plugins/input-rule.d.ts +3 -0
  61. package/dist/types/plugins/date/ui/DatePicker/index.d.ts +2 -2
  62. package/dist/types/plugins/index.d.ts +0 -2
  63. package/dist/types/plugins/insert-block/types.d.ts +7 -1
  64. package/dist/types/plugins/panel/actions.d.ts +4 -1
  65. package/dist/types/plugins/panel/index.d.ts +11 -2
  66. package/dist/types-ts4.5/index.d.ts +16 -3
  67. package/dist/types-ts4.5/labs/next/presets/default.d.ts +6 -0
  68. package/dist/types-ts4.5/plugins/block-type/commands/block-type.d.ts +1 -25
  69. package/dist/types-ts4.5/plugins/block-type/commands/index.d.ts +1 -3
  70. package/dist/types-ts4.5/plugins/block-type/index.d.ts +10 -2
  71. package/dist/types-ts4.5/plugins/code-block/actions.d.ts +11 -0
  72. package/dist/types-ts4.5/plugins/code-block/index.d.ts +6 -1
  73. package/dist/types-ts4.5/plugins/code-block/pm-plugins/input-rule.d.ts +3 -0
  74. package/dist/types-ts4.5/plugins/date/ui/DatePicker/index.d.ts +2 -2
  75. package/dist/types-ts4.5/plugins/index.d.ts +0 -2
  76. package/dist/types-ts4.5/plugins/insert-block/types.d.ts +7 -1
  77. package/dist/types-ts4.5/plugins/panel/actions.d.ts +4 -1
  78. package/dist/types-ts4.5/plugins/panel/index.d.ts +9 -2
  79. package/package.json +3 -3
  80. package/report.api.md +62 -23
  81. package/tmp/api-report-tmp.d.ts +49 -15
  82. package/dist/cjs/plugins/block-type/commands/insert-block.js +0 -60
  83. package/dist/es2019/plugins/block-type/commands/insert-block.js +0 -55
  84. package/dist/esm/plugins/block-type/commands/insert-block.js +0 -53
  85. package/dist/types/plugins/block-type/commands/insert-block.d.ts +0 -5
  86. package/dist/types-ts4.5/plugins/block-type/commands/insert-block.d.ts +0 -5
  87. /package/dist/cjs/plugins/{block-type/commands → code-block}/transform-to-code-block.js +0 -0
  88. /package/dist/es2019/plugins/{block-type/commands → code-block}/transform-to-code-block.js +0 -0
  89. /package/dist/esm/plugins/{block-type/commands → code-block}/transform-to-code-block.js +0 -0
  90. /package/dist/types/plugins/{block-type/commands → code-block}/transform-to-code-block.d.ts +0 -0
  91. /package/dist/types-ts4.5/plugins/{block-type/commands → code-block}/transform-to-code-block.d.ts +0 -0
@@ -1,10 +1,8 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
3
2
  import { createRule, createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
4
3
  import { INPUT_METHOD, ACTION, ACTION_SUBJECT, EVENT_TYPE, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
5
4
  import { inputRuleWithAnalytics } from '@atlaskit/editor-common/utils';
6
- import { isConvertableToCodeBlock, transformToCodeBlockAction } from '../commands/transform-to-code-block';
7
- import { insertBlock } from '../commands/insert-block';
5
+ import { insertBlock } from '@atlaskit/editor-common/commands';
8
6
  import { createJoinNodesRule, createWrappingTextBlockRule } from '../utils';
9
7
  var MAX_HEADING_LEVEL = 6;
10
8
  function getHeadingLevel(match) {
@@ -34,7 +32,7 @@ function getHeadingRules(editorAnalyticsAPI, schema) {
34
32
  var hashRule = headingRule(schema.nodes.heading, MAX_HEADING_LEVEL);
35
33
  var leftNodeReplacementHashRule = createRule(new RegExp("".concat(leafNodeReplacementCharacter, "(#{1,6})\\s$")), function (state, match, start, end) {
36
34
  var level = match[1].length;
37
- return insertBlock(state, schema.nodes.heading, "heading".concat(level), start, end, {
35
+ return insertBlock(state, schema.nodes.heading, start, end, {
38
36
  level: level
39
37
  });
40
38
  });
@@ -65,7 +63,7 @@ function getBlockQuoteRules(editorAnalyticsAPI, schema) {
65
63
  // '> ' for blockquote
66
64
  var greatherThanRule = blockQuoteRule(schema.nodes.blockquote);
67
65
  var leftNodeReplacementGreatherRule = createRule(new RegExp("".concat(leafNodeReplacementCharacter, "\\s*>\\s$")), function (state, _match, start, end) {
68
- return insertBlock(state, schema.nodes.blockquote, 'blockquote', start, end);
66
+ return insertBlock(state, schema.nodes.blockquote, start, end);
69
67
  });
70
68
 
71
69
  // Analytics V3 handler
@@ -80,56 +78,6 @@ function getBlockQuoteRules(editorAnalyticsAPI, schema) {
80
78
  }, editorAnalyticsAPI);
81
79
  return [ruleWithBlockQuoteAnalytics(greatherThanRule), ruleWithBlockQuoteAnalytics(leftNodeReplacementGreatherRule)];
82
80
  }
83
-
84
- /**
85
- * Get all code block input rules
86
- *
87
- * @param {Schema} schema
88
- * @returns {InputRuleWithHandler[]}
89
- */
90
- function getCodeBlockRules(editorAnalyticsAPI, schema) {
91
- var ruleAnalytics = inputRuleWithAnalytics({
92
- action: ACTION.INSERTED,
93
- actionSubject: ACTION_SUBJECT.DOCUMENT,
94
- actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
95
- attributes: {
96
- inputMethod: INPUT_METHOD.FORMATTING
97
- },
98
- eventType: EVENT_TYPE.TRACK
99
- }, editorAnalyticsAPI);
100
- var validMatchLength = function validMatchLength(match) {
101
- return match.length > 0 && match[0].length === 3;
102
- };
103
- var threeTildeRule = createRule(/(?!\s)(`{3,})$/, function (state, match, start, end) {
104
- if (!validMatchLength(match)) {
105
- return null;
106
- }
107
- var attributes = {};
108
- if (match[4]) {
109
- attributes.language = match[4];
110
- }
111
- if (isConvertableToCodeBlock(state)) {
112
- return transformToCodeBlockAction(state, start, attributes);
113
- }
114
- var tr = state.tr;
115
- tr.delete(start, end);
116
- var codeBlock = tr.doc.type.schema.nodes.codeBlock.createChecked();
117
- safeInsert(codeBlock)(tr);
118
- return tr;
119
- });
120
- var leftNodeReplacementThreeTildeRule = createRule(new RegExp("((".concat(leafNodeReplacementCharacter, "`{3,})|^\\s(`{3,}))(\\S*)$")), function (state, match, start, end) {
121
- if (!validMatchLength(match)) {
122
- return null;
123
- }
124
- var attributes = {};
125
- if (match[4]) {
126
- attributes.language = match[4];
127
- }
128
- var inlineStart = Math.max(match.index + state.selection.$from.start(), 1);
129
- return insertBlock(state, schema.nodes.codeBlock, 'codeblock', inlineStart, end, attributes);
130
- });
131
- return [ruleAnalytics(threeTildeRule), ruleAnalytics(leftNodeReplacementThreeTildeRule)];
132
- }
133
81
  function inputRulePlugin(editorAnalyticsAPI, schema, featureFlags) {
134
82
  var rules = [];
135
83
  if (schema.nodes.heading) {
@@ -138,9 +86,6 @@ function inputRulePlugin(editorAnalyticsAPI, schema, featureFlags) {
138
86
  if (schema.nodes.blockquote) {
139
87
  rules.push.apply(rules, _toConsumableArray(getBlockQuoteRules(editorAnalyticsAPI, schema)));
140
88
  }
141
- if (schema.nodes.codeBlock) {
142
- rules.push.apply(rules, _toConsumableArray(getCodeBlockRules(editorAnalyticsAPI, schema)));
143
- }
144
89
  if (rules.length !== 0) {
145
90
  return createPlugin('block-type', rules, {
146
91
  isBlockNodeRule: true
@@ -4,7 +4,7 @@ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
4
  import { bindKeymapWithCommand, moveUp, moveDown, findKeyMapForBrowser, undo as undoKeymap, redo as redoKeymap, backspace, deleteKey, forwardDelete, toggleBlockQuote, keymap, insertNewLine, findShortcutByKeymap } from '@atlaskit/editor-common/keymaps';
5
5
  import { insertNewLineWithAnalytics, createNewParagraphAbove, createNewParagraphBelow, deleteEmptyParagraphAndMoveBlockUp } from '@atlaskit/editor-common/utils';
6
6
  import * as blockTypes from '../types';
7
- import { cleanUpAtTheStartOfDocument, deleteAndMoveCursor, deleteBlockContent, insertBlockTypesWithAnalytics } from '../commands';
7
+ import { cleanUpAtTheStartOfDocument, deleteAndMoveCursor, deleteBlockContent, insertBlockQuoteWithAnalytics } from '../commands';
8
8
  import { isNodeAWrappingBlockNode } from '../utils';
9
9
  var backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
10
10
  var del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
@@ -19,7 +19,7 @@ export default function keymapPlugin(editorAnalyticsApi, schema, _featureFlags)
19
19
  bindKeymapWithCommand(deleteKey.common, del, list);
20
20
  bindKeymapWithCommand(forwardDelete.mac, del, list);
21
21
  if (schema.nodes[blockTypes.BLOCK_QUOTE.nodeName]) {
22
- bindKeymapWithCommand(findShortcutByKeymap(toggleBlockQuote), insertBlockTypesWithAnalytics(blockTypes.BLOCK_QUOTE.name, INPUT_METHOD.KEYBOARD, editorAnalyticsApi), list);
22
+ bindKeymapWithCommand(findShortcutByKeymap(toggleBlockQuote), insertBlockQuoteWithAnalytics(INPUT_METHOD.KEYBOARD, editorAnalyticsApi), list);
23
23
  }
24
24
  return keymap(list);
25
25
  }
@@ -1,11 +1,14 @@
1
- import { findParentNodeOfType, findSelectedNodeOfType, removeSelectedNode, removeParentNodeOfType, isNodeSelection } from '@atlaskit/editor-prosemirror/utils';
1
+ import { findParentNodeOfType, findSelectedNodeOfType, removeSelectedNode, removeParentNodeOfType, isNodeSelection, safeInsert } from '@atlaskit/editor-prosemirror/utils';
2
2
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { pluginKey } from './plugin-key';
4
4
  import { copySelectionPluginKey } from './pm-plugins/codeBlockCopySelectionPlugin';
5
5
  import { ACTIONS } from './pm-plugins/actions';
6
6
  import { copyToClipboard } from '../../utils/clipboard';
7
7
  import { addAnalytics } from '../analytics/utils';
8
- import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '../analytics/types';
8
+ import { shouldSplitSelectedNodeOnNodeInsertion } from '@atlaskit/editor-common/insert';
9
+ import { transformToCodeBlockAction } from './transform-to-code-block';
10
+ import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
11
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
9
12
  export var removeCodeBlock = function removeCodeBlock(state, dispatch) {
10
13
  var nodes = state.schema.nodes,
11
14
  tr = state.tr;
@@ -113,4 +116,74 @@ export var resetShouldIgnoreFollowingMutations = function resetShouldIgnoreFollo
113
116
  dispatch(ignoreFollowingMutationsTr);
114
117
  }
115
118
  return true;
116
- };
119
+ };
120
+
121
+ /**
122
+ * This function creates a new transaction that inserts a code block,
123
+ * if there is text selected it will wrap the current selection if not it will
124
+ * append the codeblock to the end of the document.
125
+ */
126
+ export function createInsertCodeBlockTransaction(_ref) {
127
+ var _state$selection$$fro;
128
+ var state = _ref.state;
129
+ var tr = state.tr;
130
+ var from = state.selection.from;
131
+ var codeBlock = state.schema.nodes.codeBlock;
132
+ var grandParentNodeType = (_state$selection$$fro = state.selection.$from.node(-1)) === null || _state$selection$$fro === void 0 ? void 0 : _state$selection$$fro.type;
133
+ var parentNodeType = state.selection.$from.parent.type;
134
+
135
+ /** We always want to append a codeBlock unless we're inserting into a paragraph
136
+ * AND it's a valid child of the grandparent node.
137
+ * Insert the current selection as codeBlock content unless it contains nodes other
138
+ * than paragraphs and inline.
139
+ */
140
+ var canInsertCodeBlock = shouldSplitSelectedNodeOnNodeInsertion({
141
+ parentNodeType: parentNodeType,
142
+ grandParentNodeType: grandParentNodeType,
143
+ content: codeBlock.createAndFill()
144
+ }) && contentAllowedInCodeBlock(state);
145
+ if (canInsertCodeBlock) {
146
+ tr = transformToCodeBlockAction(state, from);
147
+ } else {
148
+ safeInsert(codeBlock.createAndFill())(tr).scrollIntoView();
149
+ }
150
+ return tr;
151
+ }
152
+
153
+ /**
154
+ * Check if the current selection contains any nodes that are not permitted
155
+ * as codeBlock child nodes. Note that this allows paragraphs and inline nodes
156
+ * as we extract their text content.
157
+ */
158
+ function contentAllowedInCodeBlock(state) {
159
+ var _state$selection = state.selection,
160
+ $from = _state$selection.$from,
161
+ $to = _state$selection.$to;
162
+ var isAllowedChild = true;
163
+ state.doc.nodesBetween($from.pos, $to.pos, function (node) {
164
+ if (!isAllowedChild) {
165
+ return false;
166
+ }
167
+ return isAllowedChild = node.type === state.schema.nodes.listItem || node.type === state.schema.nodes.bulletList || node.type === state.schema.nodes.orderedList || node.type === state.schema.nodes.paragraph || node.isInline || node.isText;
168
+ });
169
+ return isAllowedChild;
170
+ }
171
+ export function insertCodeBlockWithAnalytics(inputMethod, analyticsAPI) {
172
+ return withAnalytics(analyticsAPI, {
173
+ action: ACTION.INSERTED,
174
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
175
+ actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
176
+ attributes: {
177
+ inputMethod: inputMethod
178
+ },
179
+ eventType: EVENT_TYPE.TRACK
180
+ })(function (state, dispatch) {
181
+ var tr = createInsertCodeBlockTransaction({
182
+ state: state
183
+ });
184
+ if (dispatch) {
185
+ dispatch(tr);
186
+ }
187
+ return true;
188
+ });
189
+ }
@@ -12,10 +12,8 @@ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD, EVENT_TYPE } f
12
12
  import { IconCode } from '@atlaskit/editor-common/quick-insert';
13
13
  import { messages } from '../block-type/messages';
14
14
  import refreshBrowserSelectionOnChange from './refresh-browser-selection';
15
- // Theres an existing interelationship between these files, where the imported function is being called for code-block
16
- // Insertions via the drop down menu
17
- // tslint-ignore-next-line
18
- import { createInsertCodeBlockTransaction } from '../block-type/commands/block-type';
15
+ import { createInsertCodeBlockTransaction, insertCodeBlockWithAnalytics } from './actions';
16
+ import { createCodeBlockInputRule } from './pm-plugins/input-rule';
19
17
  var codeBlockPlugin = function codeBlockPlugin(_ref) {
20
18
  var options = _ref.config,
21
19
  api = _ref.api;
@@ -38,6 +36,13 @@ var codeBlockPlugin = function codeBlockPlugin(_ref) {
38
36
  appearance: (_options$appearance = options === null || options === void 0 ? void 0 : options.appearance) !== null && _options$appearance !== void 0 ? _options$appearance : 'comment'
39
37
  }));
40
38
  }
39
+ }, {
40
+ name: 'codeBlockInputRule',
41
+ plugin: function plugin(_ref3) {
42
+ var _api$analytics;
43
+ var schema = _ref3.schema;
44
+ return createCodeBlockInputRule(schema, api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
45
+ }
41
46
  }, {
42
47
  name: 'codeBlockIDEKeyBindings',
43
48
  plugin: function plugin() {
@@ -45,8 +50,8 @@ var codeBlockPlugin = function codeBlockPlugin(_ref) {
45
50
  }
46
51
  }, {
47
52
  name: 'codeBlockKeyMap',
48
- plugin: function plugin(_ref3) {
49
- var schema = _ref3.schema;
53
+ plugin: function plugin(_ref4) {
54
+ var schema = _ref4.schema;
50
55
  return keymap(schema);
51
56
  }
52
57
  }, {
@@ -61,9 +66,18 @@ var codeBlockPlugin = function codeBlockPlugin(_ref) {
61
66
  onEditorViewStateUpdated: function onEditorViewStateUpdated(props) {
62
67
  refreshBrowserSelectionOnChange(props.originalTransaction, props.newEditorState);
63
68
  },
69
+ actions: {
70
+ /*
71
+ * Function will insert code block at current selection if block is empty or below current selection and set focus on it.
72
+ */
73
+ insertCodeBlock: function insertCodeBlock(inputMethod) {
74
+ var _api$analytics2;
75
+ return insertCodeBlockWithAnalytics(inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions);
76
+ }
77
+ },
64
78
  pluginsOptions: {
65
- quickInsert: function quickInsert(_ref4) {
66
- var formatMessage = _ref4.formatMessage;
79
+ quickInsert: function quickInsert(_ref5) {
80
+ var formatMessage = _ref5.formatMessage;
67
81
  return [{
68
82
  id: 'codeblock',
69
83
  title: formatMessage(messages.codeblock),
@@ -74,12 +88,12 @@ var codeBlockPlugin = function codeBlockPlugin(_ref) {
74
88
  icon: function icon() {
75
89
  return /*#__PURE__*/React.createElement(IconCode, null);
76
90
  },
77
- action: function action(insert, state) {
78
- var _api$analytics;
91
+ action: function action(_insert, state) {
92
+ var _api$analytics3;
79
93
  var tr = createInsertCodeBlockTransaction({
80
94
  state: state
81
95
  });
82
- api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.attachAnalyticsEvent({
96
+ api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.attachAnalyticsEvent({
83
97
  action: ACTION.INSERTED,
84
98
  actionSubject: ACTION_SUBJECT.DOCUMENT,
85
99
  actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
@@ -0,0 +1,62 @@
1
+ import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
2
+ import { createRule, createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
3
+ import { INPUT_METHOD, ACTION, ACTION_SUBJECT, EVENT_TYPE, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
4
+ import { inputRuleWithAnalytics } from '@atlaskit/editor-common/utils';
5
+ import { isConvertableToCodeBlock, transformToCodeBlockAction } from '../transform-to-code-block';
6
+ import { insertBlock } from '@atlaskit/editor-common/commands';
7
+ export function createCodeBlockInputRule(schema, editorAnalyticsAPI) {
8
+ var rules = getCodeBlockRules(editorAnalyticsAPI, schema);
9
+ return createPlugin('code-block-input-rule', rules, {
10
+ isBlockNodeRule: true
11
+ });
12
+ }
13
+
14
+ /**
15
+ * Get all code block input rules
16
+ *
17
+ * @param {Schema} schema
18
+ * @returns {InputRuleWithHandler[]}
19
+ */
20
+ function getCodeBlockRules(editorAnalyticsAPI, schema) {
21
+ var ruleAnalytics = inputRuleWithAnalytics({
22
+ action: ACTION.INSERTED,
23
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
24
+ actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
25
+ attributes: {
26
+ inputMethod: INPUT_METHOD.FORMATTING
27
+ },
28
+ eventType: EVENT_TYPE.TRACK
29
+ }, editorAnalyticsAPI);
30
+ var validMatchLength = function validMatchLength(match) {
31
+ return match.length > 0 && match[0].length === 3;
32
+ };
33
+ var threeTildeRule = createRule(/(?!\s)(`{3,})$/, function (state, match, start, end) {
34
+ if (!validMatchLength(match)) {
35
+ return null;
36
+ }
37
+ var attributes = {};
38
+ if (match[4]) {
39
+ attributes.language = match[4];
40
+ }
41
+ if (isConvertableToCodeBlock(state)) {
42
+ return transformToCodeBlockAction(state, start, attributes);
43
+ }
44
+ var tr = state.tr;
45
+ tr.delete(start, end);
46
+ var codeBlock = tr.doc.type.schema.nodes.codeBlock.createChecked();
47
+ safeInsert(codeBlock)(tr);
48
+ return tr;
49
+ });
50
+ var leftNodeReplacementThreeTildeRule = createRule(new RegExp("((".concat(leafNodeReplacementCharacter, "`{3,})|^\\s(`{3,}))(\\S*)$")), function (state, match, start, end) {
51
+ if (!validMatchLength(match)) {
52
+ return null;
53
+ }
54
+ var attributes = {};
55
+ if (match[4]) {
56
+ attributes.language = match[4];
57
+ }
58
+ var inlineStart = Math.max(match.index + state.selection.$from.start(), 1);
59
+ return insertBlock(state, schema.nodes.codeBlock, inlineStart, end, attributes);
60
+ });
61
+ return [ruleAnalytics(threeTildeRule), ruleAnalytics(leftNodeReplacementThreeTildeRule)];
62
+ }
@@ -24,7 +24,7 @@ var PopupWithListeners = withOuterListeners(Popup);
24
24
  import { INPUT_METHOD } from '../../../analytics/types/enums';
25
25
  import { injectIntl } from 'react-intl-next';
26
26
  import DatePickerInput from './date-picker-input';
27
- var popupContentWrapper = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: 2px;\n border-radius: ", "px;\n box-shadow: ", ";\n background-color: ", ";\n"])), borderRadius(), "var(--ds-shadow-overlay, ".concat("0 4px 8px -2px ".concat(N60A, ", 0 0 1px ").concat(N60A), ")"), "var(--ds-surface-overlay, ".concat(N0, ")"));
27
+ var popupContentWrapper = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: ", ";\n border-radius: ", "px;\n box-shadow: ", ";\n background-color: ", ";\n"])), "var(--ds-space-025, 2px)", borderRadius(), "var(--ds-shadow-overlay, ".concat("0 4px 8px -2px ".concat(N60A, ", 0 0 1px ").concat(N60A), ")"), "var(--ds-surface-overlay, ".concat(N0, ")"));
28
28
  var DatePicker = /*#__PURE__*/function (_React$Component) {
29
29
  _inherits(DatePicker, _React$Component);
30
30
  var _super = _createSuper(DatePicker);
@@ -151,7 +151,8 @@ var DatePicker = /*#__PURE__*/function (_React$Component) {
151
151
  year: year,
152
152
  selected: selected,
153
153
  ref: this.handleRef,
154
- weekStartDay: weekStartDay
154
+ weekStartDay: weekStartDay,
155
+ testId: 'datepicker'
155
156
  })));
156
157
  }
157
158
  }]);
@@ -7,7 +7,7 @@ import { addAnalytics, ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD,
7
7
  import { GapCursorSelection, Side } from '../selection/gap-cursor-selection';
8
8
  import { findExpand } from './utils';
9
9
  import { createCommand } from './pm-plugins/plugin-factory';
10
- import { createWrapSelectionTransaction } from '../block-type/commands/block-type';
10
+ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
11
11
  import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
12
12
  export var setExpandRef = function setExpandRef(ref) {
13
13
  return createCommand({
@@ -8,7 +8,7 @@ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, EVENT_TYPE, IN
8
8
  import { getToolbarConfig } from './toolbar';
9
9
  import { createExpandNode } from './commands';
10
10
  import { messages } from '../insert-block/ui/ToolbarInsertBlock/messages';
11
- import { createWrapSelectionTransaction } from '../block-type/commands/block-type';
11
+ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
12
12
  var expandPlugin = function expandPlugin(_ref) {
13
13
  var _api$featureFlags;
14
14
  var _ref$config = _ref.config,
@@ -1,6 +1,5 @@
1
1
  export { basePlugin } from './base';
2
2
  export { default as blockTypePlugin } from './block-type';
3
- export { pluginKey as blockPluginStateKey } from './block-type';
4
3
  export { default as betterTypeHistoryPlugin } from './better-type-history';
5
4
  export { default as clearMarksOnChangeToEmptyDocumentPlugin } from './clear-marks-on-change-to-empty-document';
6
5
  export { default as codeBlockPlugin } from './code-block';
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import { WithProviders } from '@atlaskit/editor-common/provider-factory';
3
- import { pluginKey as blockTypeStateKey } from '../block-type/pm-plugins/main';
4
3
  import { stateKey as mediaStateKey } from '../media/pm-plugins/plugin-key';
5
4
  import { isTypeAheadAllowed } from '../type-ahead/utils';
6
5
  import { pluginKey as layoutStateKey } from '../layout';
@@ -8,7 +7,7 @@ import { insertMacroFromMacroBrowser } from '../macro';
8
7
  import WithPluginState from '../../ui/WithPluginState';
9
8
  import ToolbarInsertBlock from './ui/ToolbarInsertBlock';
10
9
  import { pluginKey as typeAheadPluginKey } from '../type-ahead/pm-plugins/key';
11
- import { insertBlockTypesWithAnalytics } from '../block-type/commands';
10
+ import { BLOCK_QUOTE, CODE_BLOCK, PANEL } from '../block-type/types';
12
11
  import { INPUT_METHOD } from '../analytics';
13
12
  import { pluginKey as placeholderTextStateKey } from '../placeholder-text/plugin-key';
14
13
  import { pluginKey as macroStateKey } from '../macro/plugin-key';
@@ -27,6 +26,26 @@ var toolbarSizeToButtons = function toolbarSizeToButtons(toolbarSize) {
27
26
  return 0;
28
27
  }
29
28
  };
29
+ /**
30
+ * Wrapper over insertBlockTypeWithAnalytics to autobind toolbar input method
31
+ * @param name Block name
32
+ */
33
+ function handleInsertBlockType(insertCodeBlock, insertPanel, insertBlockQuote) {
34
+ return function (name) {
35
+ if (name === CODE_BLOCK.name && insertCodeBlock) {
36
+ return insertCodeBlock(INPUT_METHOD.TOOLBAR);
37
+ }
38
+ if (name === PANEL.name && insertPanel) {
39
+ return insertPanel(INPUT_METHOD.TOOLBAR);
40
+ }
41
+ if (name === BLOCK_QUOTE.name && insertBlockQuote) {
42
+ return insertBlockQuote(INPUT_METHOD.TOOLBAR);
43
+ }
44
+ return function () {
45
+ return false;
46
+ };
47
+ };
48
+ }
30
49
  var insertBlockPlugin = function insertBlockPlugin(_ref) {
31
50
  var _api$featureFlags;
32
51
  var _ref$config = _ref.config,
@@ -53,16 +72,13 @@ var insertBlockPlugin = function insertBlockPlugin(_ref) {
53
72
  return /*#__PURE__*/React.createElement(WithPluginState, {
54
73
  plugins: {
55
74
  typeAheadState: typeAheadPluginKey,
56
- // needed to check isTypeAheadAllowed in ToolbarInsertBlock
57
- blockTypeState: blockTypeStateKey,
58
75
  mediaState: mediaStateKey,
59
76
  macroState: macroStateKey,
60
77
  placeholderTextState: placeholderTextStateKey,
61
78
  layoutState: layoutStateKey
62
79
  },
63
80
  render: function render(_ref3) {
64
- var blockTypeState = _ref3.blockTypeState,
65
- mediaState = _ref3.mediaState,
81
+ var mediaState = _ref3.mediaState,
66
82
  _ref3$macroState = _ref3.macroState,
67
83
  macroState = _ref3$macroState === void 0 ? {} : _ref3$macroState,
68
84
  placeholderTextState = _ref3.placeholderTextState,
@@ -81,7 +97,6 @@ var insertBlockPlugin = function insertBlockPlugin(_ref) {
81
97
  isToolbarReducedSpacing: isToolbarReducedSpacing,
82
98
  isLastItem: isLastItem,
83
99
  featureFlags: featureFlags,
84
- blockTypeState: blockTypeState,
85
100
  mediaState: mediaState,
86
101
  macroState: macroState,
87
102
  placeholderTextState: placeholderTextState,
@@ -101,11 +116,10 @@ var insertBlockPlugin = function insertBlockPlugin(_ref) {
101
116
  };
102
117
  };
103
118
  function ToolbarInsertBlockWithInjectionApi(_ref4) {
104
- var _pluginInjectionApi$a2, _pluginInjectionApi$i;
119
+ var _pluginInjectionApi$i, _pluginInjectionApi$c, _pluginInjectionApi$p, _pluginInjectionApi$b;
105
120
  var editorView = _ref4.editorView,
106
121
  editorActions = _ref4.editorActions,
107
122
  dispatchAnalyticsEvent = _ref4.dispatchAnalyticsEvent,
108
- providerFactory = _ref4.providerFactory,
109
123
  popupsMountPoint = _ref4.popupsMountPoint,
110
124
  popupsBoundariesElement = _ref4.popupsBoundariesElement,
111
125
  popupsScrollableElement = _ref4.popupsScrollableElement,
@@ -116,28 +130,19 @@ function ToolbarInsertBlockWithInjectionApi(_ref4) {
116
130
  providers = _ref4.providers,
117
131
  pluginInjectionApi = _ref4.pluginInjectionApi,
118
132
  options = _ref4.options,
119
- blockTypeState = _ref4.blockTypeState,
120
133
  mediaState = _ref4.mediaState,
121
134
  macroState = _ref4.macroState,
122
135
  placeholderTextState = _ref4.placeholderTextState,
123
136
  layoutState = _ref4.layoutState,
124
137
  featureFlags = _ref4.featureFlags;
125
138
  var buttons = toolbarSizeToButtons(toolbarSize);
126
- var _useSharedPluginState = useSharedPluginState(pluginInjectionApi, ['hyperlink', 'date', 'imageUpload', 'mention', 'emoji']),
139
+ var _useSharedPluginState = useSharedPluginState(pluginInjectionApi, ['hyperlink', 'date', 'imageUpload', 'mention', 'emoji', 'blockType']),
127
140
  dateState = _useSharedPluginState.dateState,
128
141
  hyperlinkState = _useSharedPluginState.hyperlinkState,
129
142
  imageUploadState = _useSharedPluginState.imageUploadState,
130
143
  mentionState = _useSharedPluginState.mentionState,
131
- emojiState = _useSharedPluginState.emojiState;
132
-
133
- /**
134
- * Wrapper over insertBlockTypeWithAnalytics to autobind toolbar input method
135
- * @param name Block name
136
- */
137
- var handleInsertBlockType = React.useCallback(function (name) {
138
- var _pluginInjectionApi$a;
139
- return insertBlockTypesWithAnalytics(name, INPUT_METHOD.TOOLBAR, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions);
140
- }, [pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions]);
144
+ emojiState = _useSharedPluginState.emojiState,
145
+ blockTypeState = _useSharedPluginState.blockTypeState;
141
146
  return /*#__PURE__*/React.createElement(ToolbarInsertBlock, {
142
147
  pluginInjectionApi: pluginInjectionApi,
143
148
  buttons: buttons,
@@ -167,7 +172,7 @@ function ToolbarInsertBlockWithInjectionApi(_ref4) {
167
172
  emojiProvider: providers.emojiProvider,
168
173
  nativeStatusSupported: options.nativeStatusSupported,
169
174
  horizontalRuleEnabled: options.horizontalRuleEnabled,
170
- onInsertBlockType: handleInsertBlockType,
175
+ onInsertBlockType: handleInsertBlockType(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c = pluginInjectionApi.codeBlock) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.actions.insertCodeBlock, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$p = pluginInjectionApi.panel) === null || _pluginInjectionApi$p === void 0 ? void 0 : _pluginInjectionApi$p.actions.insertPanel, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$b = pluginInjectionApi.blockType) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.insertBlockQuote),
171
176
  onInsertMacroFromMacroBrowser: insertMacroFromMacroBrowser,
172
177
  macroProvider: macroState.macroProvider,
173
178
  popupsMountPoint: popupsMountPoint,
@@ -3,9 +3,12 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
3
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
4
  import { removeParentNodeOfType, findSelectedNodeOfType, removeSelectedNode, findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
5
5
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
6
- import { ACTION, ACTION_SUBJECT, INPUT_METHOD, EVENT_TYPE, addAnalytics } from '../analytics';
6
+ import { PanelType } from '@atlaskit/adf-schema';
7
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD, EVENT_TYPE, addAnalytics } from '../analytics';
7
8
  import { findPanel } from './utils';
8
9
  import { getPanelTypeBackgroundNoTokens } from '@atlaskit/editor-common/panel';
10
+ import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
11
+ import { wrapSelectionIn } from '@atlaskit/editor-common/utils';
9
12
  export var removePanel = function removePanel() {
10
13
  return function (state, dispatch) {
11
14
  var nodes = state.schema.nodes,
@@ -88,4 +91,23 @@ export var changePanelType = function changePanelType(panelType) {
88
91
  }
89
92
  return true;
90
93
  };
91
- };
94
+ };
95
+ export function insertPanelWithAnalytics(inputMethod, analyticsAPI) {
96
+ return withAnalytics(analyticsAPI, {
97
+ action: ACTION.INSERTED,
98
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
99
+ actionSubjectId: ACTION_SUBJECT_ID.PANEL,
100
+ attributes: {
101
+ inputMethod: inputMethod,
102
+ panelType: PanelType.INFO // only info panels can be inserted via this action
103
+ },
104
+
105
+ eventType: EVENT_TYPE.TRACK
106
+ })(function (state, dispatch) {
107
+ var nodes = state.schema.nodes;
108
+ if (nodes.panel && nodes.paragraph) {
109
+ return wrapSelectionIn(nodes.panel)(state, dispatch);
110
+ }
111
+ return false;
112
+ });
113
+ }
@@ -5,13 +5,11 @@ import { getToolbarConfig } from './toolbar';
5
5
  import keymap from './pm-plugins/keymaps';
6
6
  import { addAnalytics, ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD, EVENT_TYPE } from '../analytics';
7
7
  import { IconPanel, IconPanelNote, IconPanelSuccess, IconPanelWarning, IconPanelError } from '@atlaskit/editor-common/quick-insert';
8
+ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
8
9
  import { messages } from '../block-type/messages';
9
10
  import { IconCustomPanel } from '@atlaskit/editor-common/quick-insert';
10
11
  import { T50 } from '@atlaskit/theme/colors';
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';
12
+ import { insertPanelWithAnalytics } from './actions';
15
13
  var panelPlugin = function panelPlugin(_ref) {
16
14
  var _ref$config = _ref.config,
17
15
  options = _ref$config === void 0 ? {} : _ref$config,
@@ -40,6 +38,12 @@ var panelPlugin = function panelPlugin(_ref) {
40
38
  }
41
39
  }];
42
40
  },
41
+ actions: {
42
+ insertPanel: function insertPanel(inputMethod) {
43
+ var _api$analytics;
44
+ return insertPanelWithAnalytics(inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
45
+ }
46
+ },
43
47
  pluginsOptions: {
44
48
  quickInsert: function quickInsert(_ref3) {
45
49
  var formatMessage = _ref3.formatMessage;
@@ -1,5 +1,5 @@
1
1
  export var name = "@atlaskit/editor-core";
2
- export var version = "187.34.2";
2
+ export var version = "187.35.0";
3
3
  export var nextMajorVersion = function nextMajorVersion() {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -24,12 +24,25 @@ export { textColorPluginKey } from './plugins/text-color';
24
24
  export type { TextColorPluginState } from './plugins/text-color';
25
25
  export { changeColor } from './plugins/text-color/commands/change-color';
26
26
  export { insertHorizontalRule } from './plugins/rule/commands';
27
- export { blockPluginStateKey } from './plugins';
28
- export type { BlockTypeState } from './plugins';
27
+ export type { BlockTypeState } from './plugins/block-type/pm-plugins/main';
28
+ /**
29
+ * @private
30
+ * @deprecated DO NOT USE, temporary solution while decoupling plugins from editor-core
31
+ */
32
+ export type { BlockTypePlugin } from './plugins/block-type';
33
+ /**
34
+ * @private
35
+ * @deprecated DO NOT USE, temporary solution while decoupling plugins from editor-core
36
+ */
37
+ export type { CodeBlockPlugin } from './plugins/code-block';
38
+ /**
39
+ * @private
40
+ * @deprecated DO NOT USE, temporary solution while decoupling plugins from editor-core
41
+ */
42
+ export type { PanelPlugin } from './plugins/panel';
29
43
  export { subscribeToToolbarAndPickerUpdates } from './plugins/view-update-subscription/subscribe/toolbarAndPickerUpdates';
30
44
  export { subscribeTypeAheadUpdates } from './plugins/view-update-subscription/subscribe/type-ahead-updates';
31
45
  export type { InputMethodToolbar as TextFormattingInputMethodToolbar, InputMethodBasic as TextFormattingInputMethodBasic, } from '@atlaskit/editor-common/types';
32
- export { insertBlockType, insertBlockTypesWithAnalytics, setBlockType, setBlockTypeWithAnalytics, } from './plugins/block-type/commands';
33
46
  export type { InputMethod as BlockTypeInputMethod } from './plugins/block-type/commands';
34
47
  export { createTable } from '@atlaskit/editor-plugin-table/commands';
35
48
  export { insertTaskDecisionCommand } from './plugins/tasks-and-decisions/commands';
@@ -56,6 +56,9 @@ export declare function createDefaultPreset(options: EditorPresetProps & Default
56
56
  }, import("@atlaskit/editor-common/types").FeatureFlags>];
57
57
  actions: import("@atlaskit/editor-common/analytics").EditorAnalyticsAPI;
58
58
  }, import("@atlaskit/editor-plugin-analytics").AnalyticsPluginOptions>>];
59
+ actions: {
60
+ insertCodeBlock: (inputMethod: import("@atlaskit/editor-common/analytics").INPUT_METHOD) => import("@atlaskit/editor-common/types").Command;
61
+ };
59
62
  }, CodeBlockOptions>, import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"selection", {
60
63
  pluginConfiguration: SelectionPluginOptions | undefined;
61
64
  }, SelectionPluginOptions | undefined>, import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"floatingToolbar", {
@@ -181,6 +184,9 @@ export declare function useDefaultPreset(props: EditorPresetProps & DefaultPrese
181
184
  }, import("@atlaskit/editor-common/types").FeatureFlags>];
182
185
  actions: import("@atlaskit/editor-common/analytics").EditorAnalyticsAPI;
183
186
  }, import("@atlaskit/editor-plugin-analytics").AnalyticsPluginOptions>>];
187
+ actions: {
188
+ insertCodeBlock: (inputMethod: import("@atlaskit/editor-common/analytics").INPUT_METHOD) => import("@atlaskit/editor-common/types").Command;
189
+ };
184
190
  }, CodeBlockOptions>, import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"selection", {
185
191
  pluginConfiguration: SelectionPluginOptions | undefined;
186
192
  }, SelectionPluginOptions | undefined>, import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"floatingToolbar", {