@atlaskit/editor-plugin-selection-extension 2.0.0 → 2.1.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 (42) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/pm-plugins/main.js +39 -0
  3. package/dist/cjs/selectionExtensionPlugin.js +69 -13
  4. package/dist/cjs/types/index.js +5 -0
  5. package/dist/cjs/ui/extension/SelectionExtensionComponentWrapper.js +32 -0
  6. package/dist/cjs/ui/getBoundingBoxFromSelection.js +35 -0
  7. package/dist/cjs/ui/toolbar/SelectionExtensionDropdownMenu.js +3 -2
  8. package/dist/cjs/ui/toolbar/SelectionExtensionDropdownMenuButton.js +1 -0
  9. package/dist/cjs/ui/toolbar/SelectionExtensionItems.js +1 -0
  10. package/dist/es2019/pm-plugins/main.js +31 -0
  11. package/dist/es2019/selectionExtensionPlugin.js +59 -10
  12. package/dist/es2019/types/index.js +1 -0
  13. package/dist/es2019/ui/extension/SelectionExtensionComponentWrapper.js +25 -0
  14. package/dist/es2019/ui/getBoundingBoxFromSelection.js +29 -0
  15. package/dist/es2019/ui/toolbar/SelectionExtensionDropdownMenu.js +1 -2
  16. package/dist/es2019/ui/toolbar/SelectionExtensionDropdownMenuButton.js +1 -0
  17. package/dist/es2019/ui/toolbar/SelectionExtensionItems.js +1 -0
  18. package/dist/esm/pm-plugins/main.js +32 -0
  19. package/dist/esm/selectionExtensionPlugin.js +69 -13
  20. package/dist/esm/types/index.js +1 -0
  21. package/dist/esm/ui/extension/SelectionExtensionComponentWrapper.js +23 -0
  22. package/dist/esm/ui/getBoundingBoxFromSelection.js +29 -0
  23. package/dist/esm/ui/toolbar/SelectionExtensionDropdownMenu.js +3 -2
  24. package/dist/esm/ui/toolbar/SelectionExtensionDropdownMenuButton.js +1 -0
  25. package/dist/esm/ui/toolbar/SelectionExtensionItems.js +1 -0
  26. package/dist/types/index.d.ts +1 -0
  27. package/dist/types/pm-plugins/main.d.ts +7 -0
  28. package/dist/types/selectionExtensionPluginType.d.ts +11 -23
  29. package/dist/types/types/index.d.ts +51 -0
  30. package/dist/types/ui/extension/SelectionExtensionComponentWrapper.d.ts +10 -0
  31. package/dist/types/ui/getBoundingBoxFromSelection.d.ts +11 -0
  32. package/dist/types/ui/toolbar/SelectionExtensionDropdownMenu.d.ts +1 -1
  33. package/dist/types/ui/toolbar/SelectionExtensionItems.d.ts +2 -1
  34. package/dist/types-ts4.5/index.d.ts +1 -0
  35. package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
  36. package/dist/types-ts4.5/selectionExtensionPluginType.d.ts +11 -23
  37. package/dist/types-ts4.5/types/index.d.ts +51 -0
  38. package/dist/types-ts4.5/ui/extension/SelectionExtensionComponentWrapper.d.ts +10 -0
  39. package/dist/types-ts4.5/ui/getBoundingBoxFromSelection.d.ts +11 -0
  40. package/dist/types-ts4.5/ui/toolbar/SelectionExtensionDropdownMenu.d.ts +1 -1
  41. package/dist/types-ts4.5/ui/toolbar/SelectionExtensionItems.d.ts +2 -1
  42. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/editor-plugin-selection-extension
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#115116](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/115116)
8
+ [`344eb36211daa`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/344eb36211daa) -
9
+ [ux] ED-26394 support component rendering in editor selection plugin
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
3
15
  ## 2.0.0
4
16
 
5
17
  ### Major Changes
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.selectionExtensionPluginKey = exports.createPlugin = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
10
+ var _state = require("@atlaskit/editor-prosemirror/state");
11
+ 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; }
12
+ 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; }
13
+ var selectionExtensionPluginKey = exports.selectionExtensionPluginKey = new _state.PluginKey('selectionExtensionPlugin');
14
+ var createPlugin = exports.createPlugin = function createPlugin() {
15
+ return new _safePlugin.SafePlugin({
16
+ key: selectionExtensionPluginKey,
17
+ state: {
18
+ init: function init() {
19
+ return {
20
+ activeExtension: undefined
21
+ };
22
+ },
23
+ apply: function apply(tr, pluginState) {
24
+ var meta = tr.getMeta(selectionExtensionPluginKey);
25
+ switch (meta === null || meta === void 0 ? void 0 : meta.type) {
26
+ case 'set-active-extension':
27
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
28
+ activeExtension: meta.extension
29
+ });
30
+ case 'clear-active-extension':
31
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
32
+ activeExtension: undefined
33
+ });
34
+ }
35
+ return pluginState;
36
+ }
37
+ }
38
+ });
39
+ };
@@ -6,12 +6,47 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.selectionExtensionPlugin = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
+ var _main = require("./pm-plugins/main");
10
+ var _SelectionExtensionComponentWrapper = require("./ui/extension/SelectionExtensionComponentWrapper");
11
+ var _getBoundingBoxFromSelection = require("./ui/getBoundingBoxFromSelection");
9
12
  var _SelectionExtensionItems = require("./ui/toolbar/SelectionExtensionItems");
10
13
  var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
11
14
  var api = _ref.api,
12
15
  config = _ref.config;
