@atlaskit/editor-plugin-toolbar 3.3.3 → 3.4.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-plugin-toolbar
2
2
 
3
+ ## 3.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`7aff1e36b43e1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7aff1e36b43e1) -
8
+ Improve editor selection toolbar experience tracking
9
+ - Updated dependencies
10
+
11
+ ## 3.4.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`301c7dd0ccdd2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/301c7dd0ccdd2) -
16
+ Adds new `contextualFormattingEnabled` plugin option to editor-plugin-toolbar. This has 3 options
17
+ (always-inline, always-pinned and controlled) to allow direct control over toolbar placement in
18
+ the editor.
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 3.3.3
4
25
 
5
26
  ### Patch Changes
@@ -0,0 +1,60 @@
1
+ {
2
+ "extends": "../../../../tsconfig.entry-points.products.json",
3
+ "compilerOptions": {
4
+ "target": "es5",
5
+ "outDir": "../../../../../tsDist/@atlaskit__editor-plugin-toolbar/app",
6
+ "rootDir": "../",
7
+ "composite": true
8
+ },
9
+ "include": [
10
+ "../src/**/*.ts",
11
+ "../src/**/*.tsx"
12
+ ],
13
+ "exclude": [
14
+ "../src/**/__tests__/*",
15
+ "../src/**/*.test.*",
16
+ "../src/**/test.*",
17
+ "../src/**/examples.*"
18
+ ],
19
+ "references": [
20
+ {
21
+ "path": "../../../helpers/browser-apis/afm-products/tsconfig.json"
22
+ },
23
+ {
24
+ "path": "../../editor-plugin-analytics/afm-products/tsconfig.json"
25
+ },
26
+ {
27
+ "path": "../../editor-plugin-connectivity/afm-products/tsconfig.json"
28
+ },
29
+ {
30
+ "path": "../../editor-plugin-editor-viewmode/afm-products/tsconfig.json"
31
+ },
32
+ {
33
+ "path": "../../editor-plugin-selection/afm-products/tsconfig.json"
34
+ },
35
+ {
36
+ "path": "../../editor-plugin-user-intent/afm-products/tsconfig.json"
37
+ },
38
+ {
39
+ "path": "../../editor-plugin-user-preferences/afm-products/tsconfig.json"
40
+ },
41
+ {
42
+ "path": "../../editor-toolbar/afm-products/tsconfig.json"
43
+ },
44
+ {
45
+ "path": "../../editor-toolbar-model/afm-products/tsconfig.json"
46
+ },
47
+ {
48
+ "path": "../../../platform/feature-flags/afm-products/tsconfig.json"
49
+ },
50
+ {
51
+ "path": "../../../platform/feature-flags-react/afm-products/tsconfig.json"
52
+ },
53
+ {
54
+ "path": "../../tmp-editor-statsig/afm-products/tsconfig.json"
55
+ },
56
+ {
57
+ "path": "../../editor-common/afm-products/tsconfig.json"
58
+ }
59
+ ]
60
+ }
@@ -1,22 +1,56 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.default = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
7
9
  var _experiences = require("@atlaskit/editor-common/experiences");
8
10
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
9
11
  var _state = require("@atlaskit/editor-prosemirror/state");
10
12
  var pluginKey = new _state.PluginKey('selectionToolbarOpenExperience');
