@atlaskit/editor-plugin-native-embeds 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @atlaskit/editor-plugin-native-embeds
2
+
3
+ ## 0.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
@@ -5,28 +5,88 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.getToolbarConfig = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
8
9
  var _utils = require("@atlaskit/editor-prosemirror/utils");
9
10
  var _alignTextCenter = _interopRequireDefault(require("@atlaskit/icon/core/align-text-center"));
11
+ var _alignTextLeft = _interopRequireDefault(require("@atlaskit/icon/core/align-text-left"));
12
+ var _alignTextRight = _interopRequireDefault(require("@atlaskit/icon/core/align-text-right"));
10
13
  var _border = _interopRequireDefault(require("@atlaskit/icon/core/border"));
14
+ var _contentWrapLeft = _interopRequireDefault(require("@atlaskit/icon/core/content-wrap-left"));
15
+ var _contentWrapRight = _interopRequireDefault(require("@atlaskit/icon/core/content-wrap-right"));
11
16
  var _linkExternal = _interopRequireDefault(require("@atlaskit/icon/core/link-external"));
12
17
  var _page = _interopRequireDefault(require("@atlaskit/icon/core/page"));
13
18
  var _refresh = _interopRequireDefault(require("@atlaskit/icon/core/refresh"));
14
- var _showMoreHorizontal = _interopRequireDefault(require("@atlaskit/icon/core/show-more-horizontal"));
19
+ var _alignment = require("../../types/alignment");
15
20
  var _getSelectedNativeEmbedExtension = require("../utils/getSelectedNativeEmbedExtension");
21
+ var _moreOptionsDropdown = require("./more-options-dropdown");
22
+ // TODO: CNS-23819 - Add i18n and finalise whether these should show as just icons with tooltips or text labels.
23
+ var ALIGNMENT_LABELS = {
24
+ left: 'Align left',
25
+ center: 'Align center',
26
+ right: 'Align right',
27
+ 'wrap-left': 'Wrap left',
28
+ 'wrap-right': 'Wrap right'
29
+ };
30
+ var ALIGNMENT_ICONS = {
31
+ left: _alignTextLeft.default,
32
+ center: _alignTextCenter.default,
33
+ right: _alignTextRight.default,
34
+ 'wrap-left': _contentWrapLeft.default,
35
+ 'wrap-right': _contentWrapRight.default
36
+ };
37
+ var getAlignmentIcon = function getAlignmentIcon(alignment) {
38
+ var IconComponent = ALIGNMENT_ICONS[alignment];
39
+ return /*#__PURE__*/_react.default.createElement(IconComponent, {
40
+ color: "currentColor",
41
+ spacing: "spacious",
42
+ label: ALIGNMENT_LABELS[alignment]
43
+ });
44
+ };
16
45
  var createHandlerCommand = function createHandlerCommand(handler) {
17
46
  return function () {
18
47
  handler === null || handler === void 0 || handler();
19
48
  return true;
20
49
  };
21
50
  };
51
+ var createUpdateAlignmentCommand = function createUpdateAlignmentCommand(api, alignment) {
52
+ return function (state, _dispatch, _view) {
53
+ var _api$extension, _extensionApi$doc;
54
+ var selectedNativeEmbed = (0, _getSelectedNativeEmbedExtension.getSelectedNativeEmbedExtension)(state);
55
+ var localId = selectedNativeEmbed === null || selectedNativeEmbed === void 0 ? void 0 : selectedNativeEmbed.node.attrs.localId;
56
+ if (!localId) {
57
+ return false;
58
+ }
59
+ var extensionApi = api === null || api === void 0 || (_api$extension = api.extension) === null || _api$extension === void 0 || (_api$extension = _api$extension.actions) === null || _api$extension === void 0 ? void 0 : _api$extension.api();
60
+ if (!(extensionApi !== null && extensionApi !== void 0 && (_extensionApi$doc = extensionApi.doc) !== null && _extensionApi$doc !== void 0 && _extensionApi$doc.update)) {
61
+ return false;
62
+ }
63
+ extensionApi.doc.update(localId, function (current) {
64
+ return (0, _alignment.createAlignmentUpdate)(current, alignment);
65
+ });
66
+ return true;
67
+ };
68
+ };
22
69
  var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref) {
23
- var _api = _ref.api,
70
+ var api = _ref.api,
24
71
  handlers = _ref.handlers;
25
72
  return function (state, _intl, _providerFactory, _activeConfigs) {
73
+ var _ref2, _selectedNativeEmbed$;
26
74
  var selectedNativeEmbed = (0, _getSelectedNativeEmbedExtension.getSelectedNativeEmbedExtension)(state);
27
75
  if (!selectedNativeEmbed) {
28
76
  return undefined;
29
77
  }
78
+ var currentAlignment = (_ref2 = (_selectedNativeEmbed$ = selectedNativeEmbed.node.attrs.parameters) === null || _selectedNativeEmbed$ === void 0 ? void 0 : _selectedNativeEmbed$.alignment) !== null && _ref2 !== void 0 ? _ref2 : _alignment.DEFAULT_ALIGNMENT;
79
+ var alignmentOptions = _alignment.ALIGNMENT_VALUES.map(function (alignment) {
80
+ return {
81
+ id: "native-embed-alignment-".concat(alignment),
82
+ title: ALIGNMENT_LABELS[alignment],
83
+ onClick: createUpdateAlignmentCommand(api, alignment),
84
+ selected: currentAlignment === alignment,
85
+ icon: getAlignmentIcon(alignment)
86
+ };
87
+ });
88
+ var alignmentDropdownTitle = ALIGNMENT_LABELS[currentAlignment];
89
+ var AlignmentIconComponent = ALIGNMENT_ICONS[currentAlignment];
30
90
  var getDomRef = function getDomRef(view) {
31
91
  try {
32
92
  var node = (0, _utils.findDomRefAtPos)(selectedNativeEmbed.pos, view.domAtPos.bind(view));
@@ -49,7 +109,8 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
49
109
  focusEditoronEnter: true,
50
110
  tabIndex: null
51
111
  }, {
52
- type: 'separator'
112
+ type: 'separator',
113
+ fullHeight: true
53
114
  }, {
54
115
  id: 'native-embed-embed-dropdown',
55
116
  type: 'dropdown',
@@ -68,11 +129,18 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
68
129
  id: 'native-embed-alignment-dropdown',
69
130
  type: 'dropdown',
70
131
  title: '',
71
- iconBefore: _alignTextCenter.default,
72
- options: [],
73
- onClick: handlers === null || handlers === void 0 ? void 0 : handlers.onAlignmentClick
132
+ iconBefore: function iconBefore() {
133
+ return /*#__PURE__*/_react.default.createElement(AlignmentIconComponent, {
134
+ color: "currentColor",
135
+ spacing: "spacious",
136
+ label: alignmentDropdownTitle
137
+ });
138
+ },
139
+ options: alignmentOptions,
140
+ showSelected: true
74
141
  }, {
75
- type: 'separator'
142
+ type: 'separator',
143
+ fullHeight: true
76
144
  }, {
77
145
  id: 'native-embed-open-new-window-button',
78
146
  type: 'button',
@@ -83,16 +151,9 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
83
151
  focusEditoronEnter: true,
84
152
  tabIndex: null
85
153
  }, {
86
- type: 'separator'
87
- }, {
88
- id: 'native-embed-more-options-button',
89
- type: 'dropdown',
90
- title: 'More options',
91
- icon: _showMoreHorizontal.default,
92
- hideExpandIcon: true,
93
- options: [],
94
- onClick: handlers === null || handlers === void 0 ? void 0 : handlers.onMoreOptionsClick
95
- }]
154
+ type: 'separator',
155
+ fullHeight: true
156
+ }, (0, _moreOptionsDropdown.getMoreOptionsDropdown)()]
96
157
  };
97
158
  };
98
159
  };
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getMoreOptionsDropdown = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _database = _interopRequireDefault(require("@atlaskit/icon/core/database"));
10
+ var _delete = _interopRequireDefault(require("@atlaskit/icon/core/delete"));
11
+ var _eyeOpen = _interopRequireDefault(require("@atlaskit/icon/core/eye-open"));
12
+ var _link = _interopRequireDefault(require("@atlaskit/icon/core/link"));
13
+ var _toggle = _interopRequireDefault(require("@atlaskit/toggle"));
14
+ /**
15
+ * No-op command that returns true without dispatching any action.
16
+ * Used as a placeholder for menu items that don't have functionality yet.
17
+ */
18
+ var noopCommand = function noopCommand() {
19
+ return true;
20
+ };
21
+
22
+ /**
23
+ * Returns the "More options" overflow dropdown configuration for the native embed floating toolbar.
24
+ */
25
+ var getMoreOptionsDropdown = exports.getMoreOptionsDropdown = function getMoreOptionsDropdown() {
26
+ return {
27
+ id: 'native-embed-more-options-button',
28
+ type: 'overflow-dropdown',
29
+ dropdownWidth: 250,
30
+ options: [{
31
+ id: 'native-embed-always-show-title',
32
+ title: 'Always show title',
33
+ icon: /*#__PURE__*/_react.default.createElement(_eyeOpen.default, {
34
+ color: "currentColor",
35
+ spacing: "spacious",
36
+ label: ""
37
+ }),
38
+ elemAfter: /*#__PURE__*/_react.default.createElement(_toggle.default, {
39
+ isChecked: true,
40
+ label: "Always show title"
41
+ }),
42
+ onClick: noopCommand
43
+ }, {
44
+ id: 'native-embed-set-embed-type',
45
+ title: 'Set embed type',
46
+ icon: /*#__PURE__*/_react.default.createElement(_database.default, {
47
+ color: "currentColor",
48
+ spacing: "spacious",
49
+ label: ""
50
+ }),
51
+ onClick: noopCommand
52
+ }, {
53
+ type: 'separator'
54
+ }, {
55
+ id: 'native-embed-copy-link',
56
+ title: 'Copy link',
57
+ icon: /*#__PURE__*/_react.default.createElement(_link.default, {
58
+ color: "currentColor",
59
+ spacing: "spacious",
60
+ label: ""
61
+ }),
62
+ onClick: noopCommand
63
+ }, {
64
+ id: 'native-embed-delete',
65
+ title: 'Delete',
66
+ icon: /*#__PURE__*/_react.default.createElement(_delete.default, {
67
+ color: "currentColor",
68
+ spacing: "spacious",
69
+ label: ""
70
+ }),
71
+ onClick: noopCommand
72
+ }]
73
+ };
74
+ };
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.DEFAULT_ALIGNMENT = exports.ALIGNMENT_VALUES = void 0;
8
+ exports.createAlignmentUpdate = createAlignmentUpdate;
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
+ 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; }
12
+ 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; }
13
+ /**
14
+ * All alignment values (for dropdowns / iteration). Single source of truth for alignment options.
15
+ */
16
+ var ALIGNMENT_VALUES = exports.ALIGNMENT_VALUES = ['left', 'center', 'right', 'wrap-left', 'wrap-right'];
17
+
18
+ /**
19
+ * Alignment value for native embed extension parameters.
20
+ * Used by the editor floating toolbar when the user changes alignment;
21
+ * the editor calls extensionApi.doc.update(localId, (current) => createAlignmentUpdate(current, alignment)).
22
+ */
23
+
24
+ /** Default alignment when not set in parameters. */
25
+ var DEFAULT_ALIGNMENT = exports.DEFAULT_ALIGNMENT = 'center';
26
+
27
+ /**
28
+ * Builds the attrs update for setting alignment on a native embed extension node.
29
+ */
30
+ function createAlignmentUpdate(current, alignment) {
31
+ var _current$attrs;
32
+ var existingParams = current.attrs && 'parameters' in current.attrs && (0, _typeof2.default)(current.attrs.parameters) === 'object' ? current.attrs.parameters : {};
33
+ return {
34
+ attrs: _objectSpread(_objectSpread({}, (_current$attrs = current.attrs) !== null && _current$attrs !== void 0 ? _current$attrs : {}), {}, {
35
+ parameters: _objectSpread(_objectSpread({}, existingParams), {}, {
36
+ alignment: alignment
37
+ })
38
+ })
39
+ };
40
+ }
@@ -1,23 +1,78 @@
1
+ import React from 'react';
1
2
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
2
3
  import AlignTextCenterIcon from '@atlaskit/icon/core/align-text-center';
4
+ import AlignTextLeftIcon from '@atlaskit/icon/core/align-text-left';
5
+ import AlignTextRightIcon from '@atlaskit/icon/core/align-text-right';
3
6
  import BorderIcon from '@atlaskit/icon/core/border';
7
+ import ContentWrapLeftIcon from '@atlaskit/icon/core/content-wrap-left';
8
+ import ContentWrapRightIcon from '@atlaskit/icon/core/content-wrap-right';
4
9
  import LinkExternalIcon from '@atlaskit/icon/core/link-external';
5
10
  import PageIcon from '@atlaskit/icon/core/page';
6
11
  import RefreshIcon from '@atlaskit/icon/core/refresh';
7
- import ShowMoreHorizontalIcon from '@atlaskit/icon/core/show-more-horizontal';
12
+ import { ALIGNMENT_VALUES, createAlignmentUpdate, DEFAULT_ALIGNMENT } from '../../types/alignment';
8
13
  import { getSelectedNativeEmbedExtension } from '../utils/getSelectedNativeEmbedExtension';
14
+ import { getMoreOptionsDropdown } from './more-options-dropdown';
15
+
16
+ // TODO: CNS-23819 - Add i18n and finalise whether these should show as just icons with tooltips or text labels.
17
+ const ALIGNMENT_LABELS = {
18
+ left: 'Align left',
19
+ center: 'Align center',
20
+ right: 'Align right',
21
+ 'wrap-left': 'Wrap left',
22
+ 'wrap-right': 'Wrap right'
23
+ };
24
+ const ALIGNMENT_ICONS = {
25
+ left: AlignTextLeftIcon,
26
+ center: AlignTextCenterIcon,
27
+ right: AlignTextRightIcon,
28
+ 'wrap-left': ContentWrapLeftIcon,
29
+ 'wrap-right': ContentWrapRightIcon
30
+ };
31
+ const getAlignmentIcon = alignment => {
32
+ const IconComponent = ALIGNMENT_ICONS[alignment];
33
+ return /*#__PURE__*/React.createElement(IconComponent, {
34
+ color: "currentColor",
35
+ spacing: "spacious",
36
+ label: ALIGNMENT_LABELS[alignment]
37
+ });
38
+ };
9
39
  const createHandlerCommand = handler => () => {
10
40
  handler === null || handler === void 0 ? void 0 : handler();
11
41
  return true;
12
42
  };
43
+ const createUpdateAlignmentCommand = (api, alignment) => (state, _dispatch, _view) => {
44
+ var _api$extension, _api$extension$action, _extensionApi$doc;
45
+ const selectedNativeEmbed = getSelectedNativeEmbedExtension(state);
46
+ const localId = selectedNativeEmbed === null || selectedNativeEmbed === void 0 ? void 0 : selectedNativeEmbed.node.attrs.localId;
47
+ if (!localId) {
48
+ return false;
49
+ }
50
+ const extensionApi = api === null || api === void 0 ? void 0 : (_api$extension = api.extension) === null || _api$extension === void 0 ? void 0 : (_api$extension$action = _api$extension.actions) === null || _api$extension$action === void 0 ? void 0 : _api$extension$action.api();
51
+ if (!(extensionApi !== null && extensionApi !== void 0 && (_extensionApi$doc = extensionApi.doc) !== null && _extensionApi$doc !== void 0 && _extensionApi$doc.update)) {
52
+ return false;
53
+ }
54
+ extensionApi.doc.update(localId, current => createAlignmentUpdate(current, alignment));
55
+ return true;
56
+ };
13
57
  export const getToolbarConfig = ({
14
- api: _api,
58
+ api,
15
59
  handlers
16
60
  }) => (state, _intl, _providerFactory, _activeConfigs) => {
61
+ var _ref, _selectedNativeEmbed$;
17
62
  const selectedNativeEmbed = getSelectedNativeEmbedExtension(state);
18
63
  if (!selectedNativeEmbed) {
19
64
  return undefined;
20
65
  }
66
+ const currentAlignment = (_ref = (_selectedNativeEmbed$ = selectedNativeEmbed.node.attrs.parameters) === null || _selectedNativeEmbed$ === void 0 ? void 0 : _selectedNativeEmbed$.alignment) !== null && _ref !== void 0 ? _ref : DEFAULT_ALIGNMENT;
67
+ const alignmentOptions = ALIGNMENT_VALUES.map(alignment => ({
68
+ id: `native-embed-alignment-${alignment}`,
69
+ title: ALIGNMENT_LABELS[alignment],
70
+ onClick: createUpdateAlignmentCommand(api, alignment),
71
+ selected: currentAlignment === alignment,
72
+ icon: getAlignmentIcon(alignment)
73
+ }));
74
+ const alignmentDropdownTitle = ALIGNMENT_LABELS[currentAlignment];
75
+ const AlignmentIconComponent = ALIGNMENT_ICONS[currentAlignment];
21
76
  const getDomRef = view => {
22
77
  try {
23
78
  const node = findDomRefAtPos(selectedNativeEmbed.pos, view.domAtPos.bind(view));
@@ -40,7 +95,8 @@ export const getToolbarConfig = ({
40
95
  focusEditoronEnter: true,
41
96
  tabIndex: null
42
97
  }, {
43
- type: 'separator'
98
+ type: 'separator',
99
+ fullHeight: true
44
100
  }, {
45
101
  id: 'native-embed-embed-dropdown',
46
102
  type: 'dropdown',
@@ -59,11 +115,16 @@ export const getToolbarConfig = ({
59
115
  id: 'native-embed-alignment-dropdown',
60
116
  type: 'dropdown',
61
117
  title: '',
62
- iconBefore: AlignTextCenterIcon,
63
- options: [],
64
- onClick: handlers === null || handlers === void 0 ? void 0 : handlers.onAlignmentClick
118
+ iconBefore: () => /*#__PURE__*/React.createElement(AlignmentIconComponent, {
119
+ color: "currentColor",
120
+ spacing: "spacious",
121
+ label: alignmentDropdownTitle
122
+ }),
123
+ options: alignmentOptions,
124
+ showSelected: true
65
125
  }, {
66
- type: 'separator'
126
+ type: 'separator',
127
+ fullHeight: true
67
128
  }, {
68
129
  id: 'native-embed-open-new-window-button',
69
130
  type: 'button',
@@ -74,15 +135,8 @@ export const getToolbarConfig = ({
74
135
  focusEditoronEnter: true,
75
136
  tabIndex: null
76
137
  }, {
77
- type: 'separator'
78
- }, {
79
- id: 'native-embed-more-options-button',
80
- type: 'dropdown',
81
- title: 'More options',
82
- icon: ShowMoreHorizontalIcon,
83
- hideExpandIcon: true,
84
- options: [],
85
- onClick: handlers === null || handlers === void 0 ? void 0 : handlers.onMoreOptionsClick
86
- }]
138
+ type: 'separator',
139
+ fullHeight: true
140
+ }, getMoreOptionsDropdown()]
87
141
  };
88
142
  };
@@ -0,0 +1,68 @@
1
+ import React from 'react';
2
+ import DatabaseIcon from '@atlaskit/icon/core/database';
3
+ import DeleteIcon from '@atlaskit/icon/core/delete';
4
+ import EyeOpenIcon from '@atlaskit/icon/core/eye-open';
5
+ import LinkIcon from '@atlaskit/icon/core/link';
6
+ import Toggle from '@atlaskit/toggle';
7
+
8
+ /**
9
+ * No-op command that returns true without dispatching any action.
10
+ * Used as a placeholder for menu items that don't have functionality yet.
11
+ */
12
+ const noopCommand = () => {
13
+ return true;
14
+ };
15
+
16
+ /**
17
+ * Returns the "More options" overflow dropdown configuration for the native embed floating toolbar.
18
+ */
19
+ export const getMoreOptionsDropdown = () => {
20
+ return {
21
+ id: 'native-embed-more-options-button',
22
+ type: 'overflow-dropdown',
23
+ dropdownWidth: 250,
24
+ options: [{
25
+ id: 'native-embed-always-show-title',
26
+ title: 'Always show title',
27
+ icon: /*#__PURE__*/React.createElement(EyeOpenIcon, {
28
+ color: "currentColor",
29
+ spacing: "spacious",
30
+ label: ""
31
+ }),
32
+ elemAfter: /*#__PURE__*/React.createElement(Toggle, {
33
+ isChecked: true,
34
+ label: "Always show title"
35
+ }),
36
+ onClick: noopCommand
37
+ }, {
38
+ id: 'native-embed-set-embed-type',
39
+ title: 'Set embed type',
40
+ icon: /*#__PURE__*/React.createElement(DatabaseIcon, {
41
+ color: "currentColor",
42
+ spacing: "spacious",
43
+ label: ""
44
+ }),
45
+ onClick: noopCommand
46
+ }, {
47
+ type: 'separator'
48
+ }, {
49
+ id: 'native-embed-copy-link',
50
+ title: 'Copy link',
51
+ icon: /*#__PURE__*/React.createElement(LinkIcon, {
52
+ color: "currentColor",
53
+ spacing: "spacious",
54
+ label: ""
55
+ }),
56
+ onClick: noopCommand
57
+ }, {
58
+ id: 'native-embed-delete',
59
+ title: 'Delete',
60
+ icon: /*#__PURE__*/React.createElement(DeleteIcon, {
61
+ color: "currentColor",
62
+ spacing: "spacious",
63
+ label: ""
64
+ }),
65
+ onClick: noopCommand
66
+ }]
67
+ };
68
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * All alignment values (for dropdowns / iteration). Single source of truth for alignment options.
3
+ */
4
+ export const ALIGNMENT_VALUES = ['left', 'center', 'right', 'wrap-left', 'wrap-right'];
5
+
6
+ /**
7
+ * Alignment value for native embed extension parameters.
8
+ * Used by the editor floating toolbar when the user changes alignment;
9
+ * the editor calls extensionApi.doc.update(localId, (current) => createAlignmentUpdate(current, alignment)).
10
+ */
11
+
12
+ /** Default alignment when not set in parameters. */
13
+ export const DEFAULT_ALIGNMENT = 'center';
14
+
15
+ /**
16
+ * Builds the attrs update for setting alignment on a native embed extension node.
17
+ */
18
+ export function createAlignmentUpdate(current, alignment) {
19
+ var _current$attrs;
20
+ const existingParams = current.attrs && 'parameters' in current.attrs && typeof current.attrs.parameters === 'object' ? current.attrs.parameters : {};
21
+ return {
22
+ attrs: {
23
+ ...((_current$attrs = current.attrs) !== null && _current$attrs !== void 0 ? _current$attrs : {}),
24
+ parameters: {
25
+ ...existingParams,
26
+ alignment
27
+ }
28
+ }
29
+ };
30
+ }
@@ -1,25 +1,86 @@
1
+ import React from 'react';
1
2
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
2
3
  import AlignTextCenterIcon from '@atlaskit/icon/core/align-text-center';
4
+ import AlignTextLeftIcon from '@atlaskit/icon/core/align-text-left';
5
+ import AlignTextRightIcon from '@atlaskit/icon/core/align-text-right';
3
6
  import BorderIcon from '@atlaskit/icon/core/border';
7
+ import ContentWrapLeftIcon from '@atlaskit/icon/core/content-wrap-left';
8
+ import ContentWrapRightIcon from '@atlaskit/icon/core/content-wrap-right';
4
9
  import LinkExternalIcon from '@atlaskit/icon/core/link-external';
5
10
  import PageIcon from '@atlaskit/icon/core/page';
6
11
  import RefreshIcon from '@atlaskit/icon/core/refresh';
7
- import ShowMoreHorizontalIcon from '@atlaskit/icon/core/show-more-horizontal';
12
+ import { ALIGNMENT_VALUES, createAlignmentUpdate, DEFAULT_ALIGNMENT } from '../../types/alignment';
8
13
  import { getSelectedNativeEmbedExtension } from '../utils/getSelectedNativeEmbedExtension';
14
+ import { getMoreOptionsDropdown } from './more-options-dropdown';
15
+
16
+ // TODO: CNS-23819 - Add i18n and finalise whether these should show as just icons with tooltips or text labels.
17
+ var ALIGNMENT_LABELS = {
18
+ left: 'Align left',
19
+ center: 'Align center',
20
+ right: 'Align right',
21
+ 'wrap-left': 'Wrap left',
22
+ 'wrap-right': 'Wrap right'
23
+ };
24
+ var ALIGNMENT_ICONS = {
25
+ left: AlignTextLeftIcon,
26
+ center: AlignTextCenterIcon,
27
+ right: AlignTextRightIcon,
28
+ 'wrap-left': ContentWrapLeftIcon,
29
+ 'wrap-right': ContentWrapRightIcon
30
+ };
31
+ var getAlignmentIcon = function getAlignmentIcon(alignment) {
32
+ var IconComponent = ALIGNMENT_ICONS[alignment];
33
+ return /*#__PURE__*/React.createElement(IconComponent, {
34
+ color: "currentColor",
35
+ spacing: "spacious",
36
+ label: ALIGNMENT_LABELS[alignment]
37
+ });
38
+ };
9
39
  var createHandlerCommand = function createHandlerCommand(handler) {
10
40
  return function () {
11
41
  handler === null || handler === void 0 || handler();
12
42
  return true;
13
43
  };
14
44
  };
45
+ var createUpdateAlignmentCommand = function createUpdateAlignmentCommand(api, alignment) {
46
+ return function (state, _dispatch, _view) {
47
+ var _api$extension, _extensionApi$doc;
48
+ var selectedNativeEmbed = getSelectedNativeEmbedExtension(state);
49
+ var localId = selectedNativeEmbed === null || selectedNativeEmbed === void 0 ? void 0 : selectedNativeEmbed.node.attrs.localId;
50
+ if (!localId) {
51
+ return false;
52
+ }
53
+ var extensionApi = api === null || api === void 0 || (_api$extension = api.extension) === null || _api$extension === void 0 || (_api$extension = _api$extension.actions) === null || _api$extension === void 0 ? void 0 : _api$extension.api();
54
+ if (!(extensionApi !== null && extensionApi !== void 0 && (_extensionApi$doc = extensionApi.doc) !== null && _extensionApi$doc !== void 0 && _extensionApi$doc.update)) {
55
+ return false;
56
+ }
57
+ extensionApi.doc.update(localId, function (current) {
58
+ return createAlignmentUpdate(current, alignment);
59
+ });
60
+ return true;
61
+ };
62
+ };
15
63
  export var getToolbarConfig = function getToolbarConfig(_ref) {
16
- var _api = _ref.api,
64
+ var api = _ref.api,
17
65
  handlers = _ref.handlers;
18
66
  return function (state, _intl, _providerFactory, _activeConfigs) {
67
+ var _ref2, _selectedNativeEmbed$;
19
68
  var selectedNativeEmbed = getSelectedNativeEmbedExtension(state);
20
69
  if (!selectedNativeEmbed) {
21
70
  return undefined;
22
71
  }
72
+ var currentAlignment = (_ref2 = (_selectedNativeEmbed$ = selectedNativeEmbed.node.attrs.parameters) === null || _selectedNativeEmbed$ === void 0 ? void 0 : _selectedNativeEmbed$.alignment) !== null && _ref2 !== void 0 ? _ref2 : DEFAULT_ALIGNMENT;
73
+ var alignmentOptions = ALIGNMENT_VALUES.map(function (alignment) {
74
+ return {
75
+ id: "native-embed-alignment-".concat(alignment),
76
+ title: ALIGNMENT_LABELS[alignment],
77
+ onClick: createUpdateAlignmentCommand(api, alignment),
78
+ selected: currentAlignment === alignment,
79
+ icon: getAlignmentIcon(alignment)
80
+ };
81
+ });
82
+ var alignmentDropdownTitle = ALIGNMENT_LABELS[currentAlignment];
83
+ var AlignmentIconComponent = ALIGNMENT_ICONS[currentAlignment];
23
84
  var getDomRef = function getDomRef(view) {
24
85
  try {
25
86
  var node = findDomRefAtPos(selectedNativeEmbed.pos, view.domAtPos.bind(view));
@@ -42,7 +103,8 @@ export var getToolbarConfig = function getToolbarConfig(_ref) {
42
103
  focusEditoronEnter: true,
43
104
  tabIndex: null
44
105
  }, {
45
- type: 'separator'
106
+ type: 'separator',
107
+ fullHeight: true
46
108
  }, {
47
109
  id: 'native-embed-embed-dropdown',
48
110
  type: 'dropdown',
@@ -61,11 +123,18 @@ export var getToolbarConfig = function getToolbarConfig(_ref) {
61
123
  id: 'native-embed-alignment-dropdown',
62
124
  type: 'dropdown',
63
125
  title: '',
64
- iconBefore: AlignTextCenterIcon,
65
- options: [],
66
- onClick: handlers === null || handlers === void 0 ? void 0 : handlers.onAlignmentClick
126
+ iconBefore: function iconBefore() {
127
+ return /*#__PURE__*/React.createElement(AlignmentIconComponent, {
128
+ color: "currentColor",
129
+ spacing: "spacious",
130
+ label: alignmentDropdownTitle
131
+ });
132
+ },
133
+ options: alignmentOptions,
134
+ showSelected: true
67
135
  }, {
68
- type: 'separator'
136
+ type: 'separator',
137
+ fullHeight: true
69
138
  }, {
70
139
  id: 'native-embed-open-new-window-button',
71
140
  type: 'button',
@@ -76,16 +145,9 @@ export var getToolbarConfig = function getToolbarConfig(_ref) {
76
145
  focusEditoronEnter: true,
77
146
  tabIndex: null
78
147
  }, {
79
- type: 'separator'
80
- }, {
81
- id: 'native-embed-more-options-button',
82
- type: 'dropdown',
83
- title: 'More options',
84
- icon: ShowMoreHorizontalIcon,
85
- hideExpandIcon: true,
86
- options: [],
87
- onClick: handlers === null || handlers === void 0 ? void 0 : handlers.onMoreOptionsClick
88
- }]
148
+ type: 'separator',
149
+ fullHeight: true
150
+ }, getMoreOptionsDropdown()]
89
151
  };
90
152
  };
91
153
  };
@@ -0,0 +1,68 @@
1
+ import React from 'react';
2
+ import DatabaseIcon from '@atlaskit/icon/core/database';
3
+ import DeleteIcon from '@atlaskit/icon/core/delete';
4
+ import EyeOpenIcon from '@atlaskit/icon/core/eye-open';
5
+ import LinkIcon from '@atlaskit/icon/core/link';
6
+ import Toggle from '@atlaskit/toggle';
7
+
8
+ /**
9
+ * No-op command that returns true without dispatching any action.
10
+ * Used as a placeholder for menu items that don't have functionality yet.
11
+ */
12
+ var noopCommand = function noopCommand() {
13
+ return true;
14
+ };
15
+
16
+ /**
17
+ * Returns the "More options" overflow dropdown configuration for the native embed floating toolbar.
18
+ */
19
+ export var getMoreOptionsDropdown = function getMoreOptionsDropdown() {
20
+ return {
21
+ id: 'native-embed-more-options-button',
22
+ type: 'overflow-dropdown',
23
+ dropdownWidth: 250,
24
+ options: [{
25
+ id: 'native-embed-always-show-title',
26
+ title: 'Always show title',
27
+ icon: /*#__PURE__*/React.createElement(EyeOpenIcon, {
28
+ color: "currentColor",
29
+ spacing: "spacious",
30
+ label: ""
31
+ }),
32
+ elemAfter: /*#__PURE__*/React.createElement(Toggle, {
33
+ isChecked: true,
34
+ label: "Always show title"
35
+ }),
36
+ onClick: noopCommand
37
+ }, {
38
+ id: 'native-embed-set-embed-type',
39
+ title: 'Set embed type',
40
+ icon: /*#__PURE__*/React.createElement(DatabaseIcon, {
41
+ color: "currentColor",
42
+ spacing: "spacious",
43
+ label: ""
44
+ }),
45
+ onClick: noopCommand
46
+ }, {
47
+ type: 'separator'
48
+ }, {
49
+ id: 'native-embed-copy-link',
50
+ title: 'Copy link',
51
+ icon: /*#__PURE__*/React.createElement(LinkIcon, {
52
+ color: "currentColor",
53
+ spacing: "spacious",
54
+ label: ""
55
+ }),
56
+ onClick: noopCommand
57
+ }, {
58
+ id: 'native-embed-delete',
59
+ title: 'Delete',
60
+ icon: /*#__PURE__*/React.createElement(DeleteIcon, {
61
+ color: "currentColor",
62
+ spacing: "spacious",
63
+ label: ""
64
+ }),
65
+ onClick: noopCommand
66
+ }]
67
+ };
68
+ };
@@ -0,0 +1,32 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _typeof from "@babel/runtime/helpers/typeof";
3
+ 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; }
4
+ 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; }
5
+ /**
6
+ * All alignment values (for dropdowns / iteration). Single source of truth for alignment options.
7
+ */
8
+ export var ALIGNMENT_VALUES = ['left', 'center', 'right', 'wrap-left', 'wrap-right'];
9
+
10
+ /**
11
+ * Alignment value for native embed extension parameters.
12
+ * Used by the editor floating toolbar when the user changes alignment;
13
+ * the editor calls extensionApi.doc.update(localId, (current) => createAlignmentUpdate(current, alignment)).
14
+ */
15
+
16
+ /** Default alignment when not set in parameters. */
17
+ export var DEFAULT_ALIGNMENT = 'center';
18
+
19
+ /**
20
+ * Builds the attrs update for setting alignment on a native embed extension node.
21
+ */
22
+ export function createAlignmentUpdate(current, alignment) {
23
+ var _current$attrs;
24
+ var existingParams = current.attrs && 'parameters' in current.attrs && _typeof(current.attrs.parameters) === 'object' ? current.attrs.parameters : {};
25
+ return {
26
+ attrs: _objectSpread(_objectSpread({}, (_current$attrs = current.attrs) !== null && _current$attrs !== void 0 ? _current$attrs : {}), {}, {
27
+ parameters: _objectSpread(_objectSpread({}, existingParams), {}, {
28
+ alignment: alignment
29
+ })
30
+ })
31
+ };
32
+ }
@@ -4,5 +4,5 @@ interface GetToolbarConfigProps {
4
4
  api?: ExtractInjectionAPI<EditorPluginNativeEmbedsPlugin>;
5
5
  handlers?: EditorPluginNativeEmbedsToolbarHandlers;
6
6
  }
7
- export declare const getToolbarConfig: ({ api: _api, handlers }: GetToolbarConfigProps) => FloatingToolbarHandler;
7
+ export declare const getToolbarConfig: ({ api, handlers }: GetToolbarConfigProps) => FloatingToolbarHandler;
8
8
  export {};
@@ -0,0 +1,5 @@
1
+ import type { Command, FloatingToolbarOverflowDropdown } from '@atlaskit/editor-common/types';
2
+ /**
3
+ * Returns the "More options" overflow dropdown configuration for the native embed floating toolbar.
4
+ */
5
+ export declare const getMoreOptionsDropdown: () => FloatingToolbarOverflowDropdown<Command>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * All alignment values (for dropdowns / iteration). Single source of truth for alignment options.
3
+ */
4
+ export declare const ALIGNMENT_VALUES: readonly ["left", "center", "right", "wrap-left", "wrap-right"];
5
+ /**
6
+ * Alignment value for native embed extension parameters.
7
+ * Used by the editor floating toolbar when the user changes alignment;
8
+ * the editor calls extensionApi.doc.update(localId, (current) => createAlignmentUpdate(current, alignment)).
9
+ */
10
+ export type AlignmentValue = (typeof ALIGNMENT_VALUES)[number];
11
+ /** Default alignment when not set in parameters. */
12
+ export declare const DEFAULT_ALIGNMENT: AlignmentValue;
13
+ /**
14
+ * Builds the attrs update for setting alignment on a native embed extension node.
15
+ */
16
+ export declare function createAlignmentUpdate(current: {
17
+ attrs?: Record<string, unknown>;
18
+ }, alignment: AlignmentValue): {
19
+ attrs: Record<string, unknown>;
20
+ };
@@ -4,5 +4,5 @@ interface GetToolbarConfigProps {
4
4
  api?: ExtractInjectionAPI<EditorPluginNativeEmbedsPlugin>;
5
5
  handlers?: EditorPluginNativeEmbedsToolbarHandlers;
6
6
  }
7
- export declare const getToolbarConfig: ({ api: _api, handlers }: GetToolbarConfigProps) => FloatingToolbarHandler;
7
+ export declare const getToolbarConfig: ({ api, handlers }: GetToolbarConfigProps) => FloatingToolbarHandler;
8
8
  export {};
@@ -0,0 +1,5 @@
1
+ import type { Command, FloatingToolbarOverflowDropdown } from '@atlaskit/editor-common/types';
2
+ /**
3
+ * Returns the "More options" overflow dropdown configuration for the native embed floating toolbar.
4
+ */
5
+ export declare const getMoreOptionsDropdown: () => FloatingToolbarOverflowDropdown<Command>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * All alignment values (for dropdowns / iteration). Single source of truth for alignment options.
3
+ */
4
+ export declare const ALIGNMENT_VALUES: readonly [
5
+ "left",
6
+ "center",
7
+ "right",
8
+ "wrap-left",
9
+ "wrap-right"
10
+ ];
11
+ /**
12
+ * Alignment value for native embed extension parameters.
13
+ * Used by the editor floating toolbar when the user changes alignment;
14
+ * the editor calls extensionApi.doc.update(localId, (current) => createAlignmentUpdate(current, alignment)).
15
+ */
16
+ export type AlignmentValue = (typeof ALIGNMENT_VALUES)[number];
17
+ /** Default alignment when not set in parameters. */
18
+ export declare const DEFAULT_ALIGNMENT: AlignmentValue;
19
+ /**
20
+ * Builds the attrs update for setting alignment on a native embed extension node.
21
+ */
22
+ export declare function createAlignmentUpdate(current: {
23
+ attrs?: Record<string, unknown>;
24
+ }, alignment: AlignmentValue): {
25
+ attrs: Record<string, unknown>;
26
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-native-embeds",
3
- "version": "0.0.0",
3
+ "version": "0.0.1",
4
4
  "description": "EditorPluginNativeEmbeds plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -32,15 +32,25 @@
32
32
  "@atlaskit/editor-plugin-decorations": "^7.0.0",
33
33
  "@atlaskit/editor-plugin-extension": "^10.1.0",
34
34
  "@atlaskit/editor-prosemirror": "^7.3.0",
35
- "@atlaskit/icon": "^31.0.0",
35
+ "@atlaskit/icon": "^32.0.0",
36
+ "@atlaskit/toggle": "^15.2.0",
36
37
  "@babel/runtime": "^7.0.0",
37
38
  "react-intl-next": "npm:react-intl@^5.18.1"
38
39
  },
39
40
  "peerDependencies": {
40
- "@atlaskit/editor-common": "^111.16.0",
41
+ "@atlaskit/editor-common": "^111.20.0",
41
42
  "react": "^18.2.0"
42
43
  },
43
44
  "devDependencies": {
45
+ "@af/editor-examples-helpers": "workspace:*",
46
+ "@atlaskit/adf-schema": "^51.5.0",
47
+ "@atlaskit/button": "^23.9.0",
48
+ "@atlaskit/editor-core": "^216.12.0",
49
+ "@atlaskit/editor-test-helpers": "workspace:^",
50
+ "@atlaskit/link-provider": "^4.2.0",
51
+ "@atlaskit/logo": "^19.10.0",
52
+ "@atlaskit/synchrony-test-helpers": "workspace:^",
53
+ "@atlaskit/tmp-editor-statsig": "^29.6.0",
44
54
  "typescript": "5.9.2"
45
55
  },
46
56
  "techstack": {