13
16
  return {
14
17
  name: 'selectionExtension',
18
+ getSharedState: function getSharedState(editorState) {
19
+ if (!editorState) {
20
+ return null;
21
+ }
22
+ return _main.selectionExtensionPluginKey.getState(editorState) || null;
23
+ },
24
+ commands: {
25
+ setActiveExtension: function setActiveExtension(extension) {
26
+ return function (_ref2) {
27
+ var tr = _ref2.tr;
28
+ return tr.setMeta(_main.selectionExtensionPluginKey, {
29
+ type: 'set-active-extension',
30
+ extension: extension
31
+ });
32
+ };
33
+ },
34
+ clearActiveExtension: function clearActiveExtension() {
35
+ return function (_ref3) {
36
+ var tr = _ref3.tr;
37
+ return tr.setMeta(_main.selectionExtensionPluginKey, {
38
+ type: 'clear-active-extension'
39
+ });
40
+ };
41
+ }
42
+ },
43
+ contentComponent: function contentComponent(_ref4) {
44
+ var editorView = _ref4.editorView;
45
+ return /*#__PURE__*/_react.default.createElement(_SelectionExtensionComponentWrapper.SelectionExtensionComponentWrapper, {
46
+ editorView: editorView,
47
+ api: api
48
+ });
49
+ },
15
50
  pluginsOptions: {
16
51
  selectionToolbar: function selectionToolbar(state) {
17
52
  var _api$editorViewMode;
@@ -52,20 +87,33 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
52
87
  return;
53
88
  }
54
89
  }
55
- var handleOnExtensionClick = function handleOnExtensionClick(extension) {
56
- var selection = state.selection;
57
- var from = selection.from,
58
- to = selection.to;
59
- var text = state.doc.textBetween(from, to, '\n');
90
+ var handleOnExtensionClick = function handleOnExtensionClick(view) {
91
+ return function (extension) {
92
+ var currentSelection = state.selection;
93
+ var from = currentSelection.from,
94
+ to = currentSelection.to;
95
+ var text = state.doc.textBetween(from, to, '\n');
96
+ var coords = (0, _getBoundingBoxFromSelection.getBoundingBoxFromSelection)(view, from, to);
97
+ var selection = {
98
+ text: text,
99
+ selection: {
100
+ from: from,
101
+ to: to
102
+ },
103
+ coords: coords
104
+ };
60
105
 
61
- // TODO: Probably some validator logic here
62
- extension.onClick({
63
- text: text,
64
- selection: {
65
- from: from,
66
- to: to
106
+ // Render component here
107
+ if (extension.component) {
108
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.setActiveExtension({
109
+ extension: extension,
110
+ selection: selection
111
+ }));
67
112
  }
68
- });
113
+ if (extension.onClick) {
114
+ extension.onClick(selection);
115
+ }
116
+ };
69
117
  };
70
118
 
71
119
  /**
@@ -84,7 +132,7 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
84
132
  editorView: view,
85
133
  editorAnalyticsAPI: api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions,
86
134
  extensions: extensions,
87
- onExtensionClick: handleOnExtensionClick
135
+ onExtensionClick: handleOnExtensionClick(view)
88
136
  });
89
137
  },
90
138
  fallback: []
@@ -95,6 +143,14 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
95
143
  rank: -6
96
144
  };
97
145
  }
146
+ },
147
+ pmPlugins: function pmPlugins() {
148
+ return [{
149
+ name: 'selectionExtension',
150
+ plugin: function plugin() {
151
+ return (0, _main.createPlugin)();
152
+ }
153
+ }];
98
154
  }
99
155
  };
100
156
  };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.SelectionExtensionComponentWrapper = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _hooks = require("@atlaskit/editor-common/hooks");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ var SelectionExtensionComponentWrapper = exports.SelectionExtensionComponentWrapper = function SelectionExtensionComponentWrapper(_ref) {
13
+ var _selectionExtensionSt;
14
+ var api = _ref.api;
15
+ var _useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['selectionExtension', 'editorViewMode']),
16
+ selectionExtensionState = _useSharedPluginState.selectionExtensionState,
17
+ editorViewModeState = _useSharedPluginState.editorViewModeState;
18
+ var handleOnClose = (0, _react.useCallback)(function () {
19
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.clearActiveExtension());
20
+ }, [api]);
21
+ (0, _react.useEffect)(function () {
22
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.clearActiveExtension());
23
+ }, [editorViewModeState, api]);
24
+ if (!(selectionExtensionState !== null && selectionExtensionState !== void 0 && (_selectionExtensionSt = selectionExtensionState.activeExtension) !== null && _selectionExtensionSt !== void 0 && _selectionExtensionSt.extension.component)) {
25
+ return null;
26
+ }
27
+ var ExtensionComponent = selectionExtensionState.activeExtension.extension.component;
28
+ return /*#__PURE__*/_react.default.createElement(ExtensionComponent, {
29
+ closeExtension: handleOnClose,
30
+ selection: selectionExtensionState.activeExtension.selection
31
+ });
32
+ };
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getBoundingBoxFromSelection = void 0;
7
+ /**
8
+ * Calculates the bounding box coordinates of a text selection within an editor view.
9
+ *
10
+ * @param view - The editor view instance.
11
+ * @param from - The starting position of the selection.
12
+ * @param to - The ending position of the selection.
13
+ * @returns An object containing the top, left, bottom, and right coordinates of the bounding box.
14
+ */
15
+ var getBoundingBoxFromSelection = exports.getBoundingBoxFromSelection = function getBoundingBoxFromSelection(view, from, to) {
16
+ var top = Infinity,
17
+ left = Infinity,
18
+ bottom = -Infinity,
19
+ right = -Infinity;
20
+
21
+ // initial version
22
+ for (var pos = from; pos <= to; pos++) {
23
+ var coords = view.coordsAtPos(pos);
24
+ top = Math.min(top, coords.top);
25
+ left = Math.min(left, coords.left);
26
+ bottom = Math.max(bottom, coords.bottom);
27
+ right = Math.max(right, coords.right);
28
+ }
29
+ return {
30
+ top: top,
31
+ left: left,
32
+ bottom: bottom,
33
+ right: right
34
+ };
35
+ };
@@ -31,9 +31,10 @@ var SelectionExtensionDropdownMenuComponent = /*#__PURE__*/_react.default.memo(f
31
31
  onItemActivated: onItemActivated,
32
32
  "data-testid": "selection-extension-dropdown-menu"
33
33
  }, /*#__PURE__*/_react.default.createElement(_SelectionExtensionDropdownMenuButton.SelectionExtensionDropdownMenuButton, {
34
- "data-testid": "selection-extension-dropdown-button",
35
34
  onClick: function onClick() {
36
- return setIsMenuOpen(!isMenuOpen);
35
+ return setIsMenuOpen(function (prevIsMenuOpen) {
36
+ return !prevIsMenuOpen;
37
+ });
37
38
  }
38
39
  }));
