@atlaskit/editor-plugin-layout 11.0.3 → 11.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/editor-plugin-layout
2
2
 
3
+ ## 11.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`1f5c61250d103`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1f5c61250d103) -
8
+ Updating layout plugin to support ssr streaming
9
+
3
10
  ## 11.0.3
4
11
 
5
12
  ### Patch Changes
@@ -114,8 +114,9 @@ var layoutPlugin = exports.layoutPlugin = function layoutPlugin(_ref) {
114
114
  name: 'layoutResizing',
115
115
  plugin: function plugin(_ref2) {
116
116
  var portalProviderAPI = _ref2.portalProviderAPI,
117
- eventDispatcher = _ref2.eventDispatcher;
118
- return (0, _resizing.default)(options, api, portalProviderAPI, eventDispatcher);
117
+ eventDispatcher = _ref2.eventDispatcher,
118
+ getIntl = _ref2.getIntl;
119
+ return (0, _resizing.default)(options, api, portalProviderAPI, eventDispatcher, getIntl());
119
120
  }
120
121
  });
121
122
  }
@@ -13,8 +13,9 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
13
13
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
14
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
15
  var _react = _interopRequireWildcard(require("react"));
16
+ var _coreUtils = require("@atlaskit/editor-common/core-utils");
16
17
  var _hooks = require("@atlaskit/editor-common/hooks");
17
- var _reactNodeView = _interopRequireDefault(require("@atlaskit/editor-common/react-node-view"));
18
+ var _reactNodeView = _interopRequireWildcard(require("@atlaskit/editor-common/react-node-view"));
18
19
  var _resizer = require("@atlaskit/editor-common/resizer");
19
20
  var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
20
21
  var _model = require("@atlaskit/editor-prosemirror/model");
@@ -22,6 +23,7 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
22
23
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
23
24
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
24
25
  var _utils = require("../pm-plugins/utils");
26
+ var _LayoutSSRReactContextsProvider = require("../ui/LayoutSSRReactContextsProvider");
25
27
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
26
28
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
27
29
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
@@ -140,6 +142,7 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
140
142
  * @param props.eventDispatcher
141
143
  * @param props.pluginInjectionApi
142
144
  * @param props.options
145
+ * @param props.intl
143
146
  * @example
144
147
  */
145
148
  function LayoutSectionView(props) {
@@ -148,6 +151,7 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
148
151
  _this = _callSuper(this, LayoutSectionView, [props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props]);
149
152
  _this.isEmpty = isEmptyLayout(_this.node);
150
153
  _this.options = props.options;
154
+ _this.intl = props.intl;
151
155
  return _this;
152
156
  }
153
157
 
@@ -160,6 +164,13 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
160
164
  return (0, _createClass2.default)(LayoutSectionView, [{
161
165
  key: "getContentDOM",
162
166
  value: function getContentDOM() {
167
+ // Build the layout DOM via the schema's toDOM spec. This is the same
168
+ // path used in both CSR and SSR — the only SSR-specific concern is
169
+ // re-attaching `contentDOM` (= the `[data-layout-section]` element)
170
+ // after the portal's renderToStaticMarkup + innerHTML write detaches
171
+ // it. We handle that by stamping `data-ssr-content-dom-ref` on the
172
+ // outer container so `ReactNodeView.init()` can find a re-attach
173
+ // target inside `domRef` after the portal write.
163
174
  var _ref2 = _model.DOMSerializer.renderSpec(document, toDOM(this.node)),
164
175
  container = _ref2.dom,
165
176
  contentDOM = _ref2.contentDOM;
@@ -172,6 +183,20 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
172
183
  if ((0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid')) {
173
184
  this.layoutDOM.setAttribute('data-local-id', this.node.attrs.localId);
174
185
  }
186
+
187
+ // SSR streaming re-attach note:
188
+ // In SSR, `init()` appends `container` into `domRef`; the portal's
189
+ // renderToStaticMarkup + innerHTML write then wipes `domRef`,
190
+ // detaching the entire subtree (with PM-serialized children inside
191
+ // `[data-layout-section]`). React's `render()` emits a
192
+ // `<NodeViewContentHole/>` placeholder inside `domRef`; the SSR
193
+ // re-attach logic in `init()` finds it via `[data-ssr-content-dom-ref]`
194
+ // and calls `_handleRef`, which appends `contentDOMWrapper` (the
195
+ // detached `container`) back inside the placeholder. The end result
196
+ // is `domRef > NodeViewContentHole > layout-section-container >
197
+ // [data-layout-section] > [data-layout-column] children` — the
198
+ // layout DOM contract is preserved.
199
+
175
200
  return {
176
201
  dom: container,
177
202
  contentDOM: contentDOM
@@ -206,6 +231,29 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
206
231
  if (this.layoutDOM) {
207
232
  this.layoutDOM.setAttribute('data-empty-layout', Boolean(this.isEmpty).toString());
208
233
  }
234
+
235
+ // SSR streaming path: render only a `<NodeViewContentHole/>` placeholder
236
+ // so ReactNodeView.init()'s SSR re-attach logic can find the marker
237
+ // (`data-ssr-content-dom-ref`) and re-append the detached
238
+ // contentDOMWrapper — which is the FULL layout structure
239
+ // (`layout-section-container > [data-layout-section] > children`) built
240
+ // in `getContentDOM` via DOMSerializer.renderSpec. This avoids
241
+ // duplicating layout structure between getContentDOM and render(), which
242
+ // previously caused an extra wrapping div between `[data-layout-section]`
243
+ // and the `[data-layout-column]` children and broke the flex layout.
244
+ //
245
+ // The BreakoutResizer is intentionally omitted in SSR — it relies on
246
+ // browser-only APIs and contributes no useful static markup. The
247
+ // LayoutSSRReactContextsProvider wraps the placeholder to inject the
248
+ // editor's IntlShape, defending against any descendants that call
249
+ // `useIntl()` during renderToStaticMarkup.
250
+ if ((0, _coreUtils.isSSR)() && (0, _coreUtils.isSSRStreaming)()) {
251
+ return /*#__PURE__*/_react.default.createElement(_LayoutSSRReactContextsProvider.LayoutSSRReactContextsProvider, {
252
+ intl: this.intl
253
+ }, /*#__PURE__*/_react.default.createElement(_reactNodeView.NodeViewContentHole, {
254
+ ref: forwardRef
255
+ }));
256
+ }
209
257
  if ((0, _expValEquals.expValEquals)('platform_editor_breakout_resizing', 'isEnabled', true)) {
210
258
  return null;
211
259
  }
@@ -8,6 +8,8 @@ exports.pluginKey = exports.default = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
10
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
12
+ var _coreUtils = require("@atlaskit/editor-common/core-utils");
11
13
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
12
14
  var _model = require("@atlaskit/editor-prosemirror/model");
13
15
  var _state = require("@atlaskit/editor-prosemirror/state");
@@ -26,6 +28,28 @@ var pluginKey = exports.pluginKey = new _state.PluginKey('layoutResizingPlugin')
26
28
  * (e.g. setting flex-basis to give real-time visual feedback without dispatching
27
29
  * PM transactions) are not "corrected" back by ProseMirror's DOM reconciliation.
28
30
  */
31
+ var isLayoutElementLike = function isLayoutElementLike(element) {
32
+ if ((0, _coreUtils.isSSR)() && (0, _coreUtils.isSSRStreaming)()) {
33
+ // In SSR environments, `HTMLElement` is undefined globally so a plain
34
+ // `instanceof HTMLElement` check is always `false`. That makes the
35
+ // `DOMSerializer.renderSpec(...)` result get rejected by the guard below and
36
+ // the NodeView falls back to a bare `<div>`, losing every schema-defined
37
+ // attribute (`data-layout-column`, `style="flex-basis:..."`,
38
+ // `data-column-width`, plus the inner `<div data-layout-content="true">`
39
+ // wrapper) and breaking the layout's flex sizing in SSR output.
40
+ //
41
+ // To unblock SSR streaming without changing CSR semantics, we gate the check:
42
+ // - In SSR (and only when `platform_editor_editor_ssr_streaming` is enabled),
43
+ // use a duck-typed check that mirrors `safe-plugin`'s `isHTMLElement`.
44
+ // - Everywhere else, keep the original `instanceof HTMLElement` check exactly
45
+ // as it was so we don't accidentally widen acceptance in CSR.
46
+ if (element === null || element === undefined) {
47
+ return false;
48
+ }
49
+ return (0, _typeof2.default)(element) === 'object' && 'innerHTML' in element && 'style' in element && 'classList' in element;
50
+ }
51
+ return element instanceof HTMLElement;
52
+ };
29
53
  var LayoutColumnView = /*#__PURE__*/function () {
30
54
  function LayoutColumnView(node, view, getPos) {
31
55
  (0, _classCallCheck2.default)(this, LayoutColumnView);
@@ -43,7 +67,7 @@ var LayoutColumnView = /*#__PURE__*/function () {
43
67
  var _DOMSerializer$render = _model.DOMSerializer.renderSpec(document, nodeType.spec.toDOM(node)),
44
68
  dom = _DOMSerializer$render.dom,
45
69
  contentDOM = _DOMSerializer$render.contentDOM;
46
- if (!(dom instanceof HTMLElement) || !(contentDOM instanceof HTMLElement)) {
70
+ if (!isLayoutElementLike(dom) || !isLayoutElementLike(contentDOM)) {
47
71
  var _fallbackDiv = document.createElement('div');
48
72
  this.dom = _fallbackDiv;
49
73
  this.contentDOM = _fallbackDiv;
@@ -71,7 +95,7 @@ var LayoutColumnView = /*#__PURE__*/function () {
71
95
  }
72
96
  }]);
73
97
  }();
74
- var _default = exports.default = function _default(options, pluginInjectionApi, portalProviderAPI, eventDispatcher) {
98
+ var _default = exports.default = function _default(options, pluginInjectionApi, portalProviderAPI, eventDispatcher, intl) {
75
99
  return new _safePlugin.SafePlugin({
76
100
  key: pluginKey,
77
101
  props: {
@@ -84,10 +108,11 @@ var _default = exports.default = function _default(options, pluginInjectionApi,
84
108
  portalProviderAPI: portalProviderAPI,
85
109
  eventDispatcher: eventDispatcher,
86
110
  pluginInjectionApi: pluginInjectionApi,
87
- options: options
111
+ options: options,
112
+ intl: intl
88
113
  }).init();
89
114
  }
90
- }, (0, _experiments.editorExperiment)('platform_editor_layout_column_resize_handle', true) ? {
115
+ }, (0, _experiments.editorExperiment)('platform_editor_layout_column_resize_handle', true) || (0, _coreUtils.isSSR)() && (0, _coreUtils.isSSRStreaming)() ? {
91
116
  layoutColumn: function layoutColumn(node, view, getPos) {
92
117
  return new LayoutColumnView(node, view, getPos);
93
118
  }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.LayoutSSRReactContextsProvider = LayoutSSRReactContextsProvider;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _reactIntl = require("react-intl");
10
+ var _coreUtils = require("@atlaskit/editor-common/core-utils");
11
+ /**
12
+ * Wraps the layout section nodeview children with the editor's actual
13
+ * IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
14
+ * descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
15
+ * have a valid intl context and do not throw during the static render pass.
16
+ *
17
+ * Outside of SSR streaming this is a no-op passthrough.
18
+ *
19
+ * Follows the same pattern as `MediaSSRReactContextsProvider` and
20
+ * `SyncBlockSSRReactContextsProvider`.
21
+ */
22
+ function LayoutSSRReactContextsProvider(_ref) {
23
+ var children = _ref.children,
24
+ intl = _ref.intl;
25
+ if (!(0, _coreUtils.isSSRStreaming)() || !(0, _coreUtils.isSSR)()) {
26
+ return children;
27
+ }
28
+ if (!intl) {
29
+ return children;
30
+ }
31
+ return /*#__PURE__*/_react.default.createElement(_reactIntl.RawIntlProvider, {
32
+ value: intl
33
+ }, children);
34
+ }
@@ -106,8 +106,9 @@ export const layoutPlugin = ({
106
106
  name: 'layoutResizing',
107
107
  plugin: ({
108
108
  portalProviderAPI,
109
- eventDispatcher
110
- }) => createLayoutResizingPlugin(options, api, portalProviderAPI, eventDispatcher)
109
+ eventDispatcher,
110
+ getIntl
111
+ }) => createLayoutResizingPlugin(options, api, portalProviderAPI, eventDispatcher, getIntl())
111
112
  });
112
113
  }
113
114
  return plugins;
@@ -1,6 +1,7 @@
1
1
  import React, { useCallback } from 'react';
2
+ import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
2
3
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
- import ReactNodeView from '@atlaskit/editor-common/react-node-view';
4
+ import ReactNodeView, { NodeViewContentHole } from '@atlaskit/editor-common/react-node-view';
4
5
  import { BreakoutResizer, ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
5
6
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
6
7
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
@@ -8,6 +9,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
10
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
10
11
  import { selectIntoLayout } from '../pm-plugins/utils';
12
+ import { LayoutSSRReactContextsProvider } from '../ui/LayoutSSRReactContextsProvider';
11
13
  const layoutDynamicFullWidthGuidelineOffset = 16;
12
14
  const isEmptyParagraph = node => {
13
15
  return !!node && node.type.name === 'paragraph' && !node.childCount;
@@ -122,12 +124,14 @@ export class LayoutSectionView extends ReactNodeView {
122
124
  * @param props.eventDispatcher
123
125
  * @param props.pluginInjectionApi
124
126
  * @param props.options
127
+ * @param props.intl
125
128
  * @example
126
129
  */
127
130
  constructor(props) {
128
131
  super(props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props);
129
132
  this.isEmpty = isEmptyLayout(this.node);
130
133
  this.options = props.options;
134
+ this.intl = props.intl;
131
135
  }
132
136
 
133
137
  /**
@@ -136,6 +140,13 @@ export class LayoutSectionView extends ReactNodeView {
136
140
  * @returns
137
141
  */
138
142
  getContentDOM() {
143
+ // Build the layout DOM via the schema's toDOM spec. This is the same
144
+ // path used in both CSR and SSR — the only SSR-specific concern is
145
+ // re-attaching `contentDOM` (= the `[data-layout-section]` element)
146
+ // after the portal's renderToStaticMarkup + innerHTML write detaches
147
+ // it. We handle that by stamping `data-ssr-content-dom-ref` on the
148
+ // outer container so `ReactNodeView.init()` can find a re-attach
149
+ // target inside `domRef` after the portal write.
139
150
  const {
140
151
  dom: container,
141
152
  contentDOM
@@ -149,6 +160,20 @@ export class LayoutSectionView extends ReactNodeView {
149
160
  if (fg('platform_editor_adf_with_localid')) {
150
161
  this.layoutDOM.setAttribute('data-local-id', this.node.attrs.localId);
151
162
  }
163
+
164
+ // SSR streaming re-attach note:
165
+ // In SSR, `init()` appends `container` into `domRef`; the portal's
166
+ // renderToStaticMarkup + innerHTML write then wipes `domRef`,
167
+ // detaching the entire subtree (with PM-serialized children inside
168
+ // `[data-layout-section]`). React's `render()` emits a
169
+ // `<NodeViewContentHole/>` placeholder inside `domRef`; the SSR
170
+ // re-attach logic in `init()` finds it via `[data-ssr-content-dom-ref]`
171
+ // and calls `_handleRef`, which appends `contentDOMWrapper` (the
172
+ // detached `container`) back inside the placeholder. The end result
173
+ // is `domRef > NodeViewContentHole > layout-section-container >
174
+ // [data-layout-section] > [data-layout-column] children` — the
175
+ // layout DOM contract is preserved.
176
+
152
177
  return {
153
178
  dom: container,
154
179
  contentDOM
@@ -179,6 +204,29 @@ export class LayoutSectionView extends ReactNodeView {
179
204
  if (this.layoutDOM) {
180
205
  this.layoutDOM.setAttribute('data-empty-layout', Boolean(this.isEmpty).toString());
181
206
  }
207
+
208
+ // SSR streaming path: render only a `<NodeViewContentHole/>` placeholder
209
+ // so ReactNodeView.init()'s SSR re-attach logic can find the marker
210
+ // (`data-ssr-content-dom-ref`) and re-append the detached
211
+ // contentDOMWrapper — which is the FULL layout structure
212
+ // (`layout-section-container > [data-layout-section] > children`) built
213
+ // in `getContentDOM` via DOMSerializer.renderSpec. This avoids
214
+ // duplicating layout structure between getContentDOM and render(), which
215
+ // previously caused an extra wrapping div between `[data-layout-section]`
216
+ // and the `[data-layout-column]` children and broke the flex layout.
217
+ //
218
+ // The BreakoutResizer is intentionally omitted in SSR — it relies on
219
+ // browser-only APIs and contributes no useful static markup. The
220
+ // LayoutSSRReactContextsProvider wraps the placeholder to inject the
221
+ // editor's IntlShape, defending against any descendants that call
222
+ // `useIntl()` during renderToStaticMarkup.
223
+ if (isSSR() && isSSRStreaming()) {
224
+ return /*#__PURE__*/React.createElement(LayoutSSRReactContextsProvider, {
225
+ intl: this.intl
226
+ }, /*#__PURE__*/React.createElement(NodeViewContentHole, {
227
+ ref: forwardRef
228
+ }));
229
+ }
182
230
  if (expValEquals('platform_editor_breakout_resizing', 'isEnabled', true)) {
183
231
  return null;
184
232
  }
@@ -1,3 +1,4 @@
1
+ import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
1
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
3
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
3
4
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
@@ -14,6 +15,28 @@ export const pluginKey = new PluginKey('layoutResizingPlugin');
14
15
  * (e.g. setting flex-basis to give real-time visual feedback without dispatching
15
16
  * PM transactions) are not "corrected" back by ProseMirror's DOM reconciliation.
16
17
  */
18
+ const isLayoutElementLike = element => {
19
+ if (isSSR() && isSSRStreaming()) {
20
+ // In SSR environments, `HTMLElement` is undefined globally so a plain
21
+ // `instanceof HTMLElement` check is always `false`. That makes the
22
+ // `DOMSerializer.renderSpec(...)` result get rejected by the guard below and
23
+ // the NodeView falls back to a bare `<div>`, losing every schema-defined
24
+ // attribute (`data-layout-column`, `style="flex-basis:..."`,
25
+ // `data-column-width`, plus the inner `<div data-layout-content="true">`
26
+ // wrapper) and breaking the layout's flex sizing in SSR output.
27
+ //
28
+ // To unblock SSR streaming without changing CSR semantics, we gate the check:
29
+ // - In SSR (and only when `platform_editor_editor_ssr_streaming` is enabled),
30
+ // use a duck-typed check that mirrors `safe-plugin`'s `isHTMLElement`.
31
+ // - Everywhere else, keep the original `instanceof HTMLElement` check exactly
32
+ // as it was so we don't accidentally widen acceptance in CSR.
33
+ if (element === null || element === undefined) {
34
+ return false;
35
+ }
36
+ return typeof element === 'object' && 'innerHTML' in element && 'style' in element && 'classList' in element;
37
+ }
38
+ return element instanceof HTMLElement;
39
+ };
17
40
  class LayoutColumnView {
18
41
  constructor(node, view, getPos) {
19
42
  // Use the NodeSpec's own toDOM to produce the correct DOM structure and attributes.
@@ -31,7 +54,7 @@ class LayoutColumnView {
31
54
  dom,
32
55
  contentDOM
33
56
  } = DOMSerializer.renderSpec(document, nodeType.spec.toDOM(node));
34
- if (!(dom instanceof HTMLElement) || !(contentDOM instanceof HTMLElement)) {
57
+ if (!isLayoutElementLike(dom) || !isLayoutElementLike(contentDOM)) {
35
58
  const fallbackDiv = document.createElement('div');
36
59
  this.dom = fallbackDiv;
37
60
  this.contentDOM = fallbackDiv;
@@ -56,7 +79,7 @@ class LayoutColumnView {
56
79
  return mutation.type === 'attributes' && mutation.attributeName === 'style';
57
80
  }
58
81
  }
59
- export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher) => new SafePlugin({
82
+ export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher, intl) => new SafePlugin({
60
83
  key: pluginKey,
61
84
  props: {
62
85
  nodeViews: {
@@ -68,13 +91,20 @@ export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher
68
91
  portalProviderAPI,
69
92
  eventDispatcher,
70
93
  pluginInjectionApi,
71
- options
94
+ options,
95
+ intl
72
96
  }).init();
73
97
  },
74
- // Only register the column node view when the resize handle experiment is on.
75
- // It exists solely to suppress style-attribute MutationObserver callbacks
76
- // during drag, allowing direct flex-basis writes without PM interference.
77
- ...(editorExperiment('platform_editor_layout_column_resize_handle', true) ? {
98
+ // Register the column node view when EITHER:
99
+ // 1. The resize handle experiment is on (its original purpose:
100
+ // suppress style-attribute MutationObserver callbacks during
101
+ // drag, allowing direct flex-basis writes without PM
102
+ // interference).
103
+ // 2. SSR streaming is enabled — the column node view stamps
104
+ // `container-type: inline-size` inline on each column dom so
105
+ // that the SSR-rendered table inside the column constrains
106
+ // its width to the column (see comment in the constructor).
107
+ ...(editorExperiment('platform_editor_layout_column_resize_handle', true) || isSSR() && isSSRStreaming() ? {
78
108
  layoutColumn: (node, view, getPos) => new LayoutColumnView(node, view, getPos)
79
109
  } : {})
80
110
  }
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { RawIntlProvider } from 'react-intl';
3
+ import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
4
+ /**
5
+ * Wraps the layout section nodeview children with the editor's actual
6
+ * IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
7
+ * descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
8
+ * have a valid intl context and do not throw during the static render pass.
9
+ *
10
+ * Outside of SSR streaming this is a no-op passthrough.
11
+ *
12
+ * Follows the same pattern as `MediaSSRReactContextsProvider` and
13
+ * `SyncBlockSSRReactContextsProvider`.
14
+ */
15
+ export function LayoutSSRReactContextsProvider({
16
+ children,
17
+ intl
18
+ }) {
19
+ if (!isSSRStreaming() || !isSSR()) {
20
+ return children;
21
+ }
22
+ if (!intl) {
23
+ return children;
24
+ }
25
+ return /*#__PURE__*/React.createElement(RawIntlProvider, {
26
+ value: intl
27
+ }, children);
28
+ }
@@ -107,8 +107,9 @@ export var layoutPlugin = function layoutPlugin(_ref) {
107
107
  name: 'layoutResizing',
108
108
  plugin: function plugin(_ref2) {
109
109
  var portalProviderAPI = _ref2.portalProviderAPI,
110
- eventDispatcher = _ref2.eventDispatcher;
111
- return createLayoutResizingPlugin(options, api, portalProviderAPI, eventDispatcher);
110
+ eventDispatcher = _ref2.eventDispatcher,
111
+ getIntl = _ref2.getIntl;
112
+ return createLayoutResizingPlugin(options, api, portalProviderAPI, eventDispatcher, getIntl());
112
113
  }
113
114
  });
114
115
  }
@@ -9,8 +9,9 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
9
9
  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; }
10
10
  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; }
11
11
  import React, { useCallback } from 'react';
12
+ import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
12
13
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
13
- import ReactNodeView from '@atlaskit/editor-common/react-node-view';
14
+ import ReactNodeView, { NodeViewContentHole } from '@atlaskit/editor-common/react-node-view';
14
15
  import { BreakoutResizer, ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
15
16
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
16
17
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
@@ -18,6 +19,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
18
19
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
19
20
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
20
21
  import { selectIntoLayout } from '../pm-plugins/utils';
22
+ import { LayoutSSRReactContextsProvider } from '../ui/LayoutSSRReactContextsProvider';
21
23
  var layoutDynamicFullWidthGuidelineOffset = 16;
22
24
  var isEmptyParagraph = function isEmptyParagraph(node) {
23
25
  return !!node && node.type.name === 'paragraph' && !node.childCount;
@@ -131,6 +133,7 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
131
133
  * @param props.eventDispatcher
132
134
  * @param props.pluginInjectionApi
133
135
  * @param props.options
136
+ * @param props.intl
134
137
  * @example
135
138
  */
136
139
  function LayoutSectionView(props) {
@@ -139,6 +142,7 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
139
142
  _this = _callSuper(this, LayoutSectionView, [props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props]);
140
143
  _this.isEmpty = isEmptyLayout(_this.node);
141
144
  _this.options = props.options;
145
+ _this.intl = props.intl;
142
146
  return _this;
143
147
  }
144
148
 
@@ -151,6 +155,13 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
151
155
  return _createClass(LayoutSectionView, [{
152
156
  key: "getContentDOM",
153
157
  value: function getContentDOM() {
158
+ // Build the layout DOM via the schema's toDOM spec. This is the same
159
+ // path used in both CSR and SSR — the only SSR-specific concern is
160
+ // re-attaching `contentDOM` (= the `[data-layout-section]` element)
161
+ // after the portal's renderToStaticMarkup + innerHTML write detaches
162
+ // it. We handle that by stamping `data-ssr-content-dom-ref` on the
163
+ // outer container so `ReactNodeView.init()` can find a re-attach
164
+ // target inside `domRef` after the portal write.
154
165
  var _ref2 = DOMSerializer.renderSpec(document, toDOM(this.node)),
155
166
  container = _ref2.dom,
156
167
  contentDOM = _ref2.contentDOM;
@@ -163,6 +174,20 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
163
174
  if (fg('platform_editor_adf_with_localid')) {
164
175
  this.layoutDOM.setAttribute('data-local-id', this.node.attrs.localId);
165
176
  }
177
+
178
+ // SSR streaming re-attach note:
179
+ // In SSR, `init()` appends `container` into `domRef`; the portal's
180
+ // renderToStaticMarkup + innerHTML write then wipes `domRef`,
181
+ // detaching the entire subtree (with PM-serialized children inside
182
+ // `[data-layout-section]`). React's `render()` emits a
183
+ // `<NodeViewContentHole/>` placeholder inside `domRef`; the SSR
184
+ // re-attach logic in `init()` finds it via `[data-ssr-content-dom-ref]`
185
+ // and calls `_handleRef`, which appends `contentDOMWrapper` (the
186
+ // detached `container`) back inside the placeholder. The end result
187
+ // is `domRef > NodeViewContentHole > layout-section-container >
188
+ // [data-layout-section] > [data-layout-column] children` — the
189
+ // layout DOM contract is preserved.
190
+
166
191
  return {
167
192
  dom: container,
168
193
  contentDOM: contentDOM
@@ -197,6 +222,29 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
197
222
  if (this.layoutDOM) {
198
223
  this.layoutDOM.setAttribute('data-empty-layout', Boolean(this.isEmpty).toString());
199
224
  }
225
+
226
+ // SSR streaming path: render only a `<NodeViewContentHole/>` placeholder
227
+ // so ReactNodeView.init()'s SSR re-attach logic can find the marker
228
+ // (`data-ssr-content-dom-ref`) and re-append the detached
229
+ // contentDOMWrapper — which is the FULL layout structure
230
+ // (`layout-section-container > [data-layout-section] > children`) built
231
+ // in `getContentDOM` via DOMSerializer.renderSpec. This avoids
232
+ // duplicating layout structure between getContentDOM and render(), which
233
+ // previously caused an extra wrapping div between `[data-layout-section]`
234
+ // and the `[data-layout-column]` children and broke the flex layout.
235
+ //
236
+ // The BreakoutResizer is intentionally omitted in SSR — it relies on
237
+ // browser-only APIs and contributes no useful static markup. The
238
+ // LayoutSSRReactContextsProvider wraps the placeholder to inject the
239
+ // editor's IntlShape, defending against any descendants that call
240
+ // `useIntl()` during renderToStaticMarkup.
241
+ if (isSSR() && isSSRStreaming()) {
242
+ return /*#__PURE__*/React.createElement(LayoutSSRReactContextsProvider, {
243
+ intl: this.intl
244
+ }, /*#__PURE__*/React.createElement(NodeViewContentHole, {
245
+ ref: forwardRef
246
+ }));
247
+ }
200
248
  if (expValEquals('platform_editor_breakout_resizing', 'isEnabled', true)) {
201
249
  return null;
202
250
  }
@@ -1,8 +1,10 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
3
  import _createClass from "@babel/runtime/helpers/createClass";
4
+ import _typeof from "@babel/runtime/helpers/typeof";
4
5
  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; }
5
6
  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; }
7
+ import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
6
8
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
7
9
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
8
10
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
@@ -19,6 +21,28 @@ export var pluginKey = new PluginKey('layoutResizingPlugin');
19
21
  * (e.g. setting flex-basis to give real-time visual feedback without dispatching
20
22
  * PM transactions) are not "corrected" back by ProseMirror's DOM reconciliation.
21
23
  */
24
+ var isLayoutElementLike = function isLayoutElementLike(element) {
25
+ if (isSSR() && isSSRStreaming()) {
26
+ // In SSR environments, `HTMLElement` is undefined globally so a plain
27
+ // `instanceof HTMLElement` check is always `false`. That makes the
28
+ // `DOMSerializer.renderSpec(...)` result get rejected by the guard below and
29
+ // the NodeView falls back to a bare `<div>`, losing every schema-defined
30
+ // attribute (`data-layout-column`, `style="flex-basis:..."`,
31
+ // `data-column-width`, plus the inner `<div data-layout-content="true">`
32
+ // wrapper) and breaking the layout's flex sizing in SSR output.
33
+ //
34
+ // To unblock SSR streaming without changing CSR semantics, we gate the check:
35
+ // - In SSR (and only when `platform_editor_editor_ssr_streaming` is enabled),
36
+ // use a duck-typed check that mirrors `safe-plugin`'s `isHTMLElement`.
37
+ // - Everywhere else, keep the original `instanceof HTMLElement` check exactly
38
+ // as it was so we don't accidentally widen acceptance in CSR.
39
+ if (element === null || element === undefined) {
40
+ return false;
41
+ }
42
+ return _typeof(element) === 'object' && 'innerHTML' in element && 'style' in element && 'classList' in element;
43
+ }
44
+ return element instanceof HTMLElement;
45
+ };
22
46
  var LayoutColumnView = /*#__PURE__*/function () {
23
47
  function LayoutColumnView(node, view, getPos) {
24
48
  _classCallCheck(this, LayoutColumnView);
@@ -36,7 +60,7 @@ var LayoutColumnView = /*#__PURE__*/function () {
36
60
  var _DOMSerializer$render = DOMSerializer.renderSpec(document, nodeType.spec.toDOM(node)),
37
61
  dom = _DOMSerializer$render.dom,
38
62
  contentDOM = _DOMSerializer$render.contentDOM;
39
- if (!(dom instanceof HTMLElement) || !(contentDOM instanceof HTMLElement)) {
63
+ if (!isLayoutElementLike(dom) || !isLayoutElementLike(contentDOM)) {
40
64
  var _fallbackDiv = document.createElement('div');
41
65
  this.dom = _fallbackDiv;
42
66
  this.contentDOM = _fallbackDiv;
@@ -64,7 +88,7 @@ var LayoutColumnView = /*#__PURE__*/function () {
64
88
  }
65
89
  }]);
66
90
  }();
67
- export default (function (options, pluginInjectionApi, portalProviderAPI, eventDispatcher) {
91
+ export default (function (options, pluginInjectionApi, portalProviderAPI, eventDispatcher, intl) {
68
92
  return new SafePlugin({
69
93
  key: pluginKey,
70
94
  props: {
@@ -77,10 +101,11 @@ export default (function (options, pluginInjectionApi, portalProviderAPI, eventD
77
101
  portalProviderAPI: portalProviderAPI,
78
102
  eventDispatcher: eventDispatcher,
79
103
  pluginInjectionApi: pluginInjectionApi,
80
- options: options
104
+ options: options,
105
+ intl: intl
81
106
  }).init();
82
107
  }
83
- }, editorExperiment('platform_editor_layout_column_resize_handle', true) ? {
108
+ }, editorExperiment('platform_editor_layout_column_resize_handle', true) || isSSR() && isSSRStreaming() ? {
84
109
  layoutColumn: function layoutColumn(node, view, getPos) {
85
110
  return new LayoutColumnView(node, view, getPos);
86
111
  }
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { RawIntlProvider } from 'react-intl';
3
+ import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
4
+ /**
5
+ * Wraps the layout section nodeview children with the editor's actual
6
+ * IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
7
+ * descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
8
+ * have a valid intl context and do not throw during the static render pass.
9
+ *
10
+ * Outside of SSR streaming this is a no-op passthrough.
11
+ *
12
+ * Follows the same pattern as `MediaSSRReactContextsProvider` and
13
+ * `SyncBlockSSRReactContextsProvider`.
14
+ */
15
+ export function LayoutSSRReactContextsProvider(_ref) {
16
+ var children = _ref.children,
17
+ intl = _ref.intl;
18
+ if (!isSSRStreaming() || !isSSR()) {
19
+ return children;
20
+ }
21
+ if (!intl) {
22
+ return children;
23
+ }
24
+ return /*#__PURE__*/React.createElement(RawIntlProvider, {
25
+ value: intl
26
+ }, children);
27
+ }
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { IntlShape } from 'react-intl';
2
3
  import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
3
4
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
4
5
  import ReactNodeView from '@atlaskit/editor-common/react-node-view';
@@ -10,6 +11,7 @@ import type { LayoutPluginOptions } from '../types';
10
11
  type LayoutSectionViewProps = {
11
12
  eventDispatcher: EventDispatcher;
12
13
  getPos: getPosHandlerNode;
14
+ intl?: IntlShape;
13
15
  node: PMNode;
14
16
  options: LayoutPluginOptions;
15
17
  pluginInjectionApi?: ExtractInjectionAPI<LayoutPlugin>;
@@ -24,6 +26,7 @@ export declare class LayoutSectionView extends ReactNodeView<LayoutSectionViewPr
24
26
  options: LayoutPluginOptions;
25
27
  layoutDOM?: HTMLElement;
26
28
  isEmpty?: boolean;
29
+ private intl?;
27
30
  /**
28
31
  * constructor
29
32
  * @param props
@@ -34,11 +37,13 @@ export declare class LayoutSectionView extends ReactNodeView<LayoutSectionViewPr
34
37
  * @param props.eventDispatcher
35
38
  * @param props.pluginInjectionApi
36
39
  * @param props.options
40
+ * @param props.intl
37
41
  * @example
38
42
  */
39
43
  constructor(props: {
40
44
  eventDispatcher: EventDispatcher;
41
45
  getPos: getPosHandlerNode;
46
+ intl?: IntlShape;
42
47
  node: PMNode;
43
48
  options: LayoutPluginOptions;
44
49
  pluginInjectionApi: ExtractInjectionAPI<LayoutPlugin>;
@@ -1,3 +1,4 @@
1
+ import type { IntlShape } from 'react-intl';
1
2
  import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
2
3
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
3
4
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
@@ -6,5 +7,5 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
7
  import type { LayoutPlugin } from '../layoutPluginType';
7
8
  import type { LayoutPluginOptions } from '../types';
8
9
  export declare const pluginKey: PluginKey;
9
- declare const _default: (options: LayoutPluginOptions, pluginInjectionApi: ExtractInjectionAPI<LayoutPlugin>, portalProviderAPI: PortalProviderAPI, eventDispatcher: EventDispatcher) => SafePlugin<undefined>;
10
+ declare const _default: (options: LayoutPluginOptions, pluginInjectionApi: ExtractInjectionAPI<LayoutPlugin>, portalProviderAPI: PortalProviderAPI, eventDispatcher: EventDispatcher, intl?: IntlShape) => SafePlugin<undefined>;
10
11
  export default _default;
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type IntlShape } from 'react-intl';
3
+ interface Props {
4
+ children: ReactNode;
5
+ intl: IntlShape | undefined;
6
+ }
7
+ /**
8
+ * Wraps the layout section nodeview children with the editor's actual
9
+ * IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
10
+ * descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
11
+ * have a valid intl context and do not throw during the static render pass.
12
+ *
13
+ * Outside of SSR streaming this is a no-op passthrough.
14
+ *
15
+ * Follows the same pattern as `MediaSSRReactContextsProvider` and
16
+ * `SyncBlockSSRReactContextsProvider`.
17
+ */
18
+ export declare function LayoutSSRReactContextsProvider({ children, intl }: Props): ReactNode;
19
+ export {};
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { IntlShape } from 'react-intl';
2
3
  import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
3
4
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
4
5
  import ReactNodeView from '@atlaskit/editor-common/react-node-view';
@@ -10,6 +11,7 @@ import type { LayoutPluginOptions } from '../types';
10
11
  type LayoutSectionViewProps = {
11
12
  eventDispatcher: EventDispatcher;
12
13
  getPos: getPosHandlerNode;
14
+ intl?: IntlShape;
13
15
  node: PMNode;
14
16
  options: LayoutPluginOptions;
15
17
  pluginInjectionApi?: ExtractInjectionAPI<LayoutPlugin>;
@@ -24,6 +26,7 @@ export declare class LayoutSectionView extends ReactNodeView<LayoutSectionViewPr
24
26
  options: LayoutPluginOptions;
25
27
  layoutDOM?: HTMLElement;
26
28
  isEmpty?: boolean;
29
+ private intl?;
27
30
  /**
28
31
  * constructor
29
32
  * @param props
@@ -34,11 +37,13 @@ export declare class LayoutSectionView extends ReactNodeView<LayoutSectionViewPr
34
37
  * @param props.eventDispatcher
35
38
  * @param props.pluginInjectionApi
36
39
  * @param props.options
40
+ * @param props.intl
37
41
  * @example
38
42
  */
39
43
  constructor(props: {
40
44
  eventDispatcher: EventDispatcher;
41
45
  getPos: getPosHandlerNode;
46
+ intl?: IntlShape;
42
47
  node: PMNode;
43
48
  options: LayoutPluginOptions;
44
49
  pluginInjectionApi: ExtractInjectionAPI<LayoutPlugin>;
@@ -1,3 +1,4 @@
1
+ import type { IntlShape } from 'react-intl';
1
2
  import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
2
3
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
3
4
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
@@ -6,5 +7,5 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
7
  import type { LayoutPlugin } from '../layoutPluginType';
7
8
  import type { LayoutPluginOptions } from '../types';
8
9
  export declare const pluginKey: PluginKey;
9
- declare const _default: (options: LayoutPluginOptions, pluginInjectionApi: ExtractInjectionAPI<LayoutPlugin>, portalProviderAPI: PortalProviderAPI, eventDispatcher: EventDispatcher) => SafePlugin<undefined>;
10
+ declare const _default: (options: LayoutPluginOptions, pluginInjectionApi: ExtractInjectionAPI<LayoutPlugin>, portalProviderAPI: PortalProviderAPI, eventDispatcher: EventDispatcher, intl?: IntlShape) => SafePlugin<undefined>;
10
11
  export default _default;
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type IntlShape } from 'react-intl';
3
+ interface Props {
4
+ children: ReactNode;
5
+ intl: IntlShape | undefined;
6
+ }
7
+ /**
8
+ * Wraps the layout section nodeview children with the editor's actual
9
+ * IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
10
+ * descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
11
+ * have a valid intl context and do not throw during the static render pass.
12
+ *
13
+ * Outside of SSR streaming this is a no-op passthrough.
14
+ *
15
+ * Follows the same pattern as `MediaSSRReactContextsProvider` and
16
+ * `SyncBlockSSRReactContextsProvider`.
17
+ */
18
+ export declare function LayoutSSRReactContextsProvider({ children, intl }: Props): ReactNode;
19
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-layout",
3
- "version": "11.0.3",
3
+ "version": "11.0.4",
4
4
  "description": "Layout plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -50,14 +50,14 @@
50
50
  "@atlaskit/icon": "^35.4.0",
51
51
  "@atlaskit/icon-lab": "^6.13.0",
52
52
  "@atlaskit/platform-feature-flags": "^1.1.0",
53
- "@atlaskit/tmp-editor-statsig": "^89.0.0",
54
- "@atlaskit/tokens": "^13.1.0",
53
+ "@atlaskit/tmp-editor-statsig": "^89.4.0",
54
+ "@atlaskit/tokens": "^13.3.0",
55
55
  "@babel/runtime": "^7.0.0",
56
56
  "@emotion/react": "^11.7.1",
57
57
  "bind-event-listener": "^3.0.0"
58
58
  },
59
59
  "peerDependencies": {
60
- "@atlaskit/editor-common": "^115.3.0",
60
+ "@atlaskit/editor-common": "^115.6.0",
61
61
  "react": "^18.2.0",
62
62
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
63
63
  },