@atlaskit/editor-common 96.4.1 → 96.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/extensibility/Extension/Lozenge/EditToggle.js +22 -4
  3. package/dist/cjs/hooks/useSharedPluginState.js +3 -0
  4. package/dist/cjs/hooks/useSharedPluginStateSelector/index.js +12 -0
  5. package/dist/cjs/hooks/useSharedPluginStateSelector/useSharedPluginStateSelector.js +114 -0
  6. package/dist/cjs/monitoring/error.js +1 -1
  7. package/dist/cjs/ui/DropList/index.js +1 -1
  8. package/dist/cjs/utils/profiler/render-count.js +2 -0
  9. package/dist/es2019/extensibility/Extension/Lozenge/EditToggle.js +18 -4
  10. package/dist/es2019/hooks/useSharedPluginState.js +3 -0
  11. package/dist/es2019/hooks/useSharedPluginStateSelector/index.js +2 -0
  12. package/dist/es2019/hooks/useSharedPluginStateSelector/useSharedPluginStateSelector.js +98 -0
  13. package/dist/es2019/monitoring/error.js +1 -1
  14. package/dist/es2019/ui/DropList/index.js +1 -1
  15. package/dist/es2019/utils/profiler/render-count.js +2 -0
  16. package/dist/esm/extensibility/Extension/Lozenge/EditToggle.js +22 -4
  17. package/dist/esm/hooks/useSharedPluginState.js +3 -0
  18. package/dist/esm/hooks/useSharedPluginStateSelector/index.js +2 -0
  19. package/dist/esm/hooks/useSharedPluginStateSelector/useSharedPluginStateSelector.js +108 -0
  20. package/dist/esm/monitoring/error.js +1 -1
  21. package/dist/esm/ui/DropList/index.js +1 -1
  22. package/dist/esm/utils/profiler/render-count.js +2 -0
  23. package/dist/types/hooks/useSharedPluginState.d.ts +5 -3
  24. package/dist/types/hooks/useSharedPluginStateSelector/index.d.ts +1 -0
  25. package/dist/types/hooks/useSharedPluginStateSelector/useSharedPluginStateSelector.d.ts +74 -0
  26. package/dist/types-ts4.5/hooks/useSharedPluginState.d.ts +5 -3
  27. package/dist/types-ts4.5/hooks/useSharedPluginStateSelector/index.d.ts +1 -0
  28. package/dist/types-ts4.5/hooks/useSharedPluginStateSelector/useSharedPluginStateSelector.d.ts +74 -0
  29. package/package.json +2 -1
  30. package/use-shared-plugin-state-selector/package.json +15 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 96.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#178536](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/178536)
8
+ [`2809409329363`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2809409329363) -
9
+ Adds keyboard events to select/de-select the bodied macros EditToggle for accessibility
10
+
11
+ ## 96.5.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#175556](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/175556)
16
+ [`e883046c970ff`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e883046c970ff) -
17
+ Introduces new usePluginStateSelector hook which can be used to efficiently listen to a slice of
18
+ an editor plugins state.
19
+
3
20
  ## 96.4.1
4
21
 
5
22
  ### Patch Changes
@@ -41,7 +41,11 @@ var buttonStyles = (0, _react2.css)({
41
41
  font: "var(--ds-font-body, normal 400 14px/20px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, system-ui, \"Helvetica Neue\", sans-serif)",
42
42
  '&:hover': {
43
43
  backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
44
- }
44
+ },
45
+ outlineColor: "var(--ds-border-focused, #388BFF)",
46
+ border: 'none',
47
+ backgroundColor: "var(--ds-background-neutral-subtle, #00000000)",
48
+ color: "var(--ds-text-subtle, #44546F)"
45
49
  });