13
+ var START_METHOD = {
14
+ MOUSE_UP: 'mouse-up',
15
+ KEY_DOWN: 'key-down'
16
+ };
17
+ var ABORT_REASON = {
18
+ SELECTION_CLEARED: 'selection-cleared',
19
+ BLOCK_MENU_OPENED: 'block-menu-opened',
20
+ EDITOR_DESTROYED: 'editor-destroyed'
21
+ };
22
+ /**
23
+ * This experience tracks when the selection toolbar is opened.
24
+ *
25
+ * Start: When user makes a selection via mouseup or shift+arrow key down
26
+ * Success: When the selection toolbar is added to the DOM within 500ms of start
27
+ * Abort: When selection transition to empty or block menu is opened
28
+ */
11
29
  var _default = exports.default = function _default(_ref) {
12
30
  var popupsMountPointRef = _ref.popupsMountPointRef,
13
31
  editorViewDomRef = _ref.editorViewDomRef;
32
+ var cachedTarget = null;
14
33
  var getTarget = function getTarget() {
15
- var _editorViewDomRef$cur;
16
- return popupsMountPointRef.current || ((_editorViewDomRef$cur = editorViewDomRef.current) === null || _editorViewDomRef$cur === void 0 ? void 0 : _editorViewDomRef$cur.closest('.ak-editor-content-area'));
34
+ if (!cachedTarget) {
35
+ var _editorViewDomRef$cur;
36
+ cachedTarget = popupsMountPointRef.current || ((_editorViewDomRef$cur = editorViewDomRef.current) === null || _editorViewDomRef$cur === void 0 || (_editorViewDomRef$cur = _editorViewDomRef$cur.closest('.ak-editor-content-area')) === null || _editorViewDomRef$cur === void 0 ? void 0 : _editorViewDomRef$cur.querySelector(':scope > [data-testid="plugins-components-wrapper"]')) || null;
37
+ }
38
+ return cachedTarget;
17
39
  };
18
40
  var experience = new _experiences.Experience('selection-toolbar-open', {
19
- checks: [new _experiences.ExperienceCheckTimeout(500), new _experiences.ExperienceCheckDomMutation({
41
+ checks: [new _experiences.ExperienceCheckTimeout({
42
+ durationMs: 500,
43
+ onTimeout: function onTimeout() {
44
+ if (isBlockMenuWithinNode(getTarget())) {
45
+ return {
46
+ status: 'abort',
47
+ metadata: {
48
+ reason: ABORT_REASON.BLOCK_MENU_OPENED
49
+ }
50
+ };
51
+ }
52
+ }
53
+ }), new _experiences.ExperienceCheckDomMutation({
20
54
  onDomMutation: function onDomMutation(_ref2) {
21
55
  var mutations = _ref2.mutations;
22
56
  if (mutations.some(isSelectionToolbarAddedInMutation)) {
@@ -29,8 +63,7 @@ var _default = exports.default = function _default(_ref) {
29
63
  return {
30
64
  target: getTarget(),
31
65
  options: {
32
- childList: true,
33
- subtree: true
66
+ childList: true
34
67
  }
35
68
  };
36
69
  }
@@ -44,7 +77,11 @@ var _default = exports.default = function _default(_ref) {
44
77
  },
45
78
  apply: function apply(_tr, pluginState, oldState, newState) {
46
79
  if (!oldState.selection.empty && newState.selection.empty) {
47
- experience.abort();
80
+ experience.abort({
81
+ metadata: {
82
+ reason: ABORT_REASON.SELECTION_CLEARED
83
+ }
84
+ });
48
85
  }
49
86
  return pluginState;
50
87
  }
@@ -52,15 +89,23 @@ var _default = exports.default = function _default(_ref) {
52
89
  props: {
53
90
  handleDOMEvents: {
54
91
  mouseup: function mouseup(view) {
55
- if (!view.state.selection.empty) {
56
- experience.start();
92
+ if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
93
+ experience.start({
94
+ metadata: {
95
+ method: START_METHOD.MOUSE_UP
96
+ }
97
+ });
57
98
  }
58
99
  },
59
100
  keydown: function keydown(_view, _ref3) {
60
101
  var shiftKey = _ref3.shiftKey,
61
102
  key = _ref3.key;
62
103
  if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
63
- experience.start();
104
+ experience.start({
105
+ metadata: {
106
+ method: START_METHOD.KEY_DOWN
107
+ }
108
+ });
64
109
  }
65
110
  }
66
111
  }
@@ -68,7 +113,11 @@ var _default = exports.default = function _default(_ref) {
68
113
  view: function view() {
69
114
  return {
70
115
  destroy: function destroy() {
71
- experience.abort();
116
+ experience.abort({
117
+ metadata: {
118
+ reason: ABORT_REASON.EDITOR_DESTROYED
119
+ }
120
+ });
72
121
  }
73
122
  };
74
123
  }
@@ -77,8 +126,24 @@ var _default = exports.default = function _default(_ref) {
77
126
  var isSelectionToolbarAddedInMutation = function isSelectionToolbarAddedInMutation(_ref4) {
78
127
  var type = _ref4.type,
79
128
  addedNodes = _ref4.addedNodes;
80
- return type === 'childList' && Array.from(addedNodes).some(isSelectionToolbarWithinNode);
129
+ return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isSelectionToolbarWithinNode);
81
130
  };
82
131
  var isSelectionToolbarWithinNode = function isSelectionToolbarWithinNode(node) {
83
- return node instanceof HTMLElement && !!node.querySelector('[data-testid="editor-floating-toolbar"]');
132
+ return containsPopupWithNestedTestId(node, 'editor-floating-toolbar');
133
+ };
134
+ var isBlockMenuWithinNode = function isBlockMenuWithinNode(node) {
135
+ return containsPopupWithNestedTestId(node, 'editor-block-menu');
136
+ };
137
+ var containsPopupWithNestedTestId = function containsPopupWithNestedTestId(node, testId) {
138
+ if (!(node instanceof HTMLElement)) {
139
+ return false;
140
+ }
141
+
142
+ // Check if node itself has the popup attribute and contains the element with testId
143
+ if (node.matches('[data-editor-popup="true"]')) {
144
+ return !!node.querySelector("[data-testid=\"".concat(testId, "\"]"));
145
+ }
146
+
147
+ // Check if any direct child with popup attribute contains the element with testId
148
+ return !!node.querySelector(":scope > [data-editor-popup=\"true\"] [data-testid=\"".concat(testId, "\"]"));
84
149
  };
@@ -78,9 +78,11 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
78
78
  var popupsMountPointRef = {};
79
79
  var editorViewDomRef = {};
80
80
  var disableSelectionToolbar = config.disableSelectionToolbar,
81
- disableSelectionToolbarWhenPinned = config.disableSelectionToolbarWhenPinned;
81
+ disableSelectionToolbarWhenPinned = config.disableSelectionToolbarWhenPinned,
82
+ _config$contextualFor = config.contextualFormattingEnabled,
83
+ contextualFormattingEnabled = _config$contextualFor === void 0 ? 'always-pinned' : _config$contextualFor;
82
84
  var registry = (0, _editorToolbarModel.createComponentRegistry)();
83
- registry.register((0, _toolbarComponents.getToolbarComponents)(api, disableSelectionToolbar));
85
+ registry.register((0, _toolbarComponents.getToolbarComponents)(contextualFormattingEnabled, api, disableSelectionToolbar));
84
86
  return {
85
87
  name: 'toolbar',
86
88
  actions: {
@@ -94,6 +96,9 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
94
96
  },
95
97
  getComponents: function getComponents() {
96
98
  return registry.components;
99
+ },
100
+ contextualFormattingMode: function contextualFormattingMode() {
101
+ return contextualFormattingEnabled;
97
102
  }
98
103
  },
99
104
  getSharedState: function getSharedState(editorState) {
@@ -182,7 +187,7 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
182
187
  }
183
188
  });
184
189
  }
185
- }].concat((0, _toConsumableArray2.default)((0, _expValEquals.expValEquals)('platform_editor_experience_tracking', 'isEnabled', true) ? [{
190
+ }].concat((0, _toConsumableArray2.default)(!disableSelectionToolbar && (0, _expValEquals.expValEquals)('platform_editor_experience_tracking', 'isEnabled', true) ? [{
186
191
  name: 'selectionToolbarOpenExperience',
187
192
  plugin: function plugin() {
188
193
  return (0, _SelectionToolbarOpenExperience.default)({
@@ -9,14 +9,22 @@ var _react = _interopRequireDefault(require("react"));
9
9
  var _toolbar = require("@atlaskit/editor-common/toolbar");
10
10
  var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
11
11
  var _editorToolbar = require("@atlaskit/editor-toolbar");
12
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
13
  var _platformFeatureFlagsReact = require("@atlaskit/platform-feature-flags-react");
13
14
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
15
  var shouldShowSection = function shouldShowSection(editMode, toolbar, toolbarDocking, disableSelectionToolbar) {
15
16
  if (editMode === 'view') {
16
17
  return false;
17
18
  }
18
- if (disableSelectionToolbar) {
19
- return true;
19
+
20
+ /**
21
+ * This check is no longer needed with plugin config changes, the selection toolbar will not be registered and so
22
+ * no components will render
23
+ */
24
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_placement_config')) {
25
+ if (disableSelectionToolbar) {
26
+ return true;
27
+ }
20
28
  }
21
29
  if ((toolbar === null || toolbar === void 0 ? void 0 : toolbar.key) === _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR && toolbarDocking !== 'top') {
22
30
  return true;
@@ -10,6 +10,7 @@ var _react = _interopRequireDefault(require("react"));
10
10
  var _analytics = require("@atlaskit/editor-common/analytics");
11
11
  var _toolbar = require("@atlaskit/editor-common/toolbar");
12
12
  var _editorToolbar = require("@atlaskit/editor-toolbar");
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
14
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
15
  var _consts = require("./consts");
15
16
  var _OverflowMenu = require("./OverflowMenu");
@@ -17,8 +18,8 @@ var _OverflowSection = require("./OverflowSection");
17
18
  var _PrimaryToolbar = require("./PrimaryToolbar");
18
19
  var _Section = require("./Section");
19
20
  var _TextCollapsedMenu = require("./TextCollapsedMenu");
20
- var getToolbarComponents = exports.getToolbarComponents = function getToolbarComponents(api, disableSelectionToolbar) {
21
- var components = [{
21
+ var getInlineTextToolbarComponents = function getInlineTextToolbarComponents() {
22
+ return [{
22
23
  type: 'toolbar',
23
24
  key: _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR,
24
25
  component: function component(_ref) {
@@ -29,7 +30,10 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
29
30
  testId: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
30
31
  }, children);
31
32
  }
32
- }, {
33
+ }];
34
+ };
35
+ var getPrimaryToolbarComponents = function getPrimaryToolbarComponents() {
36
+ return [{
33
37
  type: 'toolbar',
34
38
  key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
35
39
  component: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? _PrimaryToolbar.PrimaryToolbar : function (_ref2) {
@@ -39,7 +43,10 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
39
43
  testId: "primary-toolbar"
40
44
  }, children);
41
45
  }
42
- }, {
46
+ }];
47
+ };
48
+ var getToolbarComponents = exports.getToolbarComponents = function getToolbarComponents(contextualFormattingEnabled, api, disableSelectionToolbar) {
49
+ var components = [{
43
50
  type: _toolbar.TEXT_SECTION.type,
44
51
  key: _toolbar.TEXT_SECTION.key,
45
52
  parents: [{
@@ -249,5 +256,22 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
249
256
  }
250
257
  });
251
258
  }
259
+ if ((0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_placement_config')) {
260
+ switch (contextualFormattingEnabled) {
261
+ case 'always-inline':
262
+ components.unshift.apply(components, (0, _toConsumableArray2.default)(getInlineTextToolbarComponents()));
263
+ break;
264
+ case 'always-pinned':
265
+ components.unshift.apply(components, (0, _toConsumableArray2.default)(getPrimaryToolbarComponents()));
266
+ break;
267
+ case 'controlled':
268
+ components.unshift.apply(components, (0, _toConsumableArray2.default)(getInlineTextToolbarComponents()));
269
+ components.unshift.apply(components, (0, _toConsumableArray2.default)(getPrimaryToolbarComponents()));
270
+ break;
271
+ }
272
+ } else {
273
+ components.unshift.apply(components, (0, _toConsumableArray2.default)(getInlineTextToolbarComponents()));
274
+ components.unshift.apply(components, (0, _toConsumableArray2.default)(getPrimaryToolbarComponents()));
275
+ }
252
276
  return components;
253
277
  };
@@ -2,16 +2,48 @@ import { Experience, ExperienceCheckDomMutation, ExperienceCheckTimeout } from '
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
3
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
4
  const pluginKey = new PluginKey('selectionToolbarOpenExperience');
5
+ const START_METHOD = {
6
+ MOUSE_UP: 'mouse-up',
7
+ KEY_DOWN: 'key-down'
8
+ };
9
+ const ABORT_REASON = {
10
+ SELECTION_CLEARED: 'selection-cleared',
11
+ BLOCK_MENU_OPENED: 'block-menu-opened',
12
+ EDITOR_DESTROYED: 'editor-destroyed'
13
+ };
14
+ /**
15
+ * This experience tracks when the selection toolbar is opened.
16
+ *
17
+ * Start: When user makes a selection via mouseup or shift+arrow key down
18
+ * Success: When the selection toolbar is added to the DOM within 500ms of start
19
+ * Abort: When selection transition to empty or block menu is opened
20
+ */
5
21
  export default (({
6
22
  popupsMountPointRef,
7
23
  editorViewDomRef
8
24
  }) => {
25
+ let cachedTarget = null;
9
26
  const getTarget = () => {
10
- var _editorViewDomRef$cur;
11
- return popupsMountPointRef.current || ((_editorViewDomRef$cur = editorViewDomRef.current) === null || _editorViewDomRef$cur === void 0 ? void 0 : _editorViewDomRef$cur.closest('.ak-editor-content-area'));
27
+ if (!cachedTarget) {
28
+ var _editorViewDomRef$cur, _editorViewDomRef$cur2;
29
+ cachedTarget = popupsMountPointRef.current || ((_editorViewDomRef$cur = editorViewDomRef.current) === null || _editorViewDomRef$cur === void 0 ? void 0 : (_editorViewDomRef$cur2 = _editorViewDomRef$cur.closest('.ak-editor-content-area')) === null || _editorViewDomRef$cur2 === void 0 ? void 0 : _editorViewDomRef$cur2.querySelector(':scope > [data-testid="plugins-components-wrapper"]')) || null;
30
+ }
31
+ return cachedTarget;
12
32
  };
13
33
  const experience = new Experience('selection-toolbar-open', {
14
- checks: [new ExperienceCheckTimeout(500), new ExperienceCheckDomMutation({
34
+ checks: [new ExperienceCheckTimeout({
35
+ durationMs: 500,
36
+ onTimeout: () => {
37
+ if (isBlockMenuWithinNode(getTarget())) {
38
+ return {
39
+ status: 'abort',
40
+ metadata: {
41
+ reason: ABORT_REASON.BLOCK_MENU_OPENED
42
+ }
43
+ };
44
+ }
45
+ }
46
+ }), new ExperienceCheckDomMutation({
15
47
  onDomMutation: ({
16
48
  mutations
17
49
  }) => {
@@ -24,8 +56,7 @@ export default (({
24
56
  observeConfig: () => ({
25
57
  target: getTarget(),
26
58
  options: {
27
- childList: true,
28
- subtree: true
59
+ childList: true
29
60
  }
30
61
  })
31
62
  })]
@@ -36,7 +67,11 @@ export default (({
36
67
  init: () => ({}),
37
68
  apply: (_tr, pluginState, oldState, newState) => {
38
69
  if (!oldState.selection.empty && newState.selection.empty) {
39
- experience.abort();
70
+ experience.abort({
71
+ metadata: {
72
+ reason: ABORT_REASON.SELECTION_CLEARED
73
+ }
74
+ });
40
75
  }
41
76
  return pluginState;
42
77
  }
@@ -44,8 +79,12 @@ export default (({
44
79
  props: {
45
80
  handleDOMEvents: {
46
81
  mouseup: view => {
47
- if (!view.state.selection.empty) {
48
- experience.start();
82
+ if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
83
+ experience.start({
84
+ metadata: {
85
+ method: START_METHOD.MOUSE_UP
86
+ }
87
+ });
49
88
  }
50
89
  },
51
90
  keydown: (_view, {
@@ -53,7 +92,11 @@ export default (({
53
92
  key
54
93
  }) => {
55
94
  if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
56
- experience.start();
95
+ experience.start({
96
+ metadata: {
97
+ method: START_METHOD.KEY_DOWN
98
+ }
99
+ });
57
100
  }
58
101
  }
59
102
  }
@@ -61,7 +104,11 @@ export default (({
61
104
  view: () => {
62
105
  return {
63
106
  destroy: () => {
64
- experience.abort();
107
+ experience.abort({
108
+ metadata: {
109
+ reason: ABORT_REASON.EDITOR_DESTROYED
110
+ }
111
+ });
65
112
  }
66
113
  };
67
114
  }
@@ -71,8 +118,24 @@ const isSelectionToolbarAddedInMutation = ({
71
118
  type,
72
119
  addedNodes
73
120
  }) => {
74
- return type === 'childList' && Array.from(addedNodes).some(isSelectionToolbarWithinNode);
121
+ return type === 'childList' && [...addedNodes].some(isSelectionToolbarWithinNode);
75
122
  };
76
123
  const isSelectionToolbarWithinNode = node => {
77
- return node instanceof HTMLElement && !!node.querySelector('[data-testid="editor-floating-toolbar"]');
124
+ return containsPopupWithNestedTestId(node, 'editor-floating-toolbar');
125
+ };
126
+ const isBlockMenuWithinNode = node => {
127
+ return containsPopupWithNestedTestId(node, 'editor-block-menu');
128
+ };
129
+ const containsPopupWithNestedTestId = (node, testId) => {
130
+ if (!(node instanceof HTMLElement)) {
131
+ return false;
132
+ }
133
+
134
+ // Check if node itself has the popup attribute and contains the element with testId
135
+ if (node.matches('[data-editor-popup="true"]')) {
136
+ return !!node.querySelector(`[data-testid="${testId}"]`);
137
+ }
138
+
139
+ // Check if any direct child with popup attribute contains the element with testId
140
+ return !!node.querySelector(`:scope > [data-editor-popup="true"] [data-testid="${testId}"]`);
78
141
  };
@@ -64,10 +64,11 @@ export const toolbarPlugin = ({
64
64
  const editorViewDomRef = {};
65
65
  const {
66
66
  disableSelectionToolbar,
67
- disableSelectionToolbarWhenPinned
67
+ disableSelectionToolbarWhenPinned,
68
+ contextualFormattingEnabled = 'always-pinned'
68
69
  } = config;
69
70
  const registry = createComponentRegistry();
70
- registry.register(getToolbarComponents(api, disableSelectionToolbar));
71
+ registry.register(getToolbarComponents(contextualFormattingEnabled, api, disableSelectionToolbar));
71
72
  return {
72
73
  name: 'toolbar',
73
74
  actions: {
@@ -80,6 +81,9 @@ export const toolbarPlugin = ({
80
81
  },
81
82
  getComponents: () => {
82
83
  return registry.components;
84
+ },
85
+ contextualFormattingMode: () => {
86
+ return contextualFormattingEnabled;
83
87
  }
84
88
  },
85
89
  getSharedState(editorState) {
@@ -173,7 +177,7 @@ export const toolbarPlugin = ({
173
177
  }
174
178
  });
175
179
  }
176
- }, ...(expValEquals('platform_editor_experience_tracking', 'isEnabled', true) ? [{
180
+ }, ...(!disableSelectionToolbar && expValEquals('platform_editor_experience_tracking', 'isEnabled', true) ? [{
177
181
  name: 'selectionToolbarOpenExperience',
178
182
  plugin: () => selectionToolbarOpenExperience({
179
183
  popupsMountPointRef,
@@ -2,14 +2,22 @@ import React from 'react';
2
2
  import { TOOLBARS, useEditorToolbar } from '@atlaskit/editor-common/toolbar';
3
3
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
4
4
  import { ToolbarSection, SeparatorPosition } from '@atlaskit/editor-toolbar';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
6
7
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
8
  const shouldShowSection = (editMode, toolbar, toolbarDocking, disableSelectionToolbar) => {
8
9
  if (editMode === 'view') {
9
10
  return false;
10
11
  }
11
- if (disableSelectionToolbar) {
12
- return true;
12
+
13
+ /**
14
+ * This check is no longer needed with plugin config changes, the selection toolbar will not be registered and so
15
+ * no components will render
16
+ */
17
+ if (!fg('platform_editor_toolbar_aifc_placement_config')) {
18
+ if (disableSelectionToolbar) {
19
+ return true;
20
+ }
13
21
  }
14
22
  if ((toolbar === null || toolbar === void 0 ? void 0 : toolbar.key) === TOOLBARS.INLINE_TEXT_TOOLBAR && toolbarDocking !== 'top') {
15
23
  return true;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
3
3
  import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_PRIMARY_TOOLBAR, OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_MENU_PRIMARY_TOOLBAR, OVERFLOW_SECTION, OVERFLOW_SECTION_PRIMARY_TOOLBAR, OVERFLOW_SECTION_PRIMARY_TOOLBAR_RANK, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_COLLAPSED_GROUP, TEXT_SECTION, TEXT_SECTION_PRIMARY_TOOLBAR, TEXT_SECTION_COLLAPSED, TEXT_COLLAPSED_MENU, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
4
4
  import { PrimaryToolbar as PrimaryToolbarBase, Show, Toolbar } from '@atlaskit/editor-toolbar';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
7
  import { SELECTION_TOOLBAR_LABEL } from './consts';
7
8
  import { OverflowMenu } from './OverflowMenu';
@@ -9,8 +10,8 @@ import { OverflowSection } from './OverflowSection';
9
10
  import { PrimaryToolbar } from './PrimaryToolbar';
10
11
  import { Section } from './Section';
11
12
  import { TextCollapsedMenu } from './TextCollapsedMenu';
12
- export const getToolbarComponents = (api, disableSelectionToolbar) => {
13
- const components = [{
13
+ const getInlineTextToolbarComponents = () => {
14
+ return [{
14
15
  type: 'toolbar',
15
16
  key: TOOLBARS.INLINE_TEXT_TOOLBAR,
16
17
  component: ({
@@ -22,7 +23,10 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
22
23
  testId: expValEquals('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
23
24
  }, children);
24
25
  }
25
- }, {
26
+ }];
27
+ };
28
+ const getPrimaryToolbarComponents = () => {
29
+ return [{
26
30
  type: 'toolbar',
27
31
  key: TOOLBARS.PRIMARY_TOOLBAR,
28
32
  component: expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? PrimaryToolbar : ({
@@ -31,7 +35,10 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
31
35
  label: "Primary Toolbar",
32
36
  testId: "primary-toolbar"
33
37
  }, children)
34
- }, {
38
+ }];
39
+ };
40
+ export const getToolbarComponents = (contextualFormattingEnabled, api, disableSelectionToolbar) => {
41
+ const components = [{
35
42
  type: TEXT_SECTION.type,
36
43
  key: TEXT_SECTION.key,
37
44
  parents: [{
@@ -245,5 +252,22 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
245
252
  }
246
253
  });
247
254
  }
255
+ if (fg('platform_editor_toolbar_aifc_placement_config')) {
256
+ switch (contextualFormattingEnabled) {
257
+ case 'always-inline':
258
+ components.unshift(...getInlineTextToolbarComponents());
259
+ break;
260
+ case 'always-pinned':
261
+ components.unshift(...getPrimaryToolbarComponents());
262
+ break;
263
+ case 'controlled':
264
+ components.unshift(...getInlineTextToolbarComponents());
265
+ components.unshift(...getPrimaryToolbarComponents());
266
+ break;
267
+ }
268
+ } else {
269
+ components.unshift(...getInlineTextToolbarComponents());
270
+ components.unshift(...getPrimaryToolbarComponents());
271
+ }
248
272
  return components;
249
273
  };