@prosekit/web 0.5.11 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clone-element-B55UD54E.js +50 -0
- package/dist/{get-default-state-CIEy7xrl.js → get-safe-editor-view-CqJWgxo1.js} +11 -1
- package/dist/prosekit-web-autocomplete.js +3 -2
- package/dist/prosekit-web-block-handle.d.ts +15 -8
- package/dist/prosekit-web-block-handle.js +12 -39
- package/dist/prosekit-web-table-handle.d.ts +50 -8
- package/dist/prosekit-web-table-handle.js +592 -6
- package/package.json +8 -8
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/utils/assign-styles.ts
|
|
2
|
+
/**
|
|
3
|
+
* A type-safe version of `Object.assign` for `element.style`.
|
|
4
|
+
*/
|
|
5
|
+
function assignStyles(element, styles) {
|
|
6
|
+
Object.assign(element.style, styles);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/utils/clone-element.ts
|
|
11
|
+
/**
|
|
12
|
+
* Creates a deep clone of an Element, including all computed styles so that
|
|
13
|
+
* it looks the same as the original element.
|
|
14
|
+
*/
|
|
15
|
+
function deepCloneElement(element) {
|
|
16
|
+
const clonedElement = element.cloneNode(true);
|
|
17
|
+
deepCopyStyles(element, clonedElement);
|
|
18
|
+
return clonedElement;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a clone of an Element, including all computed styles so that
|
|
22
|
+
* it looks similar enough to the original element.
|
|
23
|
+
*/
|
|
24
|
+
function cloneElement(element) {
|
|
25
|
+
const clonedElement = element.cloneNode();
|
|
26
|
+
copyStyles(element, clonedElement);
|
|
27
|
+
return clonedElement;
|
|
28
|
+
}
|
|
29
|
+
function deepCopyStyles(source, target) {
|
|
30
|
+
const sources = [source];
|
|
31
|
+
const targets = [target];
|
|
32
|
+
while (sources.length > 0 && sources.length === targets.length) {
|
|
33
|
+
const source$1 = sources.pop();
|
|
34
|
+
const target$1 = targets.pop();
|
|
35
|
+
if (!source$1 || !target$1) return;
|
|
36
|
+
copyStyles(source$1, target$1);
|
|
37
|
+
sources.push(...source$1.children);
|
|
38
|
+
targets.push(...target$1.children);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function copyStyles(source, target) {
|
|
42
|
+
if (!source || !target) return;
|
|
43
|
+
const sourceStyle = source.ownerDocument?.defaultView?.getComputedStyle(source);
|
|
44
|
+
const targetStyle = target.style;
|
|
45
|
+
if (!sourceStyle || !targetStyle) return;
|
|
46
|
+
for (const key of sourceStyle) targetStyle.setProperty(key, sourceStyle.getPropertyValue(key), sourceStyle.getPropertyPriority(key));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { assignStyles, cloneElement, deepCloneElement };
|
|
@@ -8,4 +8,14 @@ function getStateWithDefaults(state, props) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
|
-
|
|
11
|
+
//#region src/utils/get-safe-editor-view.ts
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
function getSafeEditorView(editor) {
|
|
16
|
+
if (!editor || !editor.mounted) return;
|
|
17
|
+
return editor.view;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { getSafeEditorView, getStateWithDefaults };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getStateWithDefaults } from "./get-
|
|
1
|
+
import { getSafeEditorView, getStateWithDefaults } from "./get-safe-editor-view-CqJWgxo1.js";
|
|
2
2
|
import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
|
|
3
3
|
import { createComputed, createContext, createSignal, defineCustomElement, registerCustomElement, useAnimationFrame, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
|
|
4
4
|
import { listboxProps, useListbox, useListboxEmpty, useListboxItem } from "@aria-ui/listbox/elements";
|
|
@@ -227,7 +227,8 @@ function useAutocompleteExtension(host, editor, regex, reference, query, onDismi
|
|
|
227
227
|
}
|
|
228
228
|
function createAutocompleteRule(editor, regex, reference, query, onDismiss, onSubmit) {
|
|
229
229
|
const handleEnter = (options) => {
|
|
230
|
-
const
|
|
230
|
+
const view = getSafeEditorView(editor);
|
|
231
|
+
const span = view?.dom.querySelector(".prosemirror-prediction-match");
|
|
231
232
|
if (span) reference.set(span);
|
|
232
233
|
query.set(defaultQueryBuilder(options.match));
|
|
233
234
|
onDismiss.set(options.ignoreMatch);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { BaseElementConstructor, ConnectableElement, EventDeclarations, PropDeclarations, SignalState } from "@aria-ui/core";
|
|
1
|
+
import { BaseElementConstructor, ConnectableElement, EventDeclarations, PropDeclarations, SetupOptions, SignalState } from "@aria-ui/core";
|
|
2
2
|
import { Editor } from "@prosekit/core";
|
|
3
|
-
import { OverlayPositionerProps } from "@aria-ui/overlay/elements";
|
|
3
|
+
import { OverlayPositionerEvents, OverlayPositionerProps } from "@aria-ui/overlay/elements";
|
|
4
|
+
import { ProseMirrorNode } from "@prosekit/pm/model";
|
|
4
5
|
import { Placement } from "@floating-ui/dom";
|
|
5
6
|
|
|
6
7
|
//#region src/components/block-handle/block-handle-add/types.d.ts
|
|
@@ -90,8 +91,15 @@ interface BlockHandlePopoverProps extends Omit<OverlayPositionerProps, "placemen
|
|
|
90
91
|
}
|
|
91
92
|
/** @internal */
|
|
92
93
|
declare const blockHandlePopoverProps: PropDeclarations<BlockHandlePopoverProps>;
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
interface BlockHandlePopoverEvents extends OverlayPositionerEvents {
|
|
95
|
+
/**
|
|
96
|
+
* Fired when the hovered block changes.
|
|
97
|
+
*/
|
|
98
|
+
stateChange: CustomEvent<{
|
|
99
|
+
node: ProseMirrorNode;
|
|
100
|
+
pos: number;
|
|
101
|
+
} | null>;
|
|
102
|
+
}
|
|
95
103
|
/** @internal */
|
|
96
104
|
declare const blockHandlePopoverEvents: EventDeclarations<BlockHandlePopoverEvents>;
|
|
97
105
|
//#endregion
|
|
@@ -104,9 +112,8 @@ declare class BlockHandlePopoverElement extends BlockHandlePopoverElementBase {}
|
|
|
104
112
|
* @internal
|
|
105
113
|
*/
|
|
106
114
|
declare function useBlockHandlePopover(host: ConnectableElement, {
|
|
107
|
-
state
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}): void;
|
|
115
|
+
state,
|
|
116
|
+
emit
|
|
117
|
+
}: SetupOptions<BlockHandlePopoverProps, BlockHandlePopoverEvents>): void;
|
|
111
118
|
//#endregion
|
|
112
119
|
export { BlockHandleAddElement, BlockHandleAddEvents, BlockHandleAddProps, BlockHandleDraggableElement, BlockHandleDraggableEvents, BlockHandleDraggableProps, BlockHandlePopoverElement, BlockHandlePopoverEvents, BlockHandlePopoverProps, blockHandleAddEvents, blockHandleAddProps, blockHandleDraggableEvents, blockHandleDraggableProps, blockHandlePopoverEvents, blockHandlePopoverProps, useBlockHandleAdd, useBlockHandleDraggable, useBlockHandlePopover };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
|
|
2
|
+
import { assignStyles, deepCloneElement } from "./clone-element-B55UD54E.js";
|
|
2
3
|
import { createContext, createSignal, defineCustomElement, registerCustomElement, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
|
|
3
4
|
import { defineDOMEventHandler, insertDefaultBlock, union } from "@prosekit/core";
|
|
4
|
-
import { overlayPositionerProps, useOverlayPositionerState } from "@aria-ui/overlay/elements";
|
|
5
|
+
import { overlayPositionerEvents, overlayPositionerProps, useOverlayPositionerState } from "@aria-ui/overlay/elements";
|
|
5
6
|
import { usePresence } from "@aria-ui/presence";
|
|
6
7
|
import { isElement, isHTMLElement, isTextNode } from "@ocavue/utils";
|
|
7
8
|
import { Fragment, Slice } from "@prosekit/pm/model";
|
|
@@ -49,46 +50,10 @@ const BlockHandleAddElementBase = defineCustomElement({
|
|
|
49
50
|
var BlockHandleAddElement = class extends BlockHandleAddElementBase {};
|
|
50
51
|
registerCustomElement("prosekit-block-handle-add", BlockHandleAddElement);
|
|
51
52
|
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/utils/asset-styles.ts
|
|
54
|
-
function assignStyles(element, styles) {
|
|
55
|
-
Object.assign(element.style, styles);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
53
|
//#endregion
|
|
59
54
|
//#region src/utils/max-z-index.ts
|
|
60
55
|
const maxZIndex = "2147483647";
|
|
61
56
|
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region src/components/block-handle/block-handle-draggable/deep-clone-element.ts
|
|
64
|
-
/**
|
|
65
|
-
* Creates a deep clone of an Element, including all computed styles so that
|
|
66
|
-
* it looks the same as the original element.
|
|
67
|
-
*/
|
|
68
|
-
function deepCloneElement(element) {
|
|
69
|
-
const clonedElement = element.cloneNode(true);
|
|
70
|
-
deepCopyStyles(element, clonedElement);
|
|
71
|
-
return clonedElement;
|
|
72
|
-
}
|
|
73
|
-
function deepCopyStyles(source, target) {
|
|
74
|
-
const sources = [source];
|
|
75
|
-
const targets = [target];
|
|
76
|
-
while (sources.length > 0 && sources.length === targets.length) {
|
|
77
|
-
const source$1 = sources.pop();
|
|
78
|
-
const target$1 = targets.pop();
|
|
79
|
-
if (!source$1 || !target$1) return;
|
|
80
|
-
copyStyles(source$1, target$1);
|
|
81
|
-
sources.push(...source$1.children);
|
|
82
|
-
targets.push(...target$1.children);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function copyStyles(source, target) {
|
|
86
|
-
const sourceStyle = source.ownerDocument?.defaultView?.getComputedStyle(source);
|
|
87
|
-
const targetStyle = target.style;
|
|
88
|
-
if (!sourceStyle || !targetStyle) return;
|
|
89
|
-
for (const key of sourceStyle) targetStyle.setProperty(key, sourceStyle.getPropertyValue(key), sourceStyle.getPropertyPriority(key));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
57
|
//#endregion
|
|
93
58
|
//#region src/components/block-handle/block-handle-draggable/set-drag-preview.ts
|
|
94
59
|
/**
|
|
@@ -432,7 +397,7 @@ const fallbackRect = Object.freeze({
|
|
|
432
397
|
/**
|
|
433
398
|
* @internal
|
|
434
399
|
*/
|
|
435
|
-
function useBlockHandlePopover(host, { state }) {
|
|
400
|
+
function useBlockHandlePopover(host, { state, emit }) {
|
|
436
401
|
const { editor,...overlayState } = state;
|
|
437
402
|
const reference = createSignal(null);
|
|
438
403
|
useOverlayPositionerState(host, overlayState, { reference });
|
|
@@ -445,6 +410,11 @@ function useBlockHandlePopover(host, { state }) {
|
|
|
445
410
|
useHoverExtension(host, editor, (referenceValue, hoverState) => {
|
|
446
411
|
reference.set(referenceValue);
|
|
447
412
|
context.set(hoverState);
|
|
413
|
+
const stateChangeDetails = hoverState ? {
|
|
414
|
+
node: hoverState.node,
|
|
415
|
+
pos: hoverState.pos
|
|
416
|
+
} : null;
|
|
417
|
+
emit("stateChange", stateChangeDetails);
|
|
448
418
|
});
|
|
449
419
|
useAttribute(host, "data-state", () => open.get() ? "open" : "closed");
|
|
450
420
|
usePresence(host, open);
|
|
@@ -474,7 +444,10 @@ const blockHandlePopoverProps = {
|
|
|
474
444
|
hoist: { default: false }
|
|
475
445
|
};
|
|
476
446
|
/** @internal */
|
|
477
|
-
const blockHandlePopoverEvents = {
|
|
447
|
+
const blockHandlePopoverEvents = {
|
|
448
|
+
...overlayPositionerEvents,
|
|
449
|
+
stateChange: {}
|
|
450
|
+
};
|
|
478
451
|
|
|
479
452
|
//#endregion
|
|
480
453
|
//#region src/components/block-handle/block-handle-popover/element.gen.ts
|
|
@@ -2,9 +2,9 @@ import { BaseElementConstructor, ConnectableElement, EventDeclarations, PropDecl
|
|
|
2
2
|
import { Editor } from "@prosekit/core";
|
|
3
3
|
import { OverlayPositionerEvents, OverlayPositionerProps } from "@aria-ui/overlay";
|
|
4
4
|
import { MenuContentEvents, MenuContentProps } from "@aria-ui/menu/elements";
|
|
5
|
-
import { defineTableCommands } from "@prosekit/extensions/table";
|
|
6
|
-
import { MenuItemEvents, MenuItemProps } from "@aria-ui/menu";
|
|
5
|
+
import { TableCommandsExtension, defineTableCommands } from "@prosekit/extensions/table";
|
|
7
6
|
import { Placement } from "@floating-ui/dom";
|
|
7
|
+
import { MenuItemEvents, MenuItemProps } from "@aria-ui/menu";
|
|
8
8
|
|
|
9
9
|
//#region src/components/table-handle/table-handle-column-root/types.d.ts
|
|
10
10
|
interface TableHandleColumnRootProps extends Omit<OverlayPositionerProps, "placement"> {
|
|
@@ -44,9 +44,9 @@ declare function useTableHandleColumnRoot(host: ConnectableElement, {
|
|
|
44
44
|
}): void;
|
|
45
45
|
//#endregion
|
|
46
46
|
//#region src/components/table-handle/table-handle-column-trigger/types.d.ts
|
|
47
|
-
type TableCommandsExtension$
|
|
47
|
+
type TableCommandsExtension$2 = ReturnType<typeof defineTableCommands>;
|
|
48
48
|
interface TableHandleColumnTriggerProps {
|
|
49
|
-
editor: Editor<TableCommandsExtension$
|
|
49
|
+
editor: Editor<TableCommandsExtension$2> | null;
|
|
50
50
|
}
|
|
51
51
|
/** @internal */
|
|
52
52
|
declare const tableHandleColumnTriggerProps: PropDeclarations<TableHandleColumnTriggerProps>;
|
|
@@ -65,8 +65,50 @@ declare class TableHandleColumnTriggerElement extends TableHandleColumnTriggerEl
|
|
|
65
65
|
*/
|
|
66
66
|
declare function useTableHandleColumnTrigger(host: ConnectableElement, {
|
|
67
67
|
state
|
|
68
|
+
}: SetupOptions<TableHandleColumnTriggerProps, TableHandleColumnTriggerEvents>): void;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/components/table-handle/table-handle-drag-preview/types.d.ts
|
|
71
|
+
interface TableHandleDragPreviewProps {
|
|
72
|
+
editor: Editor | null;
|
|
73
|
+
}
|
|
74
|
+
declare const tableHandleDragPreviewProps: PropDeclarations<TableHandleDragPreviewProps>;
|
|
75
|
+
interface TableHandleDragPreviewEvents {}
|
|
76
|
+
declare const tableHandleDragPreviewEvents: EventDeclarations<TableHandleDragPreviewEvents>;
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/components/table-handle/table-handle-drag-preview/element.gen.d.ts
|
|
79
|
+
declare const TableHandleDragPreviewElementBase: BaseElementConstructor<TableHandleDragPreviewProps>;
|
|
80
|
+
declare class TableHandleDragPreviewElement extends TableHandleDragPreviewElementBase {}
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/components/table-handle/table-handle-drag-preview/setup.d.ts
|
|
83
|
+
/**
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
declare function useTableHandleDragPreview(host: ConnectableElement, {
|
|
87
|
+
state
|
|
68
88
|
}: {
|
|
69
|
-
state: SignalState<
|
|
89
|
+
state: SignalState<TableHandleDragPreviewProps>;
|
|
90
|
+
}): void;
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/components/table-handle/table-handle-drop-indicator/types.d.ts
|
|
93
|
+
interface TableHandleDropIndicatorProps {
|
|
94
|
+
editor: Editor<TableCommandsExtension> | null;
|
|
95
|
+
}
|
|
96
|
+
declare const tableHandleDropIndicatorProps: PropDeclarations<TableHandleDropIndicatorProps>;
|
|
97
|
+
interface TableHandleDropIndicatorEvents {}
|
|
98
|
+
declare const tableHandleDropIndicatorEvents: EventDeclarations<TableHandleDropIndicatorEvents>;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/components/table-handle/table-handle-drop-indicator/element.gen.d.ts
|
|
101
|
+
declare const TableHandleDropIndicatorElementBase: BaseElementConstructor<TableHandleDropIndicatorProps>;
|
|
102
|
+
declare class TableHandleDropIndicatorElement extends TableHandleDropIndicatorElementBase {}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/components/table-handle/table-handle-drop-indicator/setup.d.ts
|
|
105
|
+
/**
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
declare function useTableHandleDropIndicator(host: ConnectableElement, {
|
|
109
|
+
state
|
|
110
|
+
}: {
|
|
111
|
+
state: SignalState<TableHandleDropIndicatorProps>;
|
|
70
112
|
}): void;
|
|
71
113
|
//#endregion
|
|
72
114
|
//#region src/components/table-handle/table-handle-popover-content/types.d.ts
|
|
@@ -188,9 +230,9 @@ declare function useTableHandleRowRoot(host: ConnectableElement, {
|
|
|
188
230
|
}: SetupOptions<TableHandleRowRootProps, TableHandleRowRootEvents>): void;
|
|
189
231
|
//#endregion
|
|
190
232
|
//#region src/components/table-handle/table-handle-row-trigger/types.d.ts
|
|
191
|
-
type TableCommandsExtension = ReturnType<typeof defineTableCommands>;
|
|
233
|
+
type TableCommandsExtension$1 = ReturnType<typeof defineTableCommands>;
|
|
192
234
|
interface TableHandleRowTriggerProps {
|
|
193
|
-
editor: Editor<TableCommandsExtension> | null;
|
|
235
|
+
editor: Editor<TableCommandsExtension$1> | null;
|
|
194
236
|
}
|
|
195
237
|
/** @internal */
|
|
196
238
|
declare const tableHandleRowTriggerProps: PropDeclarations<TableHandleRowTriggerProps>;
|
|
@@ -212,4 +254,4 @@ declare function useTableHandleRowTrigger(host: ConnectableElement, {
|
|
|
212
254
|
state
|
|
213
255
|
}: SetupOptions<TableHandleRowTriggerProps, TableHandleRowTriggerEvents>): void;
|
|
214
256
|
//#endregion
|
|
215
|
-
export { TableHandleColumnRootElement, TableHandleColumnRootEvents, TableHandleColumnRootProps, TableHandleColumnTriggerElement, TableHandleColumnTriggerEvents, TableHandleColumnTriggerProps, TableHandlePopoverContentElement, TableHandlePopoverContentEvents, TableHandlePopoverContentProps, TableHandlePopoverItemElement, TableHandlePopoverItemEvents, TableHandlePopoverItemProps, TableHandleRootElement, TableHandleRootEvents, TableHandleRootProps, TableHandleRowRootElement, TableHandleRowRootEvents, TableHandleRowRootProps, TableHandleRowTriggerElement, TableHandleRowTriggerEvents, TableHandleRowTriggerProps, tableHandleColumnRootEvents, tableHandleColumnRootProps, tableHandleColumnTriggerEvents, tableHandleColumnTriggerProps, tableHandlePopoverContentEvents, tableHandlePopoverContentProps, tableHandlePopoverItemEvents, tableHandlePopoverItemProps, tableHandleRootEvents, tableHandleRootProps, tableHandleRowRootEvents, tableHandleRowRootProps, tableHandleRowTriggerEvents, tableHandleRowTriggerProps, useTableHandleColumnRoot, useTableHandleColumnTrigger, useTableHandlePopoverContent, useTableHandlePopoverItem, useTableHandleRoot, useTableHandleRowRoot, useTableHandleRowTrigger };
|
|
257
|
+
export { TableHandleColumnRootElement, TableHandleColumnRootEvents, TableHandleColumnRootProps, TableHandleColumnTriggerElement, TableHandleColumnTriggerEvents, TableHandleColumnTriggerProps, TableHandleDragPreviewElement, TableHandleDragPreviewEvents, TableHandleDragPreviewProps, TableHandleDropIndicatorElement, TableHandleDropIndicatorEvents, TableHandleDropIndicatorProps, TableHandlePopoverContentElement, TableHandlePopoverContentEvents, TableHandlePopoverContentProps, TableHandlePopoverItemElement, TableHandlePopoverItemEvents, TableHandlePopoverItemProps, TableHandleRootElement, TableHandleRootEvents, TableHandleRootProps, TableHandleRowRootElement, TableHandleRowRootEvents, TableHandleRowRootProps, TableHandleRowTriggerElement, TableHandleRowTriggerEvents, TableHandleRowTriggerProps, tableHandleColumnRootEvents, tableHandleColumnRootProps, tableHandleColumnTriggerEvents, tableHandleColumnTriggerProps, tableHandleDragPreviewEvents, tableHandleDragPreviewProps, tableHandleDropIndicatorEvents, tableHandleDropIndicatorProps, tableHandlePopoverContentEvents, tableHandlePopoverContentProps, tableHandlePopoverItemEvents, tableHandlePopoverItemProps, tableHandleRootEvents, tableHandleRootProps, tableHandleRowRootEvents, tableHandleRowRootProps, tableHandleRowTriggerEvents, tableHandleRowTriggerProps, useTableHandleColumnRoot, useTableHandleColumnTrigger, useTableHandleDragPreview, useTableHandleDropIndicator, useTableHandlePopoverContent, useTableHandlePopoverItem, useTableHandleRoot, useTableHandleRowRoot, useTableHandleRowTrigger };
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { getStateWithDefaults } from "./get-
|
|
1
|
+
import { getSafeEditorView, getStateWithDefaults } from "./get-safe-editor-view-CqJWgxo1.js";
|
|
2
2
|
import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
|
|
3
|
+
import { assignStyles, cloneElement, deepCloneElement } from "./clone-element-B55UD54E.js";
|
|
3
4
|
import { createComputed, createContext, createSignal, defineCustomElement, defineEmit, registerCustomElement, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
|
|
4
5
|
import { defineDOMEventHandler, union } from "@prosekit/core";
|
|
5
6
|
import { useOverlayPositionerState } from "@aria-ui/overlay/elements";
|
|
6
7
|
import { usePresence } from "@aria-ui/presence";
|
|
8
|
+
import { isHTMLElement } from "@ocavue/utils";
|
|
7
9
|
import { overlayPositionerEvents as overlayPositionerEvents$1, overlayPositionerProps as overlayPositionerProps$1 } from "@aria-ui/overlay";
|
|
8
10
|
import { menuContentEvents, menuContentProps, menuRootEvents, menuRootProps, useMenuContent, useMenuItem, useMenuRoot, useMenuTrigger } from "@aria-ui/menu/elements";
|
|
9
|
-
import { selectTableColumn, selectTableRow } from "@prosekit/extensions/table";
|
|
11
|
+
import { moveTableColumn, moveTableRow, selectTableColumn, selectTableRow } from "@prosekit/extensions/table";
|
|
12
|
+
import { computePosition, offset } from "@floating-ui/dom";
|
|
10
13
|
import { menuItemEvents, menuItemProps } from "@aria-ui/menu";
|
|
11
14
|
import { TableMap, cellAround } from "prosemirror-tables";
|
|
12
15
|
|
|
@@ -15,6 +18,23 @@ import { TableMap, cellAround } from "prosemirror-tables";
|
|
|
15
18
|
* @internal
|
|
16
19
|
*/
|
|
17
20
|
const tableHandleRootContext = createContext("prosekit-table-handle-root-context", null);
|
|
21
|
+
/**
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
const defaultTableHandleDndContext = {
|
|
25
|
+
dragging: false,
|
|
26
|
+
direction: "row",
|
|
27
|
+
draggingIndex: -1,
|
|
28
|
+
droppingIndex: -1,
|
|
29
|
+
x: -1,
|
|
30
|
+
y: -1,
|
|
31
|
+
startX: -1,
|
|
32
|
+
startY: -1
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
const tableHandleDndContext = createContext("prosekit-table-handle-dnd-context", defaultTableHandleDndContext);
|
|
18
38
|
|
|
19
39
|
//#endregion
|
|
20
40
|
//#region src/components/table-handle/table-handle-column-root/setup.ts
|
|
@@ -29,7 +49,7 @@ function useTableHandleColumnRoot(host, { state }) {
|
|
|
29
49
|
});
|
|
30
50
|
const referenceCell = createComputed(() => {
|
|
31
51
|
const pos = colFirstCellPos.get();
|
|
32
|
-
const view = editor.get()
|
|
52
|
+
const view = getSafeEditorView(editor.get());
|
|
33
53
|
if (!pos || !view) return null;
|
|
34
54
|
return view.nodeDOM(pos);
|
|
35
55
|
});
|
|
@@ -70,6 +90,31 @@ const TableHandleColumnRootElementBase = defineCustomElement({
|
|
|
70
90
|
var TableHandleColumnRootElement = class extends TableHandleColumnRootElementBase {};
|
|
71
91
|
registerCustomElement("prosekit-table-handle-column-root", TableHandleColumnRootElement);
|
|
72
92
|
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/components/table-handle/hooks/use-empty-image.ts
|
|
95
|
+
/**
|
|
96
|
+
* Returns a function that returns a 1x1 transparent image. This is used to
|
|
97
|
+
* prevent the browser from showing the default drag image. An earth icon in
|
|
98
|
+
* chrome is used as the default drag image. This image must be loaded before
|
|
99
|
+
* the dragStart event triggers.
|
|
100
|
+
*
|
|
101
|
+
* See https://stackoverflow.com/a/40923520
|
|
102
|
+
*
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
105
|
+
function useEmptyImage(host) {
|
|
106
|
+
let image;
|
|
107
|
+
useEffect(host, () => {
|
|
108
|
+
image = new Image(1, 1);
|
|
109
|
+
image.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
110
|
+
return () => {
|
|
111
|
+
image?.remove();
|
|
112
|
+
image = void 0;
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
return () => image;
|
|
116
|
+
}
|
|
117
|
+
|
|
73
118
|
//#endregion
|
|
74
119
|
//#region src/components/table-handle/table-handle-column-trigger/setup.ts
|
|
75
120
|
/**
|
|
@@ -78,12 +123,58 @@ registerCustomElement("prosekit-table-handle-column-root", TableHandleColumnRoot
|
|
|
78
123
|
function useTableHandleColumnTrigger(host, { state }) {
|
|
79
124
|
useMenuTrigger(host);
|
|
80
125
|
const context = tableHandleRootContext.consume(host);
|
|
126
|
+
const dndContext = tableHandleDndContext.consume(host);
|
|
81
127
|
useEventListener(host, "pointerdown", () => {
|
|
82
128
|
const editor = state.editor.peek();
|
|
83
129
|
const cellPos = context.peek()?.cellPos;
|
|
84
130
|
if (!editor || !cellPos) return;
|
|
85
131
|
editor.exec(selectTableColumn({ head: cellPos }));
|
|
86
132
|
});
|
|
133
|
+
useEffect(host, () => {
|
|
134
|
+
host.draggable = true;
|
|
135
|
+
});
|
|
136
|
+
const getEmptyImage = useEmptyImage(host);
|
|
137
|
+
useEventListener(host, "dragstart", (event) => {
|
|
138
|
+
const dataTransfer = event.dataTransfer;
|
|
139
|
+
if (dataTransfer) {
|
|
140
|
+
dataTransfer.effectAllowed = "move";
|
|
141
|
+
const emptyImage = getEmptyImage();
|
|
142
|
+
if (emptyImage) dataTransfer.setDragImage(emptyImage, 0, 0);
|
|
143
|
+
}
|
|
144
|
+
const prev = dndContext.peek();
|
|
145
|
+
const index = context.peek()?.colIndex;
|
|
146
|
+
if (index == null || index < 0) {
|
|
147
|
+
console.warn("[prosekit] Invalid column index for drag operation:", index);
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
dndContext.set({
|
|
152
|
+
...prev,
|
|
153
|
+
direction: "col",
|
|
154
|
+
dragging: true,
|
|
155
|
+
draggingIndex: index,
|
|
156
|
+
startX: event.clientX,
|
|
157
|
+
startY: event.clientY
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
useEventListener(host, "drag", (event) => {
|
|
161
|
+
const prev = dndContext.peek();
|
|
162
|
+
if (event.clientX === 0 && event.clientY === 0) return;
|
|
163
|
+
dndContext.set({
|
|
164
|
+
...prev,
|
|
165
|
+
direction: "col",
|
|
166
|
+
dragging: true,
|
|
167
|
+
x: event.clientX,
|
|
168
|
+
y: event.clientY
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
useEventListener(host, "dragend", () => {
|
|
172
|
+
const prev = dndContext.peek();
|
|
173
|
+
dndContext.set({
|
|
174
|
+
...prev,
|
|
175
|
+
dragging: false
|
|
176
|
+
});
|
|
177
|
+
});
|
|
87
178
|
}
|
|
88
179
|
|
|
89
180
|
//#endregion
|
|
@@ -103,6 +194,403 @@ const TableHandleColumnTriggerElementBase = defineCustomElement({
|
|
|
103
194
|
var TableHandleColumnTriggerElement = class extends TableHandleColumnTriggerElementBase {};
|
|
104
195
|
registerCustomElement("prosekit-table-handle-column-trigger", TableHandleColumnTriggerElement);
|
|
105
196
|
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/components/table-handle/dnd.ts
|
|
199
|
+
function useInitDndPosition(host, editor, onInit) {
|
|
200
|
+
const dndContext = tableHandleDndContext.consume(host);
|
|
201
|
+
const rootContext = tableHandleRootContext.consume(host);
|
|
202
|
+
const draggingSignal = createComputed(() => {
|
|
203
|
+
const context = dndContext.get();
|
|
204
|
+
return context.dragging;
|
|
205
|
+
});
|
|
206
|
+
const directionSignal = createComputed(() => {
|
|
207
|
+
const context = dndContext.get();
|
|
208
|
+
return context.direction;
|
|
209
|
+
});
|
|
210
|
+
const draggingIndexSignal = createComputed(() => {
|
|
211
|
+
const context = dndContext.get();
|
|
212
|
+
return context.draggingIndex;
|
|
213
|
+
});
|
|
214
|
+
useEffect(host, () => {
|
|
215
|
+
const view = getSafeEditorView(editor.get());
|
|
216
|
+
if (!view) return;
|
|
217
|
+
const dragging = draggingSignal.get();
|
|
218
|
+
const direction = directionSignal.get();
|
|
219
|
+
host.dataset.direction = direction;
|
|
220
|
+
host.dataset.dragging = dragging.toString();
|
|
221
|
+
const draggingIndex = draggingIndexSignal.get();
|
|
222
|
+
const relatedDOMs = getDndRelatedDOMs(view, rootContext.peek()?.cellPos, draggingIndex, direction);
|
|
223
|
+
if (!relatedDOMs) return;
|
|
224
|
+
const { table, cell } = relatedDOMs;
|
|
225
|
+
onInit({
|
|
226
|
+
host,
|
|
227
|
+
direction,
|
|
228
|
+
dragging,
|
|
229
|
+
draggingIndex,
|
|
230
|
+
table,
|
|
231
|
+
cell
|
|
232
|
+
});
|
|
233
|
+
if (!dragging) return;
|
|
234
|
+
let cancelled = false;
|
|
235
|
+
computePosition(cell, host, {
|
|
236
|
+
placement: direction === "row" ? "right" : "bottom",
|
|
237
|
+
middleware: [offset(({ rects }) => {
|
|
238
|
+
if (direction === "col") return -rects.reference.height;
|
|
239
|
+
return -rects.reference.width;
|
|
240
|
+
})]
|
|
241
|
+
}).then(({ x, y }) => {
|
|
242
|
+
if (cancelled) return;
|
|
243
|
+
assignStyles(host, {
|
|
244
|
+
left: `${x}px`,
|
|
245
|
+
top: `${y}px`
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
return () => {
|
|
249
|
+
cancelled = true;
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
function getTableDOMByPos(view, pos) {
|
|
254
|
+
const dom = view.domAtPos(pos).node;
|
|
255
|
+
if (!dom) return;
|
|
256
|
+
const element = isHTMLElement(dom) ? dom : dom.parentElement;
|
|
257
|
+
const table = element?.closest("table");
|
|
258
|
+
return table ?? void 0;
|
|
259
|
+
}
|
|
260
|
+
function getTargetFirstCellDOM(table, index, direction) {
|
|
261
|
+
if (direction === "row") {
|
|
262
|
+
const row = table.querySelectorAll("tr")[index];
|
|
263
|
+
const cell = row?.querySelector("td");
|
|
264
|
+
return cell ?? void 0;
|
|
265
|
+
} else {
|
|
266
|
+
const row = table.querySelector("tr");
|
|
267
|
+
const cell = row?.querySelectorAll("td")[index];
|
|
268
|
+
return cell ?? void 0;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function getDndRelatedDOMs(view, cellPos, draggingIndex, direction) {
|
|
272
|
+
if (cellPos == null) return;
|
|
273
|
+
const table = getTableDOMByPos(view, cellPos);
|
|
274
|
+
if (!table) return;
|
|
275
|
+
const cell = getTargetFirstCellDOM(table, draggingIndex, direction);
|
|
276
|
+
if (!cell) return;
|
|
277
|
+
return {
|
|
278
|
+
table,
|
|
279
|
+
cell
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region src/components/table-handle/table-handle-drag-preview/render-preview.ts
|
|
285
|
+
function clearPreviewDOM(previewRoot) {
|
|
286
|
+
while (previewRoot.firstChild) previewRoot.removeChild(previewRoot.firstChild);
|
|
287
|
+
}
|
|
288
|
+
function createPreviewDOM(table, previewRoot, index, direction) {
|
|
289
|
+
clearPreviewDOM(previewRoot);
|
|
290
|
+
const previewTable = cloneElementWithoutSize(table);
|
|
291
|
+
const tableBody = table.querySelector("tbody");
|
|
292
|
+
const previewTableBody = tableBody ? cloneElementWithoutSize(tableBody) : table.ownerDocument.createElement("tbody");
|
|
293
|
+
unsetSize(previewTableBody);
|
|
294
|
+
unsetSize(previewTable);
|
|
295
|
+
previewTable.appendChild(previewTableBody);
|
|
296
|
+
previewRoot.appendChild(previewTable);
|
|
297
|
+
const rows = table.querySelectorAll("tr");
|
|
298
|
+
if (direction === "row") {
|
|
299
|
+
const row = rows[index];
|
|
300
|
+
const previewRow = deepCloneElement(row);
|
|
301
|
+
previewTableBody.appendChild(previewRow);
|
|
302
|
+
} else rows.forEach((row) => {
|
|
303
|
+
const previewRow = cloneElementWithoutSize(row);
|
|
304
|
+
unsetSize(previewRow);
|
|
305
|
+
const cells = row.querySelectorAll("td");
|
|
306
|
+
const cell = cells[index];
|
|
307
|
+
if (cell) {
|
|
308
|
+
const previewCell = deepCloneElement(cell);
|
|
309
|
+
previewRow.appendChild(previewCell);
|
|
310
|
+
previewTableBody.appendChild(previewRow);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
function cloneElementWithoutSize(element) {
|
|
315
|
+
const clonedElement = cloneElement(element);
|
|
316
|
+
unsetSize(clonedElement);
|
|
317
|
+
return clonedElement;
|
|
318
|
+
}
|
|
319
|
+
function unsetSize(element) {
|
|
320
|
+
assignStyles(element, {
|
|
321
|
+
width: "unset",
|
|
322
|
+
height: "unset",
|
|
323
|
+
minWidth: "unset",
|
|
324
|
+
minHeight: "unset",
|
|
325
|
+
maxWidth: "unset",
|
|
326
|
+
maxHeight: "unset"
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region src/components/table-handle/table-handle-drag-preview/updater.ts
|
|
332
|
+
function useUpdatePreviewPosition(host, editor) {
|
|
333
|
+
const dndContext = tableHandleDndContext.consume(host);
|
|
334
|
+
const rootContext = tableHandleRootContext.consume(host);
|
|
335
|
+
const draggingSignal = createComputed(() => {
|
|
336
|
+
const context = dndContext.get();
|
|
337
|
+
return context.dragging;
|
|
338
|
+
});
|
|
339
|
+
const clientXSignal = createComputed(() => {
|
|
340
|
+
const context = dndContext.get();
|
|
341
|
+
return context.x;
|
|
342
|
+
});
|
|
343
|
+
const clientYSignal = createComputed(() => {
|
|
344
|
+
const context = dndContext.get();
|
|
345
|
+
return context.y;
|
|
346
|
+
});
|
|
347
|
+
useEffect(host, () => {
|
|
348
|
+
const view = getSafeEditorView(editor.get());
|
|
349
|
+
if (!view) return;
|
|
350
|
+
if (!draggingSignal.get()) return;
|
|
351
|
+
const { draggingIndex, direction } = dndContext.peek();
|
|
352
|
+
const x = clientXSignal.get();
|
|
353
|
+
const y = clientYSignal.get();
|
|
354
|
+
const relatedDOMs = getDndRelatedDOMs(view, rootContext.peek()?.cellPos, draggingIndex, direction);
|
|
355
|
+
if (!relatedDOMs) return;
|
|
356
|
+
const { cell } = relatedDOMs;
|
|
357
|
+
let cancelled = false;
|
|
358
|
+
computePosition(getVirtualElement(cell, x, y), host, { placement: direction === "row" ? "right" : "bottom" }).then(({ x: x$1, y: y$1 }) => {
|
|
359
|
+
if (cancelled) return;
|
|
360
|
+
if (direction === "row") {
|
|
361
|
+
assignStyles(host, { top: `${y$1}px` });
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (direction === "col") {
|
|
365
|
+
assignStyles(host, { left: `${x$1}px` });
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
return () => {
|
|
370
|
+
cancelled = true;
|
|
371
|
+
};
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
function getVirtualElement(cell, x, y) {
|
|
375
|
+
return {
|
|
376
|
+
contextElement: cell,
|
|
377
|
+
getBoundingClientRect: () => {
|
|
378
|
+
const rect = cell.getBoundingClientRect();
|
|
379
|
+
return {
|
|
380
|
+
width: rect.width,
|
|
381
|
+
height: rect.height,
|
|
382
|
+
right: x + rect.width / 2,
|
|
383
|
+
bottom: y + rect.height / 2,
|
|
384
|
+
top: y - rect.height / 2,
|
|
385
|
+
left: x - rect.width / 2,
|
|
386
|
+
x: x - rect.width / 2,
|
|
387
|
+
y: y - rect.height / 2
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
//#endregion
|
|
394
|
+
//#region src/components/table-handle/table-handle-drag-preview/setup.ts
|
|
395
|
+
/**
|
|
396
|
+
* @internal
|
|
397
|
+
*/
|
|
398
|
+
function useTableHandleDragPreview(host, { state }) {
|
|
399
|
+
const { editor } = state;
|
|
400
|
+
useEffect(host, () => {
|
|
401
|
+
assignStyles(host, {
|
|
402
|
+
position: "absolute",
|
|
403
|
+
pointerEvents: "none"
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
useInitDndPosition(host, editor, onInitPreviewPosition);
|
|
407
|
+
useUpdatePreviewPosition(host, editor);
|
|
408
|
+
}
|
|
409
|
+
function onInitPreviewPosition({ host, direction, dragging, table, cell, draggingIndex }) {
|
|
410
|
+
assignStyles(host, { display: dragging ? "block" : "none" });
|
|
411
|
+
if (!dragging) {
|
|
412
|
+
clearPreviewDOM(host);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
createPreviewDOM(table, host, draggingIndex, direction);
|
|
416
|
+
const tableRect = table.getBoundingClientRect();
|
|
417
|
+
const cellRect = cell.getBoundingClientRect();
|
|
418
|
+
if (direction === "col") assignStyles(host, {
|
|
419
|
+
width: `${cellRect.width}px`,
|
|
420
|
+
height: `${tableRect.height}px`
|
|
421
|
+
});
|
|
422
|
+
if (direction === "row") assignStyles(host, {
|
|
423
|
+
width: `${tableRect.width}px`,
|
|
424
|
+
height: `${cellRect.height}px`
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region src/components/table-handle/table-handle-drag-preview/types.ts
|
|
430
|
+
const tableHandleDragPreviewProps = { editor: { default: null } };
|
|
431
|
+
const tableHandleDragPreviewEvents = {};
|
|
432
|
+
|
|
433
|
+
//#endregion
|
|
434
|
+
//#region src/components/table-handle/table-handle-drag-preview/element.gen.ts
|
|
435
|
+
const TableHandleDragPreviewElementBase = defineCustomElement({
|
|
436
|
+
props: tableHandleDragPreviewProps,
|
|
437
|
+
events: tableHandleDragPreviewEvents,
|
|
438
|
+
setup: useTableHandleDragPreview
|
|
439
|
+
});
|
|
440
|
+
var TableHandleDragPreviewElement = class extends TableHandleDragPreviewElementBase {};
|
|
441
|
+
registerCustomElement("prosekit-table-handle-drag-preview", TableHandleDragPreviewElement);
|
|
442
|
+
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region src/components/table-handle/table-handle-drop-indicator/calc-drag-over.ts
|
|
445
|
+
function findDragOverElement(elements, pointer, axis) {
|
|
446
|
+
const startProp = axis === "x" ? "left" : "top";
|
|
447
|
+
const endProp = axis === "x" ? "right" : "bottom";
|
|
448
|
+
const lastIndex = elements.length - 1;
|
|
449
|
+
const index = elements.findIndex((el, index$1) => {
|
|
450
|
+
const rect = el.getBoundingClientRect();
|
|
451
|
+
const boundaryStart = rect[startProp];
|
|
452
|
+
const boundaryEnd = rect[endProp];
|
|
453
|
+
if (boundaryStart <= pointer && pointer <= boundaryEnd) return true;
|
|
454
|
+
if (index$1 === lastIndex && pointer > boundaryEnd) return true;
|
|
455
|
+
if (index$1 === 0 && pointer < boundaryStart) return true;
|
|
456
|
+
return false;
|
|
457
|
+
});
|
|
458
|
+
return index >= 0 ? [elements[index], index] : void 0;
|
|
459
|
+
}
|
|
460
|
+
function getDragOverColumn(table, pointerX) {
|
|
461
|
+
const firstRow = table.querySelector("tr");
|
|
462
|
+
if (!firstRow) return;
|
|
463
|
+
const cells = Array.from(firstRow.children);
|
|
464
|
+
return findDragOverElement(cells, pointerX, "x");
|
|
465
|
+
}
|
|
466
|
+
function getDragOverRow(table, pointerY) {
|
|
467
|
+
const rows = Array.from(table.querySelectorAll("tr"));
|
|
468
|
+
return findDragOverElement(rows, pointerY, "y");
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
//#endregion
|
|
472
|
+
//#region src/components/table-handle/table-handle-drop-indicator/updater.ts
|
|
473
|
+
function useUpdateIndicatorPosition(host, editor, handleWidth) {
|
|
474
|
+
const dndContext = tableHandleDndContext.consume(host);
|
|
475
|
+
const rootContext = tableHandleRootContext.consume(host);
|
|
476
|
+
const draggingSignal = createComputed(() => {
|
|
477
|
+
const context = dndContext.get();
|
|
478
|
+
return context.dragging;
|
|
479
|
+
});
|
|
480
|
+
const clientXSignal = createComputed(() => {
|
|
481
|
+
const context = dndContext.get();
|
|
482
|
+
return context.x;
|
|
483
|
+
});
|
|
484
|
+
const clientYSignal = createComputed(() => {
|
|
485
|
+
const context = dndContext.get();
|
|
486
|
+
return context.y;
|
|
487
|
+
});
|
|
488
|
+
const startXSignal = createComputed(() => {
|
|
489
|
+
return dndContext.get().startX;
|
|
490
|
+
});
|
|
491
|
+
const startYSignal = createComputed(() => {
|
|
492
|
+
return dndContext.get().startY;
|
|
493
|
+
});
|
|
494
|
+
useEffect(host, () => {
|
|
495
|
+
const view = getSafeEditorView(editor.get());
|
|
496
|
+
if (!view) return;
|
|
497
|
+
if (!draggingSignal.get()) return;
|
|
498
|
+
const { draggingIndex, direction } = dndContext.peek();
|
|
499
|
+
const x = clientXSignal.get();
|
|
500
|
+
const y = clientYSignal.get();
|
|
501
|
+
const relatedDOMs = getDndRelatedDOMs(view, rootContext.peek()?.cellPos, draggingIndex, direction);
|
|
502
|
+
if (!relatedDOMs) return;
|
|
503
|
+
const { table } = relatedDOMs;
|
|
504
|
+
let cancelled = false;
|
|
505
|
+
let cleanup = () => {
|
|
506
|
+
cancelled = true;
|
|
507
|
+
};
|
|
508
|
+
if (direction === "col") {
|
|
509
|
+
const direction$1 = startXSignal.get() > x ? "left" : "right";
|
|
510
|
+
const dragOverColumn = getDragOverColumn(table, x);
|
|
511
|
+
if (dragOverColumn) {
|
|
512
|
+
const [col, index] = dragOverColumn;
|
|
513
|
+
dndContext.set({
|
|
514
|
+
...dndContext.peek(),
|
|
515
|
+
droppingIndex: index
|
|
516
|
+
});
|
|
517
|
+
computePosition(col, host, {
|
|
518
|
+
placement: direction$1 === "left" ? "left" : "right",
|
|
519
|
+
middleware: [offset(direction$1 === "left" ? -1 * handleWidth : 0)]
|
|
520
|
+
}).then(({ x: x$1 }) => {
|
|
521
|
+
if (cancelled) return;
|
|
522
|
+
assignStyles(host, { left: `${x$1}px` });
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
return cleanup;
|
|
526
|
+
}
|
|
527
|
+
if (direction === "row") {
|
|
528
|
+
const direction$1 = startYSignal.get() > y ? "up" : "down";
|
|
529
|
+
const dragOverRow = getDragOverRow(table, y);
|
|
530
|
+
if (dragOverRow) {
|
|
531
|
+
const [row, index] = dragOverRow;
|
|
532
|
+
dndContext.set({
|
|
533
|
+
...dndContext.peek(),
|
|
534
|
+
droppingIndex: index
|
|
535
|
+
});
|
|
536
|
+
computePosition(row, host, {
|
|
537
|
+
placement: direction$1 === "up" ? "top" : "bottom",
|
|
538
|
+
middleware: [offset(direction$1 === "up" ? -1 * handleWidth : 0)]
|
|
539
|
+
}).then(({ y: y$1 }) => {
|
|
540
|
+
if (cancelled) return;
|
|
541
|
+
assignStyles(host, { top: `${y$1}px` });
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
return cleanup;
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
//#endregion
|
|
550
|
+
//#region src/components/table-handle/table-handle-drop-indicator/setup.ts
|
|
551
|
+
const HANDLE_WIDTH = 2;
|
|
552
|
+
/**
|
|
553
|
+
* @internal
|
|
554
|
+
*/
|
|
555
|
+
function useTableHandleDropIndicator(host, { state }) {
|
|
556
|
+
const { editor } = state;
|
|
557
|
+
useEffect(host, () => {
|
|
558
|
+
assignStyles(host, {
|
|
559
|
+
pointerEvents: "none",
|
|
560
|
+
position: "absolute"
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
useInitDndPosition(host, editor, onInitIndicatorPosition);
|
|
564
|
+
useUpdateIndicatorPosition(host, editor, HANDLE_WIDTH);
|
|
565
|
+
}
|
|
566
|
+
function onInitIndicatorPosition({ host, direction, dragging, table }) {
|
|
567
|
+
assignStyles(host, { display: dragging ? "block" : "none" });
|
|
568
|
+
const tableRect = table.getBoundingClientRect();
|
|
569
|
+
if (direction === "col") assignStyles(host, {
|
|
570
|
+
width: `${HANDLE_WIDTH}px`,
|
|
571
|
+
height: `${tableRect.height}px`
|
|
572
|
+
});
|
|
573
|
+
if (direction === "row") assignStyles(host, {
|
|
574
|
+
width: `${tableRect.width}px`,
|
|
575
|
+
height: `${HANDLE_WIDTH}px`
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/components/table-handle/table-handle-drop-indicator/types.ts
|
|
581
|
+
const tableHandleDropIndicatorProps = { editor: { default: null } };
|
|
582
|
+
const tableHandleDropIndicatorEvents = {};
|
|
583
|
+
|
|
584
|
+
//#endregion
|
|
585
|
+
//#region src/components/table-handle/table-handle-drop-indicator/element.gen.ts
|
|
586
|
+
const TableHandleDropIndicatorElementBase = defineCustomElement({
|
|
587
|
+
props: tableHandleDropIndicatorProps,
|
|
588
|
+
events: tableHandleDropIndicatorEvents,
|
|
589
|
+
setup: useTableHandleDropIndicator
|
|
590
|
+
});
|
|
591
|
+
var TableHandleDropIndicatorElement = class extends TableHandleDropIndicatorElementBase {};
|
|
592
|
+
registerCustomElement("prosekit-table-handle-drop-indicator", TableHandleDropIndicatorElement);
|
|
593
|
+
|
|
106
594
|
//#endregion
|
|
107
595
|
//#region src/components/table-handle/table-handle-popover-content/setup.ts
|
|
108
596
|
/**
|
|
@@ -216,6 +704,54 @@ function useEditorTyping(host, editor) {
|
|
|
216
704
|
return typing;
|
|
217
705
|
}
|
|
218
706
|
|
|
707
|
+
//#endregion
|
|
708
|
+
//#region src/components/table-handle/hooks/use-drop.ts
|
|
709
|
+
function useDrop(host, editor, dndContext) {
|
|
710
|
+
const dragging = createComputed(() => dndContext.get().dragging);
|
|
711
|
+
useEffect(host, () => {
|
|
712
|
+
if (!dragging.get()) return;
|
|
713
|
+
const view = getSafeEditorView(editor.peek());
|
|
714
|
+
if (!view || !view.editable) return;
|
|
715
|
+
const ownerDocument = view.dom?.ownerDocument;
|
|
716
|
+
if (!ownerDocument) return;
|
|
717
|
+
const handleDrop = () => {
|
|
718
|
+
const editorValue = editor.peek();
|
|
719
|
+
if (!editorValue) return;
|
|
720
|
+
const { droppingIndex, draggingIndex, direction } = dndContext.peek();
|
|
721
|
+
if (draggingIndex < 0 || droppingIndex < 0) {
|
|
722
|
+
console.warn("[prosekit] Invalid drag indices:", {
|
|
723
|
+
draggingIndex,
|
|
724
|
+
droppingIndex
|
|
725
|
+
});
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
if (direction === "row") {
|
|
729
|
+
editorValue.exec(moveTableRow({
|
|
730
|
+
from: draggingIndex,
|
|
731
|
+
to: droppingIndex
|
|
732
|
+
}));
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (direction === "col") {
|
|
736
|
+
editorValue.exec(moveTableColumn({
|
|
737
|
+
from: draggingIndex,
|
|
738
|
+
to: droppingIndex
|
|
739
|
+
}));
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
const handleDragOver = (event) => {
|
|
744
|
+
event.preventDefault();
|
|
745
|
+
};
|
|
746
|
+
ownerDocument.addEventListener("dragover", handleDragOver);
|
|
747
|
+
ownerDocument.addEventListener("drop", handleDrop);
|
|
748
|
+
return () => {
|
|
749
|
+
ownerDocument.removeEventListener("dragover", handleDragOver);
|
|
750
|
+
ownerDocument.removeEventListener("drop", handleDrop);
|
|
751
|
+
};
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
|
|
219
755
|
//#endregion
|
|
220
756
|
//#region src/components/table-handle/utils.ts
|
|
221
757
|
function isHoveringCellInfoEqual(a, b) {
|
|
@@ -273,6 +809,7 @@ function getCellIndex(map, rowIndex, colIndex) {
|
|
|
273
809
|
function useTableHandleRoot(host, { state }) {
|
|
274
810
|
const { editor } = state;
|
|
275
811
|
const context = createSignal(null);
|
|
812
|
+
const dndContext = createSignal(defaultTableHandleDndContext);
|
|
276
813
|
const hoveringCell = useHoveringCell(host, editor);
|
|
277
814
|
const typing = useEditorTyping(host, editor);
|
|
278
815
|
const isInTable = createComputed(() => !!hoveringCell.get());
|
|
@@ -284,6 +821,8 @@ function useTableHandleRoot(host, { state }) {
|
|
|
284
821
|
context.set(typingValue || selectingValue ? null : hoveringCellValue);
|
|
285
822
|
});
|
|
286
823
|
tableHandleRootContext.provide(host, context);
|
|
824
|
+
tableHandleDndContext.provide(host, dndContext);
|
|
825
|
+
useDrop(host, editor, dndContext);
|
|
287
826
|
}
|
|
288
827
|
function useHoveringCell(host, editor) {
|
|
289
828
|
const hoveringCell = createSignal(null);
|
|
@@ -308,7 +847,8 @@ function useSelecting(host, editor, isInTable) {
|
|
|
308
847
|
const selecting = createSignal(false);
|
|
309
848
|
useEffect(host, () => {
|
|
310
849
|
if (!isInTable.get()) return;
|
|
311
|
-
const
|
|
850
|
+
const view = getSafeEditorView(editor.peek());
|
|
851
|
+
const root = view?.root;
|
|
312
852
|
if (!root) return;
|
|
313
853
|
const pointerDownHandler = (event) => {
|
|
314
854
|
const target = event.target;
|
|
@@ -358,7 +898,7 @@ function useTableHandleRowRoot(host, { state }) {
|
|
|
358
898
|
});
|
|
359
899
|
const referenceCell = createComputed(() => {
|
|
360
900
|
const pos = rowFirstCellPos.get();
|
|
361
|
-
const view = editor.get()
|
|
901
|
+
const view = getSafeEditorView(editor.get());
|
|
362
902
|
if (!pos || !view) return null;
|
|
363
903
|
return view.nodeDOM(pos);
|
|
364
904
|
});
|
|
@@ -407,12 +947,58 @@ registerCustomElement("prosekit-table-handle-row-root", TableHandleRowRootElemen
|
|
|
407
947
|
function useTableHandleRowTrigger(host, { state }) {
|
|
408
948
|
useMenuTrigger(host);
|
|
409
949
|
const context = tableHandleRootContext.consume(host);
|
|
950
|
+
const dndContext = tableHandleDndContext.consume(host);
|
|
410
951
|
useEventListener(host, "pointerdown", () => {
|
|
411
952
|
const editor = state.editor.peek();
|
|
412
953
|
const cellPos = context.peek()?.cellPos;
|
|
413
954
|
if (!editor || !cellPos) return;
|
|
414
955
|
editor.exec(selectTableRow({ head: cellPos }));
|
|
415
956
|
});
|
|
957
|
+
useEffect(host, () => {
|
|
958
|
+
host.draggable = true;
|
|
959
|
+
});
|
|
960
|
+
const getEmptyImage = useEmptyImage(host);
|
|
961
|
+
useEventListener(host, "dragstart", (event) => {
|
|
962
|
+
const dataTransfer = event.dataTransfer;
|
|
963
|
+
if (dataTransfer) {
|
|
964
|
+
dataTransfer.effectAllowed = "move";
|
|
965
|
+
const emptyImage = getEmptyImage();
|
|
966
|
+
if (emptyImage) dataTransfer.setDragImage(emptyImage, 0, 0);
|
|
967
|
+
}
|
|
968
|
+
const prev = dndContext.peek();
|
|
969
|
+
const index = context.peek()?.rowIndex;
|
|
970
|
+
if (index == null || index < 0) {
|
|
971
|
+
console.warn("[prosekit] Invalid row index for drag operation:", index);
|
|
972
|
+
event.preventDefault();
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
dndContext.set({
|
|
976
|
+
...prev,
|
|
977
|
+
direction: "row",
|
|
978
|
+
dragging: true,
|
|
979
|
+
draggingIndex: index,
|
|
980
|
+
startX: event.clientX,
|
|
981
|
+
startY: event.clientY
|
|
982
|
+
});
|
|
983
|
+
});
|
|
984
|
+
useEventListener(host, "drag", (event) => {
|
|
985
|
+
const prev = dndContext.peek();
|
|
986
|
+
if (event.clientX === 0 && event.clientY === 0) return;
|
|
987
|
+
dndContext.set({
|
|
988
|
+
...prev,
|
|
989
|
+
direction: "row",
|
|
990
|
+
dragging: true,
|
|
991
|
+
x: event.clientX,
|
|
992
|
+
y: event.clientY
|
|
993
|
+
});
|
|
994
|
+
});
|
|
995
|
+
useEventListener(host, "dragend", () => {
|
|
996
|
+
const prev = dndContext.peek();
|
|
997
|
+
dndContext.set({
|
|
998
|
+
...prev,
|
|
999
|
+
dragging: false
|
|
1000
|
+
});
|
|
1001
|
+
});
|
|
416
1002
|
}
|
|
417
1003
|
|
|
418
1004
|
//#endregion
|
|
@@ -433,4 +1019,4 @@ var TableHandleRowTriggerElement = class extends TableHandleRowTriggerElementBas
|
|
|
433
1019
|
registerCustomElement("prosekit-table-handle-row-trigger", TableHandleRowTriggerElement);
|
|
434
1020
|
|
|
435
1021
|
//#endregion
|
|
436
|
-
export { TableHandleColumnRootElement, TableHandleColumnTriggerElement, TableHandlePopoverContentElement, TableHandlePopoverItemElement, TableHandleRootElement, TableHandleRowRootElement, TableHandleRowTriggerElement, tableHandleColumnRootEvents, tableHandleColumnRootProps, tableHandleColumnTriggerEvents, tableHandleColumnTriggerProps, tableHandlePopoverContentEvents, tableHandlePopoverContentProps, tableHandlePopoverItemEvents, tableHandlePopoverItemProps, tableHandleRootEvents, tableHandleRootProps, tableHandleRowRootEvents, tableHandleRowRootProps, tableHandleRowTriggerEvents, tableHandleRowTriggerProps, useTableHandleColumnRoot, useTableHandleColumnTrigger, useTableHandlePopoverContent, useTableHandlePopoverItem, useTableHandleRoot, useTableHandleRowRoot, useTableHandleRowTrigger };
|
|
1022
|
+
export { TableHandleColumnRootElement, TableHandleColumnTriggerElement, TableHandleDragPreviewElement, TableHandleDropIndicatorElement, TableHandlePopoverContentElement, TableHandlePopoverItemElement, TableHandleRootElement, TableHandleRowRootElement, TableHandleRowTriggerElement, tableHandleColumnRootEvents, tableHandleColumnRootProps, tableHandleColumnTriggerEvents, tableHandleColumnTriggerProps, tableHandleDragPreviewEvents, tableHandleDragPreviewProps, tableHandleDropIndicatorEvents, tableHandleDropIndicatorProps, tableHandlePopoverContentEvents, tableHandlePopoverContentProps, tableHandlePopoverItemEvents, tableHandlePopoverItemProps, tableHandleRootEvents, tableHandleRootProps, tableHandleRowRootEvents, tableHandleRowRootProps, tableHandleRowTriggerEvents, tableHandleRowTriggerProps, useTableHandleColumnRoot, useTableHandleColumnTrigger, useTableHandleDragPreview, useTableHandleDropIndicator, useTableHandlePopoverContent, useTableHandlePopoverItem, useTableHandleRoot, useTableHandleRowRoot, useTableHandleRowTrigger };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosekit/web",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "A collection of web components for ProseKit",
|
|
7
7
|
"author": {
|
|
@@ -66,22 +66,22 @@
|
|
|
66
66
|
"@aria-ui/collection": "^0.0.5",
|
|
67
67
|
"@aria-ui/core": "^0.0.21",
|
|
68
68
|
"@aria-ui/listbox": "^0.0.24",
|
|
69
|
-
"@aria-ui/menu": "^0.0.
|
|
69
|
+
"@aria-ui/menu": "^0.0.20",
|
|
70
70
|
"@aria-ui/overlay": "^0.0.24",
|
|
71
71
|
"@aria-ui/popover": "^0.0.27",
|
|
72
72
|
"@aria-ui/presence": "^0.0.19",
|
|
73
73
|
"@aria-ui/tooltip": "^0.0.29",
|
|
74
|
-
"@floating-ui/dom": "^1.7.
|
|
74
|
+
"@floating-ui/dom": "^1.7.2",
|
|
75
75
|
"@ocavue/utils": "^0.5.0",
|
|
76
76
|
"prosemirror-tables": "^1.7.1",
|
|
77
|
-
"@prosekit/
|
|
78
|
-
"@prosekit/
|
|
79
|
-
"@prosekit/
|
|
77
|
+
"@prosekit/core": "^0.8.3",
|
|
78
|
+
"@prosekit/extensions": "^0.10.0",
|
|
79
|
+
"@prosekit/pm": "^0.1.11"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"tsdown": "^0.12.
|
|
82
|
+
"tsdown": "^0.12.9",
|
|
83
83
|
"typescript": "~5.8.3",
|
|
84
|
-
"vitest": "^3.2.
|
|
84
|
+
"vitest": "^3.2.4",
|
|
85
85
|
"@prosekit/config-tsdown": "0.0.0",
|
|
86
86
|
"@prosekit/config-vitest": "0.0.0"
|
|
87
87
|
},
|