@blocknote/xl-multi-column 0.47.1 → 0.47.2
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/dist/blocknote-xl-multi-column.cjs +1 -1
- package/dist/blocknote-xl-multi-column.cjs.map +1 -1
- package/dist/blocknote-xl-multi-column.js +381 -485
- package/dist/blocknote-xl-multi-column.js.map +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +3 -3
- package/src/blocks/Columns/index.ts +2 -0
- package/src/extensions/DropCursor/multiColumnDropCursor.ts +112 -0
- package/src/extensions/DropCursor/multiColumnHandleDropPlugin.ts +162 -0
- package/src/index.ts +1 -1
- package/types/src/extensions/DropCursor/multiColumnDropCursor.d.ts +21 -0
- package/types/src/extensions/DropCursor/multiColumnHandleDropPlugin.d.ts +16 -0
- package/types/src/index.d.ts +1 -1
- package/src/extensions/DropCursor/MultiColumnDropCursorPlugin.ts +0 -508
- package/types/src/extensions/DropCursor/MultiColumnDropCursorPlugin.d.ts +0 -11
|
@@ -1,508 +0,0 @@
|
|
|
1
|
-
import type { BlockNoteEditor } from "@blocknote/core";
|
|
2
|
-
import {
|
|
3
|
-
UniqueID,
|
|
4
|
-
getBlockInfo,
|
|
5
|
-
getNearestBlockPos,
|
|
6
|
-
nodeToBlock,
|
|
7
|
-
} from "@blocknote/core";
|
|
8
|
-
import { EditorState, Plugin } from "prosemirror-state";
|
|
9
|
-
import { dropPoint } from "prosemirror-transform";
|
|
10
|
-
import { EditorView } from "prosemirror-view";
|
|
11
|
-
|
|
12
|
-
const PERCENTAGE_OF_BLOCK_WIDTH_CONSIDERED_SIDE_DROP = 0.1;
|
|
13
|
-
|
|
14
|
-
function eventCoords(event: MouseEvent) {
|
|
15
|
-
return { left: event.clientX, top: event.clientY };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface DropCursorOptions {
|
|
19
|
-
/// The color of the cursor. Defaults to `black`. Use `false` to apply no color and rely only on class.
|
|
20
|
-
color?: string | false;
|
|
21
|
-
|
|
22
|
-
/// The precise width of the cursor in pixels. Defaults to 1.
|
|
23
|
-
width?: number;
|
|
24
|
-
|
|
25
|
-
/// A CSS class name to add to the cursor element.
|
|
26
|
-
class?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/// Create a plugin that, when added to a ProseMirror instance,
|
|
30
|
-
/// causes a decoration to show up at the drop position when something
|
|
31
|
-
/// is dragged over the editor.
|
|
32
|
-
///
|
|
33
|
-
/// Nodes may add a `disableDropCursor` property to their spec to
|
|
34
|
-
/// control the showing of a drop cursor inside them. This may be a
|
|
35
|
-
/// boolean or a function, which will be called with a view and a
|
|
36
|
-
/// position, and should return a boolean.
|
|
37
|
-
export function multiColumnDropCursor(
|
|
38
|
-
options: DropCursorOptions & {
|
|
39
|
-
editor: BlockNoteEditor<any, any, any>;
|
|
40
|
-
},
|
|
41
|
-
): Plugin {
|
|
42
|
-
const editor = options.editor;
|
|
43
|
-
return new Plugin({
|
|
44
|
-
view(editorView) {
|
|
45
|
-
return new DropCursorView(editorView, options);
|
|
46
|
-
},
|
|
47
|
-
props: {
|
|
48
|
-
handleDrop(view, event, slice, _moved) {
|
|
49
|
-
const eventPos = view.posAtCoords(eventCoords(event));
|
|
50
|
-
|
|
51
|
-
if (!eventPos) {
|
|
52
|
-
throw new Error("Could not get event position");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const posInfo = getTargetPosInfo(view.state, eventPos);
|
|
56
|
-
const blockInfo = getBlockInfo(posInfo);
|
|
57
|
-
|
|
58
|
-
const blockElement = view.nodeDOM(posInfo.posBeforeNode);
|
|
59
|
-
const blockRect = (blockElement as HTMLElement).getBoundingClientRect();
|
|
60
|
-
let position: "regular" | "left" | "right" = "regular";
|
|
61
|
-
if (
|
|
62
|
-
event.clientX <=
|
|
63
|
-
blockRect.left +
|
|
64
|
-
blockRect.width * PERCENTAGE_OF_BLOCK_WIDTH_CONSIDERED_SIDE_DROP
|
|
65
|
-
) {
|
|
66
|
-
position = "left";
|
|
67
|
-
}
|
|
68
|
-
if (
|
|
69
|
-
event.clientX >=
|
|
70
|
-
blockRect.right -
|
|
71
|
-
blockRect.width * PERCENTAGE_OF_BLOCK_WIDTH_CONSIDERED_SIDE_DROP
|
|
72
|
-
) {
|
|
73
|
-
position = "right";
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (position === "regular") {
|
|
77
|
-
// handled by default prosemirror drop behaviour
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const draggedBlock = nodeToBlock(
|
|
82
|
-
slice.content.child(0),
|
|
83
|
-
editor.pmSchema,
|
|
84
|
-
// TODO: cache?
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
// const block = blockInfo.block(editor);
|
|
88
|
-
if (blockInfo.blockNoteType === "column") {
|
|
89
|
-
// insert new column in existing columnList
|
|
90
|
-
const parentBlock = view.state.doc
|
|
91
|
-
.resolve(blockInfo.bnBlock.beforePos)
|
|
92
|
-
.node();
|
|
93
|
-
|
|
94
|
-
const columnList = nodeToBlock<any, any, any>(
|
|
95
|
-
parentBlock,
|
|
96
|
-
editor.pmSchema,
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
// In a `columnList`, we expect that the average width of each column
|
|
100
|
-
// is 1. However, there are cases in which this stops being true. For
|
|
101
|
-
// example, having one wider column and then removing it will cause
|
|
102
|
-
// the average width to go down. This isn't really an issue until the
|
|
103
|
-
// user tries to add a new column, which will, in this case, be wider
|
|
104
|
-
// than expected. Therefore, we normalize the column widths to an
|
|
105
|
-
// average of 1 here to avoid this issue.
|
|
106
|
-
let sumColumnWidthPercent = 0;
|
|
107
|
-
columnList.children.forEach((column) => {
|
|
108
|
-
sumColumnWidthPercent += column.props.width as number;
|
|
109
|
-
});
|
|
110
|
-
const avgColumnWidthPercent =
|
|
111
|
-
sumColumnWidthPercent / columnList.children.length;
|
|
112
|
-
|
|
113
|
-
// If the average column width is not 1, normalize it. We're dealing
|
|
114
|
-
// with floats so we need a small margin to account for precision
|
|
115
|
-
// errors.
|
|
116
|
-
if (avgColumnWidthPercent < 0.99 || avgColumnWidthPercent > 1.01) {
|
|
117
|
-
const scalingFactor = 1 / avgColumnWidthPercent;
|
|
118
|
-
|
|
119
|
-
columnList.children.forEach((column) => {
|
|
120
|
-
column.props.width =
|
|
121
|
-
(column.props.width as number) * scalingFactor;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const index = columnList.children.findIndex(
|
|
126
|
-
(b) => b.id === blockInfo.bnBlock.node.attrs.id,
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
const newChildren = columnList.children
|
|
130
|
-
// If the dragged block is in one of the columns, remove it.
|
|
131
|
-
.map((column) => ({
|
|
132
|
-
...column,
|
|
133
|
-
children: column.children.filter(
|
|
134
|
-
(block) => block.id !== draggedBlock.id,
|
|
135
|
-
),
|
|
136
|
-
}))
|
|
137
|
-
// Remove empty columns (can happen when dragged block is removed).
|
|
138
|
-
.filter((column) => column.children.length > 0)
|
|
139
|
-
// Insert the dragged block in the correct position.
|
|
140
|
-
.toSpliced(position === "left" ? index : index + 1, 0, {
|
|
141
|
-
type: "column",
|
|
142
|
-
children: [draggedBlock],
|
|
143
|
-
props: {},
|
|
144
|
-
content: undefined,
|
|
145
|
-
id: UniqueID.options.generateID(),
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
if (editor.getBlock(draggedBlock.id)) {
|
|
149
|
-
editor.removeBlocks([draggedBlock]);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
editor.updateBlock(columnList, {
|
|
153
|
-
children: newChildren,
|
|
154
|
-
});
|
|
155
|
-
} else {
|
|
156
|
-
// create new columnList with blocks as columns
|
|
157
|
-
const block = nodeToBlock(blockInfo.bnBlock.node, editor.pmSchema);
|
|
158
|
-
|
|
159
|
-
// The user is dropping next to the original block being dragged - do
|
|
160
|
-
// nothing.
|
|
161
|
-
if (block.id === draggedBlock.id) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const blocks =
|
|
166
|
-
position === "left" ? [draggedBlock, block] : [block, draggedBlock];
|
|
167
|
-
|
|
168
|
-
if (editor.getBlock(draggedBlock.id)) {
|
|
169
|
-
editor.removeBlocks([draggedBlock]);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
editor.replaceBlocks(
|
|
173
|
-
[block],
|
|
174
|
-
[
|
|
175
|
-
{
|
|
176
|
-
type: "columnList",
|
|
177
|
-
children: blocks.map((b) => {
|
|
178
|
-
return {
|
|
179
|
-
type: "column",
|
|
180
|
-
children: [b],
|
|
181
|
-
};
|
|
182
|
-
}),
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return true;
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
class DropCursorView {
|
|
195
|
-
width: number;
|
|
196
|
-
color: string | undefined;
|
|
197
|
-
class: string | undefined;
|
|
198
|
-
cursorPos:
|
|
199
|
-
| { pos: number; position: "left" | "right" | "regular" }
|
|
200
|
-
| undefined = undefined;
|
|
201
|
-
element: HTMLElement | null = null;
|
|
202
|
-
timeout: ReturnType<typeof setTimeout> | undefined = undefined;
|
|
203
|
-
handlers: { name: string; handler: (event: Event) => void }[];
|
|
204
|
-
|
|
205
|
-
constructor(
|
|
206
|
-
readonly editorView: EditorView,
|
|
207
|
-
options: DropCursorOptions,
|
|
208
|
-
) {
|
|
209
|
-
this.width = options.width ?? 1;
|
|
210
|
-
this.color = options.color === false ? undefined : options.color || "black";
|
|
211
|
-
this.class = options.class;
|
|
212
|
-
|
|
213
|
-
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map((name) => {
|
|
214
|
-
const handler = (e: Event) => {
|
|
215
|
-
(this as any)[name](e);
|
|
216
|
-
};
|
|
217
|
-
editorView.dom.addEventListener(
|
|
218
|
-
name,
|
|
219
|
-
handler,
|
|
220
|
-
// drop event captured in bubbling phase to make sure
|
|
221
|
-
// "cursorPos" is set to undefined before the "handleDrop" handler is called
|
|
222
|
-
// (otherwise an error could be thrown, see https://github.com/TypeCellOS/BlockNote/pull/1240)
|
|
223
|
-
name === "drop" ? true : undefined,
|
|
224
|
-
);
|
|
225
|
-
return { name, handler };
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
destroy() {
|
|
230
|
-
this.handlers.forEach(({ name, handler }) =>
|
|
231
|
-
this.editorView.dom.removeEventListener(
|
|
232
|
-
name,
|
|
233
|
-
handler,
|
|
234
|
-
name === "drop" ? true : undefined,
|
|
235
|
-
),
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
update(editorView: EditorView, prevState: EditorState) {
|
|
240
|
-
if (this.cursorPos != null && prevState.doc !== editorView.state.doc) {
|
|
241
|
-
if (this.cursorPos.pos > editorView.state.doc.content.size) {
|
|
242
|
-
this.setCursor(undefined);
|
|
243
|
-
} else {
|
|
244
|
-
// update overlay because document has changed
|
|
245
|
-
this.updateOverlay();
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
setCursor(
|
|
251
|
-
cursorPos:
|
|
252
|
-
| { pos: number; position: "left" | "right" | "regular" }
|
|
253
|
-
| undefined,
|
|
254
|
-
) {
|
|
255
|
-
if (
|
|
256
|
-
cursorPos === this.cursorPos ||
|
|
257
|
-
(cursorPos?.pos === this.cursorPos?.pos &&
|
|
258
|
-
cursorPos?.position === this.cursorPos?.position)
|
|
259
|
-
) {
|
|
260
|
-
// no change
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
this.cursorPos = cursorPos;
|
|
264
|
-
if (!cursorPos) {
|
|
265
|
-
this.element!.parentNode!.removeChild(this.element!);
|
|
266
|
-
this.element = null;
|
|
267
|
-
} else {
|
|
268
|
-
// update overlay because cursor has changed
|
|
269
|
-
this.updateOverlay();
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
updateOverlay() {
|
|
274
|
-
if (!this.cursorPos) {
|
|
275
|
-
throw new Error("updateOverlay called with no cursor position");
|
|
276
|
-
}
|
|
277
|
-
const $pos = this.editorView.state.doc.resolve(this.cursorPos.pos);
|
|
278
|
-
const isBlock = !$pos.parent.inlineContent;
|
|
279
|
-
let rect;
|
|
280
|
-
const editorDOM = this.editorView.dom;
|
|
281
|
-
const editorRect = editorDOM.getBoundingClientRect();
|
|
282
|
-
const scaleX = editorRect.width / editorDOM.offsetWidth;
|
|
283
|
-
const scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
284
|
-
if (isBlock) {
|
|
285
|
-
const before = $pos.nodeBefore;
|
|
286
|
-
const after = $pos.nodeAfter;
|
|
287
|
-
if (before || after) {
|
|
288
|
-
if (
|
|
289
|
-
this.cursorPos.position === "left" ||
|
|
290
|
-
this.cursorPos.position === "right"
|
|
291
|
-
) {
|
|
292
|
-
const block = this.editorView.nodeDOM(this.cursorPos.pos);
|
|
293
|
-
|
|
294
|
-
if (!block) {
|
|
295
|
-
throw new Error("nodeDOM returned null in updateOverlay");
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const blockRect = (block as HTMLElement).getBoundingClientRect();
|
|
299
|
-
const halfWidth = (this.width / 2) * scaleY;
|
|
300
|
-
const left =
|
|
301
|
-
this.cursorPos.position === "left"
|
|
302
|
-
? blockRect.left
|
|
303
|
-
: blockRect.right;
|
|
304
|
-
rect = {
|
|
305
|
-
left: left - halfWidth,
|
|
306
|
-
right: left + halfWidth,
|
|
307
|
-
top: blockRect.top,
|
|
308
|
-
bottom: blockRect.bottom,
|
|
309
|
-
// left: blockRect.left,
|
|
310
|
-
// right: blockRect.right,
|
|
311
|
-
};
|
|
312
|
-
} else {
|
|
313
|
-
// regular logic
|
|
314
|
-
const node = this.editorView.nodeDOM(
|
|
315
|
-
this.cursorPos.pos - (before ? before.nodeSize : 0),
|
|
316
|
-
);
|
|
317
|
-
if (node) {
|
|
318
|
-
const nodeRect = (node as HTMLElement).getBoundingClientRect();
|
|
319
|
-
|
|
320
|
-
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
321
|
-
if (before && after) {
|
|
322
|
-
// find the middle between the node above and below
|
|
323
|
-
top =
|
|
324
|
-
(top +
|
|
325
|
-
(
|
|
326
|
-
this.editorView.nodeDOM(this.cursorPos.pos) as HTMLElement
|
|
327
|
-
).getBoundingClientRect().top) /
|
|
328
|
-
2;
|
|
329
|
-
}
|
|
330
|
-
// console.log("node");
|
|
331
|
-
const halfWidth = (this.width / 2) * scaleY;
|
|
332
|
-
|
|
333
|
-
if (this.cursorPos.position === "regular") {
|
|
334
|
-
rect = {
|
|
335
|
-
left: nodeRect.left,
|
|
336
|
-
right: nodeRect.right,
|
|
337
|
-
top: top - halfWidth,
|
|
338
|
-
bottom: top + halfWidth,
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if (!rect) {
|
|
347
|
-
// Cursor is an inline vertical dropcursor
|
|
348
|
-
const coords = this.editorView.coordsAtPos(this.cursorPos.pos);
|
|
349
|
-
const halfWidth = (this.width / 2) * scaleX;
|
|
350
|
-
rect = {
|
|
351
|
-
left: coords.left - halfWidth,
|
|
352
|
-
right: coords.left + halfWidth,
|
|
353
|
-
top: coords.top,
|
|
354
|
-
bottom: coords.bottom,
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Code below positions the cursor overlay based on the rect
|
|
359
|
-
const parent = this.editorView.dom.offsetParent as HTMLElement;
|
|
360
|
-
if (!this.element) {
|
|
361
|
-
this.element = parent.appendChild(document.createElement("div"));
|
|
362
|
-
if (this.class) {
|
|
363
|
-
this.element.className = this.class;
|
|
364
|
-
}
|
|
365
|
-
this.element.style.cssText =
|
|
366
|
-
"position: absolute; z-index: 50; pointer-events: none;";
|
|
367
|
-
if (this.color) {
|
|
368
|
-
this.element.style.backgroundColor = this.color;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
372
|
-
this.element.classList.toggle(
|
|
373
|
-
"prosemirror-dropcursor-vertical",
|
|
374
|
-
this.cursorPos.position !== "regular",
|
|
375
|
-
);
|
|
376
|
-
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
377
|
-
let parentLeft, parentTop;
|
|
378
|
-
if (
|
|
379
|
-
!parent ||
|
|
380
|
-
(parent === document.body &&
|
|
381
|
-
getComputedStyle(parent).position === "static")
|
|
382
|
-
) {
|
|
383
|
-
parentLeft = -window.scrollX;
|
|
384
|
-
parentTop = -window.scrollY;
|
|
385
|
-
} else {
|
|
386
|
-
const rect = parent.getBoundingClientRect();
|
|
387
|
-
const parentScaleX = rect.width / parent.offsetWidth;
|
|
388
|
-
const parentScaleY = rect.height / parent.offsetHeight;
|
|
389
|
-
parentLeft = rect.left - parent.scrollLeft * parentScaleX;
|
|
390
|
-
parentTop = rect.top - parent.scrollTop * parentScaleY;
|
|
391
|
-
}
|
|
392
|
-
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
393
|
-
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
394
|
-
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
395
|
-
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
scheduleRemoval(timeout: number) {
|
|
399
|
-
clearTimeout(this.timeout);
|
|
400
|
-
this.timeout = setTimeout(() => this.setCursor(undefined), timeout);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// this gets executed on every mouse move when dragging (drag over)
|
|
404
|
-
dragover(event: DragEvent) {
|
|
405
|
-
if (!this.editorView.editable) {
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
const pos = this.editorView.posAtCoords({
|
|
409
|
-
left: event.clientX,
|
|
410
|
-
top: event.clientY,
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
// console.log("posatcoords", pos);
|
|
414
|
-
|
|
415
|
-
const node =
|
|
416
|
-
pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
417
|
-
const disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
418
|
-
const disabled =
|
|
419
|
-
typeof disableDropCursor == "function"
|
|
420
|
-
? disableDropCursor(this.editorView, pos, event)
|
|
421
|
-
: disableDropCursor;
|
|
422
|
-
|
|
423
|
-
if (pos && !disabled) {
|
|
424
|
-
let position: "regular" | "left" | "right" = "regular";
|
|
425
|
-
let target: number | null = pos.pos;
|
|
426
|
-
|
|
427
|
-
const posInfo = getTargetPosInfo(this.editorView.state, pos);
|
|
428
|
-
|
|
429
|
-
const block = this.editorView.nodeDOM(posInfo.posBeforeNode);
|
|
430
|
-
const blockRect = (block as HTMLElement).getBoundingClientRect();
|
|
431
|
-
|
|
432
|
-
if (
|
|
433
|
-
event.clientX <=
|
|
434
|
-
blockRect.left +
|
|
435
|
-
blockRect.width * PERCENTAGE_OF_BLOCK_WIDTH_CONSIDERED_SIDE_DROP
|
|
436
|
-
) {
|
|
437
|
-
position = "left";
|
|
438
|
-
target = posInfo.posBeforeNode;
|
|
439
|
-
}
|
|
440
|
-
if (
|
|
441
|
-
event.clientX >=
|
|
442
|
-
blockRect.right -
|
|
443
|
-
blockRect.width * PERCENTAGE_OF_BLOCK_WIDTH_CONSIDERED_SIDE_DROP
|
|
444
|
-
) {
|
|
445
|
-
position = "right";
|
|
446
|
-
target = posInfo.posBeforeNode;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// "regular logic"
|
|
450
|
-
if (
|
|
451
|
-
position === "regular" &&
|
|
452
|
-
this.editorView.dragging &&
|
|
453
|
-
this.editorView.dragging.slice
|
|
454
|
-
) {
|
|
455
|
-
const point = dropPoint(
|
|
456
|
-
this.editorView.state.doc,
|
|
457
|
-
target,
|
|
458
|
-
this.editorView.dragging.slice,
|
|
459
|
-
);
|
|
460
|
-
|
|
461
|
-
if (point != null) {
|
|
462
|
-
target = point;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
this.setCursor({ pos: target, position });
|
|
467
|
-
this.scheduleRemoval(5000);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
dragend() {
|
|
472
|
-
this.scheduleRemoval(20);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
drop() {
|
|
476
|
-
this.setCursor(undefined);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
dragleave(event: DragEvent) {
|
|
480
|
-
if (
|
|
481
|
-
event.target === this.editorView.dom ||
|
|
482
|
-
!this.editorView.dom.contains((event as any).relatedTarget)
|
|
483
|
-
) {
|
|
484
|
-
this.setCursor(undefined);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* From a position inside the document get the block that should be the "drop target" block.
|
|
491
|
-
*/
|
|
492
|
-
function getTargetPosInfo(
|
|
493
|
-
state: EditorState,
|
|
494
|
-
eventPos: { pos: number; inside: number },
|
|
495
|
-
) {
|
|
496
|
-
const blockPos = getNearestBlockPos(state.doc, eventPos.pos);
|
|
497
|
-
|
|
498
|
-
// if we're at a block that's in a column, we want to compare the mouse position to the column, not the block inside it
|
|
499
|
-
// why? because we want to insert a new column in the columnList, instead of a new columnList inside of the column
|
|
500
|
-
let resolved = state.doc.resolve(blockPos.posBeforeNode);
|
|
501
|
-
if (resolved.parent.type.name === "column") {
|
|
502
|
-
resolved = state.doc.resolve(resolved.before());
|
|
503
|
-
}
|
|
504
|
-
return {
|
|
505
|
-
posBeforeNode: resolved.pos,
|
|
506
|
-
node: resolved.nodeAfter!,
|
|
507
|
-
};
|
|
508
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { BlockNoteEditor } from "@blocknote/core";
|
|
2
|
-
import { Plugin } from "prosemirror-state";
|
|
3
|
-
interface DropCursorOptions {
|
|
4
|
-
color?: string | false;
|
|
5
|
-
width?: number;
|
|
6
|
-
class?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function multiColumnDropCursor(options: DropCursorOptions & {
|
|
9
|
-
editor: BlockNoteEditor<any, any, any>;
|
|
10
|
-
}): Plugin;
|
|
11
|
-
export {};
|