@atlaskit/editor-plugin-synced-block 2.1.1 → 2.2.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.
- package/CHANGELOG.md +11 -0
- package/afm-cc/tsconfig.json +6 -0
- package/afm-dev-agents/tsconfig.json +6 -0
- package/afm-jira/tsconfig.json +6 -0
- package/afm-passionfruit/tsconfig.json +6 -0
- package/afm-post-office/tsconfig.json +6 -0
- package/afm-rovo-extension/tsconfig.json +6 -0
- package/afm-townsquare/tsconfig.json +6 -0
- package/dist/cjs/pm-plugins/main.js +31 -6
- package/dist/cjs/pm-plugins/utils/track-sync-blocks.js +54 -0
- package/dist/cjs/syncedBlockPlugin.js +6 -0
- package/dist/cjs/ui/ContentComponent.js +55 -0
- package/dist/es2019/pm-plugins/main.js +32 -6
- package/dist/es2019/pm-plugins/utils/track-sync-blocks.js +50 -0
- package/dist/es2019/syncedBlockPlugin.js +6 -0
- package/dist/es2019/ui/ContentComponent.js +41 -0
- package/dist/esm/pm-plugins/main.js +31 -6
- package/dist/esm/pm-plugins/utils/track-sync-blocks.js +48 -0
- package/dist/esm/syncedBlockPlugin.js +6 -0
- package/dist/esm/ui/ContentComponent.js +46 -0
- package/dist/types/pm-plugins/main.d.ts +1 -1
- package/dist/types/pm-plugins/utils/track-sync-blocks.d.ts +7 -0
- package/dist/types/syncedBlockPluginType.d.ts +4 -0
- package/dist/types/ui/ContentComponent.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/utils/track-sync-blocks.d.ts +7 -0
- package/dist/types-ts4.5/syncedBlockPluginType.d.ts +4 -0
- package/dist/types-ts4.5/ui/ContentComponent.d.ts +5 -0
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`889f0cb60f68d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/889f0cb60f68d) -
|
|
8
|
+
EDITOR-1561 implement confirmation before deleting a source sync block
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
3
14
|
## 2.1.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/afm-cc/tsconfig.json
CHANGED
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-cc/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-cc/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-cc/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-cc/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-cc/tsconfig.json"
|
|
33
39
|
}
|
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-dev-agents/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-dev-agents/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-dev-agents/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-dev-agents/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-dev-agents/tsconfig.json"
|
|
33
39
|
}
|
package/afm-jira/tsconfig.json
CHANGED
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-jira/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-jira/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-jira/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-jira/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-jira/tsconfig.json"
|
|
33
39
|
}
|
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-passionfruit/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-passionfruit/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-passionfruit/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-passionfruit/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-passionfruit/tsconfig.json"
|
|
33
39
|
}
|
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-post-office/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-post-office/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-post-office/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-post-office/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-post-office/tsconfig.json"
|
|
33
39
|
}
|
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-rovo-extension/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-rovo-extension/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-rovo-extension/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-rovo-extension/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-rovo-extension/tsconfig.json"
|
|
33
39
|
}
|
|
@@ -22,12 +22,18 @@
|
|
|
22
22
|
"../src/**/stories/**/*"
|
|
23
23
|
],
|
|
24
24
|
"references": [
|
|
25
|
+
{
|
|
26
|
+
"path": "../../../design-system/button/afm-townsquare/tsconfig.json"
|
|
27
|
+
},
|
|
25
28
|
{
|
|
26
29
|
"path": "../../editor-plugin-selection/afm-townsquare/tsconfig.json"
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
"path": "../../../design-system/icon/afm-townsquare/tsconfig.json"
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
"path": "../../../design-system/modal-dialog/afm-townsquare/tsconfig.json"
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
"path": "../../editor-common/afm-townsquare/tsconfig.json"
|
|
33
39
|
}
|
|
@@ -7,22 +7,19 @@ exports.syncedBlockPluginKey = exports.createPlugin = void 0;
|
|
|
7
7
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
8
8
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
9
9
|
var _lazySyncedBlock = require("../nodeviews/lazySyncedBlock");
|
|
10
|
+
var _trackSyncBlocks2 = require("./utils/track-sync-blocks");
|
|
10
11
|
var syncedBlockPluginKey = exports.syncedBlockPluginKey = new _state.PluginKey('syncedBlockPlugin');
|
|
11
12
|
|
|
12
13
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
13
14
|
|
|
14
|
-
var createPlugin = exports.createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
15
|
+
var createPlugin = exports.createPlugin = function createPlugin(options, pmPluginFactoryParams, syncBlockStore, api) {
|
|
15
16
|
return new _safePlugin.SafePlugin({
|
|
16
17
|
key: syncedBlockPluginKey,
|
|
17
18
|
state: {
|
|
18
19
|
init: function init() {
|
|
19
20
|
return {};
|
|
20
21
|
},
|
|
21
|
-
apply: function apply(
|
|
22
|
-
var meta = tr.getMeta(syncedBlockPluginKey);
|
|
23
|
-
if (meta) {
|
|
24
|
-
return meta;
|
|
25
|
-
}
|
|
22
|
+
apply: function apply(_tr, currentPluginState) {
|
|
26
23
|
return currentPluginState;
|
|
27
24
|
}
|
|
28
25
|
},
|
|
@@ -34,6 +31,34 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
34
31
|
api: api
|
|
35
32
|
})
|
|
36
33
|
}
|
|
34
|
+
},
|
|
35
|
+
view: function view(editorView) {
|
|
36
|
+
syncBlockStore.setEditorView(editorView);
|
|
37
|
+
return {
|
|
38
|
+
destroy: function destroy() {
|
|
39
|
+
syncBlockStore.setEditorView(undefined);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
filterTransaction: function filterTransaction(tr, state) {
|
|
44
|
+
// Ignore transactions that don't change the document
|
|
45
|
+
// or are from remote (collab) or already confirmed sync block deletion
|
|
46
|
+
// We only care about local changes that change the document
|
|
47
|
+
// and are not yet confirmed for sync block deletion
|
|
48
|
+
if (!tr.docChanged || !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.requireConfirmationBeforeDelete()) || Boolean(tr.getMeta('isRemote')) || Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'))) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
var _trackSyncBlocks = (0, _trackSyncBlocks2.trackSyncBlocks)(syncBlockStore, tr, state),
|
|
52
|
+
removed = _trackSyncBlocks.removed;
|
|
53
|
+
if (removed.length > 0) {
|
|
54
|
+
// If there are source sync blocks being removed, and we need to confirm with user before deleting,
|
|
55
|
+
// we block the transaction here, and wait for user confirmation to proceed with deletion.
|
|
56
|
+
// See editor-common/src/sync-block/sync-block-store-manager.ts for how we handle user confirmation and
|
|
57
|
+
// proceed with deletion.
|
|
58
|
+
syncBlockStore.deleteSyncBlocksWithConfirmation(tr, removed);
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
37
62
|
}
|
|
38
63
|
});
|
|
39
64
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.trackSyncBlocks = void 0;
|
|
7
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
8
|
+
var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
|
|
9
|
+
var sourceSyncBlockRemoved = {};
|
|
10
|
+
var sourceSyncBlockAdded = {};
|
|
11
|
+
tr.steps.map(function (step) {
|
|
12
|
+
if (step instanceof _transform.ReplaceStep || step instanceof _transform.ReplaceAroundStep) {
|
|
13
|
+
var from = step.from,
|
|
14
|
+
to = step.to;
|
|
15
|
+
// replaced a range, check for deleted syncBlock
|
|
16
|
+
if (from !== to) {
|
|
17
|
+
state.doc.nodesBetween(step.from, step.to, function (node) {
|
|
18
|
+
if (storeManager.isSourceBlock(node)) {
|
|
19
|
+
if (sourceSyncBlockAdded[node.attrs.localId]) {
|
|
20
|
+
// If a source block added and then removed in the same transaction,
|
|
21
|
+
// we treat it as no-op.
|
|
22
|
+
delete sourceSyncBlockAdded[node.attrs.localId];
|
|
23
|
+
} else {
|
|
24
|
+
sourceSyncBlockRemoved[node.attrs.localId] = node.attrs;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// we don't need to go deeper
|
|
28
|
+
return false;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// replaced content, check for inserted syncBlock
|
|
33
|
+
if (step.slice.content.size > 0) {
|
|
34
|
+
step.slice.content.nodesBetween(0, step.slice.content.size, function (node) {
|
|
35
|
+
if (storeManager.isSourceBlock(node)) {
|
|
36
|
+
if (sourceSyncBlockRemoved[node.attrs.localId]) {
|
|
37
|
+
// If a source block is removed and added back in the same transaction,
|
|
38
|
+
// we treat it as no-op.
|
|
39
|
+
delete sourceSyncBlockRemoved[node.attrs.localId];
|
|
40
|
+
} else {
|
|
41
|
+
sourceSyncBlockAdded[node.attrs.localId] = node.attrs;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// we don't need to go deeper
|
|
45
|
+
return false;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
removed: Object.values(sourceSyncBlockRemoved),
|
|
52
|
+
added: Object.values(sourceSyncBlockAdded)
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -11,6 +11,7 @@ var _syncBlock = require("@atlaskit/editor-common/sync-block");
|
|
|
11
11
|
var _smartLink = _interopRequireDefault(require("@atlaskit/icon/core/smart-link"));
|
|
12
12
|
var _actions = require("./pm-plugins/actions");
|
|
13
13
|
var _main = require("./pm-plugins/main");
|
|
14
|
+
var _ContentComponent = require("./ui/ContentComponent");
|
|
14
15
|
var _floatingToolbar = require("./ui/floating-toolbar");
|
|
15
16
|
var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_ref) {
|
|
16
17
|
var config = _ref.config,
|
|
@@ -54,6 +55,11 @@ var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_
|
|
|
54
55
|
floatingToolbar: function floatingToolbar(state, intl, providerFactory) {
|
|
55
56
|
return (0, _floatingToolbar.getToolbarConfig)(state, intl, config, providerFactory);
|
|
56
57
|
}
|
|
58
|
+
},
|
|
59
|
+
contentComponent: function contentComponent() {
|
|
60
|
+
return /*#__PURE__*/_react.default.createElement(_ContentComponent.ContentComponent, {
|
|
61
|
+
syncBlockStoreManager: syncBlockStore
|
|
62
|
+
});
|
|
57
63
|
}
|
|
58
64
|
};
|
|
59
65
|
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.ContentComponent = void 0;
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
var _new = _interopRequireDefault(require("@atlaskit/button/new"));
|
|
12
|
+
var _modalDialog = _interopRequireWildcard(require("@atlaskit/modal-dialog"));
|
|
13
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
14
|
+
var ContentComponent = exports.ContentComponent = function ContentComponent(_ref) {
|
|
15
|
+
var syncBlockStoreManager = _ref.syncBlockStoreManager;
|
|
16
|
+
var _useState = (0, _react.useState)(false),
|
|
17
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
18
|
+
isOpen = _useState2[0],
|
|
19
|
+
setIsOpen = _useState2[1];
|
|
20
|
+
var resolverRef = _react.default.useRef(undefined);
|
|
21
|
+
var handleClose = (0, _react.useCallback)(function (confirm) {
|
|
22
|
+
return function () {
|
|
23
|
+
if (resolverRef.current) {
|
|
24
|
+
resolverRef.current(confirm);
|
|
25
|
+
resolverRef.current = undefined;
|
|
26
|
+
}
|
|
27
|
+
setIsOpen(false);
|
|
28
|
+
};
|
|
29
|
+
}, []);
|
|
30
|
+
var confirmationCallback = (0, _react.useCallback)(function () {
|
|
31
|
+
setIsOpen(true);
|
|
32
|
+
var confirmedPromise = new Promise(function (resolve) {
|
|
33
|
+
resolverRef.current = resolve;
|
|
34
|
+
});
|
|
35
|
+
return confirmedPromise;
|
|
36
|
+
}, []);
|
|
37
|
+
(0, _react.useEffect)(function () {
|
|
38
|
+
var unregister = syncBlockStoreManager.registerConfirmationCallback(confirmationCallback);
|
|
39
|
+
return function () {
|
|
40
|
+
unregister();
|
|
41
|
+
};
|
|
42
|
+
}, [syncBlockStoreManager, confirmationCallback]);
|
|
43
|
+
return /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTransition, null, isOpen && /*#__PURE__*/_react.default.createElement(_modalDialog.default, {
|
|
44
|
+
onClose: handleClose(false)
|
|
45
|
+
}, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalHeader, {
|
|
46
|
+
hasCloseButton: true
|
|
47
|
+
}, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTitle, null, "Confirmation")), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalBody, null, /*#__PURE__*/_react.default.createElement("div", null, "Are you sure you want to delete this synced block?")), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalFooter, null, /*#__PURE__*/_react.default.createElement(_new.default, {
|
|
48
|
+
appearance: "subtle",
|
|
49
|
+
onClick: handleClose(false)
|
|
50
|
+
}, "Cancel"), /*#__PURE__*/_react.default.createElement(_new.default, {
|
|
51
|
+
appearance: "danger",
|
|
52
|
+
onClick: handleClose(true),
|
|
53
|
+
autoFocus: true
|
|
54
|
+
}, "Delete"))));
|
|
55
|
+
};
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
2
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import { lazySyncBlockView } from '../nodeviews/lazySyncedBlock';
|
|
4
|
+
import { trackSyncBlocks } from './utils/track-sync-blocks';
|
|
4
5
|
export const syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
|
|
5
6
|
|
|
6
7
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
7
8
|
|
|
8
|
-
export const createPlugin = (options, pmPluginFactoryParams,
|
|
9
|
+
export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api) => {
|
|
9
10
|
return new SafePlugin({
|
|
10
11
|
key: syncedBlockPluginKey,
|
|
11
12
|
state: {
|
|
12
13
|
init() {
|
|
13
14
|
return {};
|
|
14
15
|
},
|
|
15
|
-
apply: (
|
|
16
|
-
const meta = tr.getMeta(syncedBlockPluginKey);
|
|
17
|
-
if (meta) {
|
|
18
|
-
return meta;
|
|
19
|
-
}
|
|
16
|
+
apply: (_tr, currentPluginState) => {
|
|
20
17
|
return currentPluginState;
|
|
21
18
|
}
|
|
22
19
|
},
|
|
@@ -28,6 +25,35 @@ export const createPlugin = (options, pmPluginFactoryParams, _syncBlockStore, ap
|
|
|
28
25
|
api
|
|
29
26
|
})
|
|
30
27
|
}
|
|
28
|
+
},
|
|
29
|
+
view: editorView => {
|
|
30
|
+
syncBlockStore.setEditorView(editorView);
|
|
31
|
+
return {
|
|
32
|
+
destroy() {
|
|
33
|
+
syncBlockStore.setEditorView(undefined);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
filterTransaction: (tr, state) => {
|
|
38
|
+
// Ignore transactions that don't change the document
|
|
39
|
+
// or are from remote (collab) or already confirmed sync block deletion
|
|
40
|
+
// We only care about local changes that change the document
|
|
41
|
+
// and are not yet confirmed for sync block deletion
|
|
42
|
+
if (!tr.docChanged || !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.requireConfirmationBeforeDelete()) || Boolean(tr.getMeta('isRemote')) || Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'))) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
const {
|
|
46
|
+
removed
|
|
47
|
+
} = trackSyncBlocks(syncBlockStore, tr, state);
|
|
48
|
+
if (removed.length > 0) {
|
|
49
|
+
// If there are source sync blocks being removed, and we need to confirm with user before deleting,
|
|
50
|
+
// we block the transaction here, and wait for user confirmation to proceed with deletion.
|
|
51
|
+
// See editor-common/src/sync-block/sync-block-store-manager.ts for how we handle user confirmation and
|
|
52
|
+
// proceed with deletion.
|
|
53
|
+
syncBlockStore.deleteSyncBlocksWithConfirmation(tr, removed);
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
31
57
|
}
|
|
32
58
|
});
|
|
33
59
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
+
export const trackSyncBlocks = (storeManager, tr, state) => {
|
|
3
|
+
const sourceSyncBlockRemoved = {};
|
|
4
|
+
const sourceSyncBlockAdded = {};
|
|
5
|
+
tr.steps.map(step => {
|
|
6
|
+
if (step instanceof ReplaceStep || step instanceof ReplaceAroundStep) {
|
|
7
|
+
const {
|
|
8
|
+
from,
|
|
9
|
+
to
|
|
10
|
+
} = step;
|
|
11
|
+
// replaced a range, check for deleted syncBlock
|
|
12
|
+
if (from !== to) {
|
|
13
|
+
state.doc.nodesBetween(step.from, step.to, node => {
|
|
14
|
+
if (storeManager.isSourceBlock(node)) {
|
|
15
|
+
if (sourceSyncBlockAdded[node.attrs.localId]) {
|
|
16
|
+
// If a source block added and then removed in the same transaction,
|
|
17
|
+
// we treat it as no-op.
|
|
18
|
+
delete sourceSyncBlockAdded[node.attrs.localId];
|
|
19
|
+
} else {
|
|
20
|
+
sourceSyncBlockRemoved[node.attrs.localId] = node.attrs;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// we don't need to go deeper
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// replaced content, check for inserted syncBlock
|
|
29
|
+
if (step.slice.content.size > 0) {
|
|
30
|
+
step.slice.content.nodesBetween(0, step.slice.content.size, node => {
|
|
31
|
+
if (storeManager.isSourceBlock(node)) {
|
|
32
|
+
if (sourceSyncBlockRemoved[node.attrs.localId]) {
|
|
33
|
+
// If a source block is removed and added back in the same transaction,
|
|
34
|
+
// we treat it as no-op.
|
|
35
|
+
delete sourceSyncBlockRemoved[node.attrs.localId];
|
|
36
|
+
} else {
|
|
37
|
+
sourceSyncBlockAdded[node.attrs.localId] = node.attrs;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// we don't need to go deeper
|
|
41
|
+
return false;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
removed: Object.values(sourceSyncBlockRemoved),
|
|
48
|
+
added: Object.values(sourceSyncBlockAdded)
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -4,6 +4,7 @@ import { SyncBlockStoreManager } from '@atlaskit/editor-common/sync-block';
|
|
|
4
4
|
import SmartLinkIcon from '@atlaskit/icon/core/smart-link';
|
|
5
5
|
import { createSyncedBlock } from './pm-plugins/actions';
|
|
6
6
|
import { createPlugin } from './pm-plugins/main';
|
|
7
|
+
import { ContentComponent } from './ui/ContentComponent';
|
|
7
8
|
import { getToolbarConfig } from './ui/floating-toolbar';
|
|
8
9
|
export const syncedBlockPlugin = ({
|
|
9
10
|
config,
|
|
@@ -40,6 +41,11 @@ export const syncedBlockPlugin = ({
|
|
|
40
41
|
}
|
|
41
42
|
}],
|
|
42
43
|
floatingToolbar: (state, intl, providerFactory) => getToolbarConfig(state, intl, config, providerFactory)
|
|
44
|
+
},
|
|
45
|
+
contentComponent: () => {
|
|
46
|
+
return /*#__PURE__*/React.createElement(ContentComponent, {
|
|
47
|
+
syncBlockStoreManager: syncBlockStore
|
|
48
|
+
});
|
|
43
49
|
}
|
|
44
50
|
};
|
|
45
51
|
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import Button from '@atlaskit/button/new';
|
|
3
|
+
import ModalDialog, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
|
|
4
|
+
export const ContentComponent = ({
|
|
5
|
+
syncBlockStoreManager
|
|
6
|
+
}) => {
|
|
7
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
8
|
+
const resolverRef = React.useRef(undefined);
|
|
9
|
+
const handleClose = useCallback(confirm => () => {
|
|
10
|
+
if (resolverRef.current) {
|
|
11
|
+
resolverRef.current(confirm);
|
|
12
|
+
resolverRef.current = undefined;
|
|
13
|
+
}
|
|
14
|
+
setIsOpen(false);
|
|
15
|
+
}, []);
|
|
16
|
+
const confirmationCallback = useCallback(() => {
|
|
17
|
+
setIsOpen(true);
|
|
18
|
+
const confirmedPromise = new Promise(resolve => {
|
|
19
|
+
resolverRef.current = resolve;
|
|
20
|
+
});
|
|
21
|
+
return confirmedPromise;
|
|
22
|
+
}, []);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const unregister = syncBlockStoreManager.registerConfirmationCallback(confirmationCallback);
|
|
25
|
+
return () => {
|
|
26
|
+
unregister();
|
|
27
|
+
};
|
|
28
|
+
}, [syncBlockStoreManager, confirmationCallback]);
|
|
29
|
+
return /*#__PURE__*/React.createElement(ModalTransition, null, isOpen && /*#__PURE__*/React.createElement(ModalDialog, {
|
|
30
|
+
onClose: handleClose(false)
|
|
31
|
+
}, /*#__PURE__*/React.createElement(ModalHeader, {
|
|
32
|
+
hasCloseButton: true
|
|
33
|
+
}, /*#__PURE__*/React.createElement(ModalTitle, null, "Confirmation")), /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement("div", null, "Are you sure you want to delete this synced block?")), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
|
|
34
|
+
appearance: "subtle",
|
|
35
|
+
onClick: handleClose(false)
|
|
36
|
+
}, "Cancel"), /*#__PURE__*/React.createElement(Button, {
|
|
37
|
+
appearance: "danger",
|
|
38
|
+
onClick: handleClose(true),
|
|
39
|
+
autoFocus: true
|
|
40
|
+
}, "Delete"))));
|
|
41
|
+
};
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
2
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import { lazySyncBlockView } from '../nodeviews/lazySyncedBlock';
|
|
4
|
+
import { trackSyncBlocks } from './utils/track-sync-blocks';
|
|
4
5
|
export var syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
|
|
5
6
|
|
|
6
7
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
7
8
|
|
|
8
|
-
export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
9
|
+
export var createPlugin = function createPlugin(options, pmPluginFactoryParams, syncBlockStore, api) {
|
|
9
10
|
return new SafePlugin({
|
|
10
11
|
key: syncedBlockPluginKey,
|
|
11
12
|
state: {
|
|
12
13
|
init: function init() {
|
|
13
14
|
return {};
|
|
14
15
|
},
|
|
15
|
-
apply: function apply(
|
|
16
|
-
var meta = tr.getMeta(syncedBlockPluginKey);
|
|
17
|
-
if (meta) {
|
|
18
|
-
return meta;
|
|
19
|
-
}
|
|
16
|
+
apply: function apply(_tr, currentPluginState) {
|
|
20
17
|
return currentPluginState;
|
|
21
18
|
}
|
|
22
19
|
},
|
|
@@ -28,6 +25,34 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
28
25
|
api: api
|
|
29
26
|
})
|
|
30
27
|
}
|
|
28
|
+
},
|
|
29
|
+
view: function view(editorView) {
|
|
30
|
+
syncBlockStore.setEditorView(editorView);
|
|
31
|
+
return {
|
|
32
|
+
destroy: function destroy() {
|
|
33
|
+
syncBlockStore.setEditorView(undefined);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
filterTransaction: function filterTransaction(tr, state) {
|
|
38
|
+
// Ignore transactions that don't change the document
|
|
39
|
+
// or are from remote (collab) or already confirmed sync block deletion
|
|
40
|
+
// We only care about local changes that change the document
|
|
41
|
+
// and are not yet confirmed for sync block deletion
|
|
42
|
+
if (!tr.docChanged || !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.requireConfirmationBeforeDelete()) || Boolean(tr.getMeta('isRemote')) || Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'))) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
var _trackSyncBlocks = trackSyncBlocks(syncBlockStore, tr, state),
|
|
46
|
+
removed = _trackSyncBlocks.removed;
|
|
47
|
+
if (removed.length > 0) {
|
|
48
|
+
// If there are source sync blocks being removed, and we need to confirm with user before deleting,
|
|
49
|
+
// we block the transaction here, and wait for user confirmation to proceed with deletion.
|
|
50
|
+
// See editor-common/src/sync-block/sync-block-store-manager.ts for how we handle user confirmation and
|
|
51
|
+
// proceed with deletion.
|
|
52
|
+
syncBlockStore.deleteSyncBlocksWithConfirmation(tr, removed);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
31
56
|
}
|
|
32
57
|
});
|
|
33
58
|
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
+
export var trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
|
|
3
|
+
var sourceSyncBlockRemoved = {};
|
|
4
|
+
var sourceSyncBlockAdded = {};
|
|
5
|
+
tr.steps.map(function (step) {
|
|
6
|
+
if (step instanceof ReplaceStep || step instanceof ReplaceAroundStep) {
|
|
7
|
+
var from = step.from,
|
|
8
|
+
to = step.to;
|
|
9
|
+
// replaced a range, check for deleted syncBlock
|
|
10
|
+
if (from !== to) {
|
|
11
|
+
state.doc.nodesBetween(step.from, step.to, function (node) {
|
|
12
|
+
if (storeManager.isSourceBlock(node)) {
|
|
13
|
+
if (sourceSyncBlockAdded[node.attrs.localId]) {
|
|
14
|
+
// If a source block added and then removed in the same transaction,
|
|
15
|
+
// we treat it as no-op.
|
|
16
|
+
delete sourceSyncBlockAdded[node.attrs.localId];
|
|
17
|
+
} else {
|
|
18
|
+
sourceSyncBlockRemoved[node.attrs.localId] = node.attrs;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// we don't need to go deeper
|
|
22
|
+
return false;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// replaced content, check for inserted syncBlock
|
|
27
|
+
if (step.slice.content.size > 0) {
|
|
28
|
+
step.slice.content.nodesBetween(0, step.slice.content.size, function (node) {
|
|
29
|
+
if (storeManager.isSourceBlock(node)) {
|
|
30
|
+
if (sourceSyncBlockRemoved[node.attrs.localId]) {
|
|
31
|
+
// If a source block is removed and added back in the same transaction,
|
|
32
|
+
// we treat it as no-op.
|
|
33
|
+
delete sourceSyncBlockRemoved[node.attrs.localId];
|
|
34
|
+
} else {
|
|
35
|
+
sourceSyncBlockAdded[node.attrs.localId] = node.attrs;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// we don't need to go deeper
|
|
39
|
+
return false;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
removed: Object.values(sourceSyncBlockRemoved),
|
|
46
|
+
added: Object.values(sourceSyncBlockAdded)
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -4,6 +4,7 @@ import { SyncBlockStoreManager } from '@atlaskit/editor-common/sync-block';
|
|
|
4
4
|
import SmartLinkIcon from '@atlaskit/icon/core/smart-link';
|
|
5
5
|
import { createSyncedBlock } from './pm-plugins/actions';
|
|
6
6
|
import { createPlugin } from './pm-plugins/main';
|
|
7
|
+
import { ContentComponent } from './ui/ContentComponent';
|
|
7
8
|
import { getToolbarConfig } from './ui/floating-toolbar';
|
|
8
9
|
export var syncedBlockPlugin = function syncedBlockPlugin(_ref) {
|
|
9
10
|
var config = _ref.config,
|
|
@@ -47,6 +48,11 @@ export var syncedBlockPlugin = function syncedBlockPlugin(_ref) {
|
|
|
47
48
|
floatingToolbar: function floatingToolbar(state, intl, providerFactory) {
|
|
48
49
|
return getToolbarConfig(state, intl, config, providerFactory);
|
|
49
50
|
}
|
|
51
|
+
},
|
|
52
|
+
contentComponent: function contentComponent() {
|
|
53
|
+
return /*#__PURE__*/React.createElement(ContentComponent, {
|
|
54
|
+
syncBlockStoreManager: syncBlockStore
|
|
55
|
+
});
|
|
50
56
|
}
|
|
51
57
|
};
|
|
52
58
|
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import Button from '@atlaskit/button/new';
|
|
4
|
+
import ModalDialog, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
|
|
5
|
+
export var ContentComponent = function ContentComponent(_ref) {
|
|
6
|
+
var syncBlockStoreManager = _ref.syncBlockStoreManager;
|
|
7
|
+
var _useState = useState(false),
|
|
8
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
9
|
+
isOpen = _useState2[0],
|
|
10
|
+
setIsOpen = _useState2[1];
|
|
11
|
+
var resolverRef = React.useRef(undefined);
|
|
12
|
+
var handleClose = useCallback(function (confirm) {
|
|
13
|
+
return function () {
|
|
14
|
+
if (resolverRef.current) {
|
|
15
|
+
resolverRef.current(confirm);
|
|
16
|
+
resolverRef.current = undefined;
|
|
17
|
+
}
|
|
18
|
+
setIsOpen(false);
|
|
19
|
+
};
|
|
20
|
+
}, []);
|
|
21
|
+
var confirmationCallback = useCallback(function () {
|
|
22
|
+
setIsOpen(true);
|
|
23
|
+
var confirmedPromise = new Promise(function (resolve) {
|
|
24
|
+
resolverRef.current = resolve;
|
|
25
|
+
});
|
|
26
|
+
return confirmedPromise;
|
|
27
|
+
}, []);
|
|
28
|
+
useEffect(function () {
|
|
29
|
+
var unregister = syncBlockStoreManager.registerConfirmationCallback(confirmationCallback);
|
|
30
|
+
return function () {
|
|
31
|
+
unregister();
|
|
32
|
+
};
|
|
33
|
+
}, [syncBlockStoreManager, confirmationCallback]);
|
|
34
|
+
return /*#__PURE__*/React.createElement(ModalTransition, null, isOpen && /*#__PURE__*/React.createElement(ModalDialog, {
|
|
35
|
+
onClose: handleClose(false)
|
|
36
|
+
}, /*#__PURE__*/React.createElement(ModalHeader, {
|
|
37
|
+
hasCloseButton: true
|
|
38
|
+
}, /*#__PURE__*/React.createElement(ModalTitle, null, "Confirmation")), /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement("div", null, "Are you sure you want to delete this synced block?")), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
|
|
39
|
+
appearance: "subtle",
|
|
40
|
+
onClick: handleClose(false)
|
|
41
|
+
}, "Cancel"), /*#__PURE__*/React.createElement(Button, {
|
|
42
|
+
appearance: "danger",
|
|
43
|
+
onClick: handleClose(true),
|
|
44
|
+
autoFocus: true
|
|
45
|
+
}, "Delete"))));
|
|
46
|
+
};
|
|
@@ -5,5 +5,5 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
|
5
5
|
import type { SyncedBlockPlugin, SyncedBlockPluginOptions } from '../syncedBlockPluginType';
|
|
6
6
|
export declare const syncedBlockPluginKey: PluginKey<any>;
|
|
7
7
|
type SyncedBlockPluginState = {};
|
|
8
|
-
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams,
|
|
8
|
+
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams, syncBlockStore: SyncBlockStoreManager, api?: ExtractInjectionAPI<SyncedBlockPlugin>) => SafePlugin<SyncedBlockPluginState>;
|
|
9
9
|
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SyncBlockStoreManager } from '@atlaskit/editor-common/sync-block';
|
|
2
|
+
import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { SyncBlockAttrs } from '../../syncedBlockPluginType';
|
|
4
|
+
export declare const trackSyncBlocks: (storeManager: SyncBlockStoreManager, tr: Transaction, state: EditorState) => {
|
|
5
|
+
removed: SyncBlockAttrs[];
|
|
6
|
+
added: SyncBlockAttrs[];
|
|
7
|
+
};
|
|
@@ -5,5 +5,5 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
|
5
5
|
import type { SyncedBlockPlugin, SyncedBlockPluginOptions } from '../syncedBlockPluginType';
|
|
6
6
|
export declare const syncedBlockPluginKey: PluginKey<any>;
|
|
7
7
|
type SyncedBlockPluginState = {};
|
|
8
|
-
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams,
|
|
8
|
+
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams, syncBlockStore: SyncBlockStoreManager, api?: ExtractInjectionAPI<SyncedBlockPlugin>) => SafePlugin<SyncedBlockPluginState>;
|
|
9
9
|
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SyncBlockStoreManager } from '@atlaskit/editor-common/sync-block';
|
|
2
|
+
import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { SyncBlockAttrs } from '../../syncedBlockPluginType';
|
|
4
|
+
export declare const trackSyncBlocks: (storeManager: SyncBlockStoreManager, tr: Transaction, state: EditorState) => {
|
|
5
|
+
removed: SyncBlockAttrs[];
|
|
6
|
+
added: SyncBlockAttrs[];
|
|
7
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,15 +29,17 @@
|
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@atlaskit/adf-schema": "^51.1.2",
|
|
32
|
+
"@atlaskit/button": "23.4.9",
|
|
32
33
|
"@atlaskit/editor-plugin-selection": "^5.0.0",
|
|
33
34
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
34
35
|
"@atlaskit/icon": "28.2.1",
|
|
36
|
+
"@atlaskit/modal-dialog": "^14.3.0",
|
|
35
37
|
"@babel/runtime": "^7.0.0",
|
|
36
38
|
"react-intl-next": "npm:react-intl@^5.18.1",
|
|
37
39
|
"uuid": "^3.1.0"
|
|
38
40
|
},
|
|
39
41
|
"peerDependencies": {
|
|
40
|
-
"@atlaskit/editor-common": "^109.
|
|
42
|
+
"@atlaskit/editor-common": "^109.12.0",
|
|
41
43
|
"react": "^18.2.0"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|