@atlaskit/editor-plugin-extension 33.0.10 → 33.0.11

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,16 @@
1
1
  # @atlaskit/editor-plugin-extension
2
2
 
3
+ ## 33.0.11
4
+
5
+ ### Patch Changes
6
+
7
+ - [`af6421f9b80ca`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/af6421f9b80ca) -
8
+ [EDITOR-9924] When `platform_editor_lovability_resize_exts_gracefully` and
9
+ `platform_editor_lovability_resize_exts_patch_1` are enabled, use the breakout mark for extension
10
+ node width across both resizing cohorts and synchronize existing layouts with breakout widths for
11
+ users in the resizing: false cohort.
12
+ - Updated dependencies
13
+
3
14
  ## 33.0.10
4
15
 
5
16
  ### Patch Changes
@@ -14,8 +14,11 @@ var _extensionEvents = require("@atlaskit/editor-common/analytics/types/extensio
14
14
  var _referentiality = require("@atlaskit/editor-common/utils/referentiality");
15
15
  var _state = require("@atlaskit/editor-prosemirror/state");
16
16
  var _utils = require("@atlaskit/editor-prosemirror/utils");
17
+ var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
18
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
17
19
  var _pluginFactory = require("../pm-plugins/plugin-factory");
18
20
  var _utils2 = require("../pm-plugins/utils");
21
+ var _getExtensionLayout = require("../utils/getExtensionLayout");
19
22
  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; }
20
23
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21
24
  // AFP-2532 TODO: Fix automatic suppressions below
@@ -66,9 +69,24 @@ var updateExtensionLayout = exports.updateExtensionLayout = function updateExten
66
69
  }, function (tr, state) {
67
70
  var selectedExtension = (0, _utils2.getSelectedExtension)(state, true);
68
71
  if (selectedExtension) {
72
+ var marks = selectedExtension.node.marks;
73
+ if ((0, _fg.fg)('platform_editor_lovability_resize_exts_gracefully') && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_lovability_resize_exts_patch_1')) {
74
+ var breakoutMark = marks.find(function (mark) {
75
+ return mark.type.name === 'breakout';
76
+ });
77
+ if (breakoutMark && (layout === 'default' || layout === 'wide' || layout === 'full-width')) {
78
+ // the resizing:false cohort is still using the layout presets, so updating
79
+ // the layout should also update the breakout mark's width, which is the source of
80
+ // truth for the node's width.
81
+ marks = breakoutMark.type.create(_objectSpread(_objectSpread({}, breakoutMark.attrs), {}, {
82
+ width: (0, _getExtensionLayout.getExtensionPresetWidth)(layout),
83
+ mode: layout === 'full-width' ? 'full-width' : 'wide'
84
+ })).addToSet(marks);
85
+ }
86
+ }
69
87
  var trWithNewNodeMarkup = tr.setNodeMarkup(selectedExtension.pos, undefined, _objectSpread(_objectSpread({}, selectedExtension.node.attrs), {}, {
70
88
  layout: layout
71
- }));
89
+ }), marks);
72
90
  trWithNewNodeMarkup.setMeta('scrollIntoView', false);
73
91
  if (analyticsApi) {
74
92
  analyticsApi.attachAnalyticsEvent({
@@ -28,6 +28,7 @@ var _fg = require("@atlaskit/platform-feature-flags/fg");
28
28
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
29
29
  var _actions = require("../editor-actions/actions");
30
30
  var _commands = require("../editor-commands/commands");
31
+ var _getExtensionLayout = require("../utils/getExtensionLayout");
31
32
  var _pluginKey = require("./macro/plugin-key");
32
33
  var _pluginFactory = require("./plugin-factory");
33
34
  var _utils3 = require("./utils");
@@ -74,12 +75,34 @@ var isLayoutSupported = function isLayoutSupported(state, selectedExtNode) {
74
75
  // and not inside a layoutSection
75
76
  return !!((isMultiBodiedExtension || isNonEmbeddedBodiedExtension || isNonEmbeddedExtension) && !(0, _utils2.hasParentNodeOfType)([layoutSection])(selection));
76
77
  };
78
+
79
+ // if an extension node has been resized via breakout resizing,
80
+ // the layout dropdown button should reflect the breakout resized with
81
+ var getToolbarLayout = function getToolbarLayout(node) {
82
+ var layout = node.attrs.layout;
83
+ var isCustomWidth = false;
84
+ var hasBreakoutMark = node.marks.some(function (mark) {
85
+ return mark.type.name === 'breakout';
86
+ });
87
+ if ((0, _fg.fg)('platform_editor_lovability_resize_exts_gracefully') && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_lovability_resize_exts_patch_1') && hasBreakoutMark) {
88
+ // a custom width leaves the presets unselected and uses the 'Custom width' dropdown label
89
+ var matchedLayout = (0, _getExtensionLayout.getExtensionLayout)(node);
90
+ isCustomWidth = matchedLayout === null;
91
+ layout = matchedLayout !== null && matchedLayout !== void 0 ? matchedLayout : layout;
92
+ }
93
+ return {
94
+ layout: layout,
95
+ isCustomWidth: isCustomWidth
96
+ };
97
+ };
77
98
  var breakoutButtonListOptions = function breakoutButtonListOptions(state, formatMessage, extensionState, breakoutEnabled, editorAnalyticsAPI) {
78
99
  var nodeWithPos = (0, _utils3.getSelectedExtension)(state, true);
79
100
 
80
101
  // we should only return breakout options when breakouts are enabled and the node supports them
81
102
  if (nodeWithPos && breakoutEnabled && isLayoutSupported(state, nodeWithPos) && !isNestedNBM(state, nodeWithPos)) {
82
- var layout = nodeWithPos.node.attrs.layout;
103
+ var _getToolbarLayout = getToolbarLayout(nodeWithPos.node),
104
+ layout = _getToolbarLayout.layout,
105
+ isCustomWidth = _getToolbarLayout.isCustomWidth;
83
106
  return [{
84
107
  type: 'button',
85
108
  icon: function icon() {
@@ -90,7 +113,7 @@ var breakoutButtonListOptions = function breakoutButtonListOptions(state, format
90
113
  },
91
114
  iconFallback: _contentWidthNarrow.default,
92
115
  onClick: (0, _commands.updateExtensionLayout)('default', editorAnalyticsAPI),
93
- selected: layout === 'default',
116
+ selected: !isCustomWidth && layout === 'default',
94
117
  title: formatMessage(_messages2.default.layoutFixedWidth),
95
118
  tabIndex: null
96
119
  }, {
@@ -103,7 +126,7 @@ var breakoutButtonListOptions = function breakoutButtonListOptions(state, format
103
126
  },
104
127
  iconFallback: _contentWidthWide.default,
105
128
  onClick: (0, _commands.updateExtensionLayout)('wide', editorAnalyticsAPI),
106
- selected: layout === 'wide',
129
+ selected: !isCustomWidth && layout === 'wide',
107
130
  title: formatMessage(_messages2.default.layoutWide),
108
131
  tabIndex: null
109
132
  }, {
@@ -116,7 +139,7 @@ var breakoutButtonListOptions = function breakoutButtonListOptions(state, format
116
139
  },
117
140
  iconFallback: _expandHorizontal.default,
118
141
  onClick: (0, _commands.updateExtensionLayout)('full-width', editorAnalyticsAPI),
119
- selected: layout === 'full-width',
142
+ selected: !isCustomWidth && layout === 'full-width',
120
143
  title: formatMessage(_messages2.default.layoutFullWidth),
121
144
  tabIndex: null
122
145
  }];
@@ -130,29 +153,37 @@ var breakoutDropdownOptions = function breakoutDropdownOptions(state, formatMess
130
153
  if (!nodeWithPos || !breakoutEnabled || !isLayoutSupported(state, nodeWithPos) || isNestedNBM(state, nodeWithPos)) {
131
154
  return [];
132
155
  }
133
- var layout = nodeWithPos.node.attrs.layout;
156
+ var _getToolbarLayout2 = getToolbarLayout(nodeWithPos.node),
157
+ layout = _getToolbarLayout2.layout,
158
+ isCustomWidth = _getToolbarLayout2.isCustomWidth;
134
159
  var title = '';
135
160
  var IconComponent;
136
- switch (layout) {
137
- case 'wide':
138
- title = formatMessage(_messages2.default.layoutStateWide);
139
- IconComponent = _contentWidthWide.default;
140
- break;
141
- case 'full-width':
142
- title = formatMessage(_messages2.default.layoutStateFullWidth);
143
- IconComponent = _expandHorizontal.default;
144
- break;
145
- case 'default':
146
- default:
147
- title = formatMessage(_messages2.default.layoutStateFixedWidth);
148
- IconComponent = _contentWidthNarrow.default;
149
- break;
161
+ // the 'Custom width' option is a label only, the dropdown items are unchanged
162
+ if (isCustomWidth) {
163
+ title = formatMessage(_messages.messages.customWidth);
164
+ IconComponent = _expandHorizontal.default;
165
+ } else {
166
+ switch (layout) {
167
+ case 'wide':
168
+ title = formatMessage(_messages2.default.layoutStateWide);
169
+ IconComponent = _contentWidthWide.default;
170
+ break;
171
+ case 'full-width':
172
+ title = formatMessage(_messages2.default.layoutStateFullWidth);
173
+ IconComponent = _expandHorizontal.default;
174
+ break;
175
+ case 'default':
176
+ default:
177
+ title = formatMessage(_messages2.default.layoutStateFixedWidth);
178
+ IconComponent = _contentWidthNarrow.default;
179
+ break;
180
+ }
150
181
  }
151
182
  var options = [{
152
183
  id: 'editor.extensions.width.default',
153
184
  title: formatMessage(_messages2.default.layoutFixedWidth),
154
185
  onClick: (0, _commands.updateExtensionLayout)('default', editorAnalyticsAPI),
155
- selected: layout === 'default',
186
+ selected: !isCustomWidth && layout === 'default',
156
187
  icon: /*#__PURE__*/_react.default.createElement(_contentWidthNarrow.default, {
157
188
  color: "currentColor",
158
189
  spacing: "spacious",
@@ -162,7 +193,7 @@ var breakoutDropdownOptions = function breakoutDropdownOptions(state, formatMess
162
193
  id: 'editor.extensions.width.wide',
163
194
  title: formatMessage(_messages2.default.layoutWide),
164
195
  onClick: (0, _commands.updateExtensionLayout)('wide', editorAnalyticsAPI),
165
- selected: layout === 'wide',
196
+ selected: !isCustomWidth && layout === 'wide',
166
197
  icon: /*#__PURE__*/_react.default.createElement(_contentWidthWide.default, {
167
198
  color: "currentColor",
168
199
  spacing: "spacious",
@@ -172,7 +203,7 @@ var breakoutDropdownOptions = function breakoutDropdownOptions(state, formatMess
172
203
  id: 'editor.extensions.width.full-width',
173
204
  title: formatMessage(_messages2.default.layoutFullWidth),
174
205
  onClick: (0, _commands.updateExtensionLayout)('full-width', editorAnalyticsAPI),
175
- selected: layout === 'full-width',
206
+ selected: !isCustomWidth && layout === 'full-width',
176
207
  icon: /*#__PURE__*/_react.default.createElement(_expandHorizontal.default, {
177
208
  color: "currentColor",
178
209
  spacing: "spacious",
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getExtensionPresetWidth = exports.getExtensionLayout = void 0;
7
+ var _getBreakoutWidth = require("@atlaskit/editor-common/extensibility/get-breakout-width");
8
+ var _constants = require("@atlaskit/editor-shared-styles/constants");
9
+ var extensionPresetWidths = {
10
+ default: _constants.akEditorDefaultLayoutWidth,
11
+ wide: _constants.akEditorCalculatedWideLayoutWidth,
12
+ 'full-width': _constants.akEditorFullWidthLayoutWidth
13
+ };
14
+ var getExtensionPresetWidth = exports.getExtensionPresetWidth = function getExtensionPresetWidth(layout) {
15
+ return extensionPresetWidths[layout];
16
+ };
17
+
18
+ /**
19
+ * getExtensionLayout tries to match the breakout mark's width (if any) to an extension layout preset.
20
+ * @returns the layout preset if the breakout width matches, null if there is no match, or
21
+ * the node's layout attribute if there is no breakout width.
22
+ */
23
+ var getExtensionLayout = exports.getExtensionLayout = function getExtensionLayout(node) {
24
+ var _node$attrs$layout = node.attrs.layout,
25
+ layout = _node$attrs$layout === void 0 ? 'default' : _node$attrs$layout;
26
+ var breakoutWidth = (0, _getBreakoutWidth.getBreakoutWidth)(node.marks);
27
+ if (breakoutWidth !== undefined) {
28
+ if (breakoutWidth === extensionPresetWidths.default) {
29
+ return 'default';
30
+ }
31
+ if (breakoutWidth === extensionPresetWidths.wide) {
32
+ return 'wide';
33
+ }
34
+ if (breakoutWidth === extensionPresetWidths['full-width']) {
35
+ return 'full-width';
36
+ }
37
+ return null;
38
+ }
39
+ // if there is no breakout width, return the node's layout attribute
40
+ return layout;
41
+ };
@@ -3,8 +3,11 @@ import { TARGET_SELECTION_SOURCE } from '@atlaskit/editor-common/analytics/types
3
3
  import { removeConnectedNodes } from '@atlaskit/editor-common/utils/referentiality';
4
4
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
5
5
  import { findParentNodeOfType, removeParentNodeOfType, removeSelectedNode } from '@atlaskit/editor-prosemirror/utils';
6
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
7
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
8
  import { createCommand } from '../pm-plugins/plugin-factory';
7
9
  import { getSelectedExtension } from '../pm-plugins/utils';
10
+ import { getExtensionPresetWidth } from '../utils/getExtensionLayout';
8
11
 
9
12
  // AFP-2532 TODO: Fix automatic suppressions below
10
13
 
@@ -47,10 +50,24 @@ export const updateExtensionLayout = (layout, analyticsApi) => createCommand({
47
50
  }, (tr, state) => {
48
51
  const selectedExtension = getSelectedExtension(state, true);
49
52
  if (selectedExtension) {
53
+ let marks = selectedExtension.node.marks;
54
+ if (fg('platform_editor_lovability_resize_exts_gracefully') && isExperimentEnabled('platform_editor_lovability_resize_exts_patch_1')) {
55
+ const breakoutMark = marks.find(mark => mark.type.name === 'breakout');
56
+ if (breakoutMark && (layout === 'default' || layout === 'wide' || layout === 'full-width')) {
57
+ // the resizing:false cohort is still using the layout presets, so updating
58
+ // the layout should also update the breakout mark's width, which is the source of
59
+ // truth for the node's width.
60
+ marks = breakoutMark.type.create({
61
+ ...breakoutMark.attrs,
62
+ width: getExtensionPresetWidth(layout),
63
+ mode: layout === 'full-width' ? 'full-width' : 'wide'
64
+ }).addToSet(marks);
65
+ }
66
+ }
50
67
  const trWithNewNodeMarkup = tr.setNodeMarkup(selectedExtension.pos, undefined, {
51
68
  ...selectedExtension.node.attrs,
52
69
  layout
53
- });
70
+ }, marks);
54
71
  trWithNewNodeMarkup.setMeta('scrollIntoView', false);
55
72
  if (analyticsApi) {
56
73
  analyticsApi.attachAnalyticsEvent({
@@ -19,6 +19,7 @@ import { fg } from '@atlaskit/platform-feature-flags/fg';
19
19
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
20
20
  import { editExtension } from '../editor-actions/actions';
21
21
  import { removeDescendantNodes, removeExtension, updateExtensionLayout } from '../editor-commands/commands';
22
+ import { getExtensionLayout } from '../utils/getExtensionLayout';
22
23
  import { pluginKey as macroPluginKey } from './macro/plugin-key';
23
24
  import { getPluginState } from './plugin-factory';
24
25
  import { copyUnsupportedContentToClipboard, getSelectedExtension, onCopyFailed } from './utils';
@@ -75,14 +76,35 @@ const isLayoutSupported = (state, selectedExtNode) => {
75
76
  // and not inside a layoutSection
76
77
  return !!((isMultiBodiedExtension || isNonEmbeddedBodiedExtension || isNonEmbeddedExtension) && !hasParentNodeOfType([layoutSection])(selection));
77
78
  };
79
+
80
+ // if an extension node has been resized via breakout resizing,
81
+ // the layout dropdown button should reflect the breakout resized with
82
+ const getToolbarLayout = node => {
83
+ let {
84
+ layout
85
+ } = node.attrs;
86
+ let isCustomWidth = false;
87
+ const hasBreakoutMark = node.marks.some(mark => mark.type.name === 'breakout');
88
+ if (fg('platform_editor_lovability_resize_exts_gracefully') && isExperimentEnabled('platform_editor_lovability_resize_exts_patch_1') && hasBreakoutMark) {
89
+ // a custom width leaves the presets unselected and uses the 'Custom width' dropdown label
90
+ const matchedLayout = getExtensionLayout(node);
91
+ isCustomWidth = matchedLayout === null;
92
+ layout = matchedLayout !== null && matchedLayout !== void 0 ? matchedLayout : layout;
93
+ }
94
+ return {
95
+ layout,
96
+ isCustomWidth
97
+ };
98
+ };
78
99
  const breakoutButtonListOptions = (state, formatMessage, extensionState, breakoutEnabled, editorAnalyticsAPI) => {
79
100
  const nodeWithPos = getSelectedExtension(state, true);
80
101
 
81
102
  // we should only return breakout options when breakouts are enabled and the node supports them
82
103
  if (nodeWithPos && breakoutEnabled && isLayoutSupported(state, nodeWithPos) && !isNestedNBM(state, nodeWithPos)) {
83
104
  const {
84
- layout
85
- } = nodeWithPos.node.attrs;
105
+ layout,
106
+ isCustomWidth
107
+ } = getToolbarLayout(nodeWithPos.node);
86
108
  return [{
87
109
  type: 'button',
88
110
  icon: () => /*#__PURE__*/React.createElement(ContentWidthNarrowIcon, {
@@ -91,7 +113,7 @@ const breakoutButtonListOptions = (state, formatMessage, extensionState, breakou
91
113
  }),
92
114
  iconFallback: ContentWidthNarrowIcon,
93
115
  onClick: updateExtensionLayout('default', editorAnalyticsAPI),
94
- selected: layout === 'default',
116
+ selected: !isCustomWidth && layout === 'default',
95
117
  title: formatMessage(commonMessages.layoutFixedWidth),
96
118
  tabIndex: null
97
119
  }, {
@@ -102,7 +124,7 @@ const breakoutButtonListOptions = (state, formatMessage, extensionState, breakou
102
124
  }),
103
125
  iconFallback: ContentWidthWideIcon,
104
126
  onClick: updateExtensionLayout('wide', editorAnalyticsAPI),
105
- selected: layout === 'wide',
127
+ selected: !isCustomWidth && layout === 'wide',
106
128
  title: formatMessage(commonMessages.layoutWide),
107
129
  tabIndex: null
108
130
  }, {
@@ -113,7 +135,7 @@ const breakoutButtonListOptions = (state, formatMessage, extensionState, breakou
113
135
  }),
114
136
  iconFallback: ExpandHorizontalIcon,
115
137
  onClick: updateExtensionLayout('full-width', editorAnalyticsAPI),
116
- selected: layout === 'full-width',
138
+ selected: !isCustomWidth && layout === 'full-width',
117
139
  title: formatMessage(commonMessages.layoutFullWidth),
118
140
  tabIndex: null
119
141
  }];
@@ -128,30 +150,37 @@ const breakoutDropdownOptions = (state, formatMessage, breakoutEnabled, editorAn
128
150
  return [];
129
151
  }
130
152
  const {
131
- layout
132
- } = nodeWithPos.node.attrs;
153
+ layout,
154
+ isCustomWidth
155
+ } = getToolbarLayout(nodeWithPos.node);
133
156
  let title = '';
134
157
  let IconComponent;
135
- switch (layout) {
136
- case 'wide':
137
- title = formatMessage(commonMessages.layoutStateWide);
138
- IconComponent = ContentWidthWideIcon;
139
- break;
140
- case 'full-width':
141
- title = formatMessage(commonMessages.layoutStateFullWidth);
142
- IconComponent = ExpandHorizontalIcon;
143
- break;
144
- case 'default':
145
- default:
146
- title = formatMessage(commonMessages.layoutStateFixedWidth);
147
- IconComponent = ContentWidthNarrowIcon;
148
- break;
158
+ // the 'Custom width' option is a label only, the dropdown items are unchanged
159
+ if (isCustomWidth) {
160
+ title = formatMessage(messages.customWidth);
161
+ IconComponent = ExpandHorizontalIcon;
162
+ } else {
163
+ switch (layout) {
164
+ case 'wide':
165
+ title = formatMessage(commonMessages.layoutStateWide);
166
+ IconComponent = ContentWidthWideIcon;
167
+ break;
168
+ case 'full-width':
169
+ title = formatMessage(commonMessages.layoutStateFullWidth);
170
+ IconComponent = ExpandHorizontalIcon;
171
+ break;
172
+ case 'default':
173
+ default:
174
+ title = formatMessage(commonMessages.layoutStateFixedWidth);
175
+ IconComponent = ContentWidthNarrowIcon;
176
+ break;
177
+ }
149
178
  }
150
179
  const options = [{
151
180
  id: 'editor.extensions.width.default',
152
181
  title: formatMessage(commonMessages.layoutFixedWidth),
153
182
  onClick: updateExtensionLayout('default', editorAnalyticsAPI),
154
- selected: layout === 'default',
183
+ selected: !isCustomWidth && layout === 'default',
155
184
  icon: /*#__PURE__*/React.createElement(ContentWidthNarrowIcon, {
156
185
  color: "currentColor",
157
186
  spacing: "spacious",
@@ -161,7 +190,7 @@ const breakoutDropdownOptions = (state, formatMessage, breakoutEnabled, editorAn
161
190
  id: 'editor.extensions.width.wide',
162
191
  title: formatMessage(commonMessages.layoutWide),
163
192
  onClick: updateExtensionLayout('wide', editorAnalyticsAPI),
164
- selected: layout === 'wide',
193
+ selected: !isCustomWidth && layout === 'wide',
165
194
  icon: /*#__PURE__*/React.createElement(ContentWidthWideIcon, {
166
195
  color: "currentColor",
167
196
  spacing: "spacious",
@@ -171,7 +200,7 @@ const breakoutDropdownOptions = (state, formatMessage, breakoutEnabled, editorAn
171
200
  id: 'editor.extensions.width.full-width',
172
201
  title: formatMessage(commonMessages.layoutFullWidth),
173
202
  onClick: updateExtensionLayout('full-width', editorAnalyticsAPI),
174
- selected: layout === 'full-width',
203
+ selected: !isCustomWidth && layout === 'full-width',
175
204
  icon: /*#__PURE__*/React.createElement(ExpandHorizontalIcon, {
176
205
  color: "currentColor",
177
206
  spacing: "spacious",
@@ -0,0 +1,34 @@
1
+ import { getBreakoutWidth } from '@atlaskit/editor-common/extensibility/get-breakout-width';
2
+ import { akEditorCalculatedWideLayoutWidth, akEditorDefaultLayoutWidth, akEditorFullWidthLayoutWidth } from '@atlaskit/editor-shared-styles/constants';
3
+ const extensionPresetWidths = {
4
+ default: akEditorDefaultLayoutWidth,
5
+ wide: akEditorCalculatedWideLayoutWidth,
6
+ 'full-width': akEditorFullWidthLayoutWidth
7
+ };
8
+ export const getExtensionPresetWidth = layout => extensionPresetWidths[layout];
9
+
10
+ /**
11
+ * getExtensionLayout tries to match the breakout mark's width (if any) to an extension layout preset.
12
+ * @returns the layout preset if the breakout width matches, null if there is no match, or
13
+ * the node's layout attribute if there is no breakout width.
14
+ */
15
+ export const getExtensionLayout = node => {
16
+ const {
17
+ layout = 'default'
18
+ } = node.attrs;
19
+ const breakoutWidth = getBreakoutWidth(node.marks);
20
+ if (breakoutWidth !== undefined) {
21
+ if (breakoutWidth === extensionPresetWidths.default) {
22
+ return 'default';
23
+ }
24
+ if (breakoutWidth === extensionPresetWidths.wide) {
25
+ return 'wide';
26
+ }
27
+ if (breakoutWidth === extensionPresetWidths['full-width']) {
28
+ return 'full-width';
29
+ }
30
+ return null;
31
+ }
32
+ // if there is no breakout width, return the node's layout attribute
33
+ return layout;
34
+ };
@@ -6,8 +6,11 @@ import { TARGET_SELECTION_SOURCE } from '@atlaskit/editor-common/analytics/types
6
6
  import { removeConnectedNodes } from '@atlaskit/editor-common/utils/referentiality';
7
7
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
8
8
  import { findParentNodeOfType, removeParentNodeOfType, removeSelectedNode } from '@atlaskit/editor-prosemirror/utils';
9
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
10
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
9
11
  import { createCommand } from '../pm-plugins/plugin-factory';
10
12
  import { getSelectedExtension } from '../pm-plugins/utils';
13
+ import { getExtensionPresetWidth } from '../utils/getExtensionLayout';
11
14
 
12
15
  // AFP-2532 TODO: Fix automatic suppressions below
13
16
 
@@ -57,9 +60,24 @@ export var updateExtensionLayout = function updateExtensionLayout(layout, analyt
57
60
  }, function (tr, state) {
58
61
  var selectedExtension = getSelectedExtension(state, true);
59
62
  if (selectedExtension) {
63
+ var marks = selectedExtension.node.marks;
64
+ if (fg('platform_editor_lovability_resize_exts_gracefully') && isExperimentEnabled('platform_editor_lovability_resize_exts_patch_1')) {
65
+ var breakoutMark = marks.find(function (mark) {
66
+ return mark.type.name === 'breakout';
67
+ });
68
+ if (breakoutMark && (layout === 'default' || layout === 'wide' || layout === 'full-width')) {
69
+ // the resizing:false cohort is still using the layout presets, so updating
70
+ // the layout should also update the breakout mark's width, which is the source of
71
+ // truth for the node's width.
72
+ marks = breakoutMark.type.create(_objectSpread(_objectSpread({}, breakoutMark.attrs), {}, {
73
+ width: getExtensionPresetWidth(layout),
74
+ mode: layout === 'full-width' ? 'full-width' : 'wide'
75
+ })).addToSet(marks);
76
+ }
77
+ }
60
78
  var trWithNewNodeMarkup = tr.setNodeMarkup(selectedExtension.pos, undefined, _objectSpread(_objectSpread({}, selectedExtension.node.attrs), {}, {
61
79
  layout: layout
62
- }));
80
+ }), marks);
63
81
  trWithNewNodeMarkup.setMeta('scrollIntoView', false);
64
82
  if (analyticsApi) {
65
83
  analyticsApi.attachAnalyticsEvent({
@@ -23,6 +23,7 @@ import { fg } from '@atlaskit/platform-feature-flags/fg';
23
23
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
24
24
  import { editExtension } from '../editor-actions/actions';
25
25
  import { removeDescendantNodes, removeExtension, updateExtensionLayout } from '../editor-commands/commands';
26
+ import { getExtensionLayout } from '../utils/getExtensionLayout';
26
27
  import { pluginKey as macroPluginKey } from './macro/plugin-key';
27
28
  import { getPluginState } from './plugin-factory';
28
29
  import { copyUnsupportedContentToClipboard, getSelectedExtension, onCopyFailed } from './utils';
@@ -68,12 +69,34 @@ var isLayoutSupported = function isLayoutSupported(state, selectedExtNode) {
68
69
  // and not inside a layoutSection
69
70
  return !!((isMultiBodiedExtension || isNonEmbeddedBodiedExtension || isNonEmbeddedExtension) && !hasParentNodeOfType([layoutSection])(selection));
70
71
  };
72
+
73
+ // if an extension node has been resized via breakout resizing,
74
+ // the layout dropdown button should reflect the breakout resized with
75
+ var getToolbarLayout = function getToolbarLayout(node) {
76
+ var layout = node.attrs.layout;
77
+ var isCustomWidth = false;
78
+ var hasBreakoutMark = node.marks.some(function (mark) {
79
+ return mark.type.name === 'breakout';
80
+ });
81
+ if (fg('platform_editor_lovability_resize_exts_gracefully') && isExperimentEnabled('platform_editor_lovability_resize_exts_patch_1') && hasBreakoutMark) {
82
+ // a custom width leaves the presets unselected and uses the 'Custom width' dropdown label
83
+ var matchedLayout = getExtensionLayout(node);
84
+ isCustomWidth = matchedLayout === null;
85
+ layout = matchedLayout !== null && matchedLayout !== void 0 ? matchedLayout : layout;
86
+ }
87
+ return {
88
+ layout: layout,
89
+ isCustomWidth: isCustomWidth
90
+ };
91
+ };
71
92
  var breakoutButtonListOptions = function breakoutButtonListOptions(state, formatMessage, extensionState, breakoutEnabled, editorAnalyticsAPI) {
72
93
  var nodeWithPos = getSelectedExtension(state, true);
73
94
 
74
95
  // we should only return breakout options when breakouts are enabled and the node supports them
75
96
  if (nodeWithPos && breakoutEnabled && isLayoutSupported(state, nodeWithPos) && !isNestedNBM(state, nodeWithPos)) {
76
- var layout = nodeWithPos.node.attrs.layout;
97
+ var _getToolbarLayout = getToolbarLayout(nodeWithPos.node),
98
+ layout = _getToolbarLayout.layout,
99
+ isCustomWidth = _getToolbarLayout.isCustomWidth;
77
100
  return [{
78
101
  type: 'button',
79
102
  icon: function icon() {
@@ -84,7 +107,7 @@ var breakoutButtonListOptions = function breakoutButtonListOptions(state, format
84
107
  },
85
108
  iconFallback: ContentWidthNarrowIcon,
86
109
  onClick: updateExtensionLayout('default', editorAnalyticsAPI),
87
- selected: layout === 'default',
110
+ selected: !isCustomWidth && layout === 'default',
88
111
  title: formatMessage(commonMessages.layoutFixedWidth),
89
112
  tabIndex: null
90
113
  }, {
@@ -97,7 +120,7 @@ var breakoutButtonListOptions = function breakoutButtonListOptions(state, format
97
120
  },
98
121
  iconFallback: ContentWidthWideIcon,
99
122
  onClick: updateExtensionLayout('wide', editorAnalyticsAPI),
100
- selected: layout === 'wide',
123
+ selected: !isCustomWidth && layout === 'wide',
101
124
  title: formatMessage(commonMessages.layoutWide),
102
125
  tabIndex: null
103
126
  }, {
@@ -110,7 +133,7 @@ var breakoutButtonListOptions = function breakoutButtonListOptions(state, format
110
133
  },
111
134
  iconFallback: ExpandHorizontalIcon,
112
135
  onClick: updateExtensionLayout('full-width', editorAnalyticsAPI),
113
- selected: layout === 'full-width',
136
+ selected: !isCustomWidth && layout === 'full-width',
114
137
  title: formatMessage(commonMessages.layoutFullWidth),
115
138
  tabIndex: null
116
139
  }];
@@ -124,29 +147,37 @@ var breakoutDropdownOptions = function breakoutDropdownOptions(state, formatMess
124
147
  if (!nodeWithPos || !breakoutEnabled || !isLayoutSupported(state, nodeWithPos) || isNestedNBM(state, nodeWithPos)) {
125
148
  return [];
126
149
  }
127
- var layout = nodeWithPos.node.attrs.layout;
150
+ var _getToolbarLayout2 = getToolbarLayout(nodeWithPos.node),
151
+ layout = _getToolbarLayout2.layout,
152
+ isCustomWidth = _getToolbarLayout2.isCustomWidth;
128
153
  var title = '';
129
154
  var IconComponent;
130
- switch (layout) {
131
- case 'wide':
132
- title = formatMessage(commonMessages.layoutStateWide);
133
- IconComponent = ContentWidthWideIcon;
134
- break;
135
- case 'full-width':
136
- title = formatMessage(commonMessages.layoutStateFullWidth);
137
- IconComponent = ExpandHorizontalIcon;
138
- break;
139
- case 'default':
140
- default:
141
- title = formatMessage(commonMessages.layoutStateFixedWidth);
142
- IconComponent = ContentWidthNarrowIcon;
143
- break;
155
+ // the 'Custom width' option is a label only, the dropdown items are unchanged
156
+ if (isCustomWidth) {
157
+ title = formatMessage(messages.customWidth);
158
+ IconComponent = ExpandHorizontalIcon;
159
+ } else {
160
+ switch (layout) {
161
+ case 'wide':
162
+ title = formatMessage(commonMessages.layoutStateWide);
163
+ IconComponent = ContentWidthWideIcon;
164
+ break;
165
+ case 'full-width':
166
+ title = formatMessage(commonMessages.layoutStateFullWidth);
167
+ IconComponent = ExpandHorizontalIcon;
168
+ break;
169
+ case 'default':
170
+ default:
171
+ title = formatMessage(commonMessages.layoutStateFixedWidth);
172
+ IconComponent = ContentWidthNarrowIcon;
173
+ break;
174
+ }
144
175
  }
145
176
  var options = [{
146
177
  id: 'editor.extensions.width.default',
147
178
  title: formatMessage(commonMessages.layoutFixedWidth),
148
179
  onClick: updateExtensionLayout('default', editorAnalyticsAPI),
149
- selected: layout === 'default',
180
+ selected: !isCustomWidth && layout === 'default',
150
181
  icon: /*#__PURE__*/React.createElement(ContentWidthNarrowIcon, {
151
182
  color: "currentColor",
152
183
  spacing: "spacious",
@@ -156,7 +187,7 @@ var breakoutDropdownOptions = function breakoutDropdownOptions(state, formatMess
156
187
  id: 'editor.extensions.width.wide',
157
188
  title: formatMessage(commonMessages.layoutWide),
158
189
  onClick: updateExtensionLayout('wide', editorAnalyticsAPI),
159
- selected: layout === 'wide',
190
+ selected: !isCustomWidth && layout === 'wide',
160
191
  icon: /*#__PURE__*/React.createElement(ContentWidthWideIcon, {
161
192
  color: "currentColor",
162
193
  spacing: "spacious",
@@ -166,7 +197,7 @@ var breakoutDropdownOptions = function breakoutDropdownOptions(state, formatMess
166
197
  id: 'editor.extensions.width.full-width',
167
198
  title: formatMessage(commonMessages.layoutFullWidth),
168
199
  onClick: updateExtensionLayout('full-width', editorAnalyticsAPI),
169
- selected: layout === 'full-width',
200
+ selected: !isCustomWidth && layout === 'full-width',
170
201
  icon: /*#__PURE__*/React.createElement(ExpandHorizontalIcon, {
171
202
  color: "currentColor",
172
203
  spacing: "spacious",
@@ -0,0 +1,35 @@
1
+ import { getBreakoutWidth } from '@atlaskit/editor-common/extensibility/get-breakout-width';
2
+ import { akEditorCalculatedWideLayoutWidth, akEditorDefaultLayoutWidth, akEditorFullWidthLayoutWidth } from '@atlaskit/editor-shared-styles/constants';
3
+ var extensionPresetWidths = {
4
+ default: akEditorDefaultLayoutWidth,
5
+ wide: akEditorCalculatedWideLayoutWidth,
6
+ 'full-width': akEditorFullWidthLayoutWidth
7
+ };
8
+ export var getExtensionPresetWidth = function getExtensionPresetWidth(layout) {
9
+ return extensionPresetWidths[layout];
10
+ };
11
+
12
+ /**
13
+ * getExtensionLayout tries to match the breakout mark's width (if any) to an extension layout preset.
14
+ * @returns the layout preset if the breakout width matches, null if there is no match, or
15
+ * the node's layout attribute if there is no breakout width.
16
+ */
17
+ export var getExtensionLayout = function getExtensionLayout(node) {
18
+ var _node$attrs$layout = node.attrs.layout,
19
+ layout = _node$attrs$layout === void 0 ? 'default' : _node$attrs$layout;
20
+ var breakoutWidth = getBreakoutWidth(node.marks);
21
+ if (breakoutWidth !== undefined) {
22
+ if (breakoutWidth === extensionPresetWidths.default) {
23
+ return 'default';
24
+ }
25
+ if (breakoutWidth === extensionPresetWidths.wide) {
26
+ return 'wide';
27
+ }
28
+ if (breakoutWidth === extensionPresetWidths['full-width']) {
29
+ return 'full-width';
30
+ }
31
+ return null;
32
+ }
33
+ // if there is no breakout width, return the node's layout attribute
34
+ return layout;
35
+ };
@@ -0,0 +1,9 @@
1
+ import type { Layout } from '@atlaskit/adf-schema/extensions';
2
+ import type { Node } from '@atlaskit/editor-prosemirror/model';
3
+ export declare const getExtensionPresetWidth: (layout: 'default' | 'wide' | 'full-width') => number;
4
+ /**
5
+ * getExtensionLayout tries to match the breakout mark's width (if any) to an extension layout preset.
6
+ * @returns the layout preset if the breakout width matches, null if there is no match, or
7
+ * the node's layout attribute if there is no breakout width.
8
+ */
9
+ export declare const getExtensionLayout: (node: Node) => Layout | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-extension",
3
- "version": "33.0.10",
3
+ "version": "33.0.11",
4
4
  "description": "editor-plugin-extension plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -29,7 +29,7 @@
29
29
  "@atlaskit/adf-schema": "^57.7.0",
30
30
  "@atlaskit/adf-utils": "^20.9.0",
31
31
  "@atlaskit/analytics-next": "^12.6.0",
32
- "@atlaskit/avatar": "^30.0.0",
32
+ "@atlaskit/avatar": "^30.1.0",
33
33
  "@atlaskit/browser-apis": "^1.2.0",
34
34
  "@atlaskit/button": "^25.7.0",
35
35
  "@atlaskit/checkbox": "^19.3.0",
@@ -85,12 +85,12 @@
85
85
  "uuid": "^11.1.1"
86
86
  },
87
87
  "peerDependencies": {
88
- "@atlaskit/editor-common": "^134.7.0",
88
+ "@atlaskit/editor-common": "^134.8.0",
89
89
  "react": "^18.2.0 || ^19.2.0",
90
90
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
91
91
  },
92
92
  "devDependencies": {
93
- "@atlaskit/editor-common": "^134.7.0",
93
+ "@atlaskit/editor-common": "^134.8.0",
94
94
  "@atlassian/structured-docs-types": "workspace:^",
95
95
  "@atlassian/workbench": "workspace:*",
96
96
  "react": "^19.2.0",