39
40
  });
@@ -12,6 +12,7 @@ var _apps = _interopRequireDefault(require("@atlaskit/icon/core/apps"));
12
12
  var SelectionExtensionDropdownMenuButtonComponent = function SelectionExtensionDropdownMenuButtonComponent(_ref) {
13
13
  var onClick = _ref.onClick;
14
14
  return /*#__PURE__*/_react.default.createElement(_uiMenu.ToolbarButton, {
15
+ testId: "selection-extension-dropdown-button",
15
16
  onClick: onClick
16
17
  }, /*#__PURE__*/_react.default.createElement(_apps.default, {
17
18
  label: "selection extension dropdown"
@@ -21,6 +21,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
21
21
  var transformExtensionsToItems = function transformExtensionsToItems(extensions) {
22
22
  var extensionToItems = extensions.map(function (extension) {
23
23
  return {
24
+ key: extension.id,
24
25
  content: extension.name,
25
26
  value: {
26
27
  name: extension.id
@@ -0,0 +1,31 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ export const selectionExtensionPluginKey = new PluginKey('selectionExtensionPlugin');
4
+ export const createPlugin = () => {
5
+ return new SafePlugin({
6
+ key: selectionExtensionPluginKey,
7
+ state: {
8
+ init: () => {
9
+ return {
10
+ activeExtension: undefined
11
+ };
12
+ },
13
+ apply: (tr, pluginState) => {
14
+ const meta = tr.getMeta(selectionExtensionPluginKey);
15
+ switch (meta === null || meta === void 0 ? void 0 : meta.type) {
16
+ case 'set-active-extension':
17
+ return {
18
+ ...pluginState,
19
+ activeExtension: meta.extension
20
+ };
21
+ case 'clear-active-extension':
22
+ return {
23
+ ...pluginState,
24
+ activeExtension: undefined
25
+ };
26
+ }
27
+ return pluginState;
28
+ }
29
+ }
30
+ });
31
+ };
@@ -1,4 +1,7 @@
1
1
  import React from 'react';
2
+ import { selectionExtensionPluginKey, createPlugin } from './pm-plugins/main';
3
+ import { SelectionExtensionComponentWrapper } from './ui/extension/SelectionExtensionComponentWrapper';
4
+ import { getBoundingBoxFromSelection } from './ui/getBoundingBoxFromSelection';
2
5
  import { SelectionExtensionItems } from './ui/toolbar/SelectionExtensionItems';
3
6
  export const selectionExtensionPlugin = ({
4
7
  api,
@@ -6,6 +9,37 @@ export const selectionExtensionPlugin = ({
6
9
  }) => {
7
10
  return {
8
11
  name: 'selectionExtension',
12
+ getSharedState(editorState) {
13
+ if (!editorState) {
14
+ return null;
15
+ }
16
+ return selectionExtensionPluginKey.getState(editorState) || null;
17
+ },
18
+ commands: {
19
+ setActiveExtension: extension => ({
20
+ tr
21
+ }) => {
22
+ return tr.setMeta(selectionExtensionPluginKey, {
23
+ type: 'set-active-extension',
24
+ extension
25
+ });
26
+ },
27
+ clearActiveExtension: () => ({
28
+ tr
29
+ }) => {
30
+ return tr.setMeta(selectionExtensionPluginKey, {
31
+ type: 'clear-active-extension'
32
+ });
33
+ }
34
+ },
35
+ contentComponent: ({
36
+ editorView
37
+ }) => {
38
+ return /*#__PURE__*/React.createElement(SelectionExtensionComponentWrapper, {
39
+ editorView: editorView,
40
+ api: api
41
+ });
42
+ },
9
43
  pluginsOptions: {
10
44
  selectionToolbar: state => {
11
45
  var _api$editorViewMode, _api$editorViewMode$s;
@@ -48,24 +82,35 @@ export const selectionExtensionPlugin = ({
48
82
  return;
49
83
  }
50
84
  }
51
- const handleOnExtensionClick = extension => {
85
+ const handleOnExtensionClick = view => extension => {
52
86
  const {
53
- selection
87
+ selection: currentSelection
54
88
  } = state;
55
89
  const {
56
90
  from,
57
91
  to
58
- } = selection;
92
+ } = currentSelection;
59
93
  const text = state.doc.textBetween(from, to, '\n');
60
-
61
- // TODO: Probably some validator logic here
62
- extension.onClick({
94
+ const coords = getBoundingBoxFromSelection(view, from, to);
95
+ const selection = {
63
96
  text,
64
97
  selection: {
65
98
  from,
66
99
  to
67
- }
68
- });
100
+ },
101
+ coords
102
+ };
103
+
104
+ // Render component here
105
+ if (extension.component) {
106
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.setActiveExtension({
107
+ extension,
108
+ selection
109
+ }));
110
+ }
111
+ if (extension.onClick) {
112
+ extension.onClick(selection);
113
+ }
69
114
  };
70
115
 
71
116
  /**
@@ -84,7 +129,7 @@ export const selectionExtensionPlugin = ({
84
129
  editorView: view,
85
130
  editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions,
86
131
  extensions: extensions,
87
- onExtensionClick: handleOnExtensionClick
132
+ onExtensionClick: handleOnExtensionClick(view)
88
133
  });
89
134
  },
90
135
  fallback: []
@@ -95,6 +140,10 @@ export const selectionExtensionPlugin = ({
95
140
  rank: -6
96
141
  };
97
142
  }
98
- }
143
+ },
144
+ pmPlugins: () => [{
145
+ name: 'selectionExtension',
146
+ plugin: () => createPlugin()
147
+ }]
99
148
  };
100
149
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import React, { useCallback, useEffect } from 'react';
2
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
3
+ export const SelectionExtensionComponentWrapper = ({
4
+ api
5
+ }) => {
6
+ var _selectionExtensionSt;
7
+ const {
8
+ selectionExtensionState,
9
+ editorViewModeState
10
+ } = useSharedPluginState(api, ['selectionExtension', 'editorViewMode']);
11
+ const handleOnClose = useCallback(() => {
12
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.clearActiveExtension());
13
+ }, [api]);
14
+ useEffect(() => {
15
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.clearActiveExtension());
16
+ }, [editorViewModeState, api]);
17
+ if (!(selectionExtensionState !== null && selectionExtensionState !== void 0 && (_selectionExtensionSt = selectionExtensionState.activeExtension) !== null && _selectionExtensionSt !== void 0 && _selectionExtensionSt.extension.component)) {
18
+ return null;
19
+ }
20
+ const ExtensionComponent = selectionExtensionState.activeExtension.extension.component;
21
+ return /*#__PURE__*/React.createElement(ExtensionComponent, {
22
+ closeExtension: handleOnClose,
23
+ selection: selectionExtensionState.activeExtension.selection
24
+ });
25
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Calculates the bounding box coordinates of a text selection within an editor view.
3
+ *
4
+ * @param view - The editor view instance.
5
+ * @param from - The starting position of the selection.
6
+ * @param to - The ending position of the selection.
7
+ * @returns An object containing the top, left, bottom, and right coordinates of the bounding box.
8
+ */
9
+ export const getBoundingBoxFromSelection = (view, from, to) => {
10
+ let top = Infinity,
11
+ left = Infinity,
12
+ bottom = -Infinity,
13
+ right = -Infinity;
14
+
15
+ // initial version
16
+ for (let pos = from; pos <= to; pos++) {
17
+ const coords = view.coordsAtPos(pos);
18
+ top = Math.min(top, coords.top);
19
+ left = Math.min(left, coords.left);
20
+ bottom = Math.max(bottom, coords.bottom);
21
+ right = Math.max(right, coords.right);
22
+ }
23
+ return {
24
+ top,
25
+ left,
26
+ bottom,
27
+ right
28
+ };
29
+ };
@@ -18,8 +18,7 @@ const SelectionExtensionDropdownMenuComponent = /*#__PURE__*/React.memo(({
18
18
  onItemActivated: onItemActivated,
19
19
  "data-testid": "selection-extension-dropdown-menu"
20
20
  }, /*#__PURE__*/React.createElement(SelectionExtensionDropdownMenuButton, {
21
- "data-testid": "selection-extension-dropdown-button",
22
- onClick: () => setIsMenuOpen(!isMenuOpen)
21
+ onClick: () => setIsMenuOpen(prevIsMenuOpen => !prevIsMenuOpen)
23
22
  }));
24
23
  });
25
24
  export const SelectionExtensionDropdownMenu = injectIntl(SelectionExtensionDropdownMenuComponent);
@@ -6,6 +6,7 @@ const SelectionExtensionDropdownMenuButtonComponent = ({
6
6
  onClick
7
7
  }) => {
8
8
  return /*#__PURE__*/React.createElement(ToolbarButton, {
9
+ testId: "selection-extension-dropdown-button",
9
10
  onClick: onClick
10
11
  }, /*#__PURE__*/React.createElement(AppsIcon, {
11
12
  label: "selection extension dropdown"
@@ -10,6 +10,7 @@ import { SelectionExtensionDropdownMenu } from './SelectionExtensionDropdownMenu
10
10
  const transformExtensionsToItems = extensions => {
11
11
  const extensionToItems = extensions.map(extension => {
12
12
  return {
13
+ key: extension.id,
13
14
  content: extension.name,
14
15
  value: {
15
16
  name: extension.id
@@ -0,0 +1,32 @@
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; }
4
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
+ export var selectionExtensionPluginKey = new PluginKey('selectionExtensionPlugin');
7
+ export var createPlugin = function createPlugin() {
8
+ return new SafePlugin({
9
+ key: selectionExtensionPluginKey,
10
+ state: {
11
+ init: function init() {
12
+ return {
13
+ activeExtension: undefined
14
+ };
15
+ },
16
+ apply: function apply(tr, pluginState) {
17
+ var meta = tr.getMeta(selectionExtensionPluginKey);
18
+ switch (meta === null || meta === void 0 ? void 0 : meta.type) {
19
+ case 'set-active-extension':
20
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
21
+ activeExtension: meta.extension
22
+ });
23
+ case 'clear-active-extension':
24
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
25
+ activeExtension: undefined
26
+ });
27
+ }
28
+ return pluginState;
29
+ }
30
+ }
31
+ });
32
+ };
@@ -1,10 +1,45 @@
1
1
  import React from 'react';
2
+ import { selectionExtensionPluginKey, createPlugin } from './pm-plugins/main';
3
+ import { SelectionExtensionComponentWrapper } from './ui/extension/SelectionExtensionComponentWrapper';
4
+ import { getBoundingBoxFromSelection } from './ui/getBoundingBoxFromSelection';
2
5
  import { SelectionExtensionItems } from './ui/toolbar/SelectionExtensionItems';
3
6
  export var selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
4
7
  var api = _ref.api,
5
8
  config = _ref.config;
6
9
  return {
7
10
  name: 'selectionExtension',
11
+ getSharedState: function getSharedState(editorState) {
12
+ if (!editorState) {
13
+ return null;
14
+ }
15
+ return selectionExtensionPluginKey.getState(editorState) || null;
16
+ },
17
+ commands: {
18
+ setActiveExtension: function setActiveExtension(extension) {
19
+ return function (_ref2) {
20
+ var tr = _ref2.tr;
21
+ return tr.setMeta(selectionExtensionPluginKey, {
22
+ type: 'set-active-extension',
23
+ extension: extension
24
+ });
25
+ };
26
+ },
27
+ clearActiveExtension: function clearActiveExtension() {
28
+ return function (_ref3) {
29
+ var tr = _ref3.tr;
30
+ return tr.setMeta(selectionExtensionPluginKey, {
31
+ type: 'clear-active-extension'
32
+ });
33
+ };
34
+ }
35
+ },
36
+ contentComponent: function contentComponent(_ref4) {
37
+ var editorView = _ref4.editorView;
38
+ return /*#__PURE__*/React.createElement(SelectionExtensionComponentWrapper, {
39
+ editorView: editorView,
40
+ api: api
41
+ });
42
+ },
8
43
  pluginsOptions: {
9
44
  selectionToolbar: function selectionToolbar(state) {
10
45
  var _api$editorViewMode;
@@ -45,20 +80,33 @@ export var selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
45
80
  return;
46
81
  }
47
82
  }
48
- var handleOnExtensionClick = function handleOnExtensionClick(extension) {
49
- var selection = state.selection;
50
- var from = selection.from,
51
- to = selection.to;
52
- var text = state.doc.textBetween(from, to, '\n');
83
+ var handleOnExtensionClick = function handleOnExtensionClick(view) {
84
+ return function (extension) {
85
+ var currentSelection = state.selection;
86
+ var from = currentSelection.from,
87
+ to = currentSelection.to;
88
+ var text = state.doc.textBetween(from, to, '\n');
89
+ var coords = getBoundingBoxFromSelection(view, from, to);
90
+ var selection = {
91
+ text: text,
92
+ selection: {
93
+ from: from,
94
+ to: to
95
+ },
96
+ coords: coords
97
+ };
53
98
 
54
- // TODO: Probably some validator logic here
55
- extension.onClick({
56
- text: text,
57
- selection: {
58
- from: from,
59
- to: to
99
+ // Render component here
100
+ if (extension.component) {
101
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.setActiveExtension({
102
+ extension: extension,
103
+ selection: selection
104
+ }));
60
105
  }
61
- });
106
+ if (extension.onClick) {
107
+ extension.onClick(selection);
108
+ }
109
+ };
62
110
  };
63
111
 
64
112
  /**
@@ -77,7 +125,7 @@ export var selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
77
125
  editorView: view,
78
126
  editorAnalyticsAPI: api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions,
79
127
  extensions: extensions,
80
- onExtensionClick: handleOnExtensionClick
128
+ onExtensionClick: handleOnExtensionClick(view)
81
129
  });
82
130
  },
83
131
  fallback: []
@@ -88,6 +136,14 @@ export var selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
88
136
  rank: -6
89
137
  };
90
138
  }
139
+ },
140
+ pmPlugins: function pmPlugins() {
141
+ return [{
142
+ name: 'selectionExtension',
143
+ plugin: function plugin() {
144
+ return createPlugin();
145
+ }
146
+ }];
91
147
  }
92
148
  };
93
149
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import React, { useCallback, useEffect } from 'react';
2
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
3
+ export var SelectionExtensionComponentWrapper = function SelectionExtensionComponentWrapper(_ref) {
4
+ var _selectionExtensionSt;
5
+ var api = _ref.api;
6
+ var _useSharedPluginState = useSharedPluginState(api, ['selectionExtension', 'editorViewMode']),
7
+ selectionExtensionState = _useSharedPluginState.selectionExtensionState,
8
+ editorViewModeState = _useSharedPluginState.editorViewModeState;
9
+ var handleOnClose = useCallback(function () {
10
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.clearActiveExtension());
11
+ }, [api]);
12
+ useEffect(function () {
13
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.selectionExtension.commands.clearActiveExtension());
14
+ }, [editorViewModeState, api]);
15
+ if (!(selectionExtensionState !== null && selectionExtensionState !== void 0 && (_selectionExtensionSt = selectionExtensionState.activeExtension) !== null && _selectionExtensionSt !== void 0 && _selectionExtensionSt.extension.component)) {
16
+ return null;
17
+ }
18
+ var ExtensionComponent = selectionExtensionState.activeExtension.extension.component;
19
+ return /*#__PURE__*/React.createElement(ExtensionComponent, {
20
+ closeExtension: handleOnClose,
21
+ selection: selectionExtensionState.activeExtension.selection
22
+ });
23
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Calculates the bounding box coordinates of a text selection within an editor view.
3
+ *
4
+ * @param view - The editor view instance.
5
+ * @param from - The starting position of the selection.
6
+ * @param to - The ending position of the selection.
7
+ * @returns An object containing the top, left, bottom, and right coordinates of the bounding box.
8
+ */
9
+ export var getBoundingBoxFromSelection = function getBoundingBoxFromSelection(view, from, to) {
10
+ var top = Infinity,
11
+ left = Infinity,
12
+ bottom = -Infinity,
13
+ right = -Infinity;
14
+
15
+ // initial version
16
+ for (var pos = from; pos <= to; pos++) {
17
+ var coords = view.coordsAtPos(pos);
18
+ top = Math.min(top, coords.top);
19
+ left = Math.min(left, coords.left);
20
+ bottom = Math.max(bottom, coords.bottom);
21
+ right = Math.max(right, coords.right);
22
+ }
23
+ return {
24
+ top: top,
25
+ left: left,
26
+ bottom: bottom,
27
+ right: right
28
+ };
29
+ };
@@ -21,9 +21,10 @@ var SelectionExtensionDropdownMenuComponent = /*#__PURE__*/React.memo(function (
21
21
  onItemActivated: onItemActivated,
22
22
  "data-testid": "selection-extension-dropdown-menu"
23
23
  }, /*#__PURE__*/React.createElement(SelectionExtensionDropdownMenuButton, {
24
- "data-testid": "selection-extension-dropdown-button",
25
24
  onClick: function onClick() {
26
- return setIsMenuOpen(!isMenuOpen);
25
+ return setIsMenuOpen(function (prevIsMenuOpen) {
26
+ return !prevIsMenuOpen;
27
+ });
27
28
  }
28
29
  }));
29
30
  });
@@ -5,6 +5,7 @@ import AppsIcon from '@atlaskit/icon/core/apps';
5
5
  var SelectionExtensionDropdownMenuButtonComponent = function SelectionExtensionDropdownMenuButtonComponent(_ref) {
6
6
  var onClick = _ref.onClick;
7
7
  return /*#__PURE__*/React.createElement(ToolbarButton, {
8
+ testId: "selection-extension-dropdown-button",
8
9
  onClick: onClick
9
10
  }, /*#__PURE__*/React.createElement(AppsIcon, {
10
11
  label: "selection extension dropdown"
@@ -13,6 +13,7 @@ import { SelectionExtensionDropdownMenu } from './SelectionExtensionDropdownMenu
13
13
  var transformExtensionsToItems = function transformExtensionsToItems(extensions) {
14
14
  var extensionToItems = extensions.map(function (extension) {
15
15
  return {
16
+ key: extension.id,
16
17
  content: extension.name,
17
18
  value: {
18
19
  name: extension.id
@@ -1,2 +1,3 @@
1
1
  export { selectionExtensionPlugin } from './selectionExtensionPlugin';
2
2
  export type { SelectionExtensionPlugin } from './selectionExtensionPluginType';
3
+ export type { SelectionExtensionComponentProps } from './types';
@@ -0,0 +1,7 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { SelectionExtensionPluginState } from '../types';
4
+ export declare const selectionExtensionPluginKey: PluginKey<SelectionExtensionPluginState>;
5
+ export declare const createPlugin: () => SafePlugin<SelectionExtensionPluginState | {
6
+ activeExtension: any;
7
+ }>;
@@ -1,27 +1,8 @@
1
- import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
- import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
1
+ import type { NextEditorPlugin, OptionalPlugin, EditorCommand } from '@atlaskit/editor-common/types';
3
2
  import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
4
- import type { ContentMode, EditorViewModePlugin, ViewMode } from '@atlaskit/editor-plugin-editor-viewmode';
3
+ import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
5
4
  import type { SelectionToolbarPlugin } from '@atlaskit/editor-plugin-selection-toolbar';
6
- export type MenuItemsType = Array<{
7
- items: MenuItem[];
8
- }>;
9
- export type SelectionExtensionContract = {
10
- name: string;
11
- onClick: (params: {
12
- text: string;
13
- selection: {
14
- from: number;
15
- to: number;
16
- };
17
- }) => void;
18
- validator?: (value: unknown) => boolean;
19
- };
20
- type SelectionExtensionModes = ViewMode | ContentMode;
21
- type SelectionExtensionPluginConfiguration = {
22
- pageModes?: SelectionExtensionModes | SelectionExtensionModes[];
23
- extensions?: SelectionExtensionContract[];
24
- };
5
+ import type { SelectionExtensionPluginConfiguration, SelectionExtensionPluginState, SelectionExtensionContract, SelectionExtensionSelectType } from './types';
25
6
  export type SelectionExtensionPlugin = NextEditorPlugin<'selectionExtension', {
26
7
  pluginConfiguration: SelectionExtensionPluginConfiguration | undefined;
27
8
  dependencies: [
@@ -29,5 +10,12 @@ export type SelectionExtensionPlugin = NextEditorPlugin<'selectionExtension', {
29
10
  OptionalPlugin<EditorViewModePlugin>,
30
11
  SelectionToolbarPlugin
31
12
  ];
13
+ sharedState: SelectionExtensionPluginState | null;
14
+ commands: {
15
+ setActiveExtension: ({ extension, selection, }: {
16
+ extension: SelectionExtensionContract;
17
+ selection: SelectionExtensionSelectType;
18
+ }) => EditorCommand;
19
+ clearActiveExtension: () => EditorCommand;
20
+ };
32
21
  }>;
33
- export {};
@@ -0,0 +1,51 @@
1
+ /// <reference types="react" />
2
+ import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
3
+ import type { ContentMode, ViewMode } from '@atlaskit/editor-plugin-editor-viewmode';
4
+ export type MenuItemsType = Array<{
5
+ items: MenuItem[];
6
+ }>;
7
+ export type SelectionExtensionComponentProps = {
8
+ closeExtension: () => void;
9
+ selection: SelectionExtensionSelectType;
10
+ };
11
+ export type SelectionExtensionSelectType = {
12
+ text: string;
13
+ selection: {
14
+ from: number;
15
+ to: number;
16
+ };
17
+ coords: SelectionExtensionCoords;
18
+ };
19
+ export type SelectionExtensionContract = {
20
+ name: string;
21
+ onClick?: (params: SelectionExtensionSelectType) => void;
22
+ component?: React.ComponentType<SelectionExtensionComponentProps>;
23
+ };
24
+ type SelectionExtensionModes = ViewMode | ContentMode;
25
+ export type SelectionExtensionPluginConfiguration = {
26
+ pageModes?: SelectionExtensionModes | SelectionExtensionModes[];
27
+ extensions?: SelectionExtensionContract[];
28
+ };
29
+ export type SelectionExtensionCoords = {
30
+ left: number;
31
+ right: number;
32
+ top: number;
33
+ bottom: number;
34
+ };
35
+ export type UpdateActiveExtensionAction = {
36
+ type: 'set-active-extension';
37
+ extension: SelectionExtensionContract;
38
+ } | {
39
+ type: 'update-active-extension-coords';
40
+ coords: SelectionExtensionCoords;
41
+ } | {
42
+ type: 'clear-active-extension';
43
+ };
44
+ export type SelectionExtensionPluginState = {
45
+ activeExtension?: {
46
+ extension: SelectionExtensionContract;
47
+ selection: SelectionExtensionSelectType;
48
+ coords: SelectionExtensionCoords;
49
+ };
50
+ };
51
+ export {};
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+ import type { SelectionExtensionPlugin } from '../../selectionExtensionPluginType';
5
+ type SelectionExtensionComponentWrapperProps = {
6
+ api: ExtractInjectionAPI<SelectionExtensionPlugin> | undefined;
7
+ editorView: EditorView;
8
+ };
9
+ export declare const SelectionExtensionComponentWrapper: ({ api, }: SelectionExtensionComponentWrapperProps) => React.JSX.Element | null;
10
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ import { SelectionExtensionCoords } from '../types';
3
+ /**
4
+ * Calculates the bounding box coordinates of a text selection within an editor view.
5
+ *
6
+ * @param view - The editor view instance.
7
+ * @param from - The starting position of the selection.
8
+ * @param to - The ending position of the selection.
9
+ * @returns An object containing the top, left, bottom, and right coordinates of the bounding box.
10
+ */
11
+ export declare const getBoundingBoxFromSelection: (view: EditorView, from: number, to: number) => SelectionExtensionCoords;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { WrappedComponentProps } from 'react-intl-next';
3
3
  import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
4
- import { type MenuItemsType } from '../../selectionExtensionPluginType';
4
+ import { type MenuItemsType } from '../../types';
5
5
  export type SelectionExtensionDropdownMenuProps = {
6
6
  items: MenuItemsType;
7
7
  onItemActivated?: (attrs: {
@@ -7,7 +7,8 @@ import type { WrappedComponentProps } from 'react-intl-next';
7
7
  import { type EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
8
8
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
9
9
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
10
- import type { SelectionExtensionPlugin, SelectionExtensionContract } from '../../selectionExtensionPluginType';
10
+ import type { SelectionExtensionPlugin } from '../../selectionExtensionPluginType';
11
+ import type { SelectionExtensionContract } from '../../types';
11
12
  type SelectionExtensionItemsProps = {
12
13
  editorView: EditorView;
13
14
  api: ExtractInjectionAPI<SelectionExtensionPlugin> | undefined;
@@ -1,2 +1,3 @@
1
1
  export { selectionExtensionPlugin } from './selectionExtensionPlugin';
2
2
  export type { SelectionExtensionPlugin } from './selectionExtensionPluginType';
3
+ export type { SelectionExtensionComponentProps } from './types';
@@ -0,0 +1,7 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { SelectionExtensionPluginState } from '../types';
4
+ export declare const selectionExtensionPluginKey: PluginKey<SelectionExtensionPluginState>;
5
+ export declare const createPlugin: () => SafePlugin<SelectionExtensionPluginState | {
6
+ activeExtension: any;
7
+ }>;
@@ -1,27 +1,8 @@
1
- import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
- import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
1
+ import type { NextEditorPlugin, OptionalPlugin, EditorCommand } from '@atlaskit/editor-common/types';
3
2
  import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
4
- import type { ContentMode, EditorViewModePlugin, ViewMode } from '@atlaskit/editor-plugin-editor-viewmode';
3
+ import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
5
4
  import type { SelectionToolbarPlugin } from '@atlaskit/editor-plugin-selection-toolbar';
6
- export type MenuItemsType = Array<{
7
- items: MenuItem[];
8
- }>;
9
- export type SelectionExtensionContract = {
10
- name: string;
11
- onClick: (params: {
12
- text: string;
13
- selection: {
14
- from: number;
15
- to: number;
16
- };
17
- }) => void;
18
- validator?: (value: unknown) => boolean;
19
- };
20
- type SelectionExtensionModes = ViewMode | ContentMode;
21
- type SelectionExtensionPluginConfiguration = {
22
- pageModes?: SelectionExtensionModes | SelectionExtensionModes[];
23
- extensions?: SelectionExtensionContract[];
24
- };
5
+ import type { SelectionExtensionPluginConfiguration, SelectionExtensionPluginState, SelectionExtensionContract, SelectionExtensionSelectType } from './types';
25
6
  export type SelectionExtensionPlugin = NextEditorPlugin<'selectionExtension', {
26
7
  pluginConfiguration: SelectionExtensionPluginConfiguration | undefined;
27
8
  dependencies: [
@@ -29,5 +10,12 @@ export type SelectionExtensionPlugin = NextEditorPlugin<'selectionExtension', {
29
10
  OptionalPlugin<EditorViewModePlugin>,
30
11
  SelectionToolbarPlugin
31
12
  ];
13
+ sharedState: SelectionExtensionPluginState | null;
14
+ commands: {
15
+ setActiveExtension: ({ extension, selection, }: {
16
+ extension: SelectionExtensionContract;
17
+ selection: SelectionExtensionSelectType;
18
+ }) => EditorCommand;
19
+ clearActiveExtension: () => EditorCommand;
20
+ };
32
21
  }>;
33
- export {};
@@ -0,0 +1,51 @@
1
+ /// <reference types="react" />
2
+ import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
3
+ import type { ContentMode, ViewMode } from '@atlaskit/editor-plugin-editor-viewmode';
4
+ export type MenuItemsType = Array<{
5
+ items: MenuItem[];
6
+ }>;
7
+ export type SelectionExtensionComponentProps = {
8
+ closeExtension: () => void;
9
+ selection: SelectionExtensionSelectType;
10
+ };
11
+ export type SelectionExtensionSelectType = {
12
+ text: string;
13
+ selection: {
14
+ from: number;
15
+ to: number;
16
+ };
17
+ coords: SelectionExtensionCoords;
18
+ };
19
+ export type SelectionExtensionContract = {
20
+ name: string;
21
+ onClick?: (params: SelectionExtensionSelectType) => void;
22
+ component?: React.ComponentType<SelectionExtensionComponentProps>;
23
+ };
24
+ type SelectionExtensionModes = ViewMode | ContentMode;
25
+ export type SelectionExtensionPluginConfiguration = {
26
+ pageModes?: SelectionExtensionModes | SelectionExtensionModes[];
27
+ extensions?: SelectionExtensionContract[];
28
+ };
29
+ export type SelectionExtensionCoords = {
30
+ left: number;
31
+ right: number;
32
+ top: number;
33
+ bottom: number;
34
+ };
35
+ export type UpdateActiveExtensionAction = {
36
+ type: 'set-active-extension';
37
+ extension: SelectionExtensionContract;
38
+ } | {
39
+ type: 'update-active-extension-coords';
40
+ coords: SelectionExtensionCoords;
41
+ } | {
42
+ type: 'clear-active-extension';
43
+ };
44
+ export type SelectionExtensionPluginState = {
45
+ activeExtension?: {
46
+ extension: SelectionExtensionContract;
47
+ selection: SelectionExtensionSelectType;
48
+ coords: SelectionExtensionCoords;
49
+ };
50
+ };
51
+ export {};
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+ import type { SelectionExtensionPlugin } from '../../selectionExtensionPluginType';
5
+ type SelectionExtensionComponentWrapperProps = {
6
+ api: ExtractInjectionAPI<SelectionExtensionPlugin> | undefined;
7
+ editorView: EditorView;
8
+ };
9
+ export declare const SelectionExtensionComponentWrapper: ({ api, }: SelectionExtensionComponentWrapperProps) => React.JSX.Element | null;
10
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ import { SelectionExtensionCoords } from '../types';
3
+ /**
4
+ * Calculates the bounding box coordinates of a text selection within an editor view.
5
+ *
6
+ * @param view - The editor view instance.
7
+ * @param from - The starting position of the selection.
8
+ * @param to - The ending position of the selection.
9
+ * @returns An object containing the top, left, bottom, and right coordinates of the bounding box.
10
+ */
11
+ export declare const getBoundingBoxFromSelection: (view: EditorView, from: number, to: number) => SelectionExtensionCoords;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { WrappedComponentProps } from 'react-intl-next';
3
3
  import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
4
- import { type MenuItemsType } from '../../selectionExtensionPluginType';
4
+ import { type MenuItemsType } from '../../types';
5
5
  export type SelectionExtensionDropdownMenuProps = {
6
6
  items: MenuItemsType;
7
7
  onItemActivated?: (attrs: {
@@ -7,7 +7,8 @@ import type { WrappedComponentProps } from 'react-intl-next';
7
7
  import { type EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
8
8
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
9
9
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
10
- import type { SelectionExtensionPlugin, SelectionExtensionContract } from '../../selectionExtensionPluginType';
10
+ import type { SelectionExtensionPlugin } from '../../selectionExtensionPluginType';
11
+ import type { SelectionExtensionContract } from '../../types';
11
12
  type SelectionExtensionItemsProps = {
12
13
  editorView: EditorView;
13
14
  api: ExtractInjectionAPI<SelectionExtensionPlugin> | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-selection-extension",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "editor-plugin-selection-extension plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -36,13 +36,13 @@
36
36
  ".": "./src/index.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@atlaskit/editor-common": "^100.0.0",
39
+ "@atlaskit/editor-common": "^100.2.0",
40
40
  "@atlaskit/editor-plugin-analytics": "^2.0.0",
41
41
  "@atlaskit/editor-plugin-editor-viewmode": "^3.0.0",
42
42
  "@atlaskit/editor-plugin-selection-toolbar": "^2.0.0",
43
43
  "@atlaskit/editor-prosemirror": "7.0.0",
44
- "@atlaskit/icon": "^24.0.0",
45
- "@atlaskit/primitives": "^14.0.0",
44
+ "@atlaskit/icon": "^24.1.0",
45
+ "@atlaskit/primitives": "^14.1.0",
46
46
  "@babel/runtime": "^7.0.0",
47
47
  "react-intl-next": "npm:react-intl@^5.18.1",
48
48
  "uuid": "^3.1.0"