@atlaskit/editor-plugin-toolbar 0.3.0 → 0.4.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 (35) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cjs/pm-plugins/plugin-key.js +8 -0
  3. package/dist/cjs/toolbarPlugin.js +83 -0
  4. package/dist/cjs/ui/{TextSection.js → Section.js} +14 -6
  5. package/dist/cjs/ui/SelectionToolbar/index.js +28 -7
  6. package/dist/cjs/ui/consts.js +6 -2
  7. package/dist/cjs/ui/toolbar-components.js +57 -7
  8. package/dist/cjs/ui/utils/toolbar.js +13 -0
  9. package/dist/es2019/pm-plugins/plugin-key.js +2 -0
  10. package/dist/es2019/toolbarPlugin.js +83 -0
  11. package/dist/es2019/ui/{TextSection.js → Section.js} +14 -6
  12. package/dist/es2019/ui/SelectionToolbar/index.js +29 -6
  13. package/dist/es2019/ui/consts.js +5 -1
  14. package/dist/es2019/ui/toolbar-components.js +55 -7
  15. package/dist/es2019/ui/utils/toolbar.js +7 -0
  16. package/dist/esm/pm-plugins/plugin-key.js +2 -0
  17. package/dist/esm/toolbarPlugin.js +83 -0
  18. package/dist/esm/ui/{TextSection.js → Section.js} +14 -6
  19. package/dist/esm/ui/SelectionToolbar/index.js +28 -8
  20. package/dist/esm/ui/consts.js +5 -1
  21. package/dist/esm/ui/toolbar-components.js +59 -9
  22. package/dist/esm/ui/utils/toolbar.js +7 -0
  23. package/dist/types/pm-plugins/plugin-key.d.ts +2 -0
  24. package/dist/types/toolbarPlugin.d.ts +3 -0
  25. package/dist/types/toolbarPluginType.d.ts +3 -0
  26. package/dist/{types-ts4.5/ui/TextSection.d.ts → types/ui/Section.d.ts} +5 -2
  27. package/dist/types/ui/consts.d.ts +5 -1
  28. package/dist/types/ui/utils/toolbar.d.ts +1 -0
  29. package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +2 -0
  30. package/dist/types-ts4.5/toolbarPlugin.d.ts +3 -0
  31. package/dist/types-ts4.5/toolbarPluginType.d.ts +3 -0
  32. package/dist/{types/ui/TextSection.d.ts → types-ts4.5/ui/Section.d.ts} +5 -2
  33. package/dist/types-ts4.5/ui/consts.d.ts +5 -1
  34. package/dist/types-ts4.5/ui/utils/toolbar.d.ts +1 -0
  35. package/package.json +5 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @atlaskit/editor-plugin-toolbar
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`e73faa5a52300`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e73faa5a52300) -
8
+ [ux] ED-28735 Fix selection toolbar opening and closing state
9
+
10
+ ### Patch Changes
11
+
12
+ - [`b27824f2875be`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b27824f2875be) -
13
+ [ux] [ED-28821] Add pin button to full page primary toolbar
14
+ - Updated dependencies
15
+
16
+ ## 0.3.1
17
+
18
+ ### Patch Changes
19
+
20
+ - [`286abb4d35eba`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/286abb4d35eba) -
21
+ [ux] [ED-28960] Finish full page primary toolbar migration
22
+
23
+ - Align with design update (separator, gap, height, icon size)
24
+ - Add keyboard shortcut to focus toolbar and arrow key navigation
25
+ - Address accessibility
26
+
27
+ - Updated dependencies
28
+
3
29
  ## 0.3.0
4
30
 
5
31
  ### Minor Changes
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.editorToolbarPluginKey = void 0;
7
+ var _state = require("@atlaskit/editor-prosemirror/state");
8
+ var editorToolbarPluginKey = exports.editorToolbarPluginKey = new _state.PluginKey('editorToolbarPluginKey');
@@ -5,10 +5,18 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.toolbarPlugin = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
8
9
  var _react = _interopRequireDefault(require("react"));
10
+ var _bindEventListener = require("bind-event-listener");
11
+ var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
9
12
  var _editorToolbarModel = require("@atlaskit/editor-toolbar-model");
13
+ var _pluginKey = require("./pm-plugins/plugin-key");
14
+ var _consts = require("./ui/consts");
10
15
  var _SelectionToolbar = require("./ui/SelectionToolbar");
11
16
  var _toolbarComponents = require("./ui/toolbar-components");
17
+ var _toolbar = require("./ui/utils/toolbar");
18
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19
+ 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) { (0, _defineProperty2.default)(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; }
12
20
  var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
13
21
  var api = _ref.api,
14
22
  _ref$config = _ref.config,
@@ -28,6 +36,81 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
28
36
  return registry.components;
29
37
  }
30
38
  },
