@atlaskit/editor-plugin-expand 7.2.5 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/editor-commands/toggleExpandRange.js +24 -0
  3. package/dist/cjs/legacyExpand/commands.js +3 -2
  4. package/dist/cjs/legacyExpand/nodeviews/index.js +26 -3
  5. package/dist/cjs/legacyExpand/plugin.js +3 -1
  6. package/dist/cjs/singlePlayerExpand/commands.js +7 -4
  7. package/dist/cjs/singlePlayerExpand/node-views/index.js +26 -3
  8. package/dist/cjs/singlePlayerExpand/plugin.js +3 -1
  9. package/dist/cjs/ui/renderExpandButton.js +61 -0
  10. package/dist/es2019/editor-commands/toggleExpandRange.js +17 -0
  11. package/dist/es2019/legacyExpand/commands.js +3 -2
  12. package/dist/es2019/legacyExpand/nodeviews/index.js +26 -2
  13. package/dist/es2019/legacyExpand/plugin.js +3 -1
  14. package/dist/es2019/singlePlayerExpand/commands.js +7 -3
  15. package/dist/es2019/singlePlayerExpand/node-views/index.js +24 -3
  16. package/dist/es2019/singlePlayerExpand/plugin.js +3 -1
  17. package/dist/es2019/ui/renderExpandButton.js +57 -0
  18. package/dist/esm/editor-commands/toggleExpandRange.js +18 -0
  19. package/dist/esm/legacyExpand/commands.js +3 -2
  20. package/dist/esm/legacyExpand/nodeviews/index.js +26 -2
  21. package/dist/esm/legacyExpand/plugin.js +3 -1
  22. package/dist/esm/singlePlayerExpand/commands.js +7 -3
  23. package/dist/esm/singlePlayerExpand/node-views/index.js +26 -3
  24. package/dist/esm/singlePlayerExpand/plugin.js +3 -1
  25. package/dist/esm/ui/renderExpandButton.js +55 -0
  26. package/dist/types/editor-commands/toggleExpandRange.d.ts +2 -0
  27. package/dist/types/legacyExpand/nodeviews/index.d.ts +1 -0
  28. package/dist/types/singlePlayerExpand/node-views/index.d.ts +1 -0
  29. package/dist/types/types.d.ts +28 -0
  30. package/dist/types/ui/renderExpandButton.d.ts +17 -0
  31. package/dist/types-ts4.5/editor-commands/toggleExpandRange.d.ts +2 -0
  32. package/dist/types-ts4.5/legacyExpand/nodeviews/index.d.ts +1 -0
  33. package/dist/types-ts4.5/singlePlayerExpand/node-views/index.d.ts +1 -0
  34. package/dist/types-ts4.5/types.d.ts +28 -0
  35. package/dist/types-ts4.5/ui/renderExpandButton.d.ts +17 -0
  36. package/package.json +6 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-plugin-expand
2
2
 
3
+ ## 7.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`fd552090f0285`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fd552090f0285) -
8
+ Introduce new toggle expand command API to toggle expands across a range.
9
+
10
+ ## 7.3.0
11
+
12
+ ### Minor Changes
13
+
14
+ - [`236d9310035ae`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/236d9310035ae) -
15
+ [https://product-fabric.atlassian.net/browse/ED-29205](ED-29205) - use native DOM element for
16
+ editor expand icon
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+
3
22
  ## 7.2.5
4
23
 
5
24
  ### Patch Changes
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.toggleExpandRange = void 0;
7
+ var _expand = require("@atlaskit/editor-common/expand");
8
+ var toggleExpandRange = exports.toggleExpandRange = function toggleExpandRange(from, to) {
9
+ var open = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
10
+ return function (_ref) {
11
+ var tr = _ref.tr;
12
+ var _tr$doc$type$schema$n = tr.doc.type.schema.nodes,
13
+ expand = _tr$doc$type$schema$n.expand,
14
+ nestedExpand = _tr$doc$type$schema$n.nestedExpand;
15
+ var fromClamped = from && from >= 0 ? from : 0;
16
+ var toClamped = to && to <= tr.doc.content.size ? to : tr.doc.content.size;
17
+ tr.doc.nodesBetween(fromClamped, toClamped, function (node) {
18
+ if ([expand, nestedExpand].includes(node.type)) {
19
+ _expand.expandedState.set(node, open);
20
+ }
21
+ });
22
+ return null;
23
+ };
24
+ };
@@ -15,6 +15,7 @@ var _utils = require("@atlaskit/editor-common/utils");
15
15
  var _state2 = require("@atlaskit/editor-prosemirror/state");
16
16
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
17
17
  var _utils3 = require("@atlaskit/editor-tables/utils");
18
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
18
19
  var _utils4 = require("../utils");
19
20
  var _pluginFactory = require("./pm-plugins/plugin-factory");
20
21
  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; }
@@ -207,8 +208,8 @@ var focusIcon = exports.focusIcon = function focusIcon(expand) {
207
208
  return false;
208
209
  }
209
210
 
210
- // eslint-disable-next-line @atlaskit/editor/no-as-casting
211
- var iconContainer = expand.querySelector(".".concat(_styles.expandClassNames.iconContainer));
211
+ // TODO: ED-29205 - During platform_editor_native_expand_button cleanup, rename `iconContainer` to `iconButton`.
212
+ var iconContainer = (0, _expValEquals.expValEquals)('platform_editor_native_expand_button', 'isEnabled', true) ? expand.querySelector(".".concat(_styles.expandClassNames.iconButton)) : expand.querySelector(".".concat(_styles.expandClassNames.iconContainer));
212
213
  if (iconContainer && iconContainer.focus) {
213
214
  var tr = state.tr;
214
215
  var pos = state.selection.from;
@@ -21,10 +21,11 @@ var _state = require("@atlaskit/editor-prosemirror/state");
21
21
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
22
22
  var _prosemirrorHistory = require("@atlaskit/prosemirror-history");
23
23
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
24
+ var _renderExpandButton = require("../../ui/renderExpandButton");
24
25
  var _commands = require("../commands");
25
26
  var _ExpandIconButton = require("../ui/ExpandIconButton");
26
27
  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; }
27
- 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; }
28
+ 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; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
28
29
  function buildExpandClassName(type, expanded) {
29
30
  return "".concat(_styles.expandClassNames.prefix, " ").concat(_styles.expandClassNames.type(type), " ").concat(expanded ? _styles.expandClassNames.expanded : '');
30
31
  }
@@ -449,8 +450,13 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
449
450
  this.input = this.dom.querySelector(".".concat(_styles.expandClassNames.titleInput));
450
451
  this.titleContainer = this.dom.querySelector(".".concat(_styles.expandClassNames.titleContainer));
451
452
  this.content = this.dom.querySelector(".".concat(_styles.expandClassNames.content));
453
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
452
454
  this.renderKey = (0, _v.default)();
453
- this.renderIcon(this.intl);
455
+ if ((0, _expValEquals.expValEquals)('platform_editor_native_expand_button', 'isEnabled', true)) {
456
+ this.renderNativeIcon(this.node);
457
+ } else {
458
+ this.renderIcon(this.intl);
459
+ }
454
460
  this.initHandlers();
455
461
  }
456
462
  return (0, _createClass2.default)(ExpandNodeView, [{
@@ -498,6 +504,19 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
498
504
  });
499
505
  }
500
506
  }
507
+ }, {
508
+ key: "renderNativeIcon",
509
+ value: function renderNativeIcon(node) {
510
+ if (!this.icon) {
511
+ return;
512
+ }
513
+ var __expanded = node.attrs.__expanded;
514
+ (0, _renderExpandButton.renderExpandButton)(this.icon, {
515
+ expanded: this.__livePage ? !__expanded : __expanded,
516
+ allowInteractiveExpand: this.allowInteractiveExpand,
517
+ intl: this.intl
518
+ });
519
+ }
501
520
  }, {
502
521
  key: "renderIcon",
503
522
  value: function renderIcon(intl, node) {
@@ -546,7 +565,11 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
546
565
  // we toggle a class name to hide the content and animate the chevron.
547
566
  if (this.dom) {
548
567
  this.dom.classList.toggle(_styles.expandClassNames.expanded);
549
- this.renderIcon(this && this.intl, node);
568
+ if ((0, _expValEquals.expValEquals)('platform_editor_native_expand_button', 'isEnabled', true)) {
569
+ this.renderNativeIcon(node);
570
+ } else {
571
+ this.renderIcon(this && this.intl, node);
572
+ }
550
573
  }
551
574
  if (this.content) {
552
575
  // Disallow interaction/selection inside when collapsed.
@@ -14,6 +14,7 @@ var _quickInsert = require("@atlaskit/editor-common/quick-insert");
14
14
  var _utils = require("@atlaskit/editor-common/utils");
15
15
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
16
  var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
17
+ var _toggleExpandRange = require("../editor-commands/toggleExpandRange");
17
18
  var _ExpandBlockMenuItem = require("../ui/ExpandBlockMenuItem");
18
19
  var _commands = require("./commands");
19
20
  var _keymap = require("./pm-plugins/keymap");
@@ -57,7 +58,8 @@ var expandPlugin = exports.expandPlugin = function expandPlugin(_ref) {
57
58
  commands: {
58
59
  toggleExpandWithMatch: function toggleExpandWithMatch(selection) {
59
60
  return (0, _commands.toggleExpandWithMatch)(selection);
60
- }
61
+ },
62
+ toggleExpandRange: _toggleExpandRange.toggleExpandRange
61
63
  },
62
64
  pmPlugins: function pmPlugins() {
63
65
  return [{
@@ -21,7 +21,7 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
21
21
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
22
22
  var _utils4 = require("../utils");
23
23
  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; }
24
- 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; }
24
+ 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; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
25
25
  // Creates either an expand or a nestedExpand node based on the current selection
26
26
  var createExpandNode = exports.createExpandNode = function createExpandNode(state) {
27
27
  var setExpandedState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
@@ -34,8 +34,11 @@ var createExpandNode = exports.createExpandNode = function createExpandNode(stat
34
34
  var isSelectionInExpand = (0, _utils4.isNestedInExpand)(state);
35
35
  var expandType = isSelectionInTable || isSelectionInExpand ? nestedExpand : expand;
36
36
  var expandNode = (0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid') ? expandType.createAndFill(addLocalId ? {
37
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
37
38
  localId: (0, _v.default)()
38
- } : {}, paragraph.createAndFill(addLocalId ? {
39
+ } : {},
40
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
41
+ paragraph.createAndFill(addLocalId ? {
39
42
  localId: (0, _v.default)()
40
43
  } : {})) : expandType.createAndFill({});
41
44
  if (setExpandedState) {
@@ -241,8 +244,8 @@ var focusIcon = exports.focusIcon = function focusIcon(expand) {
241
244
  return false;
242
245
  }
243
246
 
244
- // eslint-disable-next-line @atlaskit/editor/no-as-casting
245
- var iconContainer = expand.querySelector(".".concat(_styles.expandClassNames.iconContainer));
247
+ // TODO: ED-29205 - During platform_editor_native_expand_button cleanup, rename `iconContainer` to `iconButton`.
248
+ var iconContainer = (0, _expValEquals.expValEquals)('platform_editor_native_expand_button', 'isEnabled', true) ? expand.querySelector(".".concat(_styles.expandClassNames.iconButton)) : expand.querySelector(".".concat(_styles.expandClassNames.iconContainer));
246
249
  if (iconContainer && iconContainer.focus) {
247
250
  var tr = state.tr;
248
251
  var pos = state.selection.from;
@@ -21,10 +21,12 @@ var _state = require("@atlaskit/editor-prosemirror/state");
21
21
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
22
22
  var _prosemirrorHistory = require("@atlaskit/prosemirror-history");
23
23
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
24
+ var _renderExpandButton = require("../../ui/renderExpandButton");
24
25
  var _commands = require("../commands");
25
26
  var _ExpandButton = require("../ui/ExpandButton");
26
27
  var _NodeView = require("../ui/NodeView");
27
28
  var _utils2 = require("../utils");
29
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
28
30
  var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
29
31
  function ExpandNodeView(_node, view, getPos, getIntl, isMobile, selectNearNode, api, nodeViewPortalProviderAPI) {
30
32
  var _this = this,
@@ -415,12 +417,17 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
415
417
  this.icon = this.dom.querySelector(".".concat(_styles.expandClassNames.icon));
416
418
  this.input = this.dom.querySelector(".".concat(_styles.expandClassNames.titleInput));
417
419
  this.titleContainer = this.dom.querySelector(".".concat(_styles.expandClassNames.titleContainer));
420
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
418
421
  this.renderKey = (0, _v.default)();
419
422
  this.content = this.dom.querySelector(".".concat(_styles.expandClassNames.content));
420
423
  if (!_expand.expandedState.has(this.node)) {
421
424
  _expand.expandedState.set(this.node, false);
422
425
  }
423
- this.renderIcon(this.icon, !(0, _expand.isExpandCollapsed)(this.node));
426
+ if ((0, _expValEquals.expValEquals)('platform_editor_native_expand_button', 'isEnabled', true)) {
427
+ this.renderNativeIcon(this.node);
428
+ } else {
429
+ this.renderIcon(this.icon, !(0, _expand.isExpandCollapsed)(this.node));
430
+ }
424
431
  if (!this.input || !this.titleContainer || !this.icon) {
425
432
  return;
426
433
  }
@@ -518,7 +525,6 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
518
525
  value: function updateExpandToggleIcon(node) {
519
526
  var expanded = _expand.expandedState.get(node) ? _expand.expandedState.get(node) : false;
520
527
  if (this.dom && expanded !== undefined) {
521
- var _expandedState$get;
522
528
  if ((0, _expValEquals.expValEquals)('platform_editor_find_and_replace_improvements', 'isEnabled', true)) {
523
529
  var classes = this.dom.className.split(' ');
524
530
  // find & replace styles might be applied to the expand title and we need to keep them
@@ -530,7 +536,12 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
530
536
  this.dom.className = (0, _NodeView.buildExpandClassName)(node.type.name, expanded);
531
537
  }
532
538
  // Re-render the icon to update the aria-expanded attribute
533
- this.renderIcon(this.icon ? this.icon : null, (_expandedState$get = _expand.expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false);
539
+ if ((0, _expValEquals.expValEquals)('platform_editor_native_expand_button', 'isEnabled', true)) {
540
+ this.renderNativeIcon(node);
541
+ } else {
542
+ var _expandedState$get;
543
+ this.renderIcon(this.icon ? this.icon : null, (_expandedState$get = _expand.expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false);
544
+ }
534
545
  }
535
546
  this.updateExpandBodyContentEditable();
536
547
  if ((0, _expValEquals.expValEquals)('platform_editor_toggle_expand_on_match_found', 'isEnabled', true)) {
@@ -545,6 +556,18 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
545
556
  this.content.setAttribute('contenteditable', this.getContentEditable(this.node) ? 'true' : 'false');
546
557
  }
547
558
  }
559
+ }, {
560
+ key: "renderNativeIcon",
561
+ value: function renderNativeIcon(node) {
562
+ if (!this.icon) {
563
+ return;
564
+ }
565
+ (0, _renderExpandButton.renderExpandButton)(this.icon, {
566
+ expanded: !(0, _expand.isExpandCollapsed)(node),
567
+ allowInteractiveExpand: this.allowInteractiveExpand,
568
+ intl: this.intl
569
+ });
570
+ }
548
571
  }, {
549
572
  key: "destroy",
550
573
  value: function destroy() {
@@ -14,6 +14,7 @@ var _quickInsert = require("@atlaskit/editor-common/quick-insert");
14
14
  var _utils = require("@atlaskit/editor-common/utils");
15
15
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
16
  var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
17
+ var _toggleExpandRange = require("../editor-commands/toggleExpandRange");
17
18
  var _ExpandBlockMenuItem = require("../ui/ExpandBlockMenuItem");
18
19
  var _commands = require("./commands");
19
20
  var _keymap = require("./pm-plugins/keymap");
@@ -56,7 +57,8 @@ var expandPlugin = exports.expandPlugin = function expandPlugin(_ref) {
56
57
  commands: {
57
58
  toggleExpandWithMatch: function toggleExpandWithMatch(selection) {
58
59
  return (0, _commands.toggleExpandWithMatch)(selection);
59
- }
60
+ },
61
+ toggleExpandRange: _toggleExpandRange.toggleExpandRange
60
62
  },
61
63
  pmPlugins: function pmPlugins() {
62
64
  return [{
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.renderExpandButton = renderExpandButton;
7
+ var _browserApis = require("@atlaskit/browser-apis");
8
+ var _styles = require("@atlaskit/editor-common/styles");
9
+ var _ui = require("@atlaskit/editor-common/ui");
10
+ /**
11
+ * Renders or updates the expand/collapse button inside the provided container element.
12
+ *
13
+ * @param container - The HTML element that will contain the expand/collapse button.
14
+ * @param buttonProps - Properties for configuring the button's behavior and appearance.
15
+ */
16
+ function renderExpandButton(container, buttonProps) {
17
+ var allowInteractiveExpand = buttonProps.allowInteractiveExpand,
18
+ expanded = buttonProps.expanded,
19
+ intl = buttonProps.intl;
20
+
21
+ // Update existing button attributes
22
+ var label = intl.formatMessage(expanded ? _ui.expandMessages.collapseNode : _ui.expandMessages.expandNode);
23
+ var existingButton = container.querySelector(".".concat(_styles.expandClassNames.iconButton));
24
+ if (existingButton) {
25
+ existingButton.setAttribute('aria-label', label);
26
+ existingButton.setAttribute('aria-expanded', String(expanded));
27
+ if (allowInteractiveExpand) {
28
+ existingButton.setAttribute('title', label);
29
+ existingButton.removeAttribute('disabled');
30
+ } else {
31
+ existingButton.removeAttribute('title');
32
+ existingButton.setAttribute('disabled', 'true');
33
+ }
34
+ } else {
35
+ var doc = (0, _browserApis.getDocument)();
36
+ if (!doc) {
37
+ return;
38
+ }
39
+ var button = doc.createElement('button');
40
+ button.className = _styles.expandClassNames.iconButton;
41
+ button.setAttribute('aria-label', label);
42
+ button.setAttribute('aria-expanded', String(expanded));
43
+ if (allowInteractiveExpand) {
44
+ button.setAttribute('title', label);
45
+ } else {
46
+ button.setAttribute('disabled', 'true');
47
+ }
48
+ container.appendChild(button);
49
+ var svgIcon = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
50
+ svgIcon.setAttribute('class', _styles.expandClassNames.iconSvg);
51
+ svgIcon.setAttribute('width', '12');
52
+ svgIcon.setAttribute('height', '12');
53
+ svgIcon.setAttribute('viewBox', '0 0 16 16');
54
+ svgIcon.setAttribute('role', 'presentation');
55
+ var path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
56
+ path.setAttribute('fill', 'currentcolor');
57
+ path.setAttribute('d', 'm6.03 1.47 6 6a.75.75 0 0 1 .052 1.004l-.052.056-6 6-1.06-1.06L10.44 8 4.97 2.53z');
58
+ svgIcon.appendChild(path);
59
+ button.appendChild(svgIcon);
60
+ }
61
+ }
@@ -0,0 +1,17 @@
1
+ import { expandedState } from '@atlaskit/editor-common/expand';
2
+ export const toggleExpandRange = (from, to, open = true) => ({
3
+ tr
4
+ }) => {
5
+ const {
6
+ expand,
7
+ nestedExpand
8
+ } = tr.doc.type.schema.nodes;
9
+ const fromClamped = from && from >= 0 ? from : 0;
10
+ const toClamped = to && to <= tr.doc.content.size ? to : tr.doc.content.size;
11
+ tr.doc.nodesBetween(fromClamped, toClamped, node => {
12
+ if ([expand, nestedExpand].includes(node.type)) {
13
+ expandedState.set(node, open);
14
+ }
15
+ });
16
+ return null;
17
+ };
@@ -7,6 +7,7 @@ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
7
7
  import { Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
8
8
  import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
9
9
  import { findTable } from '@atlaskit/editor-tables/utils';
10
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
10
11
  import { isNestedInExpand } from '../utils';
11
12
  import { createCommand } from './pm-plugins/plugin-factory';
12
13
  export const setExpandRef = ref => createCommand({
@@ -187,8 +188,8 @@ export const focusIcon = expand => (state, dispatch, editorView) => {
187
188
  return false;
188
189
  }
189
190
 
190
- // eslint-disable-next-line @atlaskit/editor/no-as-casting
191
- const iconContainer = expand.querySelector(`.${expandClassNames.iconContainer}`);
191
+ // TODO: ED-29205 - During platform_editor_native_expand_button cleanup, rename `iconContainer` to `iconButton`.
192
+ const iconContainer = expValEquals('platform_editor_native_expand_button', 'isEnabled', true) ? expand.querySelector(`.${expandClassNames.iconButton}`) : expand.querySelector(`.${expandClassNames.iconContainer}`);
192
193
  if (iconContainer && iconContainer.focus) {
193
194
  const {
194
195
  tr
@@ -1,5 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
3
4
  import uuid from 'uuid/v4';
4
5
  import { keyName } from 'w3c-keyname';
5
6
  import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
@@ -11,6 +12,7 @@ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
11
12
  import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { redo, undo } from '@atlaskit/prosemirror-history';
13
14
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
+ import { renderExpandButton } from '../../ui/renderExpandButton';
14
16
  import { deleteExpandAtPos, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
15
17
  import { ExpandIconButton } from '../ui/ExpandIconButton';
16
18
  function buildExpandClassName(type, expanded) {
@@ -450,8 +452,13 @@ export class ExpandNodeView {
450
452
  this.input = this.dom.querySelector(`.${expandClassNames.titleInput}`);
451
453
  this.titleContainer = this.dom.querySelector(`.${expandClassNames.titleContainer}`);
452
454
  this.content = this.dom.querySelector(`.${expandClassNames.content}`);
455
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
453
456
  this.renderKey = uuid();
454
- this.renderIcon(this.intl);
457
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
458
+ this.renderNativeIcon(this.node);
459
+ } else {
460
+ this.renderIcon(this.intl);
461
+ }
455
462
  this.initHandlers();
456
463
  }
457
464
  initHandlers() {
@@ -496,6 +503,19 @@ export class ExpandNodeView {
496
503
  });
497
504
  }
498
505
  }
506
+ renderNativeIcon(node) {
507
+ if (!this.icon) {
508
+ return;
509
+ }
510
+ const {
511
+ __expanded
512
+ } = node.attrs;
513
+ renderExpandButton(this.icon, {
514
+ expanded: this.__livePage ? !__expanded : __expanded,
515
+ allowInteractiveExpand: this.allowInteractiveExpand,
516
+ intl: this.intl
517
+ });
518
+ }
499
519
  renderIcon(intl, node) {
500
520
  if (!this.icon) {
501
521
  return;
@@ -533,7 +553,11 @@ export class ExpandNodeView {
533
553
  // we toggle a class name to hide the content and animate the chevron.
534
554
  if (this.dom) {
535
555
  this.dom.classList.toggle(expandClassNames.expanded);
536
- this.renderIcon(this && this.intl, node);
556
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
557
+ this.renderNativeIcon(node);
558
+ } else {
559
+ this.renderIcon(this && this.intl, node);
560
+ }
537
561
  }
538
562
  if (this.content) {
539
563
  // Disallow interaction/selection inside when collapsed.
@@ -7,6 +7,7 @@ import { IconExpand } from '@atlaskit/editor-common/quick-insert';
7
7
  import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
10
+ import { toggleExpandRange } from '../editor-commands/toggleExpandRange';
10
11
  import { createExpandBlockMenuItem } from '../ui/ExpandBlockMenuItem';
11
12
  import { createExpandNode, insertExpand, insertExpandWithInputMethod, toggleExpandWithMatch } from './commands';
12
13
  import { expandKeymap } from './pm-plugins/keymap';
@@ -49,7 +50,8 @@ export let expandPlugin = ({
49
50
  insertExpandWithInputMethod: insertExpandWithInputMethod(api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions)
50
51
  },
51
52
  commands: {
52
- toggleExpandWithMatch: selection => toggleExpandWithMatch(selection)
53
+ toggleExpandWithMatch: selection => toggleExpandWithMatch(selection),
54
+ toggleExpandRange
53
55
  },
54
56
  pmPlugins() {
55
57
  return [{
@@ -1,3 +1,4 @@
1
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
1
2
  import uuid from 'uuid/v4';
2
3
  import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
3
4
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
@@ -24,8 +25,11 @@ export const createExpandNode = (state, setExpandedState = true, addLocalId) =>
24
25
  const isSelectionInExpand = isNestedInExpand(state);
25
26
  const expandType = isSelectionInTable || isSelectionInExpand ? nestedExpand : expand;
26
27
  const expandNode = fg('platform_editor_adf_with_localid') ? expandType.createAndFill(addLocalId ? {
28
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
27
29
  localId: uuid()
28
- } : {}, paragraph.createAndFill(addLocalId ? {
30
+ } : {},
31
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
32
+ paragraph.createAndFill(addLocalId ? {
29
33
  localId: uuid()
30
34
  } : {})) : expandType.createAndFill({});
31
35
  if (setExpandedState) {
@@ -220,8 +224,8 @@ export const focusIcon = expand => (state, dispatch, editorView) => {
220
224
  return false;
221
225
  }
222
226
 
223
- // eslint-disable-next-line @atlaskit/editor/no-as-casting
224
- const iconContainer = expand.querySelector(`.${expandClassNames.iconContainer}`);
227
+ // TODO: ED-29205 - During platform_editor_native_expand_button cleanup, rename `iconContainer` to `iconButton`.
228
+ const iconContainer = expValEquals('platform_editor_native_expand_button', 'isEnabled', true) ? expand.querySelector(`.${expandClassNames.iconButton}`) : expand.querySelector(`.${expandClassNames.iconContainer}`);
225
229
  if (iconContainer && iconContainer.focus) {
226
230
  const {
227
231
  tr
@@ -1,5 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
3
4
  import uuid from 'uuid/v4';
4
5
  import { keyName } from 'w3c-keyname';
5
6
  import { expandedState, isExpandCollapsed } from '@atlaskit/editor-common/expand';
@@ -11,6 +12,7 @@ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
11
12
  import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { redo, undo } from '@atlaskit/prosemirror-history';
13
14
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
+ import { renderExpandButton } from '../../ui/renderExpandButton';
14
16
  import { deleteExpand, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
15
17
  import { ExpandButton } from '../ui/ExpandButton';
16
18
  import { buildExpandClassName, toDOM } from '../ui/NodeView';
@@ -414,12 +416,17 @@ export class ExpandNodeView {
414
416
  this.icon = this.dom.querySelector(`.${expandClassNames.icon}`);
415
417
  this.input = this.dom.querySelector(`.${expandClassNames.titleInput}`);
416
418
  this.titleContainer = this.dom.querySelector(`.${expandClassNames.titleContainer}`);
419
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
417
420
  this.renderKey = uuid();
418
421
  this.content = this.dom.querySelector(`.${expandClassNames.content}`);
419
422
  if (!expandedState.has(this.node)) {
420
423
  expandedState.set(this.node, false);
421
424
  }
422
- this.renderIcon(this.icon, !isExpandCollapsed(this.node));
425
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
426
+ this.renderNativeIcon(this.node);
427
+ } else {
428
+ this.renderIcon(this.icon, !isExpandCollapsed(this.node));
429
+ }
423
430
  if (!this.input || !this.titleContainer || !this.icon) {
424
431
  return;
425
432
  }
@@ -508,7 +515,6 @@ export class ExpandNodeView {
508
515
  updateExpandToggleIcon(node) {
509
516
  const expanded = expandedState.get(node) ? expandedState.get(node) : false;
510
517
  if (this.dom && expanded !== undefined) {
511
- var _expandedState$get;
512
518
  if (expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true)) {
513
519
  const classes = this.dom.className.split(' ');
514
520
  // find & replace styles might be applied to the expand title and we need to keep them
@@ -518,7 +524,12 @@ export class ExpandNodeView {
518
524
  this.dom.className = buildExpandClassName(node.type.name, expanded);
519
525
  }
520
526
  // Re-render the icon to update the aria-expanded attribute
521
- this.renderIcon(this.icon ? this.icon : null, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false);
527
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
528
+ this.renderNativeIcon(node);
529
+ } else {
530
+ var _expandedState$get;
531
+ this.renderIcon(this.icon ? this.icon : null, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false);
532
+ }
522
533
  }
523
534
  this.updateExpandBodyContentEditable();
524
535
  if (expValEquals('platform_editor_toggle_expand_on_match_found', 'isEnabled', true)) {
@@ -531,6 +542,16 @@ export class ExpandNodeView {
531
542
  this.content.setAttribute('contenteditable', this.getContentEditable(this.node) ? 'true' : 'false');
532
543
  }
533
544
  }
545
+ renderNativeIcon(node) {
546
+ if (!this.icon) {
547
+ return;
548
+ }
549
+ renderExpandButton(this.icon, {
550
+ expanded: !isExpandCollapsed(node),
551
+ allowInteractiveExpand: this.allowInteractiveExpand,
552
+ intl: this.intl
553
+ });
554
+ }
534
555
  destroy() {
535
556
  var _this$decorationClean2;
536
557
  if (!this.dom || !this.input || !this.titleContainer || !this.icon) {
@@ -7,6 +7,7 @@ import { IconExpand } from '@atlaskit/editor-common/quick-insert';
7
7
  import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
10
+ import { toggleExpandRange } from '../editor-commands/toggleExpandRange';
10
11
  import { createExpandBlockMenuItem } from '../ui/ExpandBlockMenuItem';
11
12
  import { createExpandNode, insertExpand, insertExpandWithInputMethod, toggleExpandWithMatch, wrapSelectionAndSetExpandedState } from './commands';
12
13
  import { expandKeymap } from './pm-plugins/keymap';
@@ -48,7 +49,8 @@ export let expandPlugin = ({
48
49
  insertExpandWithInputMethod: insertExpandWithInputMethod(api)
49
50
  },
50
51
  commands: {
51
- toggleExpandWithMatch: selection => toggleExpandWithMatch(selection)
52
+ toggleExpandWithMatch: selection => toggleExpandWithMatch(selection),
53
+ toggleExpandRange
52
54
  },
53
55
  pmPlugins() {
54
56
  return [{
@@ -0,0 +1,57 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
3
+ import { expandMessages } from '@atlaskit/editor-common/ui';
4
+ /**
5
+ * Renders or updates the expand/collapse button inside the provided container element.
6
+ *
7
+ * @param container - The HTML element that will contain the expand/collapse button.
8
+ * @param buttonProps - Properties for configuring the button's behavior and appearance.
9
+ */
10
+ export function renderExpandButton(container, buttonProps) {
11
+ const {
12
+ allowInteractiveExpand,
13
+ expanded,
14
+ intl
15
+ } = buttonProps;
16
+
17
+ // Update existing button attributes
18
+ const label = intl.formatMessage(expanded ? expandMessages.collapseNode : expandMessages.expandNode);
19
+ const existingButton = container.querySelector(`.${expandClassNames.iconButton}`);
20
+ if (existingButton) {
21
+ existingButton.setAttribute('aria-label', label);
22
+ existingButton.setAttribute('aria-expanded', String(expanded));
23
+ if (allowInteractiveExpand) {
24
+ existingButton.setAttribute('title', label);
25
+ existingButton.removeAttribute('disabled');
26
+ } else {
27
+ existingButton.removeAttribute('title');
28
+ existingButton.setAttribute('disabled', 'true');
29
+ }
30
+ } else {
31
+ const doc = getDocument();
32
+ if (!doc) {
33
+ return;
34
+ }
35
+ const button = doc.createElement('button');
36
+ button.className = expandClassNames.iconButton;
37
+ button.setAttribute('aria-label', label);
38
+ button.setAttribute('aria-expanded', String(expanded));
39
+ if (allowInteractiveExpand) {
40
+ button.setAttribute('title', label);
41
+ } else {
42
+ button.setAttribute('disabled', 'true');
43
+ }
44
+ container.appendChild(button);
45
+ const svgIcon = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
46
+ svgIcon.setAttribute('class', expandClassNames.iconSvg);
47
+ svgIcon.setAttribute('width', '12');
48
+ svgIcon.setAttribute('height', '12');
49
+ svgIcon.setAttribute('viewBox', '0 0 16 16');
50
+ svgIcon.setAttribute('role', 'presentation');
51
+ const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
52
+ path.setAttribute('fill', 'currentcolor');
53
+ path.setAttribute('d', 'm6.03 1.47 6 6a.75.75 0 0 1 .052 1.004l-.052.056-6 6-1.06-1.06L10.44 8 4.97 2.53z');
54
+ svgIcon.appendChild(path);
55
+ button.appendChild(svgIcon);
56
+ }
57
+ }
@@ -0,0 +1,18 @@
1
+ import { expandedState } from '@atlaskit/editor-common/expand';
2
+ export var toggleExpandRange = function toggleExpandRange(from, to) {
3
+ var open = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
4
+ return function (_ref) {
5
+ var tr = _ref.tr;
6
+ var _tr$doc$type$schema$n = tr.doc.type.schema.nodes,
7
+ expand = _tr$doc$type$schema$n.expand,
8
+ nestedExpand = _tr$doc$type$schema$n.nestedExpand;
9
+ var fromClamped = from && from >= 0 ? from : 0;
10
+ var toClamped = to && to <= tr.doc.content.size ? to : tr.doc.content.size;
11
+ tr.doc.nodesBetween(fromClamped, toClamped, function (node) {
12
+ if ([expand, nestedExpand].includes(node.type)) {
13
+ expandedState.set(node, open);
14
+ }
15
+ });
16
+ return null;
17
+ };
18
+ };
@@ -10,6 +10,7 @@ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
10
10
  import { Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
11
11
  import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
12
12
  import { findTable } from '@atlaskit/editor-tables/utils';
13
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
14
  import { isNestedInExpand } from '../utils';
14
15
  import { createCommand } from './pm-plugins/plugin-factory';
15
16
  export var setExpandRef = function setExpandRef(ref) {
@@ -200,8 +201,8 @@ export var focusIcon = function focusIcon(expand) {
200
201
  return false;
201
202
  }
202
203
 
203
- // eslint-disable-next-line @atlaskit/editor/no-as-casting
204
- var iconContainer = expand.querySelector(".".concat(expandClassNames.iconContainer));
204
+ // TODO: ED-29205 - During platform_editor_native_expand_button cleanup, rename `iconContainer` to `iconButton`.
205
+ var iconContainer = expValEquals('platform_editor_native_expand_button', 'isEnabled', true) ? expand.querySelector(".".concat(expandClassNames.iconButton)) : expand.querySelector(".".concat(expandClassNames.iconContainer));
205
206
  if (iconContainer && iconContainer.focus) {
206
207
  var tr = state.tr;
207
208
  var pos = state.selection.from;
@@ -4,6 +4,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  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
5
  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; }
6
6
  import React from 'react';
7
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
7
8
  import uuid from 'uuid/v4';
8
9
  import { keyName } from 'w3c-keyname';
9
10
  import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
@@ -15,6 +16,7 @@ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
15
16
  import { fg } from '@atlaskit/platform-feature-flags';
16
17
  import { redo, undo } from '@atlaskit/prosemirror-history';
17
18
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
19
+ import { renderExpandButton } from '../../ui/renderExpandButton';
18
20
  import { deleteExpandAtPos, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
19
21
  import { ExpandIconButton } from '../ui/ExpandIconButton';
20
22
  function buildExpandClassName(type, expanded) {
@@ -441,8 +443,13 @@ export var ExpandNodeView = /*#__PURE__*/function () {
441
443
  this.input = this.dom.querySelector(".".concat(expandClassNames.titleInput));
442
444
  this.titleContainer = this.dom.querySelector(".".concat(expandClassNames.titleContainer));
443
445
  this.content = this.dom.querySelector(".".concat(expandClassNames.content));
446
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
444
447
  this.renderKey = uuid();
445
- this.renderIcon(this.intl);
448
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
449
+ this.renderNativeIcon(this.node);
450
+ } else {
451
+ this.renderIcon(this.intl);
452
+ }
446
453
  this.initHandlers();
447
454
  }
448
455
  return _createClass(ExpandNodeView, [{
@@ -490,6 +497,19 @@ export var ExpandNodeView = /*#__PURE__*/function () {
490
497
  });
491
498
  }
492
499
  }
500
+ }, {
501
+ key: "renderNativeIcon",
502
+ value: function renderNativeIcon(node) {
503
+ if (!this.icon) {
504
+ return;
505
+ }
506
+ var __expanded = node.attrs.__expanded;
507
+ renderExpandButton(this.icon, {
508
+ expanded: this.__livePage ? !__expanded : __expanded,
509
+ allowInteractiveExpand: this.allowInteractiveExpand,
510
+ intl: this.intl
511
+ });
512
+ }
493
513
  }, {
494
514
  key: "renderIcon",
495
515
  value: function renderIcon(intl, node) {
@@ -538,7 +558,11 @@ export var ExpandNodeView = /*#__PURE__*/function () {
538
558
  // we toggle a class name to hide the content and animate the chevron.
539
559
  if (this.dom) {
540
560
  this.dom.classList.toggle(expandClassNames.expanded);
541
- this.renderIcon(this && this.intl, node);
561
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
562
+ this.renderNativeIcon(node);
563
+ } else {
564
+ this.renderIcon(this && this.intl, node);
565
+ }
542
566
  }
543
567
  if (this.content) {
544
568
  // Disallow interaction/selection inside when collapsed.
@@ -7,6 +7,7 @@ import { IconExpand } from '@atlaskit/editor-common/quick-insert';
7
7
  import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
10
+ import { toggleExpandRange } from '../editor-commands/toggleExpandRange';
10
11
  import { createExpandBlockMenuItem } from '../ui/ExpandBlockMenuItem';
11
12
  import { createExpandNode, insertExpand, insertExpandWithInputMethod, toggleExpandWithMatch as _toggleExpandWithMatch } from './commands';
12
13
  import { expandKeymap } from './pm-plugins/keymap';
@@ -51,7 +52,8 @@ export var expandPlugin = function expandPlugin(_ref) {
51
52
  commands: {
52
53
  toggleExpandWithMatch: function toggleExpandWithMatch(selection) {
53
54
  return _toggleExpandWithMatch(selection);
54
- }
55
+ },
56
+ toggleExpandRange: toggleExpandRange
55
57
  },
56
58
  pmPlugins: function pmPlugins() {
57
59
  return [{
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
5
  import uuid from 'uuid/v4';
5
6
  import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
6
7
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
@@ -28,8 +29,11 @@ export var createExpandNode = function createExpandNode(state) {
28
29
  var isSelectionInExpand = isNestedInExpand(state);
29
30
  var expandType = isSelectionInTable || isSelectionInExpand ? nestedExpand : expand;
30
31
  var expandNode = fg('platform_editor_adf_with_localid') ? expandType.createAndFill(addLocalId ? {
32
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
31
33
  localId: uuid()
32
- } : {}, paragraph.createAndFill(addLocalId ? {
34
+ } : {},
35
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
36
+ paragraph.createAndFill(addLocalId ? {
33
37
  localId: uuid()
34
38
  } : {})) : expandType.createAndFill({});
35
39
  if (setExpandedState) {
@@ -235,8 +239,8 @@ export var focusIcon = function focusIcon(expand) {
235
239
  return false;
236
240
  }
237
241
 
238
- // eslint-disable-next-line @atlaskit/editor/no-as-casting
239
- var iconContainer = expand.querySelector(".".concat(expandClassNames.iconContainer));
242
+ // TODO: ED-29205 - During platform_editor_native_expand_button cleanup, rename `iconContainer` to `iconButton`.
243
+ var iconContainer = expValEquals('platform_editor_native_expand_button', 'isEnabled', true) ? expand.querySelector(".".concat(expandClassNames.iconButton)) : expand.querySelector(".".concat(expandClassNames.iconContainer));
240
244
  if (iconContainer && iconContainer.focus) {
241
245
  var tr = state.tr;
242
246
  var pos = state.selection.from;
@@ -2,6 +2,7 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  import React from 'react';
5
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
5
6
  import uuid from 'uuid/v4';
6
7
  import { keyName } from 'w3c-keyname';
7
8
  import { expandedState, isExpandCollapsed } from '@atlaskit/editor-common/expand';
@@ -13,6 +14,7 @@ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
13
14
  import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import { redo, undo } from '@atlaskit/prosemirror-history';
15
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
17
+ import { renderExpandButton } from '../../ui/renderExpandButton';
16
18
  import { deleteExpand, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
17
19
  import { ExpandButton } from '../ui/ExpandButton';
18
20
  import { buildExpandClassName, toDOM } from '../ui/NodeView';
@@ -407,12 +409,17 @@ export var ExpandNodeView = /*#__PURE__*/function () {
407
409
  this.icon = this.dom.querySelector(".".concat(expandClassNames.icon));
408
410
  this.input = this.dom.querySelector(".".concat(expandClassNames.titleInput));
409
411
  this.titleContainer = this.dom.querySelector(".".concat(expandClassNames.titleContainer));
412
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
410
413
  this.renderKey = uuid();
411
414
  this.content = this.dom.querySelector(".".concat(expandClassNames.content));
412
415
  if (!expandedState.has(this.node)) {
413
416
  expandedState.set(this.node, false);
414
417
  }
415
- this.renderIcon(this.icon, !isExpandCollapsed(this.node));
418
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
419
+ this.renderNativeIcon(this.node);
420
+ } else {
421
+ this.renderIcon(this.icon, !isExpandCollapsed(this.node));
422
+ }
416
423
  if (!this.input || !this.titleContainer || !this.icon) {
417
424
  return;
418
425
  }
@@ -510,7 +517,6 @@ export var ExpandNodeView = /*#__PURE__*/function () {
510
517
  value: function updateExpandToggleIcon(node) {
511
518
  var expanded = expandedState.get(node) ? expandedState.get(node) : false;
512
519
  if (this.dom && expanded !== undefined) {
513
- var _expandedState$get;
514
520
  if (expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true)) {
515
521
  var classes = this.dom.className.split(' ');
516
522
  // find & replace styles might be applied to the expand title and we need to keep them
@@ -522,7 +528,12 @@ export var ExpandNodeView = /*#__PURE__*/function () {
522
528
  this.dom.className = buildExpandClassName(node.type.name, expanded);
523
529
  }
524
530
  // Re-render the icon to update the aria-expanded attribute
525
- this.renderIcon(this.icon ? this.icon : null, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false);
531
+ if (expValEquals('platform_editor_native_expand_button', 'isEnabled', true)) {
532
+ this.renderNativeIcon(node);
533
+ } else {
534
+ var _expandedState$get;
535
+ this.renderIcon(this.icon ? this.icon : null, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false);
536
+ }
526
537
  }
527
538
  this.updateExpandBodyContentEditable();
528
539
  if (expValEquals('platform_editor_toggle_expand_on_match_found', 'isEnabled', true)) {
@@ -537,6 +548,18 @@ export var ExpandNodeView = /*#__PURE__*/function () {
537
548
  this.content.setAttribute('contenteditable', this.getContentEditable(this.node) ? 'true' : 'false');
538
549
  }
539
550
  }
551
+ }, {
552
+ key: "renderNativeIcon",
553
+ value: function renderNativeIcon(node) {
554
+ if (!this.icon) {
555
+ return;
556
+ }
557
+ renderExpandButton(this.icon, {
558
+ expanded: !isExpandCollapsed(node),
559
+ allowInteractiveExpand: this.allowInteractiveExpand,
560
+ intl: this.intl
561
+ });
562
+ }
540
563
  }, {
541
564
  key: "destroy",
542
565
  value: function destroy() {
@@ -7,6 +7,7 @@ import { IconExpand } from '@atlaskit/editor-common/quick-insert';
7
7
  import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
10
+ import { toggleExpandRange } from '../editor-commands/toggleExpandRange';
10
11
  import { createExpandBlockMenuItem } from '../ui/ExpandBlockMenuItem';
11
12
  import { createExpandNode, insertExpand, insertExpandWithInputMethod, toggleExpandWithMatch as _toggleExpandWithMatch, wrapSelectionAndSetExpandedState } from './commands';
12
13
  import { expandKeymap } from './pm-plugins/keymap';
@@ -50,7 +51,8 @@ export var expandPlugin = function expandPlugin(_ref) {
50
51
  commands: {
51
52
  toggleExpandWithMatch: function toggleExpandWithMatch(selection) {
52
53
  return _toggleExpandWithMatch(selection);
53
- }
54
+ },
55
+ toggleExpandRange: toggleExpandRange
54
56
  },
55
57
  pmPlugins: function pmPlugins() {
56
58
  return [{
@@ -0,0 +1,55 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
3
+ import { expandMessages } from '@atlaskit/editor-common/ui';
4
+ /**
5
+ * Renders or updates the expand/collapse button inside the provided container element.
6
+ *
7
+ * @param container - The HTML element that will contain the expand/collapse button.
8
+ * @param buttonProps - Properties for configuring the button's behavior and appearance.
9
+ */
10
+ export function renderExpandButton(container, buttonProps) {
11
+ var allowInteractiveExpand = buttonProps.allowInteractiveExpand,
12
+ expanded = buttonProps.expanded,
13
+ intl = buttonProps.intl;
14
+
15
+ // Update existing button attributes
16
+ var label = intl.formatMessage(expanded ? expandMessages.collapseNode : expandMessages.expandNode);
17
+ var existingButton = container.querySelector(".".concat(expandClassNames.iconButton));
18
+ if (existingButton) {
19
+ existingButton.setAttribute('aria-label', label);
20
+ existingButton.setAttribute('aria-expanded', String(expanded));
21
+ if (allowInteractiveExpand) {
22
+ existingButton.setAttribute('title', label);
23
+ existingButton.removeAttribute('disabled');
24
+ } else {
25
+ existingButton.removeAttribute('title');
26
+ existingButton.setAttribute('disabled', 'true');
27
+ }
28
+ } else {
29
+ var doc = getDocument();
30
+ if (!doc) {
31
+ return;
32
+ }
33
+ var button = doc.createElement('button');
34
+ button.className = expandClassNames.iconButton;
35
+ button.setAttribute('aria-label', label);
36
+ button.setAttribute('aria-expanded', String(expanded));
37
+ if (allowInteractiveExpand) {
38
+ button.setAttribute('title', label);
39
+ } else {
40
+ button.setAttribute('disabled', 'true');
41
+ }
42
+ container.appendChild(button);
43
+ var svgIcon = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
44
+ svgIcon.setAttribute('class', expandClassNames.iconSvg);
45
+ svgIcon.setAttribute('width', '12');
46
+ svgIcon.setAttribute('height', '12');
47
+ svgIcon.setAttribute('viewBox', '0 0 16 16');
48
+ svgIcon.setAttribute('role', 'presentation');
49
+ var path = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
50
+ path.setAttribute('fill', 'currentcolor');
51
+ path.setAttribute('d', 'm6.03 1.47 6 6a.75.75 0 0 1 .052 1.004l-.052.056-6 6-1.06-1.06L10.44 8 4.97 2.53z');
52
+ svgIcon.appendChild(path);
53
+ button.appendChild(svgIcon);
54
+ }
55
+ }
@@ -0,0 +1,2 @@
1
+ import type { EditorCommand } from '@atlaskit/editor-common/types';
2
+ export declare const toggleExpandRange: (from?: number, to?: number, open?: boolean) => EditorCommand;
@@ -29,6 +29,7 @@ export declare class ExpandNodeView implements NodeView {
29
29
  private initHandlers;
30
30
  private focusTitle;
31
31
  private handleIconKeyDown;
32
+ private renderNativeIcon;
32
33
  private renderIcon;
33
34
  private handleClick;
34
35
  private handleInput;
@@ -54,6 +54,7 @@ export declare class ExpandNodeView implements NodeView {
54
54
  update(node: PmNode, _decorations: readonly Decoration[]): boolean;
55
55
  updateExpandToggleIcon(node: PmNode): void;
56
56
  updateExpandBodyContentEditable(): void;
57
+ private renderNativeIcon;
57
58
  renderIcon: (icon: HTMLElement | null, expanded: boolean) => void;
58
59
  destroy(): void;
59
60
  }
@@ -68,6 +68,34 @@ export type ExpandPlugin = NextEditorPlugin<'expand', {
68
68
  * Toggle the expand or nested expand node open
69
69
  */
70
70
  toggleExpandWithMatch: (selection: Selection) => EditorCommand;
71
+ /**
72
+ * Expand or collapse a range of expand nodes. With no parameters
73
+ *
74
+ *
75
+ * @param from Starting range (defaults to 0)
76
+ * @param to Ending range (defaults to the document size)
77
+ * @param open Boolean to open (defaults to opening expands)
78
+ * @returns EditorCommand to be executed
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * // Opens all the expands on the page
83
+ * editorAPI.core.actions.execute(
84
+ * editorAPI.expand.commands.toggleExpandRange()
85
+ * )
86
+ *
87
+ * // Closes all the expands between positions 0 and 34 on the page
88
+ * editorAPI.core.actions.execute(
89
+ * editorAPI.expand.commands.toggleExpandRange(0, 34, false)
90
+ * )
91
+ *
92
+ * // Closes all the expands on the page
93
+ * editorAPI.core.actions.execute(
94
+ * editorAPI.expand.commands.toggleExpandRange(undefined, undefined, false)
95
+ * )
96
+ * ```
97
+ */
98
+ toggleExpandRange: (from?: number, to?: number, open?: boolean) => EditorCommand;
71
99
  };
72
100
  dependencies: ExpandPluginDependencies;
73
101
  pluginConfiguration: ExpandPluginOptions | undefined;
@@ -0,0 +1,17 @@
1
+ import type { IntlShape } from 'react-intl-next';
2
+ interface ButtonProps {
3
+ /** Indicates whether interactive expand is allowed */
4
+ allowInteractiveExpand: boolean;
5
+ /** Indicates whether the expand is currently expanded */
6
+ expanded: boolean;
7
+ /** Internationalization object for formatting messages */
8
+ intl: IntlShape;
9
+ }
10
+ /**
11
+ * Renders or updates the expand/collapse button inside the provided container element.
12
+ *
13
+ * @param container - The HTML element that will contain the expand/collapse button.
14
+ * @param buttonProps - Properties for configuring the button's behavior and appearance.
15
+ */
16
+ export declare function renderExpandButton(container: HTMLElement, buttonProps: ButtonProps): void;
17
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { EditorCommand } from '@atlaskit/editor-common/types';
2
+ export declare const toggleExpandRange: (from?: number, to?: number, open?: boolean) => EditorCommand;
@@ -29,6 +29,7 @@ export declare class ExpandNodeView implements NodeView {
29
29
  private initHandlers;
30
30
  private focusTitle;
31
31
  private handleIconKeyDown;
32
+ private renderNativeIcon;
32
33
  private renderIcon;
33
34
  private handleClick;
34
35
  private handleInput;
@@ -54,6 +54,7 @@ export declare class ExpandNodeView implements NodeView {
54
54
  update(node: PmNode, _decorations: readonly Decoration[]): boolean;
55
55
  updateExpandToggleIcon(node: PmNode): void;
56
56
  updateExpandBodyContentEditable(): void;
57
+ private renderNativeIcon;
57
58
  renderIcon: (icon: HTMLElement | null, expanded: boolean) => void;
58
59
  destroy(): void;
59
60
  }
@@ -68,6 +68,34 @@ export type ExpandPlugin = NextEditorPlugin<'expand', {
68
68
  * Toggle the expand or nested expand node open
69
69
  */
70
70
  toggleExpandWithMatch: (selection: Selection) => EditorCommand;
71
+ /**
72
+ * Expand or collapse a range of expand nodes. With no parameters
73
+ *
74
+ *
75
+ * @param from Starting range (defaults to 0)
76
+ * @param to Ending range (defaults to the document size)
77
+ * @param open Boolean to open (defaults to opening expands)
78
+ * @returns EditorCommand to be executed
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * // Opens all the expands on the page
83
+ * editorAPI.core.actions.execute(
84
+ * editorAPI.expand.commands.toggleExpandRange()
85
+ * )
86
+ *
87
+ * // Closes all the expands between positions 0 and 34 on the page
88
+ * editorAPI.core.actions.execute(
89
+ * editorAPI.expand.commands.toggleExpandRange(0, 34, false)
90
+ * )
91
+ *
92
+ * // Closes all the expands on the page
93
+ * editorAPI.core.actions.execute(
94
+ * editorAPI.expand.commands.toggleExpandRange(undefined, undefined, false)
95
+ * )
96
+ * ```
97
+ */
98
+ toggleExpandRange: (from?: number, to?: number, open?: boolean) => EditorCommand;
71
99
  };
72
100
  dependencies: ExpandPluginDependencies;
73
101
  pluginConfiguration: ExpandPluginOptions | undefined;
@@ -0,0 +1,17 @@
1
+ import type { IntlShape } from 'react-intl-next';
2
+ interface ButtonProps {
3
+ /** Indicates whether interactive expand is allowed */
4
+ allowInteractiveExpand: boolean;
5
+ /** Indicates whether the expand is currently expanded */
6
+ expanded: boolean;
7
+ /** Internationalization object for formatting messages */
8
+ intl: IntlShape;
9
+ }
10
+ /**
11
+ * Renders or updates the expand/collapse button inside the provided container element.
12
+ *
13
+ * @param container - The HTML element that will contain the expand/collapse button.
14
+ * @param buttonProps - Properties for configuring the button's behavior and appearance.
15
+ */
16
+ export declare function renderExpandButton(container: HTMLElement, buttonProps: ButtonProps): void;
17
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-expand",
3
- "version": "7.2.5",
3
+ "version": "7.4.0",
4
4
  "description": "Expand plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -30,6 +30,7 @@
30
30
  "atlaskit:src": "src/index.ts",
31
31
  "dependencies": {
32
32
  "@atlaskit/adf-schema": "^51.3.2",
33
+ "@atlaskit/browser-apis": "^0.0.1",
33
34
  "@atlaskit/button": "^23.5.0",
34
35
  "@atlaskit/editor-plugin-analytics": "^6.2.0",
35
36
  "@atlaskit/editor-plugin-block-menu": "^5.0.0",
@@ -46,8 +47,9 @@
46
47
  "@atlaskit/icon": "^28.5.0",
47
48
  "@atlaskit/icon-lab": "^5.11.0",
48
49
  "@atlaskit/platform-feature-flags": "^1.1.0",
49
- "@atlaskit/tmp-editor-statsig": "^13.22.0",
50
- "@atlaskit/tokens": "^7.0.0",
50
+ "@atlaskit/prosemirror-history": "^0.2.0",
51
+ "@atlaskit/tmp-editor-statsig": "^13.31.0",
52
+ "@atlaskit/tokens": "^7.1.0",
51
53
  "@atlaskit/tooltip": "^20.7.0",
52
54
  "@babel/runtime": "^7.0.0",
53
55
  "@emotion/react": "^11.7.1",
@@ -55,7 +57,7 @@
55
57
  "w3c-keyname": "^2.1.8"
56
58
  },
57
59
  "peerDependencies": {
58
- "@atlaskit/editor-common": "^110.19.0",
60
+ "@atlaskit/editor-common": "^110.24.0",
59
61
  "react": "^18.2.0",
60
62
  "react-dom": "^18.2.0",
61
63
  "react-intl-next": "npm:react-intl@^5.18.1"
@@ -68,7 +70,6 @@
68
70
  "@atlaskit/editor-plugin-table": "^15.3.0",
69
71
  "@atlaskit/editor-plugin-type-ahead": "^6.5.0",
70
72
  "@atlaskit/editor-plugin-width": "^7.0.0",
71
- "@atlaskit/prosemirror-history": "^0.2.0",
72
73
  "@testing-library/react": "^13.4.0",
73
74
  "react-test-renderer": "^18.2.0"
74
75
  },