46
50
  var showButtonContainerStyle = (0, _react2.css)({
47
51
  opacity: 1
@@ -80,6 +84,11 @@ var EditToggle = exports.EditToggle = function EditToggle(_ref) {
80
84
  var handleClick = (0, _react.useCallback)(function () {
81
85
  setShowBodiedExtensionRendererView === null || setShowBodiedExtensionRendererView === void 0 || setShowBodiedExtensionRendererView(!showBodiedExtensionRendererView);
82
86
  }, [showBodiedExtensionRendererView, setShowBodiedExtensionRendererView]);
87
+ var handleKeyDown = (0, _react.useCallback)(function (event) {
88
+ if (event.key === 'Enter') {
89
+ handleClick();
90
+ }
91
+ }, [handleClick]);
83
92
  return (
84
93
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
85
94
  (0, _react2.jsx)("div", {
@@ -100,8 +109,10 @@ var EditToggle = exports.EditToggle = function EditToggle(_ref) {
100
109
  },
101
110
  onMouseLeave: function onMouseLeave() {
102
111
  return setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false);
103
- }
104
- }, (0, _react2.jsx)("span", {
112
+ },
113
+ tabIndex: -1
114
+ }, (0, _react2.jsx)("button", {
115
+ type: "button",
105
116
  "data-testid": "edit-toggle"
106
117
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
107
118
  ,
@@ -109,7 +120,14 @@ var EditToggle = exports.EditToggle = function EditToggle(_ref) {
109
120
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
110
121
  ,
111
122
  className: "extension-edit-toggle",
112
- onClick: handleClick
123
+ onClick: handleClick,
124
+ onKeyDown: handleKeyDown,
125
+ onFocus: function onFocus() {
126
+ return setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(true);
127
+ },
128
+ onBlur: function onBlur() {
129
+ return setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false);
130
+ }
113
131
  }, (0, _react2.jsx)(_primitives.Flex, {
114
132
  as: "span",
115
133
  xcss: iconStyles
@@ -40,6 +40,9 @@ function useStaticPlugins(plugins) {
40
40
  }
41
41
 
42
42
  /**
43
+ *
44
+ * NOTE: Generally you may want to use `usePluginStateSelector` over this which behaves similarly
45
+ * but selects a slice of the state which is more performant.
43
46
  *
44
47
  * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
45
48
  * If the plugins you are listening to generate multiple shared states while the user is typing,
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "useSharedPluginStateSelector", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _useSharedPluginStateSelector.useSharedPluginStateSelector;
10
+ }
11
+ });
12
+ var _useSharedPluginStateSelector = require("./useSharedPluginStateSelector");
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useSharedPluginStateSelector = useSharedPluginStateSelector;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
10
+ var _react = require("react");
11
+ var _get = _interopRequireDefault(require("lodash/get"));
12
+ var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
13
+ var _usePluginStateEffect = require("../usePluginStateEffect");
14
+ /**
15
+ * This is designed to iterate through an object to get the path of its result
16
+ * based on separation via "."
17
+ *
18
+ * Example:
19
+ * ```typescript
20
+ * type Test = { deepObject: { value: number } };
21
+ * // Type should be `"deepObject" | "deepObject.value"`
22
+ * type Result = NestedKeys<Test>;
23
+ * ```
24
+ */
25
+
26
+ /**
27
+ * This is designed to iterate through a path of an object to get the type of its result
28
+ * based on separation via "."
29
+ *
30
+ * Example:
31
+ * ```typescript
32
+ * type Test = { deepObject: { value: number } }
33
+ * // Type should be `number`
34
+ * type Result = Path<Test, 'deepObject.value'>
35
+ * ```
36
+ */
37
+
38
+ /**
39
+ *
40
+ * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
41
+ * If the plugins you are listening to generate multiple shared states while the user is typing,
42
+ * your React Component will get only the last one.
43
+ *
44
+ * Used to return the current plugin state of input dependencies.
45
+ * It will recursively retrieve a slice of the state using a "." to separate
46
+ * parts of the state.
47
+ *
48
+ * Example:
49
+ *
50
+ * ```typescript
51
+ * const pluginA: NextEditorPlugin<
52
+ 'pluginA',
53
+ {
54
+ sharedState: { deepObj: { value: number | undefined } };
55
+ }
56
+ >
57
+ * ```
58
+ * You can use `const value = useSharedPluginStateSelector(api, 'pluginA.deepObj.value')` to retrieve the value
59
+ *
60
+ * Example in plugin:
61
+ *
62
+ * ```typescript
63
+ * function ExampleContent({ api }: Props) {
64
+ * const title = useSharedPluginStateSelector(api, 'dog.title')
65
+ * return <p>{ title } { exampleState.description }</p>
66
+ * }
67
+ *
68
+ * const examplePlugin: NextEditorPlugin<'example', { dependencies: [typeof pluginDog] }> = ({ api }) => {
69
+ * return {
70
+ * name: 'example',
71
+ * contentComponent: () => <ExampleContent api={api} />
72
+ * }
73
+ * }
74
+ * ```
75
+ *
76
+ * NOTE: If you pass an invalid path, `undefined` will be returned
77
+ *
78
+ * @param api
79
+ * @param plugin
80
+ * @returns
81
+ */
82
+ function useSharedPluginStateSelector(api, plugin) {
83
+ var transformer = (0, _react.useCallback)(function (pluginState) {
84
+ var _plugin$split = plugin.split('.'),
85
+ _plugin$split2 = (0, _toArray2.default)(_plugin$split),
86
+ pluginName = _plugin$split2[0],
87
+ properties = _plugin$split2.slice(1);
88
+ if (!pluginState || (properties === null || properties === void 0 ? void 0 : properties.length) === 0) {
89
+ return undefined;
90
+ }
91
+ return (0, _get.default)(pluginState === null || pluginState === void 0 ? void 0 : pluginState["".concat(pluginName, "State")], properties);
92
+ }, [plugin]);
93
+ var pluginNameArray = (0, _react.useMemo)(function () {
94
+ var _plugin$split3 = plugin.split('.'),
95
+ _plugin$split4 = (0, _slicedToArray2.default)(_plugin$split3, 1),
96
+ pluginName = _plugin$split4[0];
97
+ return [pluginName];
98
+ }, [plugin]);
99
+ return useSharedPluginStateSelectorInternal(api, pluginNameArray, transformer);
100
+ }
101
+ function useSharedPluginStateSelectorInternal(api, plugins, transformer) {
102
+ var _useState = (0, _react.useState)(),
103
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
104
+ selectedPluginState = _useState2[0],
105
+ setSelectedPluginState = _useState2[1];
106
+ (0, _usePluginStateEffect.usePluginStateEffect)(api, plugins, function (pluginStates) {
107
+ // `pluginStates`: This is the same type through inference - but typescript doesn't recognise them as they are computed slightly differently
108
+ var transformedValue = transformer(pluginStates);
109
+ if (!(0, _isEqual.default)(transformedValue, selectedPluginState)) {
110
+ setSelectedPluginState(transformedValue);
111
+ }
112
+ });
113
+ return selectedPluginState;
114
+ }
@@ -17,7 +17,7 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
17
17
  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; }
18
18
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
19
19
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
20
- var packageVersion = "96.4.1";
20
+ var packageVersion = "96.5.1";
21
21
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
22
22
  // Remove URL as it has UGC
23
23
  // TODO: Sanitise the URL instead of just removing it
@@ -23,7 +23,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
23
23
  * @jsx jsx
24
24
  */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
25
25
  var packageName = "@atlaskit/editor-common";
26
- var packageVersion = "96.4.1";
26
+ var packageVersion = "96.5.1";
27
27
  var halfFocusRing = 1;
28
28
  var dropOffset = '0, 8';
29
29
  var DropList = /*#__PURE__*/function (_Component) {
@@ -77,6 +77,7 @@ var RenderCountProfiler = exports.RenderCountProfiler = /*#__PURE__*/function ()
77
77
  var componentId = _ref3.componentId;
78
78
  var component = (_this$store$PROFILER_ = (_this$store3 = this.store) === null || _this$store3 === void 0 || (_this$store3 = _this$store3[PROFILER_KEY]) === null || _this$store3 === void 0 || (_this$store3 = _this$store3.components) === null || _this$store3 === void 0 ? void 0 : _this$store3[componentId]) !== null && _this$store$PROFILER_ !== void 0 ? _this$store$PROFILER_ : {};
79
79
  var counters = [];
80
+ // eslint-disable-next-line guard-for-in
80
81
  for (var instanceId in component) {
81
82
  var counter = {
82
83
  instanceId: instanceId,
@@ -93,6 +94,7 @@ var RenderCountProfiler = exports.RenderCountProfiler = /*#__PURE__*/function ()
93
94
  var componentId = _ref4.componentId;
94
95
  var component = (_this$store$PROFILER_2 = (_this$store4 = this.store) === null || _this$store4 === void 0 || (_this$store4 = _this$store4[PROFILER_KEY]) === null || _this$store4 === void 0 || (_this$store4 = _this$store4.components) === null || _this$store4 === void 0 ? void 0 : _this$store4[componentId]) !== null && _this$store$PROFILER_2 !== void 0 ? _this$store$PROFILER_2 : {};
95
96
  var total = 0;
97
+ // eslint-disable-next-line guard-for-in
96
98
  for (var instanceId in component) {
97
99
  total += component[instanceId].count;
98
100
  }
@@ -34,7 +34,11 @@ const buttonStyles = css({
34
34
  font: "var(--ds-font-body, normal 400 14px/20px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, system-ui, \"Helvetica Neue\", sans-serif)",
35
35
  '&:hover': {
36
36
  backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
37
- }
37
+ },
38
+ outlineColor: "var(--ds-border-focused, #388BFF)",
39
+ border: 'none',
40
+ backgroundColor: "var(--ds-background-neutral-subtle, #00000000)",
41
+ color: "var(--ds-text-subtle, #44546F)"
38
42
  });
39
43
  const showButtonContainerStyle = css({
40
44
  opacity: 1
@@ -74,6 +78,11 @@ export const EditToggle = ({
74
78
  const handleClick = useCallback(() => {
75
79
  setShowBodiedExtensionRendererView === null || setShowBodiedExtensionRendererView === void 0 ? void 0 : setShowBodiedExtensionRendererView(!showBodiedExtensionRendererView);
76
80
  }, [showBodiedExtensionRendererView, setShowBodiedExtensionRendererView]);
81
+ const handleKeyDown = useCallback(event => {
82
+ if (event.key === 'Enter') {
83
+ handleClick();
84
+ }
85
+ }, [handleClick]);
77
86
  return (
78
87
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
79
88
  jsx("div", {
@@ -90,8 +99,10 @@ export const EditToggle = ({
90
99
  // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
91
100
  ,
92
101
  onMouseOver: () => setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(true),
93
- onMouseLeave: () => setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false)
94
- }, jsx("span", {
102
+ onMouseLeave: () => setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false),
103
+ tabIndex: -1
104
+ }, jsx("button", {
105
+ type: "button",
95
106
  "data-testid": "edit-toggle"
96
107
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
97
108
  ,
@@ -99,7 +110,10 @@ export const EditToggle = ({
99
110
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
100
111
  ,
101
112
  className: "extension-edit-toggle",
102
- onClick: handleClick
113
+ onClick: handleClick,
114
+ onKeyDown: handleKeyDown,
115
+ onFocus: () => setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(true),
116
+ onBlur: () => setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false)
103
117
  }, jsx(Flex, {
104
118
  as: "span",
105
119
  xcss: iconStyles
@@ -25,6 +25,9 @@ function useStaticPlugins(plugins) {
25
25
  }
26
26
 
27
27
  /**
28
+ *
29
+ * NOTE: Generally you may want to use `usePluginStateSelector` over this which behaves similarly
30
+ * but selects a slice of the state which is more performant.
28
31
  *
29
32
  * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
30
33
  * If the plugins you are listening to generate multiple shared states while the user is typing,
@@ -0,0 +1,2 @@
1
+ // eslint-disable-next-line @atlaskit/editor/no-re-export
2
+ export { useSharedPluginStateSelector } from './useSharedPluginStateSelector';
@@ -0,0 +1,98 @@
1
+ import { useState, useCallback, useMemo } from 'react';
2
+ import get from 'lodash/get';
3
+ import isEqual from 'lodash/isEqual';
4
+ import { usePluginStateEffect } from '../usePluginStateEffect';
5
+
6
+ /**
7
+ * This is designed to iterate through an object to get the path of its result
8
+ * based on separation via "."
9
+ *
10
+ * Example:
11
+ * ```typescript
12
+ * type Test = { deepObject: { value: number } };
13
+ * // Type should be `"deepObject" | "deepObject.value"`
14
+ * type Result = NestedKeys<Test>;
15
+ * ```
16
+ */
17
+
18
+ /**
19
+ * This is designed to iterate through a path of an object to get the type of its result
20
+ * based on separation via "."
21
+ *
22
+ * Example:
23
+ * ```typescript
24
+ * type Test = { deepObject: { value: number } }
25
+ * // Type should be `number`
26
+ * type Result = Path<Test, 'deepObject.value'>
27
+ * ```
28
+ */
29
+
30
+ /**
31
+ *
32
+ * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
33
+ * If the plugins you are listening to generate multiple shared states while the user is typing,
34
+ * your React Component will get only the last one.
35
+ *
36
+ * Used to return the current plugin state of input dependencies.
37
+ * It will recursively retrieve a slice of the state using a "." to separate
38
+ * parts of the state.
39
+ *
40
+ * Example:
41
+ *
42
+ * ```typescript
43
+ * const pluginA: NextEditorPlugin<
44
+ 'pluginA',
45
+ {
46
+ sharedState: { deepObj: { value: number | undefined } };
47
+ }
48
+ >
49
+ * ```
50
+ * You can use `const value = useSharedPluginStateSelector(api, 'pluginA.deepObj.value')` to retrieve the value
51
+ *
52
+ * Example in plugin:
53
+ *
54
+ * ```typescript
55
+ * function ExampleContent({ api }: Props) {
56
+ * const title = useSharedPluginStateSelector(api, 'dog.title')
57
+ * return <p>{ title } { exampleState.description }</p>
58
+ * }
59
+ *
60
+ * const examplePlugin: NextEditorPlugin<'example', { dependencies: [typeof pluginDog] }> = ({ api }) => {
61
+ * return {
62
+ * name: 'example',
63
+ * contentComponent: () => <ExampleContent api={api} />
64
+ * }
65
+ * }
66
+ * ```
67
+ *
68
+ * NOTE: If you pass an invalid path, `undefined` will be returned
69
+ *
70
+ * @param api
71
+ * @param plugin
72
+ * @returns
73
+ */
74
+ export function useSharedPluginStateSelector(api, plugin) {
75
+ const transformer = useCallback(pluginState => {
76
+ const [pluginName, ...properties] = plugin.split('.');
77
+ if (!pluginState || (properties === null || properties === void 0 ? void 0 : properties.length) === 0) {
78
+ return undefined;
79
+ }
80
+ return get(pluginState === null || pluginState === void 0 ? void 0 : pluginState[`${pluginName}State`], properties);
81
+ }, [plugin]);
82
+ const pluginNameArray = useMemo(() => {
83
+ const [pluginName] = plugin.split('.');
84
+ return [pluginName];
85
+ }, [plugin]);
86
+ return useSharedPluginStateSelectorInternal(api, pluginNameArray, transformer);
87
+ }
88
+ function useSharedPluginStateSelectorInternal(api, plugins, transformer) {
89
+ const [selectedPluginState, setSelectedPluginState] = useState();
90
+ usePluginStateEffect(api, plugins, pluginStates => {
91
+ // `pluginStates`: This is the same type through inference - but typescript doesn't recognise them as they are computed slightly differently
92
+ const transformedValue = transformer(pluginStates);
93
+ if (!isEqual(transformedValue, selectedPluginState)) {
94
+ setSelectedPluginState(transformedValue);
95
+ }
96
+ });
97
+ return selectedPluginState;
98
+ }
@@ -1,7 +1,7 @@
1
1
  import { isFedRamp } from './environment';
2
2
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
3
3
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
4
- const packageVersion = "96.4.1";
4
+ const packageVersion = "96.5.1";
5
5
  const sanitiseSentryEvents = (data, _hint) => {
6
6
  // Remove URL as it has UGC
7
7
  // TODO: Sanitise the URL instead of just removing it
@@ -13,7 +13,7 @@ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext'
13
13
  import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import Layer from '../Layer';
15
15
  const packageName = "@atlaskit/editor-common";
16
- const packageVersion = "96.4.1";
16
+ const packageVersion = "96.5.1";
17
17
  const halfFocusRing = 1;
18
18
  const dropOffset = '0, 8';
19
19
  class DropList extends Component {
@@ -71,6 +71,7 @@ export class RenderCountProfiler {
71
71
  var _this$store$PROFILER_, _this$store3, _this$store3$PROFILER, _this$store3$PROFILER2;
72
72
  const component = (_this$store$PROFILER_ = (_this$store3 = this.store) === null || _this$store3 === void 0 ? void 0 : (_this$store3$PROFILER = _this$store3[PROFILER_KEY]) === null || _this$store3$PROFILER === void 0 ? void 0 : (_this$store3$PROFILER2 = _this$store3$PROFILER.components) === null || _this$store3$PROFILER2 === void 0 ? void 0 : _this$store3$PROFILER2[componentId]) !== null && _this$store$PROFILER_ !== void 0 ? _this$store$PROFILER_ : {};
73
73
  const counters = [];
74
+ // eslint-disable-next-line guard-for-in
74
75
  for (let instanceId in component) {
75
76
  const counter = {
76
77
  instanceId,
@@ -86,6 +87,7 @@ export class RenderCountProfiler {
86
87
  var _this$store$PROFILER_2, _this$store4, _this$store4$PROFILER, _this$store4$PROFILER2;
87
88
  const component = (_this$store$PROFILER_2 = (_this$store4 = this.store) === null || _this$store4 === void 0 ? void 0 : (_this$store4$PROFILER = _this$store4[PROFILER_KEY]) === null || _this$store4$PROFILER === void 0 ? void 0 : (_this$store4$PROFILER2 = _this$store4$PROFILER.components) === null || _this$store4$PROFILER2 === void 0 ? void 0 : _this$store4$PROFILER2[componentId]) !== null && _this$store$PROFILER_2 !== void 0 ? _this$store$PROFILER_2 : {};
88
89
  let total = 0;
90
+ // eslint-disable-next-line guard-for-in
89
91
  for (let instanceId in component) {
90
92
  total += component[instanceId].count;
91
93
  }
@@ -34,7 +34,11 @@ var buttonStyles = css({
34
34
  font: "var(--ds-font-body, normal 400 14px/20px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, system-ui, \"Helvetica Neue\", sans-serif)",
35
35
  '&:hover': {
36
36
  backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
37
- }
37
+ },
38
+ outlineColor: "var(--ds-border-focused, #388BFF)",
39
+ border: 'none',
40
+ backgroundColor: "var(--ds-background-neutral-subtle, #00000000)",
41
+ color: "var(--ds-text-subtle, #44546F)"
38
42
  });
39
43
  var showButtonContainerStyle = css({
40
44
  opacity: 1
@@ -73,6 +77,11 @@ export var EditToggle = function EditToggle(_ref) {
73
77
  var handleClick = useCallback(function () {
74
78
  setShowBodiedExtensionRendererView === null || setShowBodiedExtensionRendererView === void 0 || setShowBodiedExtensionRendererView(!showBodiedExtensionRendererView);
75
79
  }, [showBodiedExtensionRendererView, setShowBodiedExtensionRendererView]);
80
+ var handleKeyDown = useCallback(function (event) {
81
+ if (event.key === 'Enter') {
82
+ handleClick();
83
+ }
84
+ }, [handleClick]);
76
85
  return (
77
86
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
78
87
  jsx("div", {
@@ -93,8 +102,10 @@ export var EditToggle = function EditToggle(_ref) {
93
102
  },
94
103
  onMouseLeave: function onMouseLeave() {
95
104
  return setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false);
96
- }
97
- }, jsx("span", {
105
+ },
106
+ tabIndex: -1
107
+ }, jsx("button", {
108
+ type: "button",
98
109
  "data-testid": "edit-toggle"
99
110
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
100
111
  ,
@@ -102,7 +113,14 @@ export var EditToggle = function EditToggle(_ref) {
102
113
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
103
114
  ,
104
115
  className: "extension-edit-toggle",
105
- onClick: handleClick
116
+ onClick: handleClick,
117
+ onKeyDown: handleKeyDown,
118
+ onFocus: function onFocus() {
119
+ return setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(true);
120
+ },
121
+ onBlur: function onBlur() {
122
+ return setIsNodeHovered === null || setIsNodeHovered === void 0 ? void 0 : setIsNodeHovered(false);
123
+ }
106
124
  }, jsx(Flex, {
107
125
  as: "span",
108
126
  xcss: iconStyles
@@ -33,6 +33,9 @@ function useStaticPlugins(plugins) {
33
33
  }
34
34
 
35
35
  /**
36
+ *
37
+ * NOTE: Generally you may want to use `usePluginStateSelector` over this which behaves similarly
38
+ * but selects a slice of the state which is more performant.
36
39
  *
37
40
  * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
38
41
  * If the plugins you are listening to generate multiple shared states while the user is typing,
@@ -0,0 +1,2 @@
1
+ // eslint-disable-next-line @atlaskit/editor/no-re-export
2
+ export { useSharedPluginStateSelector } from './useSharedPluginStateSelector';
@@ -0,0 +1,108 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _toArray from "@babel/runtime/helpers/toArray";
3
+ import { useState, useCallback, useMemo } from 'react';
4
+ import get from 'lodash/get';
5
+ import isEqual from 'lodash/isEqual';
6
+ import { usePluginStateEffect } from '../usePluginStateEffect';
7
+
8
+ /**
9
+ * This is designed to iterate through an object to get the path of its result
10
+ * based on separation via "."
11
+ *
12
+ * Example:
13
+ * ```typescript
14
+ * type Test = { deepObject: { value: number } };
15
+ * // Type should be `"deepObject" | "deepObject.value"`
16
+ * type Result = NestedKeys<Test>;
17
+ * ```
18
+ */
19
+
20
+ /**
21
+ * This is designed to iterate through a path of an object to get the type of its result
22
+ * based on separation via "."
23
+ *
24
+ * Example:
25
+ * ```typescript
26
+ * type Test = { deepObject: { value: number } }
27
+ * // Type should be `number`
28
+ * type Result = Path<Test, 'deepObject.value'>
29
+ * ```
30
+ */
31
+
32
+ /**
33
+ *
34
+ * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
35
+ * If the plugins you are listening to generate multiple shared states while the user is typing,
36
+ * your React Component will get only the last one.
37
+ *
38
+ * Used to return the current plugin state of input dependencies.
39
+ * It will recursively retrieve a slice of the state using a "." to separate
40
+ * parts of the state.
41
+ *
42
+ * Example:
43
+ *
44
+ * ```typescript
45
+ * const pluginA: NextEditorPlugin<
46
+ 'pluginA',
47
+ {
48
+ sharedState: { deepObj: { value: number | undefined } };
49
+ }
50
+ >
51
+ * ```
52
+ * You can use `const value = useSharedPluginStateSelector(api, 'pluginA.deepObj.value')` to retrieve the value
53
+ *
54
+ * Example in plugin:
55
+ *
56
+ * ```typescript
57
+ * function ExampleContent({ api }: Props) {
58
+ * const title = useSharedPluginStateSelector(api, 'dog.title')
59
+ * return <p>{ title } { exampleState.description }</p>
60
+ * }
61
+ *
62
+ * const examplePlugin: NextEditorPlugin<'example', { dependencies: [typeof pluginDog] }> = ({ api }) => {
63
+ * return {
64
+ * name: 'example',
65
+ * contentComponent: () => <ExampleContent api={api} />
66
+ * }
67
+ * }
68
+ * ```
69
+ *
70
+ * NOTE: If you pass an invalid path, `undefined` will be returned
71
+ *
72
+ * @param api
73
+ * @param plugin
74
+ * @returns
75
+ */
76
+ export function useSharedPluginStateSelector(api, plugin) {
77
+ var transformer = useCallback(function (pluginState) {
78
+ var _plugin$split = plugin.split('.'),
79
+ _plugin$split2 = _toArray(_plugin$split),
80
+ pluginName = _plugin$split2[0],
81
+ properties = _plugin$split2.slice(1);
82
+ if (!pluginState || (properties === null || properties === void 0 ? void 0 : properties.length) === 0) {
83
+ return undefined;
84
+ }
85
+ return get(pluginState === null || pluginState === void 0 ? void 0 : pluginState["".concat(pluginName, "State")], properties);
86
+ }, [plugin]);
87
+ var pluginNameArray = useMemo(function () {
88
+ var _plugin$split3 = plugin.split('.'),
89
+ _plugin$split4 = _slicedToArray(_plugin$split3, 1),
90
+ pluginName = _plugin$split4[0];
91
+ return [pluginName];
92
+ }, [plugin]);
93
+ return useSharedPluginStateSelectorInternal(api, pluginNameArray, transformer);
94
+ }
95
+ function useSharedPluginStateSelectorInternal(api, plugins, transformer) {
96
+ var _useState = useState(),
97
+ _useState2 = _slicedToArray(_useState, 2),
98
+ selectedPluginState = _useState2[0],
99
+ setSelectedPluginState = _useState2[1];
100
+ usePluginStateEffect(api, plugins, function (pluginStates) {
101
+ // `pluginStates`: This is the same type through inference - but typescript doesn't recognise them as they are computed slightly differently
102
+ var transformedValue = transformer(pluginStates);
103
+ if (!isEqual(transformedValue, selectedPluginState)) {
104
+ setSelectedPluginState(transformedValue);
105
+ }
106
+ });
107
+ return selectedPluginState;
108
+ }
@@ -7,7 +7,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
7
7
  import { isFedRamp } from './environment';
8
8
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
9
9
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
10
- var packageVersion = "96.4.1";
10
+ var packageVersion = "96.5.1";
11
11
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
12
12
  // Remove URL as it has UGC
13
13
  // TODO: Sanitise the URL instead of just removing it
@@ -20,7 +20,7 @@ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext'
20
20
  import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
21
21
  import Layer from '../Layer';
22
22
  var packageName = "@atlaskit/editor-common";
23
- var packageVersion = "96.4.1";
23
+ var packageVersion = "96.5.1";
24
24
  var halfFocusRing = 1;
25
25
  var dropOffset = '0, 8';
26
26
  var DropList = /*#__PURE__*/function (_Component) {
@@ -70,6 +70,7 @@ export var RenderCountProfiler = /*#__PURE__*/function () {
70
70
  var componentId = _ref3.componentId;
71
71
  var component = (_this$store$PROFILER_ = (_this$store3 = this.store) === null || _this$store3 === void 0 || (_this$store3 = _this$store3[PROFILER_KEY]) === null || _this$store3 === void 0 || (_this$store3 = _this$store3.components) === null || _this$store3 === void 0 ? void 0 : _this$store3[componentId]) !== null && _this$store$PROFILER_ !== void 0 ? _this$store$PROFILER_ : {};
72
72
  var counters = [];
73
+ // eslint-disable-next-line guard-for-in
73
74
  for (var instanceId in component) {
74
75
  var counter = {
75
76
  instanceId: instanceId,
@@ -86,6 +87,7 @@ export var RenderCountProfiler = /*#__PURE__*/function () {
86
87
  var componentId = _ref4.componentId;
87
88
  var component = (_this$store$PROFILER_2 = (_this$store4 = this.store) === null || _this$store4 === void 0 || (_this$store4 = _this$store4[PROFILER_KEY]) === null || _this$store4 === void 0 || (_this$store4 = _this$store4.components) === null || _this$store4 === void 0 ? void 0 : _this$store4[componentId]) !== null && _this$store$PROFILER_2 !== void 0 ? _this$store$PROFILER_2 : {};
88
89
  var total = 0;
90
+ // eslint-disable-next-line guard-for-in
89
91
  for (var instanceId in component) {
90
92
  total += component[instanceId].count;
91
93
  }
@@ -1,9 +1,12 @@
1
1
  import type { BasePluginDependenciesAPI, EditorInjectionAPI, ExtractInjectionAPI, ExtractPluginSharedState, NextEditorPlugin, NextEditorPluginMetadata } from '../types/next-editor-plugin';
2
- type NamedPluginStatesFromInjectionAPI<API extends ExtractInjectionAPI<NextEditorPlugin<any, any>>, PluginNames extends string | number | symbol> = Readonly<{
2
+ export type NamedPluginStatesFromInjectionAPI<API extends ExtractInjectionAPI<NextEditorPlugin<any, any>>, PluginNames extends string | number | symbol> = Readonly<{
3
3
  [K in PluginNames as `${K extends string ? K : never}State`]: API[K] extends BasePluginDependenciesAPI<any> | undefined ? Exclude<API[K], undefined> extends BasePluginDependenciesAPI<infer Metadata> ? Metadata extends NextEditorPluginMetadata ? ExtractPluginSharedState<Metadata> | undefined : never : never : never;
4
4
  }>;
5
- type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API;
5
+ export type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API;
6
6
  /**
7
+ *
8
+ * NOTE: Generally you may want to use `usePluginStateSelector` over this which behaves similarly
9
+ * but selects a slice of the state which is more performant.
7
10
  *
8
11
  * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
9
12
  * If the plugins you are listening to generate multiple shared states while the user is typing,
@@ -65,4 +68,3 @@ type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API;
65
68
  * the values are the shared state exposed by that plugin.
66
69
  */
67
70
  export declare function useSharedPluginState<API extends EditorInjectionAPI<any, any>, PluginNames extends ExtractPluginNames<API>>(injectionApi: API | null | undefined, plugins: PluginNames[]): NamedPluginStatesFromInjectionAPI<API, PluginNames>;
68
- export {};
@@ -0,0 +1 @@
1
+ export { useSharedPluginStateSelector } from './useSharedPluginStateSelector';
@@ -0,0 +1,74 @@
1
+ import type { EditorInjectionAPI } from '../../types/next-editor-plugin';
2
+ type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API extends string ? keyof API : never;
3
+ /**
4
+ * This is designed to iterate through an object to get the path of its result
5
+ * based on separation via "."
6
+ *
7
+ * Example:
8
+ * ```typescript
9
+ * type Test = { deepObject: { value: number } };
10
+ * // Type should be `"deepObject" | "deepObject.value"`
11
+ * type Result = NestedKeys<Test>;
12
+ * ```
13
+ */
14
+ type NestedKeys<T> = {
15
+ [K in keyof T]: T[K] extends object ? T[K] extends any[] ? K extends string ? K : never : T[K] extends object ? K extends string ? K | `${K}.${NestedKeys<T[K]>}` : never : never : K extends string ? K : never;
16
+ }[keyof T];
17
+ /**
18
+ * This is designed to iterate through a path of an object to get the type of its result
19
+ * based on separation via "."
20
+ *
21
+ * Example:
22
+ * ```typescript
23
+ * type Test = { deepObject: { value: number } }
24
+ * // Type should be `number`
25
+ * type Result = Path<Test, 'deepObject.value'>
26
+ * ```
27
+ */
28
+ type Path<T, K extends string> = K extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? Path<T[Key], Rest> : never : K extends keyof T ? T[K] : never;
29
+ /**
30
+ *
31
+ * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
32
+ * If the plugins you are listening to generate multiple shared states while the user is typing,
33
+ * your React Component will get only the last one.
34
+ *
35
+ * Used to return the current plugin state of input dependencies.
36
+ * It will recursively retrieve a slice of the state using a "." to separate
37
+ * parts of the state.
38
+ *
39
+ * Example:
40
+ *
41
+ * ```typescript
42
+ * const pluginA: NextEditorPlugin<
43
+ 'pluginA',
44
+ {
45
+ sharedState: { deepObj: { value: number | undefined } };
46
+ }
47
+ >
48
+ * ```
49
+ * You can use `const value = useSharedPluginStateSelector(api, 'pluginA.deepObj.value')` to retrieve the value
50
+ *
51
+ * Example in plugin:
52
+ *
53
+ * ```typescript
54
+ * function ExampleContent({ api }: Props) {
55
+ * const title = useSharedPluginStateSelector(api, 'dog.title')
56
+ * return <p>{ title } { exampleState.description }</p>
57
+ * }
58
+ *
59
+ * const examplePlugin: NextEditorPlugin<'example', { dependencies: [typeof pluginDog] }> = ({ api }) => {
60
+ * return {
61
+ * name: 'example',
62
+ * contentComponent: () => <ExampleContent api={api} />
63
+ * }
64
+ * }
65
+ * ```
66
+ *
67
+ * NOTE: If you pass an invalid path, `undefined` will be returned
68
+ *
69
+ * @param api
70
+ * @param plugin
71
+ * @returns
72
+ */
73
+ export declare function useSharedPluginStateSelector<API extends EditorInjectionAPI<any, any>, PluginName extends ExtractPluginNames<API>, SharedState extends ReturnType<Exclude<API[PluginName], null | undefined>['sharedState']['currentState']>, Key extends NestedKeys<Exclude<SharedState, null | undefined>>, Result extends Path<Exclude<SharedState, null | undefined>, Key>>(api: API | undefined | null, plugin: `${PluginName}.${Key}`): Result | undefined;
74
+ export {};
@@ -1,9 +1,12 @@
1
1
  import type { BasePluginDependenciesAPI, EditorInjectionAPI, ExtractInjectionAPI, ExtractPluginSharedState, NextEditorPlugin, NextEditorPluginMetadata } from '../types/next-editor-plugin';
2
- type NamedPluginStatesFromInjectionAPI<API extends ExtractInjectionAPI<NextEditorPlugin<any, any>>, PluginNames extends string | number | symbol> = Readonly<{
2
+ export type NamedPluginStatesFromInjectionAPI<API extends ExtractInjectionAPI<NextEditorPlugin<any, any>>, PluginNames extends string | number | symbol> = Readonly<{
3
3
  [K in PluginNames as `${K extends string ? K : never}State`]: API[K] extends BasePluginDependenciesAPI<any> | undefined ? Exclude<API[K], undefined> extends BasePluginDependenciesAPI<infer Metadata> ? Metadata extends NextEditorPluginMetadata ? ExtractPluginSharedState<Metadata> | undefined : never : never : never;
4
4
  }>;
5
- type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API;
5
+ export type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API;
6
6
  /**
7
+ *
8
+ * NOTE: Generally you may want to use `usePluginStateSelector` over this which behaves similarly
9
+ * but selects a slice of the state which is more performant.
7
10
  *
8
11
  * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
9
12
  * If the plugins you are listening to generate multiple shared states while the user is typing,
@@ -65,4 +68,3 @@ type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API;
65
68
  * the values are the shared state exposed by that plugin.
66
69
  */
67
70
  export declare function useSharedPluginState<API extends EditorInjectionAPI<any, any>, PluginNames extends ExtractPluginNames<API>>(injectionApi: API | null | undefined, plugins: PluginNames[]): NamedPluginStatesFromInjectionAPI<API, PluginNames>;
68
- export {};
@@ -0,0 +1 @@
1
+ export { useSharedPluginStateSelector } from './useSharedPluginStateSelector';
@@ -0,0 +1,74 @@
1
+ import type { EditorInjectionAPI } from '../../types/next-editor-plugin';
2
+ type ExtractPluginNames<API extends EditorInjectionAPI<any, any>> = keyof API extends string ? keyof API : never;
3
+ /**
4
+ * This is designed to iterate through an object to get the path of its result
5
+ * based on separation via "."
6
+ *
7
+ * Example:
8
+ * ```typescript
9
+ * type Test = { deepObject: { value: number } };
10
+ * // Type should be `"deepObject" | "deepObject.value"`
11
+ * type Result = NestedKeys<Test>;
12
+ * ```
13
+ */
14
+ type NestedKeys<T> = {
15
+ [K in keyof T]: T[K] extends object ? T[K] extends any[] ? K extends string ? K : never : T[K] extends object ? K extends string ? K | `${K}.${NestedKeys<T[K]>}` : never : never : K extends string ? K : never;
16
+ }[keyof T];
17
+ /**
18
+ * This is designed to iterate through a path of an object to get the type of its result
19
+ * based on separation via "."
20
+ *
21
+ * Example:
22
+ * ```typescript
23
+ * type Test = { deepObject: { value: number } }
24
+ * // Type should be `number`
25
+ * type Result = Path<Test, 'deepObject.value'>
26
+ * ```
27
+ */
28
+ type Path<T, K extends string> = K extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? Path<T[Key], Rest> : never : K extends keyof T ? T[K] : never;
29
+ /**
30
+ *
31
+ * ⚠️⚠️⚠️ This is a debounced hook ⚠️⚠️⚠️
32
+ * If the plugins you are listening to generate multiple shared states while the user is typing,
33
+ * your React Component will get only the last one.
34
+ *
35
+ * Used to return the current plugin state of input dependencies.
36
+ * It will recursively retrieve a slice of the state using a "." to separate
37
+ * parts of the state.
38
+ *
39
+ * Example:
40
+ *
41
+ * ```typescript
42
+ * const pluginA: NextEditorPlugin<
43
+ 'pluginA',
44
+ {
45
+ sharedState: { deepObj: { value: number | undefined } };
46
+ }
47
+ >
48
+ * ```
49
+ * You can use `const value = useSharedPluginStateSelector(api, 'pluginA.deepObj.value')` to retrieve the value
50
+ *
51
+ * Example in plugin:
52
+ *
53
+ * ```typescript
54
+ * function ExampleContent({ api }: Props) {
55
+ * const title = useSharedPluginStateSelector(api, 'dog.title')
56
+ * return <p>{ title } { exampleState.description }</p>
57
+ * }
58
+ *
59
+ * const examplePlugin: NextEditorPlugin<'example', { dependencies: [typeof pluginDog] }> = ({ api }) => {
60
+ * return {
61
+ * name: 'example',
62
+ * contentComponent: () => <ExampleContent api={api} />
63
+ * }
64
+ * }
65
+ * ```
66
+ *
67
+ * NOTE: If you pass an invalid path, `undefined` will be returned
68
+ *
69
+ * @param api
70
+ * @param plugin
71
+ * @returns
72
+ */
73
+ export declare function useSharedPluginStateSelector<API extends EditorInjectionAPI<any, any>, PluginName extends ExtractPluginNames<API>, SharedState extends ReturnType<Exclude<API[PluginName], null | undefined>['sharedState']['currentState']>, Key extends NestedKeys<Exclude<SharedState, null | undefined>>, Result extends Path<Exclude<SharedState, null | undefined>, Key>>(api: API | undefined | null, plugin: `${PluginName}.${Key}`): Result | undefined;
74
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "96.4.1",
3
+ "version": "96.5.1",
4
4
  "description": "A package that contains common classes and components for editor and renderer",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -105,6 +105,7 @@
105
105
  "./code-block": "./src/code-block/index.ts",
106
106
  "./table": "./src/table/index.ts",
107
107
  "./use-plugin-state-effect": "./src/hooks/usePluginStateEffect.ts",
108
+ "./use-shared-plugin-state-selector": "./src/hooks/useSharedPluginStateSelector/index.ts",
108
109
  "./lazy-node-view": "./src/lazy-node-view/index.ts",
109
110
  "./nesting": "./src/nesting/utilities.ts",
110
111
  "./UNSAFE_do_not_use_editor_context": "./src/ui/EditorContext/index.ts"
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@atlaskit/editor-common/use-shared-plugin-state-selector",
3
+ "main": "../dist/cjs/hooks/useSharedPluginStateSelector/index.js",
4
+ "module": "../dist/esm/hooks/useSharedPluginStateSelector/index.js",
5
+ "module:es2019": "../dist/es2019/hooks/useSharedPluginStateSelector/index.js",
6
+ "sideEffects": false,
7
+ "types": "../dist/types/hooks/useSharedPluginStateSelector/index.d.ts",
8
+ "typesVersions": {
9
+ ">=4.5 <5.4": {
10
+ "*": [
11
+ "../dist/types-ts4.5/hooks/useSharedPluginStateSelector/index.d.ts"
12
+ ]
13
+ }
14
+ }
15
+ }