39
+ getSharedState: function getSharedState(editorState) {
40
+ if (!editorState) {
41
+ return undefined;
42
+ }
43
+ return _pluginKey.editorToolbarPluginKey.getState(editorState);
44
+ },
45
+ pmPlugins: function pmPlugins() {
46
+ return [{
47
+ name: 'editor-toolbar-selection',
48
+ plugin: function plugin() {
49
+ return new _safePlugin.SafePlugin({
50
+ key: _pluginKey.editorToolbarPluginKey,
51
+ state: {
52
+ init: function init() {
53
+ return {
54
+ shouldShowToolbar: false
55
+ };
56
+ },
57
+ apply: function apply(tr, pluginState) {
58
+ var meta = tr.getMeta(_pluginKey.editorToolbarPluginKey);
59
+ var newPluginState = pluginState;
60
+ if (meta) {
61
+ return _objectSpread(_objectSpread({}, newPluginState), meta);
62
+ }
63
+ return newPluginState;
64
+ }
65
+ },
66
+ view: function view(_view) {
67
+ var unbind = (0, _bindEventListener.bind)(_view.root, {
68
+ type: 'mouseup',
69
+ listener: function listener(ev) {
70
+ var _api$editorViewMode;
71
+ var event = ev;
72
+ var isInToolbar = (0, _toolbar.isEventInContainer)(event, _consts.DEFAULT_POPUP_SELECTORS.toolbarContainer);
73
+ var isInPortal = (0, _toolbar.isEventInContainer)(event, _consts.DEFAULT_POPUP_SELECTORS.portal);
74
+
75
+ // We only want to set selectionStable to true if the editor has focus
76
+ // to prevent the toolbar from showing when the editor is blurred
77
+ // due to a click outside the editor.
78
+ var editorViewModePlugin = api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.sharedState.currentState();
79
+ var isViewModeEnabled = (editorViewModePlugin === null || editorViewModePlugin === void 0 ? void 0 : editorViewModePlugin.mode) === 'view';
80
+ _view.dispatch(_view.state.tr.setMeta(_pluginKey.editorToolbarPluginKey, {
81
+ shouldShowToolbar: !isViewModeEnabled ? _view.hasFocus() || isInToolbar || isInPortal : true
82
+ }));
83
+ }
84
+ });
85
+ var unbindEditorViewFocus = (0, _bindEventListener.bind)(_view.dom, {
86
+ type: 'focus',
87
+ listener: function listener() {
88
+ _view.dispatch(_view.state.tr.setMeta(_pluginKey.editorToolbarPluginKey, {
89
+ shouldShowToolbar: true
90
+ }));
91
+ }
92
+ });
93
+ return {
94
+ destroy: function destroy() {
95
+ unbind();
96
+ unbindEditorViewFocus();
97
+ }
98
+ };
99
+ },
100
+ props: {
101
+ handleDOMEvents: {
102
+ mousedown: function mousedown(view) {
103
+ view.dispatch(view.state.tr.setMeta(_pluginKey.editorToolbarPluginKey, {
104
+ shouldShowToolbar: false
105
+ }));
106
+ return false;
107
+ }
108
+ }
109
+ }
110
+ });
111
+ }
112
+ }];
113
+ },
31
114
  contentComponent: !disableSelectionToolbar ? function (_ref2) {
32
115
  var editorView = _ref2.editorView,
33
116
  popupsMountPoint = _ref2.popupsMountPoint;
@@ -4,12 +4,12 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.TextSection = void 0;
7
+ exports.Section = void 0;
8
8
  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 shouldShowTextSection = function shouldShowTextSection(editMode, toolbar, toolbarDocking) {
12
+ var shouldShowSection = function shouldShowSection(editMode, toolbar, toolbarDocking) {
13
13
  if (editMode === 'view') {
14
14
  return false;
15
15
  }
@@ -21,19 +21,27 @@ var shouldShowTextSection = function shouldShowTextSection(editMode, toolbar, to
21
21
  }
22
22
  return false;
23
23
  };
24
- var TextSection = exports.TextSection = function TextSection(_ref) {
24
+ var Section = exports.Section = function Section(_ref) {
25
25
  var children = _ref.children,
26
26
  parents = _ref.parents,
27
- api = _ref.api;
27
+ api = _ref.api,
28
+ testId = _ref.testId,
29
+ showSeparatorInFullPagePrimaryToolbar = _ref.showSeparatorInFullPagePrimaryToolbar,
30
+ _ref$isSharedSection = _ref.isSharedSection,
31
+ isSharedSection = _ref$isSharedSection === void 0 ? true : _ref$isSharedSection;
28
32
  var editMode = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(api, 'editorViewMode.mode');
29
33
  var toolbarDocking = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(api, 'userPreferences.preferences.toolbarDockingPosition');
30
34
  var toolbar = parents.find(function (parent) {
31
35
  return parent.type === 'toolbar';
32
36
  });
33
- if (!shouldShowTextSection(editMode, toolbar, toolbarDocking)) {
37
+ var _useEditorToolbar = (0, _toolbar.useEditorToolbar)(),
38
+ editorAppearance = _useEditorToolbar.editorAppearance;
39
+ if (isSharedSection && !shouldShowSection(editMode, toolbar, toolbarDocking)) {
34
40
  return null;
35
41
  }
42
+ var isFullPage = editorAppearance === 'full-page';
36
43
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarSection, {
37
- testId: "text-section"
44
+ testId: testId,
45
+ hasSeparator: showSeparatorInFullPagePrimaryToolbar && isFullPage
38
46
  }, children);
39
47
  };
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.SelectionToolbar = void 0;
8
- var _react = _interopRequireDefault(require("react"));
8
+ var _react = _interopRequireWildcard(require("react"));
9
9
  var _coreUtils = require("@atlaskit/editor-common/core-utils");
10
+ var _hooks = require("@atlaskit/editor-common/hooks");
10
11
  var _toolbar = require("@atlaskit/editor-common/toolbar");
11
12
  var _ui = require("@atlaskit/editor-common/ui");
12
13
  var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
@@ -15,16 +16,26 @@ var _state = require("@atlaskit/editor-prosemirror/state");
15
16
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
16
17
  var _editorToolbar = require("@atlaskit/editor-toolbar");
17
18
  var _editorToolbarModel = require("@atlaskit/editor-toolbar-model");
19
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
18
20
  var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
19
21
  var _consts = require("../consts");
22
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
20
23
  var isToolbarComponent = function isToolbarComponent(component) {
21
24
  return component.type === 'toolbar' && component.key === 'inline-text-toolbar';
22
25
  };
23
26
  var SelectionToolbar = exports.SelectionToolbar = function SelectionToolbar(_ref) {
27
+ var _api$toolbar, _api$toolbar$getCompo;
24
28
  var api = _ref.api,
25
29
  editorView = _ref.editorView,
26
30
  mountPoint = _ref.mountPoint;
27
- var components = api === null || api === void 0 ? void 0 : api.toolbar.actions.getComponents();
31
+ var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['toolbar'], function (state) {
32
+ var _state$toolbarState;
33
+ return {
34
+ shouldShowToolbar: (_state$toolbarState = state.toolbarState) === null || _state$toolbarState === void 0 ? void 0 : _state$toolbarState.shouldShowToolbar
35
+ };
36
+ }),
37
+ shouldShowToolbar = _useSharedPluginState.shouldShowToolbar;
38
+ var components = api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 || (_api$toolbar = _api$toolbar.actions) === null || _api$toolbar === void 0 || (_api$toolbar$getCompo = _api$toolbar.getComponents) === null || _api$toolbar$getCompo === void 0 ? void 0 : _api$toolbar$getCompo.call(_api$toolbar);
28
39
  var toolbar = components === null || components === void 0 ? void 0 : components.find(function (component) {
29
40
  return isToolbarComponent(component);
30
41
  });
@@ -36,18 +47,28 @@ var SelectionToolbar = exports.SelectionToolbar = function SelectionToolbar(_ref
36
47
  var selection = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(api, 'selection.selection');
37
48
  var isTextSelection = !editorView.state.selection.empty && editorView.state.selection instanceof _state.TextSelection;
38
49
  var isCellSelection = !editorView.state.selection.empty && '$anchorCell' in editorView.state.selection;
50
+ var onPositionCalculated = (0, _react.useCallback)(function (position) {
51
+ var toolbarTitle = _consts.SELECTION_TOOLBAR_LABEL;
52
+
53
+ // Show special position on cell selection only when editor controls experiment is enabled
54
+ var isEditorControlsEnabled = (0, _expValEquals.expValEquals)('platform_editor_controls', 'cohort', 'variant1');
55
+ var isCellSelection = ('$anchorCell' in editorView.state.selection);
56
+ if (isCellSelection && isEditorControlsEnabled) {
57
+ return (0, _utils.calculateToolbarPositionOnCellSelection)(toolbarTitle)(editorView, position);
58
+ }
59
+ var calc = _utils.calculateToolbarPositionTrackHead;
60
+ return calc(toolbarTitle)(editorView, position);
61
+ }, [editorView]);
39
62
  if (!components || !toolbar) {
40
63
  return null;
41
64
  }
42
- if (!(isTextSelection || isCellSelection) || currentUserIntent === 'dragging' || currentUserIntent === 'blockMenuOpen' && (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true) || (0, _coreUtils.isSSR)()) {
65
+ if (!(isTextSelection || isCellSelection) || currentUserIntent === 'dragging' || !shouldShowToolbar || currentUserIntent === 'blockMenuOpen' && (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true) || (0, _coreUtils.isSSR)()) {
43
66
  return null;
44
67
  }
45
68
  return /*#__PURE__*/_react.default.createElement(_ui.Popup, {
46
69
  offset: [0, 10],
47
70
  target: getDomRefFromSelection(editorView),
48
- onPositionCalculated: function onPositionCalculated(position) {
49
- return (0, _utils.calculateToolbarPositionTrackHead)(_consts.TOOLBAR_LABEL)(editorView, position);
50
- },
71
+ onPositionCalculated: onPositionCalculated,
51
72
  mountTo: mountPoint
52
73
  }, /*#__PURE__*/_react.default.createElement(_toolbar.EditorToolbarProvider, {
53
74
  editorView: editorView
@@ -3,5 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TOOLBAR_LABEL = void 0;
7
- var TOOLBAR_LABEL = exports.TOOLBAR_LABEL = 'Editor Toolbar';
6
+ exports.SELECTION_TOOLBAR_LABEL = exports.DEFAULT_POPUP_SELECTORS = void 0;
7
+ var SELECTION_TOOLBAR_LABEL = exports.SELECTION_TOOLBAR_LABEL = 'Selection toolbar';
8
+ var DEFAULT_POPUP_SELECTORS = exports.DEFAULT_POPUP_SELECTORS = {
9
+ toolbarContainer: '[role="toolbar"]',
10
+ portal: '.atlaskit-portal'
11
+ };
@@ -10,7 +10,7 @@ var _toolbar = require("@atlaskit/editor-common/toolbar");
10
10
  var _editorToolbar = require("@atlaskit/editor-toolbar");
11
11
  var _consts = require("./consts");
12
12
  var _OverflowMenu = require("./OverflowMenu");
13
- var _TextSection = require("./TextSection");
13
+ var _Section = require("./Section");
14
14
  var getToolbarComponents = exports.getToolbarComponents = function getToolbarComponents(api) {
15
15
  return [{
16
16
  type: 'toolbar',
@@ -18,7 +18,7 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
18
18
  component: function component(_ref) {
19
19
  var children = _ref.children;
20
20
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.Toolbar, {
21
- label: _consts.TOOLBAR_LABEL
21
+ label: _consts.SELECTION_TOOLBAR_LABEL
22
22
  }, children);
23
23
  }
24
24
  }, {
@@ -27,7 +27,7 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
27
27
  component: function component(_ref2) {
28
28
  var children = _ref2.children;
29
29
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.PrimaryToolbar, {
30
- label: "Primary Toolbar"
30
+ label: 'Primary Toolbar'
31
31
  }, children);
32
32
  }
33
33
  }, {
@@ -45,9 +45,51 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
45
45
  component: function component(_ref3) {
46
46
  var children = _ref3.children,
47
47
  parents = _ref3.parents;
48
- return /*#__PURE__*/_react.default.createElement(_TextSection.TextSection, {
48
+ return /*#__PURE__*/_react.default.createElement(_Section.Section, {
49
49
  parents: parents,
50
- api: api
50
+ api: api,
51
+ testId: "text-section"
52
+ }, children);
53
+ }
54
+ }, {
55
+ type: _toolbar.INSERT_BLOCK_SECTION.type,
56
+ key: _toolbar.INSERT_BLOCK_SECTION.key,
57
+ parents: [{
58
+ type: 'toolbar',
59
+ key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
60
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.INSERT_BLOCK_SECTION.key]
61
+ }],
62
+ component: function component(_ref4) {
63
+ var children = _ref4.children,
64
+ parents = _ref4.parents;
65
+ return /*#__PURE__*/_react.default.createElement(_Section.Section, {
66
+ testId: "insert-block-section",
67
+ parents: parents,
68
+ api: api,
69
+ showSeparatorInFullPagePrimaryToolbar: true,
70
+ isSharedSection: false
71
+ }, children);
72
+ }
73
+ }, {
74
+ type: _toolbar.LINKING_SECTION.type,
75
+ key: _toolbar.LINKING_SECTION.key,
76
+ parents: [{
77
+ type: 'toolbar',
78
+ key: _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR,
79
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.LINKING_SECTION.key]
80
+ }, {
81
+ type: 'toolbar',
82
+ key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
83
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.LINKING_SECTION.key]
84
+ }],
85
+ component: function component(_ref5) {
86
+ var children = _ref5.children,
87
+ parents = _ref5.parents;
88
+ return /*#__PURE__*/_react.default.createElement(_Section.Section, {
89
+ testId: "link-section",
90
+ parents: parents,
91
+ api: api,
92
+ showSeparatorInFullPagePrimaryToolbar: true
51
93
  }, children);
52
94
  }
53
95
  }, {
@@ -74,9 +116,17 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
74
116
  key: _toolbar.OVERFLOW_GROUP.key,
75
117
  rank: _toolbar.OVERFLOW_GROUP_RANK[_toolbar.OVERFLOW_MENU.key]
76
118
  }],
77
- component: function component(_ref4) {
78
- var children = _ref4.children;
119
+ component: function component(_ref6) {
120
+ var children = _ref6.children;
79
121
  return /*#__PURE__*/_react.default.createElement(_OverflowMenu.OverflowMenu, null, children);
80
122
  }
123
+ }, {
124
+ type: _toolbar.PIN_SECTION.type,
125
+ key: _toolbar.PIN_SECTION.key,
126
+ parents: [{
127
+ type: 'toolbar',
128
+ key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
129
+ rank: _toolbar.TOOLBAR_RANK[_toolbar.PIN_SECTION.key]
130
+ }]
81
131
  }];
82
132
  };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isEventInContainer = void 0;
7
+ var isEventInContainer = exports.isEventInContainer = function isEventInContainer(event, containerSelector) {
8
+ var target = event.target instanceof Element ? event.target : null;
9
+ if (!target) {
10
+ return false;
11
+ }
12
+ return !!target.closest(containerSelector);
13
+ };
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export const editorToolbarPluginKey = new PluginKey('editorToolbarPluginKey');
@@ -1,7 +1,12 @@
1
1
  import React from 'react';
2
+ import { bind } from 'bind-event-listener';
3
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
4
  import { createComponentRegistry } from '@atlaskit/editor-toolbar-model';
5
+ import { editorToolbarPluginKey } from './pm-plugins/plugin-key';
6
+ import { DEFAULT_POPUP_SELECTORS } from './ui/consts';
3
7
  import { SelectionToolbar } from './ui/SelectionToolbar';
4
8
  import { getToolbarComponents } from './ui/toolbar-components';
9
+ import { isEventInContainer } from './ui/utils/toolbar';
5
10
  export const toolbarPlugin = ({
6
11
  api,
7
12
  config = {
@@ -23,6 +28,84 @@ export const toolbarPlugin = ({
23
28
  return registry.components;
24
29
  }
25
30
  },
31
+ getSharedState(editorState) {
32
+ if (!editorState) {
33
+ return undefined;
34
+ }
35
+ return editorToolbarPluginKey.getState(editorState);
36
+ },
37
+ pmPlugins() {
38
+ return [{
39
+ name: 'editor-toolbar-selection',
40
+ plugin: () => {
41
+ return new SafePlugin({
42
+ key: editorToolbarPluginKey,
43
+ state: {
44
+ init() {
45
+ return {
46
+ shouldShowToolbar: false
47
+ };
48
+ },
49
+ apply(tr, pluginState) {
50
+ const meta = tr.getMeta(editorToolbarPluginKey);
51
+ const newPluginState = pluginState;
52
+ if (meta) {
53
+ return {
54
+ ...newPluginState,
55
+ ...meta
56
+ };
57
+ }
58
+ return newPluginState;
59
+ }
60
+ },
61
+ view(view) {
62
+ const unbind = bind(view.root, {
63
+ type: 'mouseup',
64
+ listener: function (ev) {
65
+ var _api$editorViewMode;
66
+ const event = ev;
67
+ const isInToolbar = isEventInContainer(event, DEFAULT_POPUP_SELECTORS.toolbarContainer);
68
+ const isInPortal = isEventInContainer(event, DEFAULT_POPUP_SELECTORS.portal);
69
+
70
+ // We only want to set selectionStable to true if the editor has focus
71
+ // to prevent the toolbar from showing when the editor is blurred
72
+ // due to a click outside the editor.
73
+ const editorViewModePlugin = api === null || api === void 0 ? void 0 : (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.sharedState.currentState();
74
+ const isViewModeEnabled = (editorViewModePlugin === null || editorViewModePlugin === void 0 ? void 0 : editorViewModePlugin.mode) === 'view';
75
+ view.dispatch(view.state.tr.setMeta(editorToolbarPluginKey, {
76
+ shouldShowToolbar: !isViewModeEnabled ? view.hasFocus() || isInToolbar || isInPortal : true
77
+ }));
78
+ }
79
+ });
80
+ const unbindEditorViewFocus = bind(view.dom, {
81
+ type: 'focus',
82
+ listener: () => {
83
+ view.dispatch(view.state.tr.setMeta(editorToolbarPluginKey, {
84
+ shouldShowToolbar: true
85
+ }));
86
+ }
87
+ });
88
+ return {
89
+ destroy() {
90
+ unbind();
91
+ unbindEditorViewFocus();
92
+ }
93
+ };
94
+ },
95
+ props: {
96
+ handleDOMEvents: {
97
+ mousedown: view => {
98
+ view.dispatch(view.state.tr.setMeta(editorToolbarPluginKey, {
99
+ shouldShowToolbar: false
100
+ }));
101
+ return false;
102
+ }
103
+ }
104
+ }
105
+ });
106
+ }
107
+ }];
108
+ },
26
109
  contentComponent: !disableSelectionToolbar ? ({
27
110
  editorView,
28
111
  popupsMountPoint
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { TOOLBARS } from '@atlaskit/editor-common/toolbar';
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 } from '@atlaskit/editor-toolbar';
5
- const shouldShowTextSection = (editMode, toolbar, toolbarDocking) => {
5
+ const shouldShowSection = (editMode, toolbar, toolbarDocking) => {
6
6
  if (editMode === 'view') {
7
7
  return false;
8
8
  }
@@ -14,18 +14,26 @@ const shouldShowTextSection = (editMode, toolbar, toolbarDocking) => {
14
14
  }
15
15
  return false;
16
16
  };
17
- export const TextSection = ({
17
+ export const Section = ({
18
18
  children,
19
19
  parents,
20
- api
20
+ api,
21
+ testId,
22
+ showSeparatorInFullPagePrimaryToolbar,
23
+ isSharedSection = true
21
24
  }) => {
22
25
  const editMode = useSharedPluginStateSelector(api, 'editorViewMode.mode');
23
26
  const toolbarDocking = useSharedPluginStateSelector(api, 'userPreferences.preferences.toolbarDockingPosition');
24
27
  const toolbar = parents.find(parent => parent.type === 'toolbar');
25
- if (!shouldShowTextSection(editMode, toolbar, toolbarDocking)) {
28
+ const {
29
+ editorAppearance
30
+ } = useEditorToolbar();
31
+ if (isSharedSection && !shouldShowSection(editMode, toolbar, toolbarDocking)) {
26
32
  return null;
27
33
  }
34
+ const isFullPage = editorAppearance === 'full-page';
28
35
  return /*#__PURE__*/React.createElement(ToolbarSection, {
29
- testId: "text-section"
36
+ testId: testId,
37
+ hasSeparator: showSeparatorInFullPagePrimaryToolbar && isFullPage
30
38
  }, children);
31
39
  };
@@ -1,15 +1,17 @@
1
- import React from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import { isSSR } from '@atlaskit/editor-common/core-utils';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
4
  import { EditorToolbarProvider, EditorToolbarUIProvider } from '@atlaskit/editor-common/toolbar';
4
5
  import { Popup } from '@atlaskit/editor-common/ui';
5
6
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
6
- import { calculateToolbarPositionTrackHead } from '@atlaskit/editor-common/utils';
7
+ import { calculateToolbarPositionTrackHead, calculateToolbarPositionOnCellSelection } from '@atlaskit/editor-common/utils';
7
8
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
8
9
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
9
10
  import { ToolbarSection, ToolbarButtonGroup, ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
10
11
  import { ToolbarModelRenderer } from '@atlaskit/editor-toolbar-model';
12
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
11
13
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
12
- import { TOOLBAR_LABEL } from '../consts';
14
+ import { SELECTION_TOOLBAR_LABEL } from '../consts';
13
15
  const isToolbarComponent = component => {
14
16
  return component.type === 'toolbar' && component.key === 'inline-text-toolbar';
15
17
  };
@@ -18,7 +20,16 @@ export const SelectionToolbar = ({
18
20
  editorView,
19
21
  mountPoint
20
22
  }) => {
21
- const components = api === null || api === void 0 ? void 0 : api.toolbar.actions.getComponents();
23
+ var _api$toolbar, _api$toolbar$actions, _api$toolbar$actions$;
24
+ const {
25
+ shouldShowToolbar
26
+ } = useSharedPluginStateWithSelector(api, ['toolbar'], state => {
27
+ var _state$toolbarState;
28
+ return {
29
+ shouldShowToolbar: (_state$toolbarState = state.toolbarState) === null || _state$toolbarState === void 0 ? void 0 : _state$toolbarState.shouldShowToolbar
30
+ };
31
+ });
32
+ const components = api === null || api === void 0 ? void 0 : (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : (_api$toolbar$actions = _api$toolbar.actions) === null || _api$toolbar$actions === void 0 ? void 0 : (_api$toolbar$actions$ = _api$toolbar$actions.getComponents) === null || _api$toolbar$actions$ === void 0 ? void 0 : _api$toolbar$actions$.call(_api$toolbar$actions);
22
33
  const toolbar = components === null || components === void 0 ? void 0 : components.find(component => isToolbarComponent(component));
23
34
  const currentUserIntent = useSharedPluginStateSelector(api, 'userIntent.currentUserIntent');
24
35
  const connectivityStateMode = useSharedPluginStateSelector(api, 'connectivity.mode');
@@ -28,16 +39,28 @@ export const SelectionToolbar = ({
28
39
  const selection = useSharedPluginStateSelector(api, 'selection.selection');
29
40
  const isTextSelection = !editorView.state.selection.empty && editorView.state.selection instanceof TextSelection;
30
41
  const isCellSelection = !editorView.state.selection.empty && '$anchorCell' in editorView.state.selection;
42
+ const onPositionCalculated = useCallback(position => {
43
+ const toolbarTitle = SELECTION_TOOLBAR_LABEL;
44
+
45
+ // Show special position on cell selection only when editor controls experiment is enabled
46
+ const isEditorControlsEnabled = expValEquals('platform_editor_controls', 'cohort', 'variant1');
47
+ const isCellSelection = ('$anchorCell' in editorView.state.selection);
48
+ if (isCellSelection && isEditorControlsEnabled) {
49
+ return calculateToolbarPositionOnCellSelection(toolbarTitle)(editorView, position);
50
+ }
51
+ const calc = calculateToolbarPositionTrackHead;
52
+ return calc(toolbarTitle)(editorView, position);
53
+ }, [editorView]);
31
54
  if (!components || !toolbar) {
32
55
  return null;
33
56
  }
34
- if (!(isTextSelection || isCellSelection) || currentUserIntent === 'dragging' || currentUserIntent === 'blockMenuOpen' && expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true) || isSSR()) {
57
+ if (!(isTextSelection || isCellSelection) || currentUserIntent === 'dragging' || !shouldShowToolbar || currentUserIntent === 'blockMenuOpen' && expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true) || isSSR()) {
35
58
  return null;
36
59
  }
37
60
  return /*#__PURE__*/React.createElement(Popup, {
38
61
  offset: [0, 10],
39
62
  target: getDomRefFromSelection(editorView),
40
- onPositionCalculated: position => calculateToolbarPositionTrackHead(TOOLBAR_LABEL)(editorView, position),
63
+ onPositionCalculated: onPositionCalculated,
41
64
  mountTo: mountPoint
42
65
  }, /*#__PURE__*/React.createElement(EditorToolbarProvider, {
43
66
  editorView: editorView
@@ -1 +1,5 @@
1
- export const TOOLBAR_LABEL = 'Editor Toolbar';
1
+ export const SELECTION_TOOLBAR_LABEL = 'Selection toolbar';
2
+ export const DEFAULT_POPUP_SELECTORS = {
3
+ toolbarContainer: '[role="toolbar"]',
4
+ portal: '.atlaskit-portal'
5
+ };
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import { OVERFLOW_GROUP, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_SECTION, OVERFLOW_SECTION_RANK, TEXT_SECTION, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
2
+ import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_SECTION, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_SECTION, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
3
3
  import { PrimaryToolbar, Toolbar } from '@atlaskit/editor-toolbar';
4
- import { TOOLBAR_LABEL } from './consts';
4
+ import { SELECTION_TOOLBAR_LABEL } from './consts';
5
5
  import { OverflowMenu } from './OverflowMenu';
6
- import { TextSection } from './TextSection';
6
+ import { Section } from './Section';
7
7
  export const getToolbarComponents = api => {
8
8
  return [{
9
9
  type: 'toolbar',
@@ -12,7 +12,7 @@ export const getToolbarComponents = api => {
12
12
  children
13
13
  }) => {
14
14
  return /*#__PURE__*/React.createElement(Toolbar, {
15
- label: TOOLBAR_LABEL
15
+ label: SELECTION_TOOLBAR_LABEL
16
16
  }, children);
17
17
  }
18
18
  }, {
@@ -21,7 +21,7 @@ export const getToolbarComponents = api => {
21
21
  component: ({
22
22
  children
23
23
  }) => /*#__PURE__*/React.createElement(PrimaryToolbar, {
24
- label: "Primary Toolbar"
24
+ label: 'Primary Toolbar'
25
25
  }, children)
26
26
  }, {
27
27
  type: TEXT_SECTION.type,
@@ -39,11 +39,51 @@ export const getToolbarComponents = api => {
39
39
  children,
40
40
  parents
41
41
  }) => {
42
- return /*#__PURE__*/React.createElement(TextSection, {
42
+ return /*#__PURE__*/React.createElement(Section, {
43
43
  parents: parents,
44
- api: api
44
+ api: api,
45
+ testId: "text-section"
45
46
  }, children);
46
47
  }
48
+ }, {
49
+ type: INSERT_BLOCK_SECTION.type,
50
+ key: INSERT_BLOCK_SECTION.key,
51
+ parents: [{
52
+ type: 'toolbar',
53
+ key: TOOLBARS.PRIMARY_TOOLBAR,
54
+ rank: TOOLBAR_RANK[INSERT_BLOCK_SECTION.key]
55
+ }],
56
+ component: ({
57
+ children,
58
+ parents
59
+ }) => /*#__PURE__*/React.createElement(Section, {
60
+ testId: "insert-block-section",
61
+ parents: parents,
62
+ api: api,
63
+ showSeparatorInFullPagePrimaryToolbar: true,
64
+ isSharedSection: false
65
+ }, children)
66
+ }, {
67
+ type: LINKING_SECTION.type,
68
+ key: LINKING_SECTION.key,
69
+ parents: [{
70
+ type: 'toolbar',
71
+ key: TOOLBARS.INLINE_TEXT_TOOLBAR,
72
+ rank: TOOLBAR_RANK[LINKING_SECTION.key]
73
+ }, {
74
+ type: 'toolbar',
75
+ key: TOOLBARS.PRIMARY_TOOLBAR,
76
+ rank: TOOLBAR_RANK[LINKING_SECTION.key]
77
+ }],
78
+ component: ({
79
+ children,
80
+ parents
81
+ }) => /*#__PURE__*/React.createElement(Section, {
82
+ testId: "link-section",
83
+ parents: parents,
84
+ api: api,
85
+ showSeparatorInFullPagePrimaryToolbar: true
86
+ }, children)
47
87
  }, {
48
88
  type: OVERFLOW_SECTION.type,
49
89
  key: OVERFLOW_SECTION.key,
@@ -73,5 +113,13 @@ export const getToolbarComponents = api => {
73
113
  }) => {
74
114
  return /*#__PURE__*/React.createElement(OverflowMenu, null, children);
75
115
  }
116
+ }, {
117
+ type: PIN_SECTION.type,
118
+ key: PIN_SECTION.key,
119
+ parents: [{
120
+ type: 'toolbar',
121
+ key: TOOLBARS.PRIMARY_TOOLBAR,
122
+ rank: TOOLBAR_RANK[PIN_SECTION.key]
123
+ }]
76
124
  }];
77
125
  };
@@ -0,0 +1,7 @@
1
+ export const isEventInContainer = (event, containerSelector) => {
2
+ const target = event.target instanceof Element ? event.target : null;
3
+ if (!target) {
4
+ return false;
5
+ }
6
+ return !!target.closest(containerSelector);
7
+ };
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export var editorToolbarPluginKey = new PluginKey('editorToolbarPluginKey');
@@ -1,7 +1,15 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1
4
  import React from 'react';
5
+ import { bind } from 'bind-event-listener';
6
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
7
  import { createComponentRegistry } from '@atlaskit/editor-toolbar-model';
8
+ import { editorToolbarPluginKey } from './pm-plugins/plugin-key';
9
+ import { DEFAULT_POPUP_SELECTORS } from './ui/consts';
3
10
  import { SelectionToolbar } from './ui/SelectionToolbar';
4
11
  import { getToolbarComponents } from './ui/toolbar-components';
12
+ import { isEventInContainer } from './ui/utils/toolbar';
5
13
  export var toolbarPlugin = function toolbarPlugin(_ref) {
6
14
  var api = _ref.api,
7
15
  _ref$config = _ref.config,
@@ -21,6 +29,81 @@ export var toolbarPlugin = function toolbarPlugin(_ref) {
21
29
  return registry.components;
22
30
  }
23
31
  },
32
+ getSharedState: function getSharedState(editorState) {
33
+ if (!editorState) {
34
+ return undefined;
35
+ }
36
+ return editorToolbarPluginKey.getState(editorState);
37
+ },
38
+ pmPlugins: function pmPlugins() {
39
+ return [{
40
+ name: 'editor-toolbar-selection',
41
+ plugin: function plugin() {
42
+ return new SafePlugin({
43
+ key: editorToolbarPluginKey,
44
+ state: {
45
+ init: function init() {
46
+ return {
47
+ shouldShowToolbar: false
48
+ };
49
+ },
50
+ apply: function apply(tr, pluginState) {
51
+ var meta = tr.getMeta(editorToolbarPluginKey);
52
+ var newPluginState = pluginState;
53
+ if (meta) {
54
+ return _objectSpread(_objectSpread({}, newPluginState), meta);
55
+ }
56
+ return newPluginState;
57
+ }
58
+ },
59
+ view: function view(_view) {
60
+ var unbind = bind(_view.root, {
61
+ type: 'mouseup',
62
+ listener: function listener(ev) {
63
+ var _api$editorViewMode;
64
+ var event = ev;
65
+ var isInToolbar = isEventInContainer(event, DEFAULT_POPUP_SELECTORS.toolbarContainer);
66
+ var isInPortal = isEventInContainer(event, DEFAULT_POPUP_SELECTORS.portal);
67
+
68
+ // We only want to set selectionStable to true if the editor has focus
69
+ // to prevent the toolbar from showing when the editor is blurred
70
+ // due to a click outside the editor.
71
+ var editorViewModePlugin = api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.sharedState.currentState();
72
+ var isViewModeEnabled = (editorViewModePlugin === null || editorViewModePlugin === void 0 ? void 0 : editorViewModePlugin.mode) === 'view';
73
+ _view.dispatch(_view.state.tr.setMeta(editorToolbarPluginKey, {
74
+ shouldShowToolbar: !isViewModeEnabled ? _view.hasFocus() || isInToolbar || isInPortal : true
75
+ }));
76
+ }
77
+ });
78
+ var unbindEditorViewFocus = bind(_view.dom, {
79
+ type: 'focus',
80
+ listener: function listener() {
81
+ _view.dispatch(_view.state.tr.setMeta(editorToolbarPluginKey, {
82
+ shouldShowToolbar: true
83
+ }));
84
+ }
85
+ });
86
+ return {
87
+ destroy: function destroy() {
88
+ unbind();
89
+ unbindEditorViewFocus();
90
+ }
91
+ };
92
+ },
93
+ props: {
94
+ handleDOMEvents: {
95
+ mousedown: function mousedown(view) {
96
+ view.dispatch(view.state.tr.setMeta(editorToolbarPluginKey, {
97
+ shouldShowToolbar: false
98
+ }));
99
+ return false;
100
+ }
101
+ }
102
+ }
103
+ });
104
+ }
105
+ }];
106
+ },
24
107
  contentComponent: !disableSelectionToolbar ? function (_ref2) {
25
108
  var editorView = _ref2.editorView,
26
109
  popupsMountPoint = _ref2.popupsMountPoint;
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { TOOLBARS } from '@atlaskit/editor-common/toolbar';
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 } from '@atlaskit/editor-toolbar';
5
- var shouldShowTextSection = function shouldShowTextSection(editMode, toolbar, toolbarDocking) {
5
+ var shouldShowSection = function shouldShowSection(editMode, toolbar, toolbarDocking) {
6
6
  if (editMode === 'view') {
7
7
  return false;
8
8
  }
@@ -14,19 +14,27 @@ var shouldShowTextSection = function shouldShowTextSection(editMode, toolbar, to
14
14
  }
15
15
  return false;
16
16
  };
17
- export var TextSection = function TextSection(_ref) {
17
+ export var Section = function Section(_ref) {
18
18
  var children = _ref.children,
19
19
  parents = _ref.parents,
20
- api = _ref.api;
20
+ api = _ref.api,
21
+ testId = _ref.testId,
22
+ showSeparatorInFullPagePrimaryToolbar = _ref.showSeparatorInFullPagePrimaryToolbar,
23
+ _ref$isSharedSection = _ref.isSharedSection,
24
+ isSharedSection = _ref$isSharedSection === void 0 ? true : _ref$isSharedSection;
21
25
  var editMode = useSharedPluginStateSelector(api, 'editorViewMode.mode');
22
26
  var toolbarDocking = useSharedPluginStateSelector(api, 'userPreferences.preferences.toolbarDockingPosition');
23
27
  var toolbar = parents.find(function (parent) {
24
28
  return parent.type === 'toolbar';
25
29
  });
26
- if (!shouldShowTextSection(editMode, toolbar, toolbarDocking)) {
30
+ var _useEditorToolbar = useEditorToolbar(),
31
+ editorAppearance = _useEditorToolbar.editorAppearance;
32
+ if (isSharedSection && !shouldShowSection(editMode, toolbar, toolbarDocking)) {
27
33
  return null;
28
34
  }
35
+ var isFullPage = editorAppearance === 'full-page';
29
36
  return /*#__PURE__*/React.createElement(ToolbarSection, {
30
- testId: "text-section"
37
+ testId: testId,
38
+ hasSeparator: showSeparatorInFullPagePrimaryToolbar && isFullPage
31
39
  }, children);
32
40
  };
@@ -1,23 +1,33 @@
1
- import React from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import { isSSR } from '@atlaskit/editor-common/core-utils';
3
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
4
  import { EditorToolbarProvider, EditorToolbarUIProvider } from '@atlaskit/editor-common/toolbar';
4
5
  import { Popup } from '@atlaskit/editor-common/ui';
5
6
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
6
- import { calculateToolbarPositionTrackHead } from '@atlaskit/editor-common/utils';
7
+ import { calculateToolbarPositionTrackHead, calculateToolbarPositionOnCellSelection } from '@atlaskit/editor-common/utils';
7
8
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
8
9
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
9
10
  import { ToolbarSection, ToolbarButtonGroup, ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
10
11
  import { ToolbarModelRenderer } from '@atlaskit/editor-toolbar-model';
12
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
11
13
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
12
- import { TOOLBAR_LABEL } from '../consts';
14
+ import { SELECTION_TOOLBAR_LABEL } from '../consts';
13
15
  var isToolbarComponent = function isToolbarComponent(component) {
14
16
  return component.type === 'toolbar' && component.key === 'inline-text-toolbar';
15
17
  };
16
18
  export var SelectionToolbar = function SelectionToolbar(_ref) {
19
+ var _api$toolbar, _api$toolbar$getCompo;
17
20
  var api = _ref.api,
18
21
  editorView = _ref.editorView,
19
22
  mountPoint = _ref.mountPoint;
20
- var components = api === null || api === void 0 ? void 0 : api.toolbar.actions.getComponents();
23
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['toolbar'], function (state) {
24
+ var _state$toolbarState;
25
+ return {
26
+ shouldShowToolbar: (_state$toolbarState = state.toolbarState) === null || _state$toolbarState === void 0 ? void 0 : _state$toolbarState.shouldShowToolbar
27
+ };
28
+ }),
29
+ shouldShowToolbar = _useSharedPluginState.shouldShowToolbar;
30
+ var components = api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 || (_api$toolbar = _api$toolbar.actions) === null || _api$toolbar === void 0 || (_api$toolbar$getCompo = _api$toolbar.getComponents) === null || _api$toolbar$getCompo === void 0 ? void 0 : _api$toolbar$getCompo.call(_api$toolbar);
21
31
  var toolbar = components === null || components === void 0 ? void 0 : components.find(function (component) {
22
32
  return isToolbarComponent(component);
23
33
  });
@@ -29,18 +39,28 @@ export var SelectionToolbar = function SelectionToolbar(_ref) {
29
39
  var selection = useSharedPluginStateSelector(api, 'selection.selection');
30
40
  var isTextSelection = !editorView.state.selection.empty && editorView.state.selection instanceof TextSelection;
31
41
  var isCellSelection = !editorView.state.selection.empty && '$anchorCell' in editorView.state.selection;
42
+ var onPositionCalculated = useCallback(function (position) {
43
+ var toolbarTitle = SELECTION_TOOLBAR_LABEL;
44
+
45
+ // Show special position on cell selection only when editor controls experiment is enabled
46
+ var isEditorControlsEnabled = expValEquals('platform_editor_controls', 'cohort', 'variant1');
47
+ var isCellSelection = ('$anchorCell' in editorView.state.selection);
48
+ if (isCellSelection && isEditorControlsEnabled) {
49
+ return calculateToolbarPositionOnCellSelection(toolbarTitle)(editorView, position);
50
+ }
51
+ var calc = calculateToolbarPositionTrackHead;
52
+ return calc(toolbarTitle)(editorView, position);
53
+ }, [editorView]);
32
54
  if (!components || !toolbar) {
33
55
  return null;
34
56
  }
35
- if (!(isTextSelection || isCellSelection) || currentUserIntent === 'dragging' || currentUserIntent === 'blockMenuOpen' && expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true) || isSSR()) {
57
+ if (!(isTextSelection || isCellSelection) || currentUserIntent === 'dragging' || !shouldShowToolbar || currentUserIntent === 'blockMenuOpen' && expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true) || isSSR()) {
36
58
  return null;
37
59
  }
38
60
  return /*#__PURE__*/React.createElement(Popup, {
39
61
  offset: [0, 10],
40
62
  target: getDomRefFromSelection(editorView),
41
- onPositionCalculated: function onPositionCalculated(position) {
42
- return calculateToolbarPositionTrackHead(TOOLBAR_LABEL)(editorView, position);
43
- },
63
+ onPositionCalculated: onPositionCalculated,
44
64
  mountTo: mountPoint
45
65
  }, /*#__PURE__*/React.createElement(EditorToolbarProvider, {
46
66
  editorView: editorView
@@ -1 +1,5 @@
1
- export var TOOLBAR_LABEL = 'Editor Toolbar';
1
+ export var SELECTION_TOOLBAR_LABEL = 'Selection toolbar';
2
+ export var DEFAULT_POPUP_SELECTORS = {
3
+ toolbarContainer: '[role="toolbar"]',
4
+ portal: '.atlaskit-portal'
5
+ };
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import { OVERFLOW_GROUP, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_SECTION, OVERFLOW_SECTION_RANK, TEXT_SECTION, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
2
+ import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_SECTION, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_SECTION, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
3
3
  import { PrimaryToolbar, Toolbar } from '@atlaskit/editor-toolbar';
4
- import { TOOLBAR_LABEL } from './consts';
4
+ import { SELECTION_TOOLBAR_LABEL } from './consts';
5
5
  import { OverflowMenu } from './OverflowMenu';
6
- import { TextSection } from './TextSection';
6
+ import { Section } from './Section';
7
7
  export var getToolbarComponents = function getToolbarComponents(api) {
8
8
  return [{
9
9
  type: 'toolbar',
@@ -11,7 +11,7 @@ export var getToolbarComponents = function getToolbarComponents(api) {
11
11
  component: function component(_ref) {
12
12
  var children = _ref.children;
13
13
  return /*#__PURE__*/React.createElement(Toolbar, {
14
- label: TOOLBAR_LABEL
14
+ label: SELECTION_TOOLBAR_LABEL
15
15
  }, children);
16
16
  }
17
17
  }, {
@@ -20,7 +20,7 @@ export var getToolbarComponents = function getToolbarComponents(api) {
20
20
  component: function component(_ref2) {
21
21
  var children = _ref2.children;
22
22
  return /*#__PURE__*/React.createElement(PrimaryToolbar, {
23
- label: "Primary Toolbar"
23
+ label: 'Primary Toolbar'
24
24
  }, children);
25
25
  }
26
26
  }, {
@@ -38,9 +38,51 @@ export var getToolbarComponents = function getToolbarComponents(api) {
38
38
  component: function component(_ref3) {
39
39
  var children = _ref3.children,
40
40
  parents = _ref3.parents;
41
- return /*#__PURE__*/React.createElement(TextSection, {
41
+ return /*#__PURE__*/React.createElement(Section, {
42
42
  parents: parents,
43
- api: api
43
+ api: api,
44
+ testId: "text-section"
45
+ }, children);
46
+ }
47
+ }, {
48
+ type: INSERT_BLOCK_SECTION.type,
49
+ key: INSERT_BLOCK_SECTION.key,
50
+ parents: [{
51
+ type: 'toolbar',
52
+ key: TOOLBARS.PRIMARY_TOOLBAR,
53
+ rank: TOOLBAR_RANK[INSERT_BLOCK_SECTION.key]
54
+ }],
55
+ component: function component(_ref4) {
56
+ var children = _ref4.children,
57
+ parents = _ref4.parents;
58
+ return /*#__PURE__*/React.createElement(Section, {
59
+ testId: "insert-block-section",
60
+ parents: parents,
61
+ api: api,
62
+ showSeparatorInFullPagePrimaryToolbar: true,
63
+ isSharedSection: false
64
+ }, children);
65
+ }
66
+ }, {
67
+ type: LINKING_SECTION.type,
68
+ key: LINKING_SECTION.key,
69
+ parents: [{
70
+ type: 'toolbar',
71
+ key: TOOLBARS.INLINE_TEXT_TOOLBAR,
72
+ rank: TOOLBAR_RANK[LINKING_SECTION.key]
73
+ }, {
74
+ type: 'toolbar',
75
+ key: TOOLBARS.PRIMARY_TOOLBAR,
76
+ rank: TOOLBAR_RANK[LINKING_SECTION.key]
77
+ }],
78
+ component: function component(_ref5) {
79
+ var children = _ref5.children,
80
+ parents = _ref5.parents;
81
+ return /*#__PURE__*/React.createElement(Section, {
82
+ testId: "link-section",
83
+ parents: parents,
84
+ api: api,
85
+ showSeparatorInFullPagePrimaryToolbar: true
44
86
  }, children);
45
87
  }
46
88
  }, {
@@ -67,9 +109,17 @@ export var getToolbarComponents = function getToolbarComponents(api) {
67
109
  key: OVERFLOW_GROUP.key,
68
110
  rank: OVERFLOW_GROUP_RANK[OVERFLOW_MENU.key]
69
111
  }],
70
- component: function component(_ref4) {
71
- var children = _ref4.children;
112
+ component: function component(_ref6) {
113
+ var children = _ref6.children;
72
114
  return /*#__PURE__*/React.createElement(OverflowMenu, null, children);
73
115
  }
116
+ }, {
117
+ type: PIN_SECTION.type,
118
+ key: PIN_SECTION.key,
119
+ parents: [{
120
+ type: 'toolbar',
121
+ key: TOOLBARS.PRIMARY_TOOLBAR,
122
+ rank: TOOLBAR_RANK[PIN_SECTION.key]
123
+ }]
74
124
  }];
75
125
  };
@@ -0,0 +1,7 @@
1
+ export var isEventInContainer = function isEventInContainer(event, containerSelector) {
2
+ var target = event.target instanceof Element ? event.target : null;
3
+ if (!target) {
4
+ return false;
5
+ }
6
+ return !!target.closest(containerSelector);
7
+ };
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const editorToolbarPluginKey: PluginKey<any>;
@@ -1,2 +1,5 @@
1
1
  import type { ToolbarPlugin } from './toolbarPluginType';
2
+ export type EditorToolbarPluginState = {
3
+ shouldShowToolbar: boolean;
4
+ };
2
5
  export declare const toolbarPlugin: ToolbarPlugin;
@@ -8,6 +8,9 @@ import type { RegisterComponent } from '@atlaskit/editor-toolbar-model';
8
8
  import type { ToolbarPluginOptions } from './types';
9
9
  export type ToolbarPlugin = NextEditorPlugin<'toolbar', {
10
10
  pluginConfiguration?: ToolbarPluginOptions;
11
+ sharedState: {
12
+ shouldShowToolbar: boolean;
13
+ };
11
14
  dependencies: [
12
15
  OptionalPlugin<UserIntentPlugin>,
13
16
  OptionalPlugin<SelectionPlugin>,
@@ -2,10 +2,13 @@ import React from 'react';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import type { ToolbarComponentTypes } from '@atlaskit/editor-toolbar-model';
4
4
  import type { ToolbarPlugin } from '../toolbarPluginType';
5
- type TextSectionProps = {
5
+ type SectionProps = {
6
6
  children: React.ReactNode;
7
7
  parents: ToolbarComponentTypes;
8
8
  api?: ExtractInjectionAPI<ToolbarPlugin>;
9
+ testId?: string;
10
+ showSeparatorInFullPagePrimaryToolbar?: boolean;
11
+ isSharedSection?: boolean;
9
12
  };
10
- export declare const TextSection: ({ children, parents, api }: TextSectionProps) => React.JSX.Element | null;
13
+ export declare const Section: ({ children, parents, api, testId, showSeparatorInFullPagePrimaryToolbar, isSharedSection, }: SectionProps) => React.JSX.Element | null;
11
14
  export {};
@@ -1 +1,5 @@
1
- export declare const TOOLBAR_LABEL = "Editor Toolbar";
1
+ export declare const SELECTION_TOOLBAR_LABEL = "Selection toolbar";
2
+ export declare const DEFAULT_POPUP_SELECTORS: {
3
+ readonly toolbarContainer: "[role=\"toolbar\"]";
4
+ readonly portal: ".atlaskit-portal";
5
+ };
@@ -0,0 +1 @@
1
+ export declare const isEventInContainer: (event: Event, containerSelector: string) => boolean;
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const editorToolbarPluginKey: PluginKey<any>;
@@ -1,2 +1,5 @@
1
1
  import type { ToolbarPlugin } from './toolbarPluginType';
2
+ export type EditorToolbarPluginState = {
3
+ shouldShowToolbar: boolean;
4
+ };
2
5
  export declare const toolbarPlugin: ToolbarPlugin;
@@ -8,6 +8,9 @@ import type { RegisterComponent } from '@atlaskit/editor-toolbar-model';
8
8
  import type { ToolbarPluginOptions } from './types';
9
9
  export type ToolbarPlugin = NextEditorPlugin<'toolbar', {
10
10
  pluginConfiguration?: ToolbarPluginOptions;
11
+ sharedState: {
12
+ shouldShowToolbar: boolean;
13
+ };
11
14
  dependencies: [
12
15
  OptionalPlugin<UserIntentPlugin>,
13
16
  OptionalPlugin<SelectionPlugin>,
@@ -2,10 +2,13 @@ import React from 'react';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import type { ToolbarComponentTypes } from '@atlaskit/editor-toolbar-model';
4
4
  import type { ToolbarPlugin } from '../toolbarPluginType';
5
- type TextSectionProps = {
5
+ type SectionProps = {
6
6
  children: React.ReactNode;
7
7
  parents: ToolbarComponentTypes;
8
8
  api?: ExtractInjectionAPI<ToolbarPlugin>;
9
+ testId?: string;
10
+ showSeparatorInFullPagePrimaryToolbar?: boolean;
11
+ isSharedSection?: boolean;
9
12
  };
10
- export declare const TextSection: ({ children, parents, api }: TextSectionProps) => React.JSX.Element | null;
13
+ export declare const Section: ({ children, parents, api, testId, showSeparatorInFullPagePrimaryToolbar, isSharedSection, }: SectionProps) => React.JSX.Element | null;
11
14
  export {};
@@ -1 +1,5 @@
1
- export declare const TOOLBAR_LABEL = "Editor Toolbar";
1
+ export declare const SELECTION_TOOLBAR_LABEL = "Selection toolbar";
2
+ export declare const DEFAULT_POPUP_SELECTORS: {
3
+ readonly toolbarContainer: "[role=\"toolbar\"]";
4
+ readonly portal: ".atlaskit-portal";
5
+ };
@@ -0,0 +1 @@
1
+ export declare const isEventInContainer: (event: Event, containerSelector: string) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-toolbar",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Toolbar plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,18 +33,19 @@
33
33
  "dependencies": {
34
34
  "@atlaskit/editor-plugin-connectivity": "^3.1.0",
35
35
  "@atlaskit/editor-plugin-editor-viewmode": "^5.0.0",
36
- "@atlaskit/editor-plugin-selection": "^3.1.0",
36
+ "@atlaskit/editor-plugin-selection": "^3.2.0",
37
37
  "@atlaskit/editor-plugin-user-intent": "^1.1.0",
38
38
  "@atlaskit/editor-plugin-user-preferences": "^1.2.0",
39
39
  "@atlaskit/editor-prosemirror": "7.0.0",
40
40
  "@atlaskit/editor-toolbar": "^0.3.0",
41
41
  "@atlaskit/editor-toolbar-model": "^0.1.0",
42
- "@atlaskit/tmp-editor-statsig": "^11.3.0",
42
+ "@atlaskit/tmp-editor-statsig": "^11.5.0",
43
43
  "@babel/runtime": "^7.0.0",
44
+ "bind-event-listener": "^3.0.0",
44
45
  "react-intl-next": "npm:react-intl@^5.18.1"
45
46
  },
46
47
  "peerDependencies": {
47
- "@atlaskit/editor-common": "^107.26.0",
48
+ "@atlaskit/editor-common": "^107.28.0",
48
49
  "react": "^18.2.0"
49
50
  },
50
51
  "techstack": {