@atlaskit/editor-common 102.11.2 → 102.11.4

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 (31) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/extensions/messages.js +0 -5
  3. package/dist/cjs/monitoring/error.js +1 -1
  4. package/dist/cjs/portal/common.js +29 -3
  5. package/dist/cjs/portal/index.js +7 -0
  6. package/dist/cjs/react-node-view/getInlineNodeViewProducer.js +13 -2
  7. package/dist/cjs/ui/DropList/index.js +1 -1
  8. package/dist/cjs/ui-menu/Dropdown/index.js +15 -6
  9. package/dist/es2019/extensions/messages.js +0 -5
  10. package/dist/es2019/monitoring/error.js +1 -1
  11. package/dist/es2019/portal/common.js +30 -4
  12. package/dist/es2019/portal/index.js +1 -0
  13. package/dist/es2019/react-node-view/getInlineNodeViewProducer.js +13 -2
  14. package/dist/es2019/ui/DropList/index.js +1 -1
  15. package/dist/es2019/ui-menu/Dropdown/index.js +15 -6
  16. package/dist/esm/extensions/messages.js +0 -5
  17. package/dist/esm/monitoring/error.js +1 -1
  18. package/dist/esm/portal/common.js +29 -4
  19. package/dist/esm/portal/index.js +1 -0
  20. package/dist/esm/react-node-view/getInlineNodeViewProducer.js +13 -2
  21. package/dist/esm/ui/DropList/index.js +1 -1
  22. package/dist/esm/ui-menu/Dropdown/index.js +15 -6
  23. package/dist/types/extensions/messages.d.ts +0 -5
  24. package/dist/types/portal/common.d.ts +9 -1
  25. package/dist/types/portal/index.d.ts +1 -0
  26. package/dist/types/ui-menu/Dropdown/index.d.ts +6 -1
  27. package/dist/types-ts4.5/extensions/messages.d.ts +0 -5
  28. package/dist/types-ts4.5/portal/common.d.ts +9 -1
  29. package/dist/types-ts4.5/portal/index.d.ts +1 -0
  30. package/dist/types-ts4.5/ui-menu/Dropdown/index.d.ts +9 -1
  31. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 102.11.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#129262](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/129262)
8
+ [`9408a99b473bb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9408a99b473bb) -
9
+ EDF-2570 Fixed config panel not closing when navigating to other page issue is fixed.
10
+
11
+ ## 102.11.3
12
+
13
+ ### Patch Changes
14
+
15
+ - [#128680](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/128680)
16
+ [`c621508ab44f7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c621508ab44f7) -
17
+ Fixes rendering delay under virtualization
18
+
3
19
  ## 102.11.2
4
20
 
5
21
  ### Patch Changes
@@ -137,10 +137,5 @@ var configPanelMessages = exports.configPanelMessages = (0, _reactIntlNext.defin
137
137
  id: 'fabric.editor.configPanel.errorBoundary.note',
138
138
  defaultMessage: "We've let the team know. You can still edit and publish this page, or check the error console for more information.",
139
139
  description: 'Note for uncaught config panel error'
140
- },
141
- objectSidebarPanelHeaderLabel: {
142
- id: 'fabric.editor.configPanel.objectSidebarPanelHeaderLabel',
143
- defaultMessage: ' ',
144
- description: 'Keep this empty. Defined it as headerLabel is required field.'
145
140
  }
146
141
  });
@@ -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 = "102.11.2";
20
+ var packageVersion = "102.11.4";
21
21
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
22
22
  // Remove URL as it has UGC
23
23
  // Ignored via go/ees007
@@ -5,6 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
+ exports.PortalRenderWrapperInner = void 0;
8
9
  exports.createPortalRendererComponent = createPortalRendererComponent;
9
10
  exports.getPortalProviderAPI = void 0;
10
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
@@ -41,6 +42,23 @@ function createPortalRendererComponent(portalManager) {
41
42
  };
42
43
  }
43
44
 
45
+ /**
46
+ * Wraps the children of a portal to allow for React rendering
47
+ * lifecycle hook to be exposed, primarily for node virtualization.
48
+ */
49
+ var PortalRenderWrapperInner = exports.PortalRenderWrapperInner = function PortalRenderWrapperInner(_ref) {
50
+ var getChildren = _ref.getChildren,
51
+ onBeforeRender = _ref.onBeforeRender;
52
+ (0, _react.useLayoutEffect)(function () {
53
+ if (onBeforeRender) {
54
+ onBeforeRender();
55
+ }
56
+ }, [onBeforeRender]);
57
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, getChildren());
58
+ };
59
+ var PortalRenderWrapper = /*#__PURE__*/(0, _react.memo)(PortalRenderWrapperInner);
60
+ PortalRenderWrapper.displayName = 'PortalRenderWrapper';
61
+
44
62
  /**
45
63
  * Creates a portal provider for managing multiple React portals. The provider
46
64
  * facilitates rendering, removing, and destroying portals managed by a given
@@ -62,9 +80,17 @@ function createPortalRendererComponent(portalManager) {
62
80
  var getPortalProviderAPI = exports.getPortalProviderAPI = function getPortalProviderAPI(portalManager) {
63
81
  var portalsMap = new Map();
64
82
  return {
65
- render: function render(children, container, key) {
66
- var portal = /*#__PURE__*/(0, _reactDom.createPortal)(children(), container, key);
67
- portalsMap.set(key, portalManager.registerPortal(key, portal));
83
+ render: function render(children, container, key, onBeforeReactDomRender) {
84
+ if (typeof onBeforeReactDomRender === 'function') {
85
+ var portal = /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/_react.default.createElement(PortalRenderWrapper, {
86
+ getChildren: children,
87
+ onBeforeRender: onBeforeReactDomRender
88
+ }), container, key);
89
+ portalsMap.set(key, portalManager.registerPortal(key, portal));
90
+ } else {
91
+ var _portal = /*#__PURE__*/(0, _reactDom.createPortal)(children(), container, key);
92
+ portalsMap.set(key, portalManager.registerPortal(key, _portal));
93
+ }
68
94
  },
69
95
  remove: function remove(key) {
70
96
  var _portalsMap$get;
@@ -15,6 +15,12 @@ Object.defineProperty(exports, "PortalManager", {
15
15
  return _PortalManager.PortalManager;
16
16
  }
17
17
  });
18
+ Object.defineProperty(exports, "PortalRenderWrapperInner", {
19
+ enumerable: true,
20
+ get: function get() {
21
+ return _common.PortalRenderWrapperInner;
22
+ }
23
+ });
18
24
  Object.defineProperty(exports, "usePortalProvider", {
19
25
  enumerable: true,
20
26
  get: function get() {
@@ -22,5 +28,6 @@ Object.defineProperty(exports, "usePortalProvider", {
22
28
  }
23
29
  });
24
30
  var _PortalManager = require("./PortalManager");
31
+ var _common = require("./common");
25
32
  var _PortalBucket = require("./PortalBucket");
26
33
  var _usePortalProvider = require("./usePortalProvider");
@@ -100,12 +100,22 @@ function createNodeView(_ref) {
100
100
  var domRef = document.createElement('span');
101
101
  domRef.contentEditable = 'false';
102
102
  setDomAttrs(nodeViewParams.node, domRef);
103
+ var fallbackRef = {
104
+ current: null
105
+ };
103
106
 
104
107
  // @see ED-3790
105
108
  // something gets messed up during mutation processing inside of a
106
109
  // nodeView if DOM structure has nested plain "div"s, it doesn't see the
107
110
  // difference between them and it kills the nodeView
108
111
  domRef.classList.add("".concat(nodeViewParams.node.type.name, "View-content-wrap"), "".concat(inlineNodeViewClassname));
112
+ function onBeforeReactDomRender() {
113
+ if (!fallbackRef.current) {
114
+ return;
115
+ }
116
+ domRef.removeChild(fallbackRef.current);
117
+ fallbackRef.current = null;
118
+ }
109
119
 
110
120
  // This util is shared for tracking rendering, and the ErrorBoundary that
111
121
  // is setup to wrap the Component when rendering
@@ -128,7 +138,7 @@ function createNodeView(_ref) {
128
138
  nodeViewParams: nodeViewParams,
129
139
  Component: Component,
130
140
  extraComponentProps: extraComponentProps
131
- }), domRef, key);
141
+ }), domRef, key, enableVirtualization ? onBeforeReactDomRender : undefined);
132
142
  }
133
143
  var didRenderComponentWithIntersectionObserver = false;
134
144
  var destroyed = false;
@@ -137,6 +147,7 @@ function createNodeView(_ref) {
137
147
  var _currentNode$type;
138
148
  if (canRenderFallback(currentNode) && typeof ((_currentNode$type = currentNode.type) === null || _currentNode$type === void 0 || (_currentNode$type = _currentNode$type.spec) === null || _currentNode$type === void 0 ? void 0 : _currentNode$type.toDOM) === 'function') {
139
149
  var fallback = _model.DOMSerializer.renderSpec(document, currentNode.type.spec.toDOM(currentNode));
150
+ fallbackRef.current = fallback.dom;
140
151
  domRef.replaceChildren(fallback.dom);
141
152
  }
142
153
  }
@@ -145,7 +156,6 @@ function createNodeView(_ref) {
145
156
  if (domRef) {
146
157
  removeIntersectionObserver = observer.observe(domRef, function () {
147
158
  if (!didRenderComponentWithIntersectionObserver && !destroyed) {
148
- domRef.replaceChildren();
149
159
  renderComponent();
150
160
  didRenderComponentWithIntersectionObserver = true;
151
161
  }
@@ -243,6 +253,7 @@ function createNodeView(_ref) {
243
253
  // of HTMLSpanElement type however once the node view has
244
254
  // been destroyed no other consumers should still be using it.
245
255
  domRef = undefined;
256
+ fallbackRef.current = null;
246
257
  if (virtualizeNode) {
247
258
  destroyed = true;
248
259
  }
@@ -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 = "102.11.2";
26
+ var packageVersion = "102.11.4";
27
27
  var halfFocusRing = 1;
28
28
  var dropOffset = '0, 8';
29
29
  // Ignored via go/ees005
@@ -84,19 +84,28 @@ var Dropdown = exports.Dropdown = /*#__PURE__*/function (_PureComponent) {
84
84
  zIndex = _this$props.zIndex,
85
85
  arrowKeyNavigationProviderOptions = _this$props.arrowKeyNavigationProviderOptions,
86
86
  dropdownListId = _this$props.dropdownListId,
87
- alignDropdownWithParentElement = _this$props.alignDropdownWithParentElement;
87
+ alignDropdownWithParentElement = _this$props.alignDropdownWithParentElement,
88
+ targetProp = _this$props.target,
89
+ forcePlacement = _this$props.forcePlacement,
90
+ alignX = _this$props.alignX,
91
+ alignY = _this$props.alignY,
92
+ offset = _this$props.offset;
88
93
  return /*#__PURE__*/_react.default.createElement(_Popup.default, {
89
- target: alignDropdownWithParentElement ? // Ignored via go/ees005
94
+ target: targetProp !== null && targetProp !== void 0 ? targetProp : alignDropdownWithParentElement ? // Ignored via go/ees005
90
95
  // eslint-disable-next-line @atlaskit/editor/no-as-casting
91
96
  target === null || target === void 0 ? void 0 : target.closest("[data-testid='editor-floating-toolbar']") : target,
92
97
  mountTo: mountTo,
93
98
  boundariesElement: boundariesElement,
94
99
  scrollableElement: scrollableElement,
95
- onPlacementChanged: this.updatePopupPlacement,
100
+ onPlacementChanged: forcePlacement ? undefined : this.updatePopupPlacement,
96
101
  fitHeight: fitHeight,
97
102
  fitWidth: fitWidth,
98
103
  zIndex: zIndex,
99
- allowOutOfBounds: alignDropdownWithParentElement
104
+ allowOutOfBounds: alignDropdownWithParentElement,
105
+ alignX: alignX,
106
+ alignY: alignY,
107
+ forcePlacement: forcePlacement,
108
+ offset: offset
100
109
  }, /*#__PURE__*/_react.default.createElement(_ArrowKeyNavigationProvider.ArrowKeyNavigationProvider
101
110
  // Ignored via go/ees005
102
111
  // eslint-disable-next-line react/jsx-props-no-spreading
@@ -123,11 +132,11 @@ var Dropdown = exports.Dropdown = /*#__PURE__*/function (_PureComponent) {
123
132
  var _this$props2 = this.props,
124
133
  trigger = _this$props2.trigger,
125
134
  isOpen = _this$props2.isOpen;
126
- return /*#__PURE__*/_react.default.createElement(_uiReact.OutsideClickTargetRefContext.Consumer, null, function (setOutsideClickTargetRef) {
135
+ return trigger ? /*#__PURE__*/_react.default.createElement(_uiReact.OutsideClickTargetRefContext.Consumer, null, function (setOutsideClickTargetRef) {
127
136
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
128
137
  ref: _this2.handleRef(setOutsideClickTargetRef)
129
138
  }, trigger), isOpen ? _this2.renderDropdown() : null);
130
- });
139
+ }) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isOpen ? this.renderDropdown() : null);
131
140
  }
132
141
  }]);
133
142
  }(_react.PureComponent);
@@ -131,10 +131,5 @@ export const configPanelMessages = defineMessages({
131
131
  id: 'fabric.editor.configPanel.errorBoundary.note',
132
132
  defaultMessage: `We've let the team know. You can still edit and publish this page, or check the error console for more information.`,
133
133
  description: 'Note for uncaught config panel error'
134
- },
135
- objectSidebarPanelHeaderLabel: {
136
- id: 'fabric.editor.configPanel.objectSidebarPanelHeaderLabel',
137
- defaultMessage: ' ',
138
- description: 'Keep this empty. Defined it as headerLabel is required field.'
139
134
  }
140
135
  });
@@ -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 = "102.11.2";
4
+ const packageVersion = "102.11.4";
5
5
  const sanitiseSentryEvents = (data, _hint) => {
6
6
  // Remove URL as it has UGC
7
7
  // Ignored via go/ees007
@@ -1,4 +1,4 @@
1
- import React, { useLayoutEffect, useMemo, useState } from 'react';
1
+ import React, { memo, useLayoutEffect, useMemo, useState } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
  import { PortalBucket } from './PortalBucket';
4
4
  export function createPortalRendererComponent(portalManager) {
@@ -22,6 +22,24 @@ export function createPortalRendererComponent(portalManager) {
22
22
  };
23
23
  }
24
24
 
25
+ /**
26
+ * Wraps the children of a portal to allow for React rendering
27
+ * lifecycle hook to be exposed, primarily for node virtualization.
28
+ */
29
+ export const PortalRenderWrapperInner = ({
30
+ getChildren,
31
+ onBeforeRender
32
+ }) => {
33
+ useLayoutEffect(() => {
34
+ if (onBeforeRender) {
35
+ onBeforeRender();
36
+ }
37
+ }, [onBeforeRender]);
38
+ return /*#__PURE__*/React.createElement(React.Fragment, null, getChildren());
39
+ };
40
+ const PortalRenderWrapper = /*#__PURE__*/memo(PortalRenderWrapperInner);
41
+ PortalRenderWrapper.displayName = 'PortalRenderWrapper';
42
+
25
43
  /**
26
44
  * Creates a portal provider for managing multiple React portals. The provider
27
45
  * facilitates rendering, removing, and destroying portals managed by a given
@@ -43,9 +61,17 @@ export function createPortalRendererComponent(portalManager) {
43
61
  export const getPortalProviderAPI = portalManager => {
44
62
  const portalsMap = new Map();
45
63
  return {
46
- render: (children, container, key) => {
47
- const portal = /*#__PURE__*/createPortal(children(), container, key);
48
- portalsMap.set(key, portalManager.registerPortal(key, portal));
64
+ render: (children, container, key, onBeforeReactDomRender) => {
65
+ if (typeof onBeforeReactDomRender === 'function') {
66
+ const portal = /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(PortalRenderWrapper, {
67
+ getChildren: children,
68
+ onBeforeRender: onBeforeReactDomRender
69
+ }), container, key);
70
+ portalsMap.set(key, portalManager.registerPortal(key, portal));
71
+ } else {
72
+ const portal = /*#__PURE__*/createPortal(children(), container, key);
73
+ portalsMap.set(key, portalManager.registerPortal(key, portal));
74
+ }
49
75
  },
50
76
  remove: key => {
51
77
  var _portalsMap$get;
@@ -2,5 +2,6 @@
2
2
  /* eslint-disable @atlaskit/editor/no-re-export */
3
3
 
4
4
  export { PortalManager } from './PortalManager';
5
+ export { PortalRenderWrapperInner } from './common';
5
6
  export { PortalBucket } from './PortalBucket';
6
7
  export { usePortalProvider } from './usePortalProvider';
@@ -90,12 +90,22 @@ function createNodeView({
90
90
  let domRef = document.createElement('span');
91
91
  domRef.contentEditable = 'false';
92
92
  setDomAttrs(nodeViewParams.node, domRef);
93
+ const fallbackRef = {
94
+ current: null
95
+ };
93
96
 
94
97
  // @see ED-3790
95
98
  // something gets messed up during mutation processing inside of a
96
99
  // nodeView if DOM structure has nested plain "div"s, it doesn't see the
97
100
  // difference between them and it kills the nodeView
98
101
  domRef.classList.add(`${nodeViewParams.node.type.name}View-content-wrap`, `${inlineNodeViewClassname}`);
102
+ function onBeforeReactDomRender() {
103
+ if (!fallbackRef.current) {
104
+ return;
105
+ }
106
+ domRef.removeChild(fallbackRef.current);
107
+ fallbackRef.current = null;
108
+ }
99
109
 
100
110
  // This util is shared for tracking rendering, and the ErrorBoundary that
101
111
  // is setup to wrap the Component when rendering
@@ -118,7 +128,7 @@ function createNodeView({
118
128
  nodeViewParams,
119
129
  Component,
120
130
  extraComponentProps
121
- }), domRef, key);
131
+ }), domRef, key, enableVirtualization ? onBeforeReactDomRender : undefined);
122
132
  }
123
133
  let didRenderComponentWithIntersectionObserver = false;
124
134
  let destroyed = false;
@@ -127,6 +137,7 @@ function createNodeView({
127
137
  var _currentNode$type, _currentNode$type$spe;
128
138
  if (canRenderFallback(currentNode) && typeof ((_currentNode$type = currentNode.type) === null || _currentNode$type === void 0 ? void 0 : (_currentNode$type$spe = _currentNode$type.spec) === null || _currentNode$type$spe === void 0 ? void 0 : _currentNode$type$spe.toDOM) === 'function') {
129
139
  const fallback = DOMSerializer.renderSpec(document, currentNode.type.spec.toDOM(currentNode));
140
+ fallbackRef.current = fallback.dom;
130
141
  domRef.replaceChildren(fallback.dom);
131
142
  }
132
143
  }
@@ -135,7 +146,6 @@ function createNodeView({
135
146
  if (domRef) {
136
147
  removeIntersectionObserver = observer.observe(domRef, () => {
137
148
  if (!didRenderComponentWithIntersectionObserver && !destroyed) {
138
- domRef.replaceChildren();
139
149
  renderComponent();
140
150
  didRenderComponentWithIntersectionObserver = true;
141
151
  }
@@ -237,6 +247,7 @@ function createNodeView({
237
247
  // of HTMLSpanElement type however once the node view has
238
248
  // been destroyed no other consumers should still be using it.
239
249
  domRef = undefined;
250
+ fallbackRef.current = null;
240
251
  if (virtualizeNode) {
241
252
  destroyed = true;
242
253
  }
@@ -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 = "102.11.2";
16
+ const packageVersion = "102.11.4";
17
17
  const halfFocusRing = 1;
18
18
  const dropOffset = '0, 8';
19
19
  // Ignored via go/ees005
@@ -60,20 +60,29 @@ export class Dropdown extends PureComponent {
60
60
  zIndex,
61
61
  arrowKeyNavigationProviderOptions,
62
62
  dropdownListId,
63
- alignDropdownWithParentElement
63
+ alignDropdownWithParentElement,
64
+ target: targetProp,
65
+ forcePlacement,
66
+ alignX,
67
+ alignY,
68
+ offset
64
69
  } = this.props;
65
70
  return /*#__PURE__*/React.createElement(Popup, {
66
- target: alignDropdownWithParentElement ? // Ignored via go/ees005
71
+ target: targetProp !== null && targetProp !== void 0 ? targetProp : alignDropdownWithParentElement ? // Ignored via go/ees005
67
72
  // eslint-disable-next-line @atlaskit/editor/no-as-casting
68
73
  target === null || target === void 0 ? void 0 : target.closest("[data-testid='editor-floating-toolbar']") : target,
69
74
  mountTo: mountTo,
70
75
  boundariesElement: boundariesElement,
71
76
  scrollableElement: scrollableElement,
72
- onPlacementChanged: this.updatePopupPlacement,
77
+ onPlacementChanged: forcePlacement ? undefined : this.updatePopupPlacement,
73
78
  fitHeight: fitHeight,
74
79
  fitWidth: fitWidth,
75
80
  zIndex: zIndex,
76
- allowOutOfBounds: alignDropdownWithParentElement
81
+ allowOutOfBounds: alignDropdownWithParentElement,
82
+ alignX: alignX,
83
+ alignY: alignY,
84
+ forcePlacement: forcePlacement,
85
+ offset: offset
77
86
  }, /*#__PURE__*/React.createElement(ArrowKeyNavigationProvider
78
87
  // Ignored via go/ees005
79
88
  // eslint-disable-next-line react/jsx-props-no-spreading
@@ -98,9 +107,9 @@ export class Dropdown extends PureComponent {
98
107
  trigger,
99
108
  isOpen
100
109
  } = this.props;
101
- return /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Consumer, null, setOutsideClickTargetRef => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
110
+ return trigger ? /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Consumer, null, setOutsideClickTargetRef => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
102
111
  ref: this.handleRef(setOutsideClickTargetRef)
103
- }, trigger), isOpen ? this.renderDropdown() : null));
112
+ }, trigger), isOpen ? this.renderDropdown() : null)) : /*#__PURE__*/React.createElement(React.Fragment, null, isOpen ? this.renderDropdown() : null);
104
113
  }
105
114
  }
106
115
  const DropdownWithOuterListeners = withReactEditorViewOuterListeners(Dropdown);
@@ -131,10 +131,5 @@ export var configPanelMessages = defineMessages({
131
131
  id: 'fabric.editor.configPanel.errorBoundary.note',
132
132
  defaultMessage: "We've let the team know. You can still edit and publish this page, or check the error console for more information.",
133
133
  description: 'Note for uncaught config panel error'
134
- },
135
- objectSidebarPanelHeaderLabel: {
136
- id: 'fabric.editor.configPanel.objectSidebarPanelHeaderLabel',
137
- defaultMessage: ' ',
138
- description: 'Keep this empty. Defined it as headerLabel is required field.'
139
134
  }
140
135
  });
@@ -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 = "102.11.2";
10
+ var packageVersion = "102.11.4";
11
11
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
12
12
  // Remove URL as it has UGC
13
13
  // Ignored via go/ees007
@@ -1,5 +1,5 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { useLayoutEffect, useMemo, useState } from 'react';
2
+ import React, { memo, useLayoutEffect, useMemo, useState } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { PortalBucket } from './PortalBucket';
5
5
  export function createPortalRendererComponent(portalManager) {
@@ -30,6 +30,23 @@ export function createPortalRendererComponent(portalManager) {
30
30
  };
31
31
  }
32
32
 
33
+ /**
34
+ * Wraps the children of a portal to allow for React rendering
35
+ * lifecycle hook to be exposed, primarily for node virtualization.
36
+ */
37
+ export var PortalRenderWrapperInner = function PortalRenderWrapperInner(_ref) {
38
+ var getChildren = _ref.getChildren,
39
+ onBeforeRender = _ref.onBeforeRender;
40
+ useLayoutEffect(function () {
41
+ if (onBeforeRender) {
42
+ onBeforeRender();
43
+ }
44
+ }, [onBeforeRender]);
45
+ return /*#__PURE__*/React.createElement(React.Fragment, null, getChildren());
46
+ };
47
+ var PortalRenderWrapper = /*#__PURE__*/memo(PortalRenderWrapperInner);
48
+ PortalRenderWrapper.displayName = 'PortalRenderWrapper';
49
+
33
50
  /**
34
51
  * Creates a portal provider for managing multiple React portals. The provider
35
52
  * facilitates rendering, removing, and destroying portals managed by a given
@@ -51,9 +68,17 @@ export function createPortalRendererComponent(portalManager) {
51
68
  export var getPortalProviderAPI = function getPortalProviderAPI(portalManager) {
52
69
  var portalsMap = new Map();
53
70
  return {
54
- render: function render(children, container, key) {
55
- var portal = /*#__PURE__*/createPortal(children(), container, key);
56
- portalsMap.set(key, portalManager.registerPortal(key, portal));
71
+ render: function render(children, container, key, onBeforeReactDomRender) {
72
+ if (typeof onBeforeReactDomRender === 'function') {
73
+ var portal = /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(PortalRenderWrapper, {
74
+ getChildren: children,
75
+ onBeforeRender: onBeforeReactDomRender
76
+ }), container, key);
77
+ portalsMap.set(key, portalManager.registerPortal(key, portal));
78
+ } else {
79
+ var _portal = /*#__PURE__*/createPortal(children(), container, key);
80
+ portalsMap.set(key, portalManager.registerPortal(key, _portal));
81
+ }
57
82
  },
58
83
  remove: function remove(key) {
59
84
  var _portalsMap$get;
@@ -2,5 +2,6 @@
2
2
  /* eslint-disable @atlaskit/editor/no-re-export */
3
3
 
4
4
  export { PortalManager } from './PortalManager';
5
+ export { PortalRenderWrapperInner } from './common';
5
6
  export { PortalBucket } from './PortalBucket';
6
7
  export { usePortalProvider } from './usePortalProvider';
@@ -95,12 +95,22 @@ function createNodeView(_ref) {
95
95
  var domRef = document.createElement('span');
96
96
  domRef.contentEditable = 'false';
97
97
  setDomAttrs(nodeViewParams.node, domRef);
98
+ var fallbackRef = {
99
+ current: null
100
+ };
98
101
 
99
102
  // @see ED-3790
100
103
  // something gets messed up during mutation processing inside of a
101
104
  // nodeView if DOM structure has nested plain "div"s, it doesn't see the
102
105
  // difference between them and it kills the nodeView
103
106
  domRef.classList.add("".concat(nodeViewParams.node.type.name, "View-content-wrap"), "".concat(inlineNodeViewClassname));
107
+ function onBeforeReactDomRender() {
108
+ if (!fallbackRef.current) {
109
+ return;
110
+ }
111
+ domRef.removeChild(fallbackRef.current);
112
+ fallbackRef.current = null;
113
+ }
104
114
 
105
115
  // This util is shared for tracking rendering, and the ErrorBoundary that
106
116
  // is setup to wrap the Component when rendering
@@ -123,7 +133,7 @@ function createNodeView(_ref) {
123
133
  nodeViewParams: nodeViewParams,
124
134
  Component: Component,
125
135
  extraComponentProps: extraComponentProps
126
- }), domRef, key);
136
+ }), domRef, key, enableVirtualization ? onBeforeReactDomRender : undefined);
127
137
  }
128
138
  var didRenderComponentWithIntersectionObserver = false;
129
139
  var destroyed = false;
@@ -132,6 +142,7 @@ function createNodeView(_ref) {
132
142
  var _currentNode$type;
133
143
  if (canRenderFallback(currentNode) && typeof ((_currentNode$type = currentNode.type) === null || _currentNode$type === void 0 || (_currentNode$type = _currentNode$type.spec) === null || _currentNode$type === void 0 ? void 0 : _currentNode$type.toDOM) === 'function') {
134
144
  var fallback = DOMSerializer.renderSpec(document, currentNode.type.spec.toDOM(currentNode));
145
+ fallbackRef.current = fallback.dom;
135
146
  domRef.replaceChildren(fallback.dom);
136
147
  }
137
148
  }
@@ -140,7 +151,6 @@ function createNodeView(_ref) {
140
151
  if (domRef) {
141
152
  removeIntersectionObserver = observer.observe(domRef, function () {
142
153
  if (!didRenderComponentWithIntersectionObserver && !destroyed) {
143
- domRef.replaceChildren();
144
154
  renderComponent();
145
155
  didRenderComponentWithIntersectionObserver = true;
146
156
  }
@@ -238,6 +248,7 @@ function createNodeView(_ref) {
238
248
  // of HTMLSpanElement type however once the node view has
239
249
  // been destroyed no other consumers should still be using it.
240
250
  domRef = undefined;
251
+ fallbackRef.current = null;
241
252
  if (virtualizeNode) {
242
253
  destroyed = true;
243
254
  }
@@ -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 = "102.11.2";
23
+ var packageVersion = "102.11.4";
24
24
  var halfFocusRing = 1;
25
25
  var dropOffset = '0, 8';
26
26
  // Ignored via go/ees005
@@ -74,19 +74,28 @@ export var Dropdown = /*#__PURE__*/function (_PureComponent) {
74
74
  zIndex = _this$props.zIndex,
75
75
  arrowKeyNavigationProviderOptions = _this$props.arrowKeyNavigationProviderOptions,
76
76
  dropdownListId = _this$props.dropdownListId,
77
- alignDropdownWithParentElement = _this$props.alignDropdownWithParentElement;
77
+ alignDropdownWithParentElement = _this$props.alignDropdownWithParentElement,
78
+ targetProp = _this$props.target,
79
+ forcePlacement = _this$props.forcePlacement,
80
+ alignX = _this$props.alignX,
81
+ alignY = _this$props.alignY,
82
+ offset = _this$props.offset;
78
83
  return /*#__PURE__*/React.createElement(Popup, {
79
- target: alignDropdownWithParentElement ? // Ignored via go/ees005
84
+ target: targetProp !== null && targetProp !== void 0 ? targetProp : alignDropdownWithParentElement ? // Ignored via go/ees005
80
85
  // eslint-disable-next-line @atlaskit/editor/no-as-casting
81
86
  target === null || target === void 0 ? void 0 : target.closest("[data-testid='editor-floating-toolbar']") : target,
82
87
  mountTo: mountTo,
83
88
  boundariesElement: boundariesElement,
84
89
  scrollableElement: scrollableElement,
85
- onPlacementChanged: this.updatePopupPlacement,
90
+ onPlacementChanged: forcePlacement ? undefined : this.updatePopupPlacement,
86
91
  fitHeight: fitHeight,
87
92
  fitWidth: fitWidth,
88
93
  zIndex: zIndex,
89
- allowOutOfBounds: alignDropdownWithParentElement
94
+ allowOutOfBounds: alignDropdownWithParentElement,
95
+ alignX: alignX,
96
+ alignY: alignY,
97
+ forcePlacement: forcePlacement,
98
+ offset: offset
90
99
  }, /*#__PURE__*/React.createElement(ArrowKeyNavigationProvider
91
100
  // Ignored via go/ees005
92
101
  // eslint-disable-next-line react/jsx-props-no-spreading
@@ -113,11 +122,11 @@ export var Dropdown = /*#__PURE__*/function (_PureComponent) {
113
122
  var _this$props2 = this.props,
114
123
  trigger = _this$props2.trigger,
115
124
  isOpen = _this$props2.isOpen;
116
- return /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Consumer, null, function (setOutsideClickTargetRef) {
125
+ return trigger ? /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Consumer, null, function (setOutsideClickTargetRef) {
117
126
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
118
127
  ref: _this2.handleRef(setOutsideClickTargetRef)
119
128
  }, trigger), isOpen ? _this2.renderDropdown() : null);
120
- });
129
+ }) : /*#__PURE__*/React.createElement(React.Fragment, null, isOpen ? this.renderDropdown() : null);
121
130
  }
122
131
  }]);
123
132
  }(PureComponent);
@@ -131,9 +131,4 @@ export declare const configPanelMessages: {
131
131
  defaultMessage: string;
132
132
  description: string;
133
133
  };
134
- objectSidebarPanelHeaderLabel: {
135
- id: string;
136
- defaultMessage: string;
137
- description: string;
138
- };
139
134
  };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type PortalManager } from './PortalManager';
3
- type RenderFn = (children: () => React.ReactChild | JSX.Element | null, container: HTMLElement, key: string) => void;
3
+ type RenderFn = (children: () => React.ReactChild | JSX.Element | null, container: HTMLElement, key: string, onBeforeReactDomRender?: () => void) => void;
4
4
  type RemoveFn = (key: string) => void;
5
5
  type DestoryFn = () => void;
6
6
  export interface PortalProviderAPI {
@@ -11,6 +11,14 @@ export interface PortalProviderAPI {
11
11
  export type PortalRendererComponent = () => JSX.Element;
12
12
  export type UsePortalProviderReturnType = [PortalProviderAPI, PortalRendererComponent];
13
13
  export declare function createPortalRendererComponent(portalManager: PortalManager): () => React.JSX.Element;
14
+ /**
15
+ * Wraps the children of a portal to allow for React rendering
16
+ * lifecycle hook to be exposed, primarily for node virtualization.
17
+ */
18
+ export declare const PortalRenderWrapperInner: ({ getChildren, onBeforeRender, }: {
19
+ getChildren: () => React.ReactNode;
20
+ onBeforeRender: () => void;
21
+ }) => React.JSX.Element;
14
22
  /**
15
23
  * Creates a portal provider for managing multiple React portals. The provider
16
24
  * facilitates rendering, removing, and destroying portals managed by a given
@@ -1,4 +1,5 @@
1
1
  export { PortalManager } from './PortalManager';
2
+ export { PortalRenderWrapperInner } from './common';
2
3
  export { PortalBucket } from './PortalBucket';
3
4
  export { usePortalProvider } from './usePortalProvider';
4
5
  export type { PortalProviderAPI } from './common';
@@ -7,7 +7,7 @@ export interface Props {
7
7
  mountTo?: HTMLElement;
8
8
  boundariesElement?: HTMLElement;
9
9
  scrollableElement?: HTMLElement;
10
- trigger: React.ReactElement<any>;
10
+ trigger?: React.ReactElement<any>;
11
11
  isOpen?: boolean;
12
12
  onOpenChange?: (attrs: OpenChangedEvent) => void;
13
13
  fitWidth?: number;
@@ -16,6 +16,11 @@ export interface Props {
16
16
  arrowKeyNavigationProviderOptions: ArrowKeyNavigationProviderOptions;
17
17
  dropdownListId?: string;
18
18
  alignDropdownWithParentElement?: boolean;
19
+ target?: HTMLElement;
20
+ forcePlacement?: boolean;
21
+ alignX?: 'left' | 'right' | 'center';
22
+ alignY?: 'start' | 'bottom' | 'top';
23
+ offset?: [number, number];
19
24
  }
20
25
  export interface State {
21
26
  target?: HTMLElement;
@@ -131,9 +131,4 @@ export declare const configPanelMessages: {
131
131
  defaultMessage: string;
132
132
  description: string;
133
133
  };
134
- objectSidebarPanelHeaderLabel: {
135
- id: string;
136
- defaultMessage: string;
137
- description: string;
138
- };
139
134
  };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type PortalManager } from './PortalManager';
3
- type RenderFn = (children: () => React.ReactChild | JSX.Element | null, container: HTMLElement, key: string) => void;
3
+ type RenderFn = (children: () => React.ReactChild | JSX.Element | null, container: HTMLElement, key: string, onBeforeReactDomRender?: () => void) => void;
4
4
  type RemoveFn = (key: string) => void;
5
5
  type DestoryFn = () => void;
6
6
  export interface PortalProviderAPI {
@@ -14,6 +14,14 @@ export type UsePortalProviderReturnType = [
14
14
  PortalRendererComponent
15
15
  ];
16
16
  export declare function createPortalRendererComponent(portalManager: PortalManager): () => React.JSX.Element;
17
+ /**
18
+ * Wraps the children of a portal to allow for React rendering
19
+ * lifecycle hook to be exposed, primarily for node virtualization.
20
+ */
21
+ export declare const PortalRenderWrapperInner: ({ getChildren, onBeforeRender, }: {
22
+ getChildren: () => React.ReactNode;
23
+ onBeforeRender: () => void;
24
+ }) => React.JSX.Element;
17
25
  /**
18
26
  * Creates a portal provider for managing multiple React portals. The provider
19
27
  * facilitates rendering, removing, and destroying portals managed by a given
@@ -1,4 +1,5 @@
1
1
  export { PortalManager } from './PortalManager';
2
+ export { PortalRenderWrapperInner } from './common';
2
3
  export { PortalBucket } from './PortalBucket';
3
4
  export { usePortalProvider } from './usePortalProvider';
4
5
  export type { PortalProviderAPI } from './common';
@@ -7,7 +7,7 @@ export interface Props {
7
7
  mountTo?: HTMLElement;
8
8
  boundariesElement?: HTMLElement;
9
9
  scrollableElement?: HTMLElement;
10
- trigger: React.ReactElement<any>;
10
+ trigger?: React.ReactElement<any>;
11
11
  isOpen?: boolean;
12
12
  onOpenChange?: (attrs: OpenChangedEvent) => void;
13
13
  fitWidth?: number;
@@ -16,6 +16,14 @@ export interface Props {
16
16
  arrowKeyNavigationProviderOptions: ArrowKeyNavigationProviderOptions;
17
17
  dropdownListId?: string;
18
18
  alignDropdownWithParentElement?: boolean;
19
+ target?: HTMLElement;
20
+ forcePlacement?: boolean;
21
+ alignX?: 'left' | 'right' | 'center';
22
+ alignY?: 'start' | 'bottom' | 'top';
23
+ offset?: [
24
+ number,
25
+ number
26
+ ];
19
27
  }
20
28
  export interface State {
21
29
  target?: HTMLElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "102.11.2",
3
+ "version": "102.11.4",
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/"