@atlaskit/editor-plugin-block-controls 1.4.11 → 1.4.13
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 +20 -0
- package/dist/cjs/pm-plugins/main.js +5 -2
- package/dist/cjs/ui/drag-handle.js +45 -19
- package/dist/cjs/utils/drag-handle-positions.js +9 -6
- package/dist/es2019/pm-plugins/main.js +5 -2
- package/dist/es2019/ui/drag-handle.js +42 -14
- package/dist/es2019/utils/drag-handle-positions.js +9 -6
- package/dist/esm/pm-plugins/main.js +5 -2
- package/dist/esm/ui/drag-handle.js +45 -19
- package/dist/esm/utils/drag-handle-positions.js +9 -6
- package/dist/types/types.d.ts +7 -1
- package/dist/types/utils/drag-handle-positions.d.ts +1 -1
- package/dist/types-ts4.5/types.d.ts +5 -1
- package/dist/types-ts4.5/utils/drag-handle-positions.d.ts +1 -1
- package/package.json +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 1.4.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#108531](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108531)
|
|
8
|
+
[`bc1dab1f64bd8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/bc1dab1f64bd8) -
|
|
9
|
+
[ux] Don't render decorations when Editor is disabled or in 'view' mode
|
|
10
|
+
- [#110258](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/110258)
|
|
11
|
+
[`e12a40c7d31ee`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e12a40c7d31ee) -
|
|
12
|
+
set selection on drag handle mouse down to ensure drag and drop does not use native behaviour
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 1.4.12
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#108853](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108853)
|
|
20
|
+
[`390f442689fd6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/390f442689fd6) -
|
|
21
|
+
Fix position of drag handle for extension/ bodiedExtension nodes in wide or fullWidth layout
|
|
22
|
+
|
|
3
23
|
## 1.4.11
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -30,7 +30,6 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
30
30
|
},
|
|
31
31
|
apply: function apply(tr, currentState, oldState, newState) {
|
|
32
32
|
var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
|
|
33
|
-
// return currentState;
|
|
34
33
|
var activeNode = currentState.activeNode,
|
|
35
34
|
decorations = currentState.decorations,
|
|
36
35
|
isMenuOpen = currentState.isMenuOpen,
|
|
@@ -115,7 +114,11 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
115
114
|
},
|
|
116
115
|
props: {
|
|
117
116
|
decorations: function decorations(state) {
|
|
118
|
-
var _key$getState;
|
|
117
|
+
var _api$editorDisabled, _key$getState;
|
|
118
|
+
var isDisabled = api === null || api === void 0 || (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 || (_api$editorDisabled = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled === void 0 ? void 0 : _api$editorDisabled.editorDisabled;
|
|
119
|
+
if (isDisabled) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
119
122
|
return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
|
|
120
123
|
}
|
|
121
124
|
},
|
|
@@ -8,6 +8,7 @@ exports.DragHandle = void 0;
|
|
|
8
8
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
9
|
var _react = require("react");
|
|
10
10
|
var _react2 = require("@emotion/react");
|
|
11
|
+
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
11
12
|
var _dragHandler = _interopRequireDefault(require("@atlaskit/icon/glyph/drag-handler"));
|
|
12
13
|
var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
|
|
13
14
|
var _setCustomNativeDragPreview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
|
|
@@ -57,7 +58,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
|
57
58
|
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
58
59
|
dragHandleSelected = _useState2[0],
|
|
59
60
|
setDragHandleSelected = _useState2[1];
|
|
60
|
-
var
|
|
61
|
+
var _useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['featureFlags']),
|
|
62
|
+
featureFlagsState = _useSharedPluginState.featureFlagsState;
|
|
63
|
+
var handleOnClick = (0, _react.useCallback)(function () {
|
|
61
64
|
var _api$core, _api$core2;
|
|
62
65
|
setDragHandleSelected(!dragHandleSelected);
|
|
63
66
|
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
|
|
@@ -73,6 +76,25 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
|
73
76
|
});
|
|
74
77
|
api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
|
|
75
78
|
}, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
|
|
79
|
+
|
|
80
|
+
// handleMouseDown required along with onClick to ensure the correct selection
|
|
81
|
+
// is set immediately when the drag handle is clicked. Otherwise browser native
|
|
82
|
+
// drag and drop can take over and cause unpredictable behaviour.
|
|
83
|
+
var handleMouseDown = (0, _react.useCallback)(function () {
|
|
84
|
+
var _api$core3, _api$core4;
|
|
85
|
+
api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref3) {
|
|
86
|
+
var tr = _ref3.tr;
|
|
87
|
+
if (start === undefined) {
|
|
88
|
+
return tr;
|
|
89
|
+
}
|
|
90
|
+
tr = (0, _utils.selectNode)(tr, start, nodeType);
|
|
91
|
+
tr.setMeta(_main.key, {
|
|
92
|
+
pos: start
|
|
93
|
+
});
|
|
94
|
+
return tr;
|
|
95
|
+
});
|
|
96
|
+
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
|
|
97
|
+
}, [start, api, nodeType]);
|
|
76
98
|
(0, _react.useEffect)(function () {
|
|
77
99
|
var element = buttonRef.current;
|
|
78
100
|
if (!element) {
|
|
@@ -80,11 +102,11 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
|
80
102
|
}
|
|
81
103
|
return (0, _adapter.draggable)({
|
|
82
104
|
element: element,
|
|
83
|
-
onGenerateDragPreview: function onGenerateDragPreview(
|
|
84
|
-
var nativeSetDragImage =
|
|
105
|
+
onGenerateDragPreview: function onGenerateDragPreview(_ref4) {
|
|
106
|
+
var nativeSetDragImage = _ref4.nativeSetDragImage;
|
|
85
107
|
(0, _setCustomNativeDragPreview.setCustomNativeDragPreview)({
|
|
86
|
-
render: function render(
|
|
87
|
-
var container =
|
|
108
|
+
render: function render(_ref5) {
|
|
109
|
+
var container = _ref5.container;
|
|
88
110
|
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
|
|
89
111
|
if (!dom) {
|
|
90
112
|
return;
|
|
@@ -95,17 +117,17 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
|
95
117
|
});
|
|
96
118
|
},
|
|
97
119
|
onDragStart: function onDragStart() {
|
|
98
|
-
var _api$
|
|
120
|
+
var _api$core5, _api$blockControls, _api$core6;
|
|
99
121
|
if (start === undefined) {
|
|
100
122
|
return;
|
|
101
123
|
}
|
|
102
|
-
api === null || api === void 0 || (_api$
|
|
103
|
-
api === null || api === void 0 || (_api$
|
|
124
|
+
api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
|
|
125
|
+
api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.focus();
|
|
104
126
|
},
|
|
105
127
|
onDrop: function onDrop() {
|
|
106
|
-
var _api$
|
|
107
|
-
api === null || api === void 0 || (_api$
|
|
108
|
-
var tr =
|
|
128
|
+
var _api$core7;
|
|
129
|
+
api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref6) {
|
|
130
|
+
var tr = _ref6.tr;
|
|
109
131
|
return tr.setMeta(_main.key, {
|
|
110
132
|
isDragging: false
|
|
111
133
|
});
|
|
@@ -113,30 +135,34 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
|
113
135
|
}
|
|
114
136
|
});
|
|
115
137
|
}, [api, start, view, anchorName, nodeType]);
|
|
138
|
+
var macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
|
|
116
139
|
var positionStyles = (0, _react.useMemo)(function () {
|
|
117
140
|
var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
|
|
118
141
|
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
|
|
142
|
+
if (!dom) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
var hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
|
|
146
|
+
var isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
|
|
147
|
+
var innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
|
|
119
148
|
if (supportsAnchor) {
|
|
120
|
-
var hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
|
|
121
149
|
return {
|
|
122
|
-
left: hasResizer ? (0, _dragHandlePositions.getLeftPosition)(dom, nodeType) : "calc(anchor(".concat(anchorName, " start) - ").concat(_consts.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts.dragHandleGap)(nodeType), "px)"),
|
|
150
|
+
left: hasResizer || isExtension ? (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, macroInteractionUpdates) : "calc(anchor(".concat(anchorName, " start) - ").concat(_consts.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts.dragHandleGap)(nodeType), "px)"),
|
|
123
151
|
top: anchorName.includes('table') ? "calc(anchor(".concat(anchorName, " start) + ").concat(_consts.DRAG_HANDLE_HEIGHT, "px)") : "anchor(".concat(anchorName, " start)")
|
|
124
152
|
};
|
|
125
153
|
}
|
|
126
|
-
if (!dom) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
154
|
return {
|
|
130
|
-
left: (0, _dragHandlePositions.getLeftPosition)(dom, nodeType),
|
|
155
|
+
left: (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, macroInteractionUpdates),
|
|
131
156
|
top: (0, _dragHandlePositions.getTopPosition)(dom)
|
|
132
157
|
};
|
|
133
|
-
}, [anchorName, view, nodeType]);
|
|
158
|
+
}, [anchorName, view, nodeType, macroInteractionUpdates]);
|
|
134
159
|
return (0, _react2.jsx)("button", {
|
|
135
160
|
type: "button",
|
|
136
161
|
css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
|
|
137
162
|
ref: buttonRef,
|
|
138
163
|
style: positionStyles,
|
|
139
|
-
onClick:
|
|
164
|
+
onClick: handleOnClick,
|
|
165
|
+
onMouseDown: handleMouseDown,
|
|
140
166
|
"data-testid": "block-ctrl-drag-handle"
|
|
141
167
|
}, (0, _react2.jsx)(_dragHandler.default, {
|
|
142
168
|
label: "",
|
|
@@ -13,11 +13,14 @@ var getTopPosition = exports.getTopPosition = function getTopPosition(dom) {
|
|
|
13
13
|
return "".concat(dom.offsetTop, "px");
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
|
-
var getLeftPosition = exports.getLeftPosition = function getLeftPosition(dom, type) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (resizer) {
|
|
20
|
-
left = getComputedStyle(resizer).transform === 'none' ? "".concat(resizer.offsetLeft - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px") : "".concat(resizer.offsetLeft - resizer.offsetWidth / 2 - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
|
|
16
|
+
var getLeftPosition = exports.getLeftPosition = function getLeftPosition(dom, type, innerContainer, macroInteractionUpdates) {
|
|
17
|
+
if (!innerContainer) {
|
|
18
|
+
return "".concat(dom.offsetLeft - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
|
|
21
19
|
}
|
|
22
|
-
|
|
20
|
+
|
|
21
|
+
// There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
|
|
22
|
+
// We need to adjust the left offset position of the drag handle to account for the relative span
|
|
23
|
+
var relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
|
|
24
|
+
var leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
|
|
25
|
+
return getComputedStyle(innerContainer).transform === 'none' ? "".concat(innerContainer.offsetLeft + leftAdjustment - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px") : "".concat(innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
|
|
23
26
|
};
|
|
@@ -22,7 +22,6 @@ export const createPlugin = api => {
|
|
|
22
22
|
},
|
|
23
23
|
apply(tr, currentState, oldState, newState) {
|
|
24
24
|
var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
|
|
25
|
-
// return currentState;
|
|
26
25
|
let {
|
|
27
26
|
activeNode,
|
|
28
27
|
decorations,
|
|
@@ -109,7 +108,11 @@ export const createPlugin = api => {
|
|
|
109
108
|
},
|
|
110
109
|
props: {
|
|
111
110
|
decorations: state => {
|
|
112
|
-
var _key$getState;
|
|
111
|
+
var _api$editorDisabled, _api$editorDisabled$s, _key$getState;
|
|
112
|
+
const isDisabled = api === null || api === void 0 ? void 0 : (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 ? void 0 : (_api$editorDisabled$s = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled$s === void 0 ? void 0 : _api$editorDisabled$s.editorDisabled;
|
|
113
|
+
if (isDisabled) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
113
116
|
return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
|
|
114
117
|
}
|
|
115
118
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { css, jsx } from '@emotion/react';
|
|
4
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
4
5
|
import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
|
|
5
6
|
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
6
7
|
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
|
|
@@ -46,7 +47,10 @@ export const DragHandle = ({
|
|
|
46
47
|
const start = getPos();
|
|
47
48
|
const buttonRef = useRef(null);
|
|
48
49
|
const [dragHandleSelected, setDragHandleSelected] = useState(false);
|
|
49
|
-
const
|
|
50
|
+
const {
|
|
51
|
+
featureFlagsState
|
|
52
|
+
} = useSharedPluginState(api, ['featureFlags']);
|
|
53
|
+
const handleOnClick = useCallback(() => {
|
|
50
54
|
var _api$core, _api$core2;
|
|
51
55
|
setDragHandleSelected(!dragHandleSelected);
|
|
52
56
|
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
|
|
@@ -63,6 +67,26 @@ export const DragHandle = ({
|
|
|
63
67
|
});
|
|
64
68
|
api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.focus();
|
|
65
69
|
}, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
|
|
70
|
+
|
|
71
|
+
// handleMouseDown required along with onClick to ensure the correct selection
|
|
72
|
+
// is set immediately when the drag handle is clicked. Otherwise browser native
|
|
73
|
+
// drag and drop can take over and cause unpredictable behaviour.
|
|
74
|
+
const handleMouseDown = useCallback(() => {
|
|
75
|
+
var _api$core3, _api$core4;
|
|
76
|
+
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({
|
|
77
|
+
tr
|
|
78
|
+
}) => {
|
|
79
|
+
if (start === undefined) {
|
|
80
|
+
return tr;
|
|
81
|
+
}
|
|
82
|
+
tr = selectNode(tr, start, nodeType);
|
|
83
|
+
tr.setMeta(key, {
|
|
84
|
+
pos: start
|
|
85
|
+
});
|
|
86
|
+
return tr;
|
|
87
|
+
});
|
|
88
|
+
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.focus();
|
|
89
|
+
}, [start, api, nodeType]);
|
|
66
90
|
useEffect(() => {
|
|
67
91
|
const element = buttonRef.current;
|
|
68
92
|
if (!element) {
|
|
@@ -87,16 +111,16 @@ export const DragHandle = ({
|
|
|
87
111
|
});
|
|
88
112
|
},
|
|
89
113
|
onDragStart() {
|
|
90
|
-
var _api$
|
|
114
|
+
var _api$core5, _api$blockControls, _api$core6;
|
|
91
115
|
if (start === undefined) {
|
|
92
116
|
return;
|
|
93
117
|
}
|
|
94
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
95
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
118
|
+
api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
|
|
119
|
+
api === null || api === void 0 ? void 0 : (_api$core6 = api.core) === null || _api$core6 === void 0 ? void 0 : _api$core6.actions.focus();
|
|
96
120
|
},
|
|
97
121
|
onDrop() {
|
|
98
|
-
var _api$
|
|
99
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
122
|
+
var _api$core7;
|
|
123
|
+
api === null || api === void 0 ? void 0 : (_api$core7 = api.core) === null || _api$core7 === void 0 ? void 0 : _api$core7.actions.execute(({
|
|
100
124
|
tr
|
|
101
125
|
}) => {
|
|
102
126
|
return tr.setMeta(key, {
|
|
@@ -106,30 +130,34 @@ export const DragHandle = ({
|
|
|
106
130
|
}
|
|
107
131
|
});
|
|
108
132
|
}, [api, start, view, anchorName, nodeType]);
|
|
133
|
+
const macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
|
|
109
134
|
const positionStyles = useMemo(() => {
|
|
110
135
|
const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
|
|
111
136
|
const dom = view.dom.querySelector(`[data-drag-handler-anchor-name="${anchorName}"]`);
|
|
137
|
+
if (!dom) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
|
|
141
|
+
const isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
|
|
142
|
+
const innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
|
|
112
143
|
if (supportsAnchor) {
|
|
113
|
-
const hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
|
|
114
144
|
return {
|
|
115
|
-
left: hasResizer ? getLeftPosition(dom, nodeType) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
|
|
145
|
+
left: hasResizer || isExtension ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
|
|
116
146
|
top: anchorName.includes('table') ? `calc(anchor(${anchorName} start) + ${DRAG_HANDLE_HEIGHT}px)` : `anchor(${anchorName} start)`
|
|
117
147
|
};
|
|
118
148
|
}
|
|
119
|
-
if (!dom) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
149
|
return {
|
|
123
|
-
left: getLeftPosition(dom, nodeType),
|
|
150
|
+
left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
|
|
124
151
|
top: getTopPosition(dom)
|
|
125
152
|
};
|
|
126
|
-
}, [anchorName, view, nodeType]);
|
|
153
|
+
}, [anchorName, view, nodeType, macroInteractionUpdates]);
|
|
127
154
|
return jsx("button", {
|
|
128
155
|
type: "button",
|
|
129
156
|
css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
|
|
130
157
|
ref: buttonRef,
|
|
131
158
|
style: positionStyles,
|
|
132
|
-
onClick:
|
|
159
|
+
onClick: handleOnClick,
|
|
160
|
+
onMouseDown: handleMouseDown,
|
|
133
161
|
"data-testid": "block-ctrl-drag-handle"
|
|
134
162
|
}, jsx(DragHandlerIcon, {
|
|
135
163
|
label: "",
|
|
@@ -7,11 +7,14 @@ export const getTopPosition = dom => {
|
|
|
7
7
|
return `${dom.offsetTop}px`;
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
|
-
export const getLeftPosition = (dom, type) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (resizer) {
|
|
14
|
-
left = getComputedStyle(resizer).transform === 'none' ? `${resizer.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px` : `${resizer.offsetLeft - resizer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
|
|
10
|
+
export const getLeftPosition = (dom, type, innerContainer, macroInteractionUpdates) => {
|
|
11
|
+
if (!innerContainer) {
|
|
12
|
+
return `${dom.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
|
|
15
13
|
}
|
|
16
|
-
|
|
14
|
+
|
|
15
|
+
// There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
|
|
16
|
+
// We need to adjust the left offset position of the drag handle to account for the relative span
|
|
17
|
+
const relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
|
|
18
|
+
const leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
|
|
19
|
+
return getComputedStyle(innerContainer).transform === 'none' ? `${innerContainer.offsetLeft + leftAdjustment - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px` : `${innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
|
|
17
20
|
};
|
|
@@ -23,7 +23,6 @@ export var createPlugin = function createPlugin(api) {
|
|
|
23
23
|
},
|
|
24
24
|
apply: function apply(tr, currentState, oldState, newState) {
|
|
25
25
|
var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
|
|
26
|
-
// return currentState;
|
|
27
26
|
var activeNode = currentState.activeNode,
|
|
28
27
|
decorations = currentState.decorations,
|
|
29
28
|
isMenuOpen = currentState.isMenuOpen,
|
|
@@ -108,7 +107,11 @@ export var createPlugin = function createPlugin(api) {
|
|
|
108
107
|
},
|
|
109
108
|
props: {
|
|
110
109
|
decorations: function decorations(state) {
|
|
111
|
-
var _key$getState;
|
|
110
|
+
var _api$editorDisabled, _key$getState;
|
|
111
|
+
var isDisabled = api === null || api === void 0 || (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 || (_api$editorDisabled = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled === void 0 ? void 0 : _api$editorDisabled.editorDisabled;
|
|
112
|
+
if (isDisabled) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
112
115
|
return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
|
|
113
116
|
}
|
|
114
117
|
},
|
|
@@ -2,6 +2,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
2
2
|
/** @jsx jsx */
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { css, jsx } from '@emotion/react';
|
|
5
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
5
6
|
import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
|
|
6
7
|
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
8
|
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
|
|
@@ -49,7 +50,9 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
49
50
|
_useState2 = _slicedToArray(_useState, 2),
|
|
50
51
|
dragHandleSelected = _useState2[0],
|
|
51
52
|
setDragHandleSelected = _useState2[1];
|
|
52
|
-
var
|
|
53
|
+
var _useSharedPluginState = useSharedPluginState(api, ['featureFlags']),
|
|
54
|
+
featureFlagsState = _useSharedPluginState.featureFlagsState;
|
|
55
|
+
var handleOnClick = useCallback(function () {
|
|
53
56
|
var _api$core, _api$core2;
|
|
54
57
|
setDragHandleSelected(!dragHandleSelected);
|
|
55
58
|
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
|
|
@@ -65,6 +68,25 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
65
68
|
});
|
|
66
69
|
api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
|
|
67
70
|
}, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
|
|
71
|
+
|
|
72
|
+
// handleMouseDown required along with onClick to ensure the correct selection
|
|
73
|
+
// is set immediately when the drag handle is clicked. Otherwise browser native
|
|
74
|
+
// drag and drop can take over and cause unpredictable behaviour.
|
|
75
|
+
var handleMouseDown = useCallback(function () {
|
|
76
|
+
var _api$core3, _api$core4;
|
|
77
|
+
api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref3) {
|
|
78
|
+
var tr = _ref3.tr;
|
|
79
|
+
if (start === undefined) {
|
|
80
|
+
return tr;
|
|
81
|
+
}
|
|
82
|
+
tr = selectNode(tr, start, nodeType);
|
|
83
|
+
tr.setMeta(key, {
|
|
84
|
+
pos: start
|
|
85
|
+
});
|
|
86
|
+
return tr;
|
|
87
|
+
});
|
|
88
|
+
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
|
|
89
|
+
}, [start, api, nodeType]);
|
|
68
90
|
useEffect(function () {
|
|
69
91
|
var element = buttonRef.current;
|
|
70
92
|
if (!element) {
|
|
@@ -72,11 +94,11 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
72
94
|
}
|
|
73
95
|
return draggable({
|
|
74
96
|
element: element,
|
|
75
|
-
onGenerateDragPreview: function onGenerateDragPreview(
|
|
76
|
-
var nativeSetDragImage =
|
|
97
|
+
onGenerateDragPreview: function onGenerateDragPreview(_ref4) {
|
|
98
|
+
var nativeSetDragImage = _ref4.nativeSetDragImage;
|
|
77
99
|
setCustomNativeDragPreview({
|
|
78
|
-
render: function render(
|
|
79
|
-
var container =
|
|
100
|
+
render: function render(_ref5) {
|
|
101
|
+
var container = _ref5.container;
|
|
80
102
|
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
|
|
81
103
|
if (!dom) {
|
|
82
104
|
return;
|
|
@@ -87,17 +109,17 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
87
109
|
});
|
|
88
110
|
},
|
|
89
111
|
onDragStart: function onDragStart() {
|
|
90
|
-
var _api$
|
|
112
|
+
var _api$core5, _api$blockControls, _api$core6;
|
|
91
113
|
if (start === undefined) {
|
|
92
114
|
return;
|
|
93
115
|
}
|
|
94
|
-
api === null || api === void 0 || (_api$
|
|
95
|
-
api === null || api === void 0 || (_api$
|
|
116
|
+
api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
|
|
117
|
+
api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.focus();
|
|
96
118
|
},
|
|
97
119
|
onDrop: function onDrop() {
|
|
98
|
-
var _api$
|
|
99
|
-
api === null || api === void 0 || (_api$
|
|
100
|
-
var tr =
|
|
120
|
+
var _api$core7;
|
|
121
|
+
api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref6) {
|
|
122
|
+
var tr = _ref6.tr;
|
|
101
123
|
return tr.setMeta(key, {
|
|
102
124
|
isDragging: false
|
|
103
125
|
});
|
|
@@ -105,30 +127,34 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
105
127
|
}
|
|
106
128
|
});
|
|
107
129
|
}, [api, start, view, anchorName, nodeType]);
|
|
130
|
+
var macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
|
|
108
131
|
var positionStyles = useMemo(function () {
|
|
109
132
|
var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
|
|
110
133
|
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
|
|
134
|
+
if (!dom) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
var hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
|
|
138
|
+
var isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
|
|
139
|
+
var innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
|
|
111
140
|
if (supportsAnchor) {
|
|
112
|
-
var hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
|
|
113
141
|
return {
|
|
114
|
-
left: hasResizer ? getLeftPosition(dom, nodeType) : "calc(anchor(".concat(anchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType), "px)"),
|
|
142
|
+
left: hasResizer || isExtension ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : "calc(anchor(".concat(anchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType), "px)"),
|
|
115
143
|
top: anchorName.includes('table') ? "calc(anchor(".concat(anchorName, " start) + ").concat(DRAG_HANDLE_HEIGHT, "px)") : "anchor(".concat(anchorName, " start)")
|
|
116
144
|
};
|
|
117
145
|
}
|
|
118
|
-
if (!dom) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
146
|
return {
|
|
122
|
-
left: getLeftPosition(dom, nodeType),
|
|
147
|
+
left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
|
|
123
148
|
top: getTopPosition(dom)
|
|
124
149
|
};
|
|
125
|
-
}, [anchorName, view, nodeType]);
|
|
150
|
+
}, [anchorName, view, nodeType, macroInteractionUpdates]);
|
|
126
151
|
return jsx("button", {
|
|
127
152
|
type: "button",
|
|
128
153
|
css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
|
|
129
154
|
ref: buttonRef,
|
|
130
155
|
style: positionStyles,
|
|
131
|
-
onClick:
|
|
156
|
+
onClick: handleOnClick,
|
|
157
|
+
onMouseDown: handleMouseDown,
|
|
132
158
|
"data-testid": "block-ctrl-drag-handle"
|
|
133
159
|
}, jsx(DragHandlerIcon, {
|
|
134
160
|
label: "",
|
|
@@ -7,11 +7,14 @@ export var getTopPosition = function getTopPosition(dom) {
|
|
|
7
7
|
return "".concat(dom.offsetTop, "px");
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
|
-
export var getLeftPosition = function getLeftPosition(dom, type) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (resizer) {
|
|
14
|
-
left = getComputedStyle(resizer).transform === 'none' ? "".concat(resizer.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px") : "".concat(resizer.offsetLeft - resizer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
|
|
10
|
+
export var getLeftPosition = function getLeftPosition(dom, type, innerContainer, macroInteractionUpdates) {
|
|
11
|
+
if (!innerContainer) {
|
|
12
|
+
return "".concat(dom.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
|
|
15
13
|
}
|
|
16
|
-
|
|
14
|
+
|
|
15
|
+
// There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
|
|
16
|
+
// We need to adjust the left offset position of the drag handle to account for the relative span
|
|
17
|
+
var relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
|
|
18
|
+
var leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
|
|
19
|
+
return getComputedStyle(innerContainer).transform === 'none' ? "".concat(innerContainer.offsetLeft + leftAdjustment - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px") : "".concat(innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
|
|
17
20
|
};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
|
|
3
|
+
import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
|
|
2
4
|
import type { WidthPlugin } from '@atlaskit/editor-plugin-width';
|
|
3
5
|
import { type DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
4
6
|
export interface PluginState {
|
|
@@ -15,7 +17,11 @@ export interface PluginState {
|
|
|
15
17
|
}
|
|
16
18
|
export type ReleaseHiddenDecoration = () => boolean | undefined;
|
|
17
19
|
export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
18
|
-
dependencies: [
|
|
20
|
+
dependencies: [
|
|
21
|
+
OptionalPlugin<EditorDisabledPlugin>,
|
|
22
|
+
OptionalPlugin<WidthPlugin>,
|
|
23
|
+
OptionalPlugin<FeatureFlagsPlugin>
|
|
24
|
+
];
|
|
19
25
|
sharedState: {
|
|
20
26
|
isMenuOpen: boolean;
|
|
21
27
|
activeNode: {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const getTopPosition: (dom: HTMLElement) => string;
|
|
2
|
-
export declare const getLeftPosition: (dom: HTMLElement, type: string) => string;
|
|
2
|
+
export declare const getLeftPosition: (dom: HTMLElement, type: string, innerContainer?: HTMLElement | null, macroInteractionUpdates?: boolean) => string;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
|
|
3
|
+
import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
|
|
2
4
|
import type { WidthPlugin } from '@atlaskit/editor-plugin-width';
|
|
3
5
|
import { type DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
4
6
|
export interface PluginState {
|
|
@@ -16,7 +18,9 @@ export interface PluginState {
|
|
|
16
18
|
export type ReleaseHiddenDecoration = () => boolean | undefined;
|
|
17
19
|
export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
18
20
|
dependencies: [
|
|
19
|
-
OptionalPlugin<
|
|
21
|
+
OptionalPlugin<EditorDisabledPlugin>,
|
|
22
|
+
OptionalPlugin<WidthPlugin>,
|
|
23
|
+
OptionalPlugin<FeatureFlagsPlugin>
|
|
20
24
|
];
|
|
21
25
|
sharedState: {
|
|
22
26
|
isMenuOpen: boolean;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const getTopPosition: (dom: HTMLElement) => string;
|
|
2
|
-
export declare const getLeftPosition: (dom: HTMLElement, type: string) => string;
|
|
2
|
+
export declare const getLeftPosition: (dom: HTMLElement, type: string, innerContainer?: HTMLElement | null, macroInteractionUpdates?: boolean) => string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.13",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
".": "./src/index.ts"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@atlaskit/editor-common": "^82.
|
|
34
|
+
"@atlaskit/editor-common": "^82.3.0",
|
|
35
|
+
"@atlaskit/editor-plugin-editor-disabled": "^1.1.5",
|
|
36
|
+
"@atlaskit/editor-plugin-feature-flags": "^1.1.0",
|
|
35
37
|
"@atlaskit/editor-plugin-width": "^1.1.0",
|
|
36
38
|
"@atlaskit/editor-prosemirror": "4.0.1",
|
|
37
39
|
"@atlaskit/editor-tables": "^2.7.0",
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
"@atlaskit/pragmatic-drag-and-drop": "^1.1.0",
|
|
40
42
|
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.3.0",
|
|
41
43
|
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
|
|
42
|
-
"@atlaskit/tokens": "^1.
|
|
44
|
+
"@atlaskit/tokens": "^1.50.0",
|
|
43
45
|
"@babel/runtime": "^7.0.0",
|
|
44
46
|
"@emotion/react": "^11.7.1",
|
|
45
47
|
"raf-schd": "^4.0.3"
|