@prosekit/web 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/dist/_tsup-dts-rollup.d.ts +664 -0
- package/dist/chunk-LJ7LCZM7.js +26 -0
- package/dist/chunk-VJEVDINM.js +14 -0
- package/dist/prosekit-web-autocomplete.d.ts +12 -0
- package/dist/prosekit-web-autocomplete.js +354 -0
- package/dist/prosekit-web-block-handle.d.ts +6 -0
- package/dist/prosekit-web-block-handle.js +242 -0
- package/dist/prosekit-web-inline-popover.d.ts +3 -0
- package/dist/prosekit-web-inline-popover.js +161 -0
- package/dist/prosekit-web-popover.d.ts +9 -0
- package/dist/prosekit-web-popover.js +79 -0
- package/dist/prosekit-web-resizable.d.ts +6 -0
- package/dist/prosekit-web-resizable.js +286 -0
- package/dist/prosekit-web-tooltip.d.ts +9 -0
- package/dist/prosekit-web-tooltip.js +73 -0
- package/dist/prosekit-web.d.ts +1 -0
- package/dist/prosekit-web.js +0 -0
- package/package.json +116 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/hooks/use-editor-extension.ts
|
|
2
|
+
import {
|
|
3
|
+
useEffect
|
|
4
|
+
} from "@aria-ui/core";
|
|
5
|
+
function useEditorExtension(host, editor, extension) {
|
|
6
|
+
useEffect(host, () => {
|
|
7
|
+
var _a;
|
|
8
|
+
return (_a = editor.value) == null ? void 0 : _a.use(extension);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
useEditorExtension
|
|
14
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { AutocompleteEmptyElement } from './_tsup-dts-rollup';
|
|
2
|
+
export { defaultAutocompleteEmptyProps } from './_tsup-dts-rollup';
|
|
3
|
+
export { AutocompleteEmptyProps } from './_tsup-dts-rollup';
|
|
4
|
+
export { AutocompleteItemElement } from './_tsup-dts-rollup';
|
|
5
|
+
export { defaultAutocompleteItemProps } from './_tsup-dts-rollup';
|
|
6
|
+
export { AutocompleteItemProps } from './_tsup-dts-rollup';
|
|
7
|
+
export { AutocompleteListElement } from './_tsup-dts-rollup';
|
|
8
|
+
export { defaultAutocompleteListProps } from './_tsup-dts-rollup';
|
|
9
|
+
export { AutocompleteListProps } from './_tsup-dts-rollup';
|
|
10
|
+
export { AutocompletePopoverElement } from './_tsup-dts-rollup';
|
|
11
|
+
export { defaultAutocompletePopoverProps } from './_tsup-dts-rollup';
|
|
12
|
+
export { AutocompletePopoverProps } from './_tsup-dts-rollup';
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineCustomElement,
|
|
3
|
+
defineProperties
|
|
4
|
+
} from "./chunk-LJ7LCZM7.js";
|
|
5
|
+
|
|
6
|
+
// src/components/autocomplete/autocomplete-empty/element.gen.ts
|
|
7
|
+
import { BaseElement } from "@aria-ui/core";
|
|
8
|
+
|
|
9
|
+
// src/components/autocomplete/autocomplete-empty/props.ts
|
|
10
|
+
var defaultAutocompleteEmptyProps = {};
|
|
11
|
+
|
|
12
|
+
// src/components/autocomplete/autocomplete-empty/state.ts
|
|
13
|
+
import { useListboxEmpty } from "@aria-ui/listbox";
|
|
14
|
+
function useAutocompleteEmpty(element, _props) {
|
|
15
|
+
useListboxEmpty(element);
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/components/autocomplete/autocomplete-empty/element.gen.ts
|
|
20
|
+
var AutocompleteEmptyElement = class extends BaseElement {
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this._s = useAutocompleteEmpty(this);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
defineProperties(AutocompleteEmptyElement, defaultAutocompleteEmptyProps);
|
|
27
|
+
defineCustomElement("prosekit-autocomplete-empty", AutocompleteEmptyElement);
|
|
28
|
+
|
|
29
|
+
// src/components/autocomplete/autocomplete-item/element.gen.ts
|
|
30
|
+
import { BaseElement as BaseElement2 } from "@aria-ui/core";
|
|
31
|
+
|
|
32
|
+
// src/components/autocomplete/autocomplete-item/props.ts
|
|
33
|
+
var defaultAutocompleteItemProps = {
|
|
34
|
+
value: "",
|
|
35
|
+
onSelect: null
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/components/autocomplete/autocomplete-item/state.ts
|
|
39
|
+
import {
|
|
40
|
+
useEffect
|
|
41
|
+
} from "@aria-ui/core";
|
|
42
|
+
import { useListboxItem } from "@aria-ui/listbox";
|
|
43
|
+
|
|
44
|
+
// src/components/autocomplete/context.ts
|
|
45
|
+
import { createContext } from "@aria-ui/core";
|
|
46
|
+
var queryContext = createContext(
|
|
47
|
+
"prosekit/autocomplete-popover/query",
|
|
48
|
+
""
|
|
49
|
+
);
|
|
50
|
+
var onSubmitContext = createContext(
|
|
51
|
+
"prosekit/autocomplete-popover/onSubmit",
|
|
52
|
+
null
|
|
53
|
+
);
|
|
54
|
+
var openContext = createContext(
|
|
55
|
+
"prosekit/autocomplete-popover/open",
|
|
56
|
+
false
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// src/components/autocomplete/autocomplete-item/state.ts
|
|
60
|
+
function useAutocompleteItem(element, props) {
|
|
61
|
+
const { onSelect, value } = useListboxItem(element, props);
|
|
62
|
+
const open = openContext.consume(element);
|
|
63
|
+
useEffect(element, () => {
|
|
64
|
+
var _a;
|
|
65
|
+
if (!value.peek() && open.value) {
|
|
66
|
+
value.value = (_a = element.textContent) != null ? _a : "";
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return { onSelect, value };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/components/autocomplete/autocomplete-item/element.gen.ts
|
|
73
|
+
var AutocompleteItemElement = class extends BaseElement2 {
|
|
74
|
+
constructor() {
|
|
75
|
+
super();
|
|
76
|
+
this._s = useAutocompleteItem(this);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
defineProperties(AutocompleteItemElement, defaultAutocompleteItemProps);
|
|
80
|
+
defineCustomElement("prosekit-autocomplete-item", AutocompleteItemElement);
|
|
81
|
+
|
|
82
|
+
// src/components/autocomplete/autocomplete-list/element.gen.ts
|
|
83
|
+
import { BaseElement as BaseElement3 } from "@aria-ui/core";
|
|
84
|
+
|
|
85
|
+
// src/components/autocomplete/autocomplete-list/props.ts
|
|
86
|
+
var defaultAutocompleteListProps = {
|
|
87
|
+
editor: null
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// src/components/autocomplete/autocomplete-list/state.ts
|
|
91
|
+
import {
|
|
92
|
+
assignProps,
|
|
93
|
+
createSignal,
|
|
94
|
+
mapSignals,
|
|
95
|
+
useEffect as useEffect2
|
|
96
|
+
} from "@aria-ui/core";
|
|
97
|
+
import { useListbox } from "@aria-ui/listbox";
|
|
98
|
+
import {
|
|
99
|
+
Priority,
|
|
100
|
+
defineDOMEventHandler,
|
|
101
|
+
withPriority
|
|
102
|
+
} from "@prosekit/core";
|
|
103
|
+
function useAutocompleteList(element, props) {
|
|
104
|
+
const state = mapSignals(assignProps(defaultAutocompleteListProps, props));
|
|
105
|
+
const open = openContext.consume(element);
|
|
106
|
+
const query = queryContext.consume(element);
|
|
107
|
+
const onSubmit = onSubmitContext.consume(element);
|
|
108
|
+
const onKeydownHandlerAdd = useKeyboardHandler(element, open, state.editor);
|
|
109
|
+
const {
|
|
110
|
+
query: listboxQuery,
|
|
111
|
+
value: listboxValue,
|
|
112
|
+
autoFocus
|
|
113
|
+
} = useListbox(element, {
|
|
114
|
+
onKeydownHandlerAdd,
|
|
115
|
+
// This function will be called before `onSubmit()`.
|
|
116
|
+
onValueChange: (value) => {
|
|
117
|
+
var _a;
|
|
118
|
+
if (value) {
|
|
119
|
+
(_a = onSubmit.value) == null ? void 0 : _a.call(onSubmit);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
useEffect2(element, () => {
|
|
124
|
+
listboxQuery.value = query.value;
|
|
125
|
+
});
|
|
126
|
+
useEffect2(element, () => {
|
|
127
|
+
if (!open.value) {
|
|
128
|
+
listboxValue.value = "";
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
useEffect2(element, () => {
|
|
132
|
+
if (!open.value) {
|
|
133
|
+
autoFocus.value = false;
|
|
134
|
+
} else {
|
|
135
|
+
query.value;
|
|
136
|
+
let canceled = false;
|
|
137
|
+
requestAnimationFrame(() => {
|
|
138
|
+
if (canceled)
|
|
139
|
+
return;
|
|
140
|
+
autoFocus.value = true;
|
|
141
|
+
setTimeout(() => {
|
|
142
|
+
if (canceled)
|
|
143
|
+
return;
|
|
144
|
+
autoFocus.value = false;
|
|
145
|
+
}, 40);
|
|
146
|
+
});
|
|
147
|
+
return () => {
|
|
148
|
+
canceled = true;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return state;
|
|
153
|
+
}
|
|
154
|
+
function useKeyboardHandler(element, open, editor) {
|
|
155
|
+
const keydownHandler = createSignal(
|
|
156
|
+
null
|
|
157
|
+
);
|
|
158
|
+
let disposeKeydownHandler = null;
|
|
159
|
+
useEffect2(element, () => {
|
|
160
|
+
const editorValue = editor.value;
|
|
161
|
+
const keydownHandlerValue = keydownHandler.value;
|
|
162
|
+
if (!editorValue || !keydownHandlerValue) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const extension = defineDOMEventHandler(
|
|
166
|
+
"keydown",
|
|
167
|
+
(view, event) => {
|
|
168
|
+
if (view.composing || event.defaultPrevented || !open.value) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
keydownHandlerValue(event);
|
|
172
|
+
return event.defaultPrevented;
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
disposeKeydownHandler == null ? void 0 : disposeKeydownHandler();
|
|
176
|
+
disposeKeydownHandler = editorValue.use(
|
|
177
|
+
withPriority(extension, Priority.highest)
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
return (keydownHandlerValue) => {
|
|
181
|
+
keydownHandler.value = keydownHandlerValue;
|
|
182
|
+
return () => {
|
|
183
|
+
disposeKeydownHandler == null ? void 0 : disposeKeydownHandler();
|
|
184
|
+
disposeKeydownHandler = null;
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/components/autocomplete/autocomplete-list/element.gen.ts
|
|
190
|
+
var AutocompleteListElement = class extends BaseElement3 {
|
|
191
|
+
constructor() {
|
|
192
|
+
super();
|
|
193
|
+
this._s = useAutocompleteList(this);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
defineProperties(AutocompleteListElement, defaultAutocompleteListProps);
|
|
197
|
+
defineCustomElement("prosekit-autocomplete-list", AutocompleteListElement);
|
|
198
|
+
|
|
199
|
+
// src/components/autocomplete/autocomplete-popover/element.gen.ts
|
|
200
|
+
import { BaseElement as BaseElement4 } from "@aria-ui/core";
|
|
201
|
+
|
|
202
|
+
// src/components/autocomplete/autocomplete-popover/props.ts
|
|
203
|
+
import { defaultOverlayPositionerProps } from "@aria-ui/overlay";
|
|
204
|
+
var body = typeof document !== "undefined" && document.querySelector("body");
|
|
205
|
+
var defaultBoundary = body || "clippingAncestors";
|
|
206
|
+
var defaultAutocompletePopoverProps = Object.freeze({
|
|
207
|
+
...defaultOverlayPositionerProps,
|
|
208
|
+
editor: null,
|
|
209
|
+
regex: null,
|
|
210
|
+
placement: "bottom-start",
|
|
211
|
+
offset: 4,
|
|
212
|
+
inline: true,
|
|
213
|
+
hoist: true,
|
|
214
|
+
fitViewport: true,
|
|
215
|
+
boundary: defaultBoundary,
|
|
216
|
+
overflowPadding: 8
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// src/components/autocomplete/autocomplete-popover/state.ts
|
|
220
|
+
import {
|
|
221
|
+
assignProps as assignProps2,
|
|
222
|
+
createComputed,
|
|
223
|
+
createSignal as createSignal2,
|
|
224
|
+
mapSignals as mapSignals2,
|
|
225
|
+
useEffect as useEffect3
|
|
226
|
+
} from "@aria-ui/core";
|
|
227
|
+
import { useOverlayPositionerState } from "@aria-ui/overlay";
|
|
228
|
+
import { usePresence } from "@aria-ui/presence";
|
|
229
|
+
import {
|
|
230
|
+
AutocompleteRule,
|
|
231
|
+
defineAutocomplete
|
|
232
|
+
} from "@prosekit/extensions/autocomplete";
|
|
233
|
+
|
|
234
|
+
// src/components/autocomplete/autocomplete-popover/helpers.ts
|
|
235
|
+
function defaultQueryBuilder(match) {
|
|
236
|
+
return match[0].toLowerCase().replace(/[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/g, "").replace(/\s\s+/g, " ").trim();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// src/components/autocomplete/autocomplete-popover/state.ts
|
|
240
|
+
function useAutocompletePopover(host, props) {
|
|
241
|
+
const state = mapSignals2(assignProps2(defaultAutocompletePopoverProps, props));
|
|
242
|
+
useAutocompletePopoverState(host, state);
|
|
243
|
+
return state;
|
|
244
|
+
}
|
|
245
|
+
function useAutocompletePopoverState(host, state) {
|
|
246
|
+
const { editor, regex, ...overlayState } = state;
|
|
247
|
+
const reference = createSignal2(null);
|
|
248
|
+
const query = createSignal2("");
|
|
249
|
+
const onDismiss = createSignal2(null);
|
|
250
|
+
const onSubmit = createSignal2(null);
|
|
251
|
+
const presence = createComputed(() => !!reference.value);
|
|
252
|
+
queryContext.provide(host, query);
|
|
253
|
+
onSubmitContext.provide(host, onSubmit);
|
|
254
|
+
openContext.provide(host, presence);
|
|
255
|
+
useEscapeKeydown(host, createKeymapHandler(onDismiss, presence));
|
|
256
|
+
useAutocompleteExtension(
|
|
257
|
+
host,
|
|
258
|
+
editor,
|
|
259
|
+
regex,
|
|
260
|
+
reference,
|
|
261
|
+
query,
|
|
262
|
+
onDismiss,
|
|
263
|
+
onSubmit
|
|
264
|
+
);
|
|
265
|
+
useOverlayPositionerState(host, overlayState, { reference });
|
|
266
|
+
usePresence(host, presence);
|
|
267
|
+
}
|
|
268
|
+
function useAutocompleteExtension(host, editor, regex, reference, query, onDismiss, onSubmit) {
|
|
269
|
+
useEffect3(host, () => {
|
|
270
|
+
const editorValue = editor.value;
|
|
271
|
+
const regexValue = regex.value;
|
|
272
|
+
if (!editorValue || !regexValue) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
return addAutocompleteExtension(
|
|
276
|
+
editorValue,
|
|
277
|
+
regexValue,
|
|
278
|
+
reference,
|
|
279
|
+
query,
|
|
280
|
+
onDismiss,
|
|
281
|
+
onSubmit
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function addAutocompleteExtension(editor, regex, reference, query, onDismiss, onSubmit) {
|
|
286
|
+
const handleEnter = (options) => {
|
|
287
|
+
const span = editor.view.dom.querySelector(".prosemirror-prediction-match");
|
|
288
|
+
if (span) {
|
|
289
|
+
reference.value = span;
|
|
290
|
+
}
|
|
291
|
+
query.value = defaultQueryBuilder(options.match);
|
|
292
|
+
onDismiss.value = options.ignoreMatch;
|
|
293
|
+
onSubmit.value = options.deleteMatch;
|
|
294
|
+
};
|
|
295
|
+
const handleLeave = () => {
|
|
296
|
+
reference.value = null;
|
|
297
|
+
query.value = "";
|
|
298
|
+
onDismiss.value = null;
|
|
299
|
+
onSubmit.value = null;
|
|
300
|
+
};
|
|
301
|
+
const rule = new AutocompleteRule({
|
|
302
|
+
regex,
|
|
303
|
+
onEnter: handleEnter,
|
|
304
|
+
onLeave: handleLeave
|
|
305
|
+
});
|
|
306
|
+
const extension = defineAutocomplete(rule);
|
|
307
|
+
return editor.use(extension);
|
|
308
|
+
}
|
|
309
|
+
function createKeymapHandler(handler, enabled) {
|
|
310
|
+
return () => {
|
|
311
|
+
if (!enabled.value) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
const fn = handler.peek();
|
|
315
|
+
if (!fn)
|
|
316
|
+
return false;
|
|
317
|
+
fn();
|
|
318
|
+
return true;
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function useEscapeKeydown(host, handler) {
|
|
322
|
+
useEffect3(host, () => {
|
|
323
|
+
const handleKeyDown = (event) => {
|
|
324
|
+
if (event.key !== "Escape") {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (handler()) {
|
|
328
|
+
event.preventDefault();
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
332
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/components/autocomplete/autocomplete-popover/element.gen.ts
|
|
337
|
+
var AutocompletePopoverElement = class extends BaseElement4 {
|
|
338
|
+
constructor() {
|
|
339
|
+
super();
|
|
340
|
+
this._s = useAutocompletePopover(this);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
defineProperties(AutocompletePopoverElement, defaultAutocompletePopoverProps);
|
|
344
|
+
defineCustomElement("prosekit-autocomplete-popover", AutocompletePopoverElement);
|
|
345
|
+
export {
|
|
346
|
+
AutocompleteEmptyElement,
|
|
347
|
+
AutocompleteItemElement,
|
|
348
|
+
AutocompleteListElement,
|
|
349
|
+
AutocompletePopoverElement,
|
|
350
|
+
defaultAutocompleteEmptyProps,
|
|
351
|
+
defaultAutocompleteItemProps,
|
|
352
|
+
defaultAutocompleteListProps,
|
|
353
|
+
defaultAutocompletePopoverProps
|
|
354
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BlockDragHandleElement } from './_tsup-dts-rollup';
|
|
2
|
+
export { defaultBlockDragHandleProps } from './_tsup-dts-rollup';
|
|
3
|
+
export { BlockDragHandleProps } from './_tsup-dts-rollup';
|
|
4
|
+
export { BlockPopoverElement } from './_tsup-dts-rollup';
|
|
5
|
+
export { defaultBlockPopoverProps } from './_tsup-dts-rollup';
|
|
6
|
+
export { BlockPopoverProps } from './_tsup-dts-rollup';
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useEditorExtension
|
|
3
|
+
} from "./chunk-VJEVDINM.js";
|
|
4
|
+
import {
|
|
5
|
+
defineCustomElement,
|
|
6
|
+
defineProperties
|
|
7
|
+
} from "./chunk-LJ7LCZM7.js";
|
|
8
|
+
|
|
9
|
+
// src/components/block-handle/block-drag-handle/element.gen.ts
|
|
10
|
+
import { BaseElement } from "@aria-ui/core";
|
|
11
|
+
|
|
12
|
+
// src/components/block-handle/block-drag-handle/props.ts
|
|
13
|
+
var defaultBlockDragHandleProps = Object.freeze({
|
|
14
|
+
editor: null
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// src/components/block-handle/block-drag-handle/state.ts
|
|
18
|
+
import {
|
|
19
|
+
assignProps,
|
|
20
|
+
mapSignals,
|
|
21
|
+
useEffect,
|
|
22
|
+
useEventListener
|
|
23
|
+
} from "@aria-ui/core";
|
|
24
|
+
import { Fragment, Slice } from "@prosekit/pm/model";
|
|
25
|
+
import { NodeSelection } from "@prosekit/pm/state";
|
|
26
|
+
|
|
27
|
+
// src/components/block-handle/context.ts
|
|
28
|
+
import { createContext } from "@aria-ui/core";
|
|
29
|
+
var blockPopoverContext = createContext(
|
|
30
|
+
"prosekit-block-popover-context",
|
|
31
|
+
{
|
|
32
|
+
pos: null,
|
|
33
|
+
node: null,
|
|
34
|
+
element: null
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// src/components/block-handle/block-drag-handle/state.ts
|
|
39
|
+
function useBlockDragHandle(host, props) {
|
|
40
|
+
const context = blockPopoverContext.consume(host);
|
|
41
|
+
const state = mapSignals(assignProps(defaultBlockDragHandleProps, props));
|
|
42
|
+
useEffect(host, () => {
|
|
43
|
+
host.draggable = true;
|
|
44
|
+
});
|
|
45
|
+
useEventListener(host, "pointerdown", () => {
|
|
46
|
+
var _a, _b;
|
|
47
|
+
const { pos } = (_a = context.value) != null ? _a : {};
|
|
48
|
+
const { view } = (_b = state.editor.value) != null ? _b : {};
|
|
49
|
+
if (pos == null || view == null) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
view.dispatch(
|
|
53
|
+
view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos))
|
|
54
|
+
);
|
|
55
|
+
requestAnimationFrame(() => {
|
|
56
|
+
view.focus();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
useEventListener(host, "dragstart", (event) => {
|
|
60
|
+
var _a, _b;
|
|
61
|
+
const { pos, element, node } = (_a = context.value) != null ? _a : {};
|
|
62
|
+
const { view } = (_b = state.editor.value) != null ? _b : {};
|
|
63
|
+
if (pos == null || !element || !node || !view || !event.dataTransfer) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
event.dataTransfer.clearData();
|
|
67
|
+
event.dataTransfer.setData("text/html", element.outerHTML);
|
|
68
|
+
event.dataTransfer.effectAllowed = "copyMove";
|
|
69
|
+
event.dataTransfer.setDragImage(element, 0, 0);
|
|
70
|
+
view.dragging = {
|
|
71
|
+
slice: new Slice(Fragment.from(node), 0, 0),
|
|
72
|
+
move: true
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
return state;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/components/block-handle/block-drag-handle/element.gen.ts
|
|
79
|
+
var BlockDragHandleElement = class extends BaseElement {
|
|
80
|
+
constructor() {
|
|
81
|
+
super();
|
|
82
|
+
this._s = useBlockDragHandle(this);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
defineProperties(BlockDragHandleElement, defaultBlockDragHandleProps);
|
|
86
|
+
defineCustomElement("prosekit-block-drag-handle", BlockDragHandleElement);
|
|
87
|
+
|
|
88
|
+
// src/components/block-handle/block-popover/element.gen.ts
|
|
89
|
+
import { BaseElement as BaseElement2 } from "@aria-ui/core";
|
|
90
|
+
|
|
91
|
+
// src/components/block-handle/block-popover/props.ts
|
|
92
|
+
import { defaultOverlayPositionerProps } from "@aria-ui/overlay";
|
|
93
|
+
var defaultBlockPopoverProps = Object.freeze({
|
|
94
|
+
...defaultOverlayPositionerProps,
|
|
95
|
+
editor: null,
|
|
96
|
+
placement: "left-start",
|
|
97
|
+
offset: 4
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// src/components/block-handle/block-popover/state.ts
|
|
101
|
+
import {
|
|
102
|
+
assignProps as assignProps2,
|
|
103
|
+
createComputed,
|
|
104
|
+
createSignal,
|
|
105
|
+
mapSignals as mapSignals2,
|
|
106
|
+
useAttribute,
|
|
107
|
+
useEffect as useEffect2
|
|
108
|
+
} from "@aria-ui/core";
|
|
109
|
+
import { useOverlayPositionerState } from "@aria-ui/overlay";
|
|
110
|
+
import { usePresence } from "@aria-ui/presence";
|
|
111
|
+
|
|
112
|
+
// src/components/block-handle/block-popover/pointer-move.ts
|
|
113
|
+
import { defineDOMEventHandler, union } from "@prosekit/core";
|
|
114
|
+
|
|
115
|
+
// src/utils/throttle.ts
|
|
116
|
+
function throttle(callback, wait) {
|
|
117
|
+
let lastTime = 0;
|
|
118
|
+
return (...args) => {
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
if (now - lastTime >= wait) {
|
|
121
|
+
callback(...args);
|
|
122
|
+
lastTime = now;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/components/block-handle/block-popover/pointer-move.ts
|
|
128
|
+
function defineElementHoverHandler(handler) {
|
|
129
|
+
const handlePointerEvent = (view, event) => {
|
|
130
|
+
var _a;
|
|
131
|
+
const rect = view.dom.getBoundingClientRect();
|
|
132
|
+
const pos = (_a = view.posAtCoords({
|
|
133
|
+
top: event.clientY,
|
|
134
|
+
// Use the center of the editor
|
|
135
|
+
left: rect.left + rect.width / 2
|
|
136
|
+
})) == null ? void 0 : _a.inside;
|
|
137
|
+
if (pos == null || pos < 0) {
|
|
138
|
+
handler(null, null, null, null);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const $pos = view.state.doc.resolve(pos);
|
|
142
|
+
const node = view.state.doc.nodeAt(pos);
|
|
143
|
+
const element = view.nodeDOM(pos);
|
|
144
|
+
if ($pos.depth >= 1 && $pos.index($pos.depth) === 0) {
|
|
145
|
+
const ancestorPos = $pos.before($pos.depth);
|
|
146
|
+
const node2 = view.state.doc.nodeAt(ancestorPos);
|
|
147
|
+
const element2 = view.nodeDOM(ancestorPos);
|
|
148
|
+
if (!element2) {
|
|
149
|
+
handler(null, null, null, null);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const reference = {
|
|
153
|
+
contextElement: element2,
|
|
154
|
+
// Get the bounding client rect of the parent node, including its
|
|
155
|
+
// margins.
|
|
156
|
+
getBoundingClientRect: () => {
|
|
157
|
+
const rect2 = element2.getBoundingClientRect();
|
|
158
|
+
const style = window.getComputedStyle(element2);
|
|
159
|
+
const marginTop = Number.parseInt(style.marginTop, 10) || 0;
|
|
160
|
+
const marginRight = Number.parseInt(style.marginRight, 10) || 0;
|
|
161
|
+
const marginBottom = Number.parseInt(style.marginBottom, 10) || 0;
|
|
162
|
+
const marginLeft = Number.parseInt(style.marginLeft, 10) || 0;
|
|
163
|
+
return {
|
|
164
|
+
top: rect2.top - marginTop,
|
|
165
|
+
right: rect2.right + marginRight,
|
|
166
|
+
bottom: rect2.bottom + marginBottom,
|
|
167
|
+
left: rect2.left - marginLeft,
|
|
168
|
+
width: rect2.width + marginLeft + marginRight,
|
|
169
|
+
height: rect2.height + marginTop + marginBottom,
|
|
170
|
+
x: rect2.x - marginLeft,
|
|
171
|
+
y: rect2.y - marginTop
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
handler(reference, element2, node2, ancestorPos);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
handler(element, element, node, pos);
|
|
179
|
+
};
|
|
180
|
+
return union([
|
|
181
|
+
defineDOMEventHandler("pointermove", throttle(handlePointerEvent, 200)),
|
|
182
|
+
defineDOMEventHandler("pointerout", handlePointerEvent),
|
|
183
|
+
defineDOMEventHandler("keypress", () => handler(null, null, null, null))
|
|
184
|
+
]);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/components/block-handle/block-popover/state.ts
|
|
188
|
+
function useBlockPopover(host, props) {
|
|
189
|
+
const state = mapSignals2(assignProps2(defaultBlockPopoverProps, props));
|
|
190
|
+
const { editor, ...overlayState } = state;
|
|
191
|
+
const reference = createSignal(null);
|
|
192
|
+
useOverlayPositionerState(host, overlayState, { reference });
|
|
193
|
+
const context = createSignal({
|
|
194
|
+
pos: null,
|
|
195
|
+
node: null,
|
|
196
|
+
element: null
|
|
197
|
+
});
|
|
198
|
+
blockPopoverContext.provide(host, context);
|
|
199
|
+
const open = createSignal(false);
|
|
200
|
+
useEffect2(host, () => {
|
|
201
|
+
open.value = !!context.value.element;
|
|
202
|
+
});
|
|
203
|
+
useHoverExtension(host, editor, (referenceValue, element, node, pos) => {
|
|
204
|
+
reference.value = referenceValue;
|
|
205
|
+
context.value = { element, node, pos };
|
|
206
|
+
});
|
|
207
|
+
const presence = createComputed(() => !!reference.value);
|
|
208
|
+
useAttribute(host, "data-state", () => presence.value ? "open" : "closed");
|
|
209
|
+
usePresence(host, presence);
|
|
210
|
+
return state;
|
|
211
|
+
}
|
|
212
|
+
function useHoverExtension(host, editor, handler) {
|
|
213
|
+
let prevElement = null;
|
|
214
|
+
let prevPos = null;
|
|
215
|
+
const extension = defineElementHoverHandler(
|
|
216
|
+
(reference, element, node, pos) => {
|
|
217
|
+
if (prevElement === element && prevPos === pos) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
prevElement = element;
|
|
221
|
+
prevPos = pos;
|
|
222
|
+
handler(reference, element, node, pos);
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
useEditorExtension(host, editor, extension);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/components/block-handle/block-popover/element.gen.ts
|
|
229
|
+
var BlockPopoverElement = class extends BaseElement2 {
|
|
230
|
+
constructor() {
|
|
231
|
+
super();
|
|
232
|
+
this._s = useBlockPopover(this);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
defineProperties(BlockPopoverElement, defaultBlockPopoverProps);
|
|
236
|
+
defineCustomElement("prosekit-block-popover", BlockPopoverElement);
|
|
237
|
+
export {
|
|
238
|
+
BlockDragHandleElement,
|
|
239
|
+
BlockPopoverElement,
|
|
240
|
+
defaultBlockDragHandleProps,
|
|
241
|
+
defaultBlockPopoverProps
|
|
242
|
+
};
|