@atlaskit/editor-plugin-block-controls 7.5.5 → 7.5.6
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 +8 -0
- package/dist/cjs/pm-plugins/decorations-drop-target.js +4 -1
- package/dist/cjs/ui/drop-target-layout.js +115 -2
- package/dist/es2019/pm-plugins/decorations-drop-target.js +5 -2
- package/dist/es2019/ui/drop-target-layout.js +114 -2
- package/dist/esm/pm-plugins/decorations-drop-target.js +5 -2
- package/dist/esm/ui/drop-target-layout.js +115 -2
- package/dist/types/ui/drop-target-layout.d.ts +3 -0
- package/dist/types-ts4.5/ui/drop-target-layout.d.ts +3 -0
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 7.5.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`945cca63ae433`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/945cca63ae433) -
|
|
8
|
+
ED-29335: Fixed drop hints height not right for layout column inline drop targets
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 7.5.5
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -11,6 +11,8 @@ var _uuid = _interopRequireDefault(require("uuid"));
|
|
|
11
11
|
var _selection = require("@atlaskit/editor-common/selection");
|
|
12
12
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
13
13
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
14
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
15
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
14
16
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
15
17
|
var _consts = require("../ui/consts");
|
|
16
18
|
var _dropTarget = require("../ui/drop-target");
|
|
@@ -136,8 +138,9 @@ var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration
|
|
|
136
138
|
element.setAttribute('data-blocks-drop-target-container', 'true');
|
|
137
139
|
element.setAttribute('data-blocks-drop-target-key', key);
|
|
138
140
|
element.style.clear = 'unset';
|
|
141
|
+
var DropTargetLayoutComponent = (0, _expValEquals.expValEquals)('platform_editor_native_anchor_support', 'isEnabled', true) && (0, _platformFeatureFlags.fg)('editor_native_anchor_update_layout_drop_hint') ? _dropTargetLayout.DropTargetLayoutNativeAnchorSupport : _dropTargetLayout.DropTargetLayout;
|
|
139
142
|
nodeViewPortalProviderAPI.render(function () {
|
|
140
|
-
return /*#__PURE__*/(0, _react.createElement)(
|
|
143
|
+
return /*#__PURE__*/(0, _react.createElement)(DropTargetLayoutComponent, _objectSpread(_objectSpread({}, props), {}, {
|
|
141
144
|
getPos: getPos,
|
|
142
145
|
anchorRectCache: anchorRectCache
|
|
143
146
|
}));
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.DropTargetLayout = void 0;
|
|
7
|
+
exports.DropTargetLayoutNativeAnchorSupport = exports.DropTargetLayout = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
10
|
var _react = require("react");
|
|
@@ -130,9 +130,122 @@ var DropTargetLayout = exports.DropTargetLayout = function DropTargetLayout(prop
|
|
|
130
130
|
edge: "right",
|
|
131
131
|
gap: "-".concat(DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH, "px")
|
|
132
132
|
}) : (isActiveAnchor || (0, _expValEquals.expValEquals)('platform_editor_native_anchor_support', 'isEnabled', true)) && (0, _react2.jsx)("div", {
|
|
133
|
-
"data-testid": "block-ctrl-drop-hint"
|
|
133
|
+
"data-testid": "block-ctrl-drop-hint",
|
|
134
|
+
css: dropTargetLayoutHintStyle
|
|
135
|
+
}));
|
|
136
|
+
};
|
|
137
|
+
var DropTargetLayoutNativeAnchorSupport = exports.DropTargetLayoutNativeAnchorSupport = function DropTargetLayoutNativeAnchorSupport(props) {
|
|
138
|
+
var _api$blockControls3;
|
|
139
|
+
var api = props.api,
|
|
140
|
+
getPos = props.getPos,
|
|
141
|
+
parent = props.parent,
|
|
142
|
+
anchorRectCache = props.anchorRectCache;
|
|
143
|
+
var ref = (0, _react.useRef)(null);
|
|
144
|
+
var _useState3 = (0, _react.useState)(false),
|
|
145
|
+
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
146
|
+
isDraggedOver = _useState4[0],
|
|
147
|
+
setIsDraggedOver = _useState4[1];
|
|
148
|
+
var anchorName = (0, _decorationsCommon.getNodeAnchor)(parent);
|
|
149
|
+
var _useState5 = (0, _react.useState)(null),
|
|
150
|
+
_useState6 = (0, _slicedToArray2.default)(_useState5, 2),
|
|
151
|
+
nextNodeAnchorName = _useState6[0],
|
|
152
|
+
setNextNodeAnchorName = _useState6[1];
|
|
153
|
+
var readNextNodeAnchor = (0, _react.useCallback)(function () {
|
|
154
|
+
var _ref$current2, _nextElementSibling$g;
|
|
155
|
+
var nextElementSibling = (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || (_ref$current2 = _ref$current2.parentElement) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.nextElementSibling;
|
|
156
|
+
var attrName = (0, _domAttrName.getAnchorAttrName)();
|
|
157
|
+
var nextAnchorName = (_nextElementSibling$g = nextElementSibling === null || nextElementSibling === void 0 ? void 0 : nextElementSibling.getAttribute(attrName)) !== null && _nextElementSibling$g !== void 0 ? _nextElementSibling$g : null;
|
|
158
|
+
setNextNodeAnchorName(function (prev) {
|
|
159
|
+
return prev === nextAnchorName ? prev : nextAnchorName;
|
|
160
|
+
});
|
|
161
|
+
}, []);
|
|
162
|
+
var height = (0, _react.useMemo)(function () {
|
|
163
|
+
if (nextNodeAnchorName) {
|
|
164
|
+
if ((0, _anchorUtils.isAnchorSupported)()) {
|
|
165
|
+
return "anchor-size(".concat(nextNodeAnchorName, " height)");
|
|
166
|
+
} else if (anchorRectCache) {
|
|
167
|
+
var layoutColumnRect = anchorRectCache.getRect(nextNodeAnchorName);
|
|
168
|
+
return "".concat((layoutColumnRect === null || layoutColumnRect === void 0 ? void 0 : layoutColumnRect.height) || 0, "px");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Stacked mode fallback: minimal height to avoid oversized hint on first render
|
|
172
|
+
return '0px';
|
|
173
|
+
}, [nextNodeAnchorName, anchorRectCache]);
|
|
174
|
+
(0, _react.useLayoutEffect)(function () {
|
|
175
|
+
var raf = requestAnimationFrame(function () {
|
|
176
|
+
readNextNodeAnchor();
|
|
177
|
+
});
|
|
178
|
+
return function () {
|
|
179
|
+
return cancelAnimationFrame(raf);
|
|
180
|
+
};
|
|
181
|
+
}, [readNextNodeAnchor]);
|
|
182
|
+
var dropTargetStackLayoutHintStyle = (0, _react2.css)((0, _defineProperty2.default)({}, "@container layout-area (max-width:".concat(_editorSharedStyles.layoutBreakpointWidth.MEDIUM - 1, "px)"), {
|
|
183
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
|
|
184
|
+
height: height,
|
|
185
|
+
marginTop: "var(--ds-space-050, 4px)"
|
|
186
|
+
}));
|
|
187
|
+
var _useActiveAnchorTrack3 = (0, _activeAnchorTracker.useActiveAnchorTracker)(anchorName),
|
|
188
|
+
_useActiveAnchorTrack4 = (0, _slicedToArray2.default)(_useActiveAnchorTrack3, 1),
|
|
189
|
+
isActiveAnchor = _useActiveAnchorTrack4[0];
|
|
190
|
+
var _ref4 = (api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.sharedState.currentState()) || {},
|
|
191
|
+
activeNode = _ref4.activeNode;
|
|
192
|
+
var onDrop = (0, _react.useCallback)(function () {
|
|
193
|
+
if (!activeNode) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
var to = getPos();
|
|
197
|
+
var mappedTo;
|
|
198
|
+
if (to !== undefined) {
|
|
199
|
+
var _api$core3, _api$core4;
|
|
200
|
+
var from = activeNode.pos;
|
|
201
|
+
api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref5) {
|
|
202
|
+
var _api$blockControls4;
|
|
203
|
+
var tr = _ref5.tr;
|
|
204
|
+
api === null || api === void 0 || (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 || (_api$blockControls4 = _api$blockControls4.commands) === null || _api$blockControls4 === void 0 || _api$blockControls4.moveToLayout(from, to)({
|
|
205
|
+
tr: tr
|
|
206
|
+
});
|
|
207
|
+
var insertColumnStep = (0, _updateSelection.getInsertLayoutStep)(tr);
|
|
208
|
+
mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
|
|
209
|
+
return tr;
|
|
210
|
+
});
|
|
211
|
+
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref6) {
|
|
212
|
+
var tr = _ref6.tr;
|
|
213
|
+
if (mappedTo !== undefined) {
|
|
214
|
+
(0, _updateSelection.updateSelection)(tr, mappedTo);
|
|
215
|
+
}
|
|
216
|
+
return tr;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}, [api, getPos, activeNode]);
|
|
220
|
+
(0, _react.useEffect)(function () {
|
|
221
|
+
if (ref.current) {
|
|
222
|
+
return (0, _adapter.dropTargetForElements)({
|
|
223
|
+
element: ref.current,
|
|
224
|
+
onDragEnter: function onDragEnter() {
|
|
225
|
+
setIsDraggedOver(true);
|
|
226
|
+
readNextNodeAnchor();
|
|
227
|
+
},
|
|
228
|
+
onDragLeave: function onDragLeave() {
|
|
229
|
+
setIsDraggedOver(false);
|
|
230
|
+
},
|
|
231
|
+
onDrop: onDrop
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}, [onDrop, readNextNodeAnchor]);
|
|
235
|
+
if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) === 'layoutSection') {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return (0, _react2.jsx)("div", {
|
|
239
|
+
ref: ref
|
|
134
240
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
135
241
|
,
|
|
242
|
+
css: [dropTargetLayoutStyle, dropTargetStackLayoutHintStyle],
|
|
243
|
+
"data-testid": "block-ctrl-drop-indicator"
|
|
244
|
+
}, isDraggedOver ? (0, _react2.jsx)(_box.DropIndicator, {
|
|
245
|
+
edge: "right",
|
|
246
|
+
gap: "-".concat(DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH, "px")
|
|
247
|
+
}) : (isActiveAnchor || (0, _expValEquals.expValEquals)('platform_editor_native_anchor_support', 'isEnabled', true)) && (0, _react2.jsx)("div", {
|
|
248
|
+
"data-testid": "block-ctrl-drop-hint",
|
|
136
249
|
css: dropTargetLayoutHintStyle
|
|
137
250
|
}));
|
|
138
251
|
};
|
|
@@ -4,10 +4,12 @@ import uuid from 'uuid';
|
|
|
4
4
|
import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
5
5
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
6
6
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
9
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
8
10
|
import { nodeMargins } from '../ui/consts';
|
|
9
11
|
import { DropTarget, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target';
|
|
10
|
-
import { DropTargetLayout } from '../ui/drop-target-layout';
|
|
12
|
+
import { DropTargetLayout, DropTargetLayoutNativeAnchorSupport } from '../ui/drop-target-layout';
|
|
11
13
|
import { NESTED_DEPTH, TYPE_DROP_TARGET_DEC } from './decorations-common';
|
|
12
14
|
import { maxLayoutColumnSupported } from './utils/consts';
|
|
13
15
|
import { canMoveNodeToIndex, canMoveSliceToIndex, isInSameLayout } from './utils/validation';
|
|
@@ -125,7 +127,8 @@ export const createLayoutDropTargetDecoration = (pos, props, nodeViewPortalProvi
|
|
|
125
127
|
element.setAttribute('data-blocks-drop-target-container', 'true');
|
|
126
128
|
element.setAttribute('data-blocks-drop-target-key', key);
|
|
127
129
|
element.style.clear = 'unset';
|
|
128
|
-
|
|
130
|
+
const DropTargetLayoutComponent = expValEquals('platform_editor_native_anchor_support', 'isEnabled', true) && fg('editor_native_anchor_update_layout_drop_hint') ? DropTargetLayoutNativeAnchorSupport : DropTargetLayout;
|
|
131
|
+
nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DropTargetLayoutComponent, {
|
|
129
132
|
...props,
|
|
130
133
|
getPos,
|
|
131
134
|
anchorRectCache
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @jsxRuntime classic
|
|
3
3
|
* @jsx jsx
|
|
4
4
|
*/
|
|
5
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled
|
|
8
8
|
import { css, jsx } from '@emotion/react';
|
|
@@ -127,9 +127,121 @@ export const DropTargetLayout = props => {
|
|
|
127
127
|
edge: "right",
|
|
128
128
|
gap: `-${DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH}px`
|
|
129
129
|
}) : (isActiveAnchor || expValEquals('platform_editor_native_anchor_support', 'isEnabled', true)) && jsx("div", {
|
|
130
|
-
"data-testid": "block-ctrl-drop-hint"
|
|
130
|
+
"data-testid": "block-ctrl-drop-hint",
|
|
131
|
+
css: dropTargetLayoutHintStyle
|
|
132
|
+
}));
|
|
133
|
+
};
|
|
134
|
+
export const DropTargetLayoutNativeAnchorSupport = props => {
|
|
135
|
+
var _api$blockControls3;
|
|
136
|
+
const {
|
|
137
|
+
api,
|
|
138
|
+
getPos,
|
|
139
|
+
parent,
|
|
140
|
+
anchorRectCache
|
|
141
|
+
} = props;
|
|
142
|
+
const ref = useRef(null);
|
|
143
|
+
const [isDraggedOver, setIsDraggedOver] = useState(false);
|
|
144
|
+
const anchorName = getNodeAnchor(parent);
|
|
145
|
+
const [nextNodeAnchorName, setNextNodeAnchorName] = useState(null);
|
|
146
|
+
const readNextNodeAnchor = useCallback(() => {
|
|
147
|
+
var _ref$current2, _ref$current2$parentE, _nextElementSibling$g;
|
|
148
|
+
const nextElementSibling = (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : (_ref$current2$parentE = _ref$current2.parentElement) === null || _ref$current2$parentE === void 0 ? void 0 : _ref$current2$parentE.nextElementSibling;
|
|
149
|
+
const attrName = getAnchorAttrName();
|
|
150
|
+
const nextAnchorName = (_nextElementSibling$g = nextElementSibling === null || nextElementSibling === void 0 ? void 0 : nextElementSibling.getAttribute(attrName)) !== null && _nextElementSibling$g !== void 0 ? _nextElementSibling$g : null;
|
|
151
|
+
setNextNodeAnchorName(prev => prev === nextAnchorName ? prev : nextAnchorName);
|
|
152
|
+
}, []);
|
|
153
|
+
const height = useMemo(() => {
|
|
154
|
+
if (nextNodeAnchorName) {
|
|
155
|
+
if (isAnchorSupported()) {
|
|
156
|
+
return `anchor-size(${nextNodeAnchorName} height)`;
|
|
157
|
+
} else if (anchorRectCache) {
|
|
158
|
+
const layoutColumnRect = anchorRectCache.getRect(nextNodeAnchorName);
|
|
159
|
+
return `${(layoutColumnRect === null || layoutColumnRect === void 0 ? void 0 : layoutColumnRect.height) || 0}px`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Stacked mode fallback: minimal height to avoid oversized hint on first render
|
|
163
|
+
return '0px';
|
|
164
|
+
}, [nextNodeAnchorName, anchorRectCache]);
|
|
165
|
+
useLayoutEffect(() => {
|
|
166
|
+
const raf = requestAnimationFrame(() => {
|
|
167
|
+
readNextNodeAnchor();
|
|
168
|
+
});
|
|
169
|
+
return () => cancelAnimationFrame(raf);
|
|
170
|
+
}, [readNextNodeAnchor]);
|
|
171
|
+
const dropTargetStackLayoutHintStyle = css({
|
|
172
|
+
// jest warning: JSDOM version (22) doesn't support the new @container CSS rule
|
|
173
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-container-queries, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
|
|
174
|
+
[`@container layout-area (max-width:${layoutBreakpointWidth.MEDIUM - 1}px)`]: {
|
|
175
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
|
|
176
|
+
height,
|
|
177
|
+
marginTop: `${"var(--ds-space-050, 4px)"}`
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
const [isActiveAnchor] = useActiveAnchorTracker(anchorName);
|
|
181
|
+
const {
|
|
182
|
+
activeNode
|
|
183
|
+
} = (api === null || api === void 0 ? void 0 : (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.sharedState.currentState()) || {};
|
|
184
|
+
const onDrop = useCallback(() => {
|
|
185
|
+
if (!activeNode) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const to = getPos();
|
|
189
|
+
let mappedTo;
|
|
190
|
+
if (to !== undefined) {
|
|
191
|
+
var _api$core3, _api$core4;
|
|
192
|
+
const {
|
|
193
|
+
pos: from
|
|
194
|
+
} = activeNode;
|
|
195
|
+
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({
|
|
196
|
+
tr
|
|
197
|
+
}) => {
|
|
198
|
+
var _api$blockControls4, _api$blockControls4$c;
|
|
199
|
+
api === null || api === void 0 ? void 0 : (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 ? void 0 : (_api$blockControls4$c = _api$blockControls4.commands) === null || _api$blockControls4$c === void 0 ? void 0 : _api$blockControls4$c.moveToLayout(from, to)({
|
|
200
|
+
tr
|
|
201
|
+
});
|
|
202
|
+
const insertColumnStep = getInsertLayoutStep(tr);
|
|
203
|
+
mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
|
|
204
|
+
return tr;
|
|
205
|
+
});
|
|
206
|
+
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
|
|
207
|
+
tr
|
|
208
|
+
}) => {
|
|
209
|
+
if (mappedTo !== undefined) {
|
|
210
|
+
updateSelection(tr, mappedTo);
|
|
211
|
+
}
|
|
212
|
+
return tr;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}, [api, getPos, activeNode]);
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
if (ref.current) {
|
|
218
|
+
return dropTargetForElements({
|
|
219
|
+
element: ref.current,
|
|
220
|
+
onDragEnter: () => {
|
|
221
|
+
setIsDraggedOver(true);
|
|
222
|
+
readNextNodeAnchor();
|
|
223
|
+
},
|
|
224
|
+
onDragLeave: () => {
|
|
225
|
+
setIsDraggedOver(false);
|
|
226
|
+
},
|
|
227
|
+
onDrop
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}, [onDrop, readNextNodeAnchor]);
|
|
231
|
+
if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) === 'layoutSection') {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return jsx("div", {
|
|
235
|
+
ref: ref
|
|
131
236
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
132
237
|
,
|
|
238
|
+
css: [dropTargetLayoutStyle, dropTargetStackLayoutHintStyle],
|
|
239
|
+
"data-testid": "block-ctrl-drop-indicator"
|
|
240
|
+
}, isDraggedOver ? jsx(DropIndicator, {
|
|
241
|
+
edge: "right",
|
|
242
|
+
gap: `-${DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH}px`
|
|
243
|
+
}) : (isActiveAnchor || expValEquals('platform_editor_native_anchor_support', 'isEnabled', true)) && jsx("div", {
|
|
244
|
+
"data-testid": "block-ctrl-drop-hint",
|
|
133
245
|
css: dropTargetLayoutHintStyle
|
|
134
246
|
}));
|
|
135
247
|
};
|
|
@@ -7,10 +7,12 @@ import uuid from 'uuid';
|
|
|
7
7
|
import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
8
8
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
9
9
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
10
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
10
12
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
11
13
|
import { nodeMargins } from '../ui/consts';
|
|
12
14
|
import { DropTarget, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target';
|
|
13
|
-
import { DropTargetLayout } from '../ui/drop-target-layout';
|
|
15
|
+
import { DropTargetLayout, DropTargetLayoutNativeAnchorSupport } from '../ui/drop-target-layout';
|
|
14
16
|
import { NESTED_DEPTH, TYPE_DROP_TARGET_DEC } from './decorations-common';
|
|
15
17
|
import { maxLayoutColumnSupported } from './utils/consts';
|
|
16
18
|
import { canMoveNodeToIndex, canMoveSliceToIndex, isInSameLayout } from './utils/validation';
|
|
@@ -130,8 +132,9 @@ export var createLayoutDropTargetDecoration = function createLayoutDropTargetDec
|
|
|
130
132
|
element.setAttribute('data-blocks-drop-target-container', 'true');
|
|
131
133
|
element.setAttribute('data-blocks-drop-target-key', key);
|
|
132
134
|
element.style.clear = 'unset';
|
|
135
|
+
var DropTargetLayoutComponent = expValEquals('platform_editor_native_anchor_support', 'isEnabled', true) && fg('editor_native_anchor_update_layout_drop_hint') ? DropTargetLayoutNativeAnchorSupport : DropTargetLayout;
|
|
133
136
|
nodeViewPortalProviderAPI.render(function () {
|
|
134
|
-
return /*#__PURE__*/createElement(
|
|
137
|
+
return /*#__PURE__*/createElement(DropTargetLayoutComponent, _objectSpread(_objectSpread({}, props), {}, {
|
|
135
138
|
getPos: getPos,
|
|
136
139
|
anchorRectCache: anchorRectCache
|
|
137
140
|
}));
|
|
@@ -4,7 +4,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
4
4
|
* @jsxRuntime classic
|
|
5
5
|
* @jsx jsx
|
|
6
6
|
*/
|
|
7
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
7
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
8
8
|
|
|
9
9
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled
|
|
10
10
|
import { css, jsx } from '@emotion/react';
|
|
@@ -123,9 +123,122 @@ export var DropTargetLayout = function DropTargetLayout(props) {
|
|
|
123
123
|
edge: "right",
|
|
124
124
|
gap: "-".concat(DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH, "px")
|
|
125
125
|
}) : (isActiveAnchor || expValEquals('platform_editor_native_anchor_support', 'isEnabled', true)) && jsx("div", {
|
|
126
|
-
"data-testid": "block-ctrl-drop-hint"
|
|
126
|
+
"data-testid": "block-ctrl-drop-hint",
|
|
127
|
+
css: dropTargetLayoutHintStyle
|
|
128
|
+
}));
|
|
129
|
+
};
|
|
130
|
+
export var DropTargetLayoutNativeAnchorSupport = function DropTargetLayoutNativeAnchorSupport(props) {
|
|
131
|
+
var _api$blockControls3;
|
|
132
|
+
var api = props.api,
|
|
133
|
+
getPos = props.getPos,
|
|
134
|
+
parent = props.parent,
|
|
135
|
+
anchorRectCache = props.anchorRectCache;
|
|
136
|
+
var ref = useRef(null);
|
|
137
|
+
var _useState3 = useState(false),
|
|
138
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
139
|
+
isDraggedOver = _useState4[0],
|
|
140
|
+
setIsDraggedOver = _useState4[1];
|
|
141
|
+
var anchorName = getNodeAnchor(parent);
|
|
142
|
+
var _useState5 = useState(null),
|
|
143
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
144
|
+
nextNodeAnchorName = _useState6[0],
|
|
145
|
+
setNextNodeAnchorName = _useState6[1];
|
|
146
|
+
var readNextNodeAnchor = useCallback(function () {
|
|
147
|
+
var _ref$current2, _nextElementSibling$g;
|
|
148
|
+
var nextElementSibling = (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || (_ref$current2 = _ref$current2.parentElement) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.nextElementSibling;
|
|
149
|
+
var attrName = getAnchorAttrName();
|
|
150
|
+
var nextAnchorName = (_nextElementSibling$g = nextElementSibling === null || nextElementSibling === void 0 ? void 0 : nextElementSibling.getAttribute(attrName)) !== null && _nextElementSibling$g !== void 0 ? _nextElementSibling$g : null;
|
|
151
|
+
setNextNodeAnchorName(function (prev) {
|
|
152
|
+
return prev === nextAnchorName ? prev : nextAnchorName;
|
|
153
|
+
});
|
|
154
|
+
}, []);
|
|
155
|
+
var height = useMemo(function () {
|
|
156
|
+
if (nextNodeAnchorName) {
|
|
157
|
+
if (isAnchorSupported()) {
|
|
158
|
+
return "anchor-size(".concat(nextNodeAnchorName, " height)");
|
|
159
|
+
} else if (anchorRectCache) {
|
|
160
|
+
var layoutColumnRect = anchorRectCache.getRect(nextNodeAnchorName);
|
|
161
|
+
return "".concat((layoutColumnRect === null || layoutColumnRect === void 0 ? void 0 : layoutColumnRect.height) || 0, "px");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Stacked mode fallback: minimal height to avoid oversized hint on first render
|
|
165
|
+
return '0px';
|
|
166
|
+
}, [nextNodeAnchorName, anchorRectCache]);
|
|
167
|
+
useLayoutEffect(function () {
|
|
168
|
+
var raf = requestAnimationFrame(function () {
|
|
169
|
+
readNextNodeAnchor();
|
|
170
|
+
});
|
|
171
|
+
return function () {
|
|
172
|
+
return cancelAnimationFrame(raf);
|
|
173
|
+
};
|
|
174
|
+
}, [readNextNodeAnchor]);
|
|
175
|
+
var dropTargetStackLayoutHintStyle = css(_defineProperty({}, "@container layout-area (max-width:".concat(layoutBreakpointWidth.MEDIUM - 1, "px)"), {
|
|
176
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
|
|
177
|
+
height: height,
|
|
178
|
+
marginTop: "var(--ds-space-050, 4px)"
|
|
179
|
+
}));
|
|
180
|
+
var _useActiveAnchorTrack3 = useActiveAnchorTracker(anchorName),
|
|
181
|
+
_useActiveAnchorTrack4 = _slicedToArray(_useActiveAnchorTrack3, 1),
|
|
182
|
+
isActiveAnchor = _useActiveAnchorTrack4[0];
|
|
183
|
+
var _ref4 = (api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.sharedState.currentState()) || {},
|
|
184
|
+
activeNode = _ref4.activeNode;
|
|
185
|
+
var onDrop = useCallback(function () {
|
|
186
|
+
if (!activeNode) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
var to = getPos();
|
|
190
|
+
var mappedTo;
|
|
191
|
+
if (to !== undefined) {
|
|
192
|
+
var _api$core3, _api$core4;
|
|
193
|
+
var from = activeNode.pos;
|
|
194
|
+
api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref5) {
|
|
195
|
+
var _api$blockControls4;
|
|
196
|
+
var tr = _ref5.tr;
|
|
197
|
+
api === null || api === void 0 || (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 || (_api$blockControls4 = _api$blockControls4.commands) === null || _api$blockControls4 === void 0 || _api$blockControls4.moveToLayout(from, to)({
|
|
198
|
+
tr: tr
|
|
199
|
+
});
|
|
200
|
+
var insertColumnStep = getInsertLayoutStep(tr);
|
|
201
|
+
mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
|
|
202
|
+
return tr;
|
|
203
|
+
});
|
|
204
|
+
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref6) {
|
|
205
|
+
var tr = _ref6.tr;
|
|
206
|
+
if (mappedTo !== undefined) {
|
|
207
|
+
updateSelection(tr, mappedTo);
|
|
208
|
+
}
|
|
209
|
+
return tr;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}, [api, getPos, activeNode]);
|
|
213
|
+
useEffect(function () {
|
|
214
|
+
if (ref.current) {
|
|
215
|
+
return dropTargetForElements({
|
|
216
|
+
element: ref.current,
|
|
217
|
+
onDragEnter: function onDragEnter() {
|
|
218
|
+
setIsDraggedOver(true);
|
|
219
|
+
readNextNodeAnchor();
|
|
220
|
+
},
|
|
221
|
+
onDragLeave: function onDragLeave() {
|
|
222
|
+
setIsDraggedOver(false);
|
|
223
|
+
},
|
|
224
|
+
onDrop: onDrop
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}, [onDrop, readNextNodeAnchor]);
|
|
228
|
+
if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) === 'layoutSection') {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
return jsx("div", {
|
|
232
|
+
ref: ref
|
|
127
233
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
128
234
|
,
|
|
235
|
+
css: [dropTargetLayoutStyle, dropTargetStackLayoutHintStyle],
|
|
236
|
+
"data-testid": "block-ctrl-drop-indicator"
|
|
237
|
+
}, isDraggedOver ? jsx(DropIndicator, {
|
|
238
|
+
edge: "right",
|
|
239
|
+
gap: "-".concat(DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH, "px")
|
|
240
|
+
}) : (isActiveAnchor || expValEquals('platform_editor_native_anchor_support', 'isEnabled', true)) && jsx("div", {
|
|
241
|
+
"data-testid": "block-ctrl-drop-hint",
|
|
129
242
|
css: dropTargetLayoutHintStyle
|
|
130
243
|
}));
|
|
131
244
|
};
|
|
@@ -13,3 +13,6 @@ export type DropTargetLayoutProps = {
|
|
|
13
13
|
export declare const DropTargetLayout: (props: DropTargetLayoutProps & {
|
|
14
14
|
anchorRectCache?: AnchorRectCache;
|
|
15
15
|
}) => jsx.JSX.Element | null;
|
|
16
|
+
export declare const DropTargetLayoutNativeAnchorSupport: (props: DropTargetLayoutProps & {
|
|
17
|
+
anchorRectCache?: AnchorRectCache;
|
|
18
|
+
}) => jsx.JSX.Element | null;
|
|
@@ -13,3 +13,6 @@ export type DropTargetLayoutProps = {
|
|
|
13
13
|
export declare const DropTargetLayout: (props: DropTargetLayoutProps & {
|
|
14
14
|
anchorRectCache?: AnchorRectCache;
|
|
15
15
|
}) => jsx.JSX.Element | null;
|
|
16
|
+
export declare const DropTargetLayoutNativeAnchorSupport: (props: DropTargetLayoutProps & {
|
|
17
|
+
anchorRectCache?: AnchorRectCache;
|
|
18
|
+
}) => jsx.JSX.Element | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.6",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
|
|
54
54
|
"@atlaskit/primitives": "^16.1.0",
|
|
55
55
|
"@atlaskit/theme": "^21.0.0",
|
|
56
|
-
"@atlaskit/tmp-editor-statsig": "^13.
|
|
56
|
+
"@atlaskit/tmp-editor-statsig": "^13.32.0",
|
|
57
57
|
"@atlaskit/tokens": "^7.1.0",
|
|
58
|
-
"@atlaskit/tooltip": "^20.
|
|
58
|
+
"@atlaskit/tooltip": "^20.8.0",
|
|
59
59
|
"@babel/runtime": "^7.0.0",
|
|
60
60
|
"@emotion/react": "^11.7.1",
|
|
61
61
|
"@popperjs/core": "^2.11.8",
|
|
@@ -156,6 +156,9 @@
|
|
|
156
156
|
},
|
|
157
157
|
"platform_editor_toolbar_aifc_user_intent_fix": {
|
|
158
158
|
"type": "boolean"
|
|
159
|
+
},
|
|
160
|
+
"editor_native_anchor_update_layout_drop_hint": {
|
|
161
|
+
"type": "boolean"
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
164
|
}
|