@prosekit/web 0.6.1 → 0.7.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.
@@ -1,16 +1,7 @@
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
1
  //#region src/utils/clone-element.ts
11
2
  /**
12
3
  * Creates a deep clone of an Element, including all computed styles so that
13
- * it looks the same as the original element.
4
+ * it looks almost exactly the same as the original element.
14
5
  */
15
6
  function deepCloneElement(element) {
16
7
  const clonedElement = element.cloneNode(true);
@@ -47,4 +38,4 @@ function copyStyles(source, target) {
47
38
  }
48
39
 
49
40
  //#endregion
50
- export { assignStyles, cloneElement, deepCloneElement };
41
+ export { cloneElement, deepCloneElement };
@@ -8,14 +8,4 @@ function getStateWithDefaults(state, props) {
8
8
  }
9
9
 
10
10
  //#endregion
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 };
11
+ export { getStateWithDefaults };
@@ -0,0 +1,11 @@
1
+ //#region src/utils/get-safe-editor-view.ts
2
+ /**
3
+ * @internal
4
+ */
5
+ function getSafeEditorView(editor) {
6
+ if (!editor || !editor.mounted) return;
7
+ return editor.view;
8
+ }
9
+
10
+ //#endregion
11
+ export { getSafeEditorView };
@@ -157,4 +157,4 @@ declare function useAutocompletePopover(host: ConnectableElement, {
157
157
  emit
158
158
  }: SetupOptions<AutocompletePopoverProps, AutocompletePopoverEvents>): void;
159
159
  //#endregion
160
- export { AutocompleteEmptyElement, AutocompleteEmptyEvents, AutocompleteEmptyProps, AutocompleteItemElement, AutocompleteItemEvents, AutocompleteItemProps, AutocompleteListElement, AutocompleteListEvents, AutocompleteListProps, AutocompletePopoverElement, AutocompletePopoverEvents, AutocompletePopoverProps, autocompleteEmptyEvents, autocompleteEmptyProps, autocompleteItemEvents, autocompleteItemProps, autocompleteListEvents, autocompleteListProps, autocompletePopoverEvents, autocompletePopoverProps, useAutocompleteEmpty, useAutocompleteItem, useAutocompleteList, useAutocompletePopover };
160
+ export { AutocompleteEmptyElement, type AutocompleteEmptyEvents, type AutocompleteEmptyProps, AutocompleteItemElement, type AutocompleteItemEvents, type AutocompleteItemProps, AutocompleteListElement, type AutocompleteListEvents, type AutocompleteListProps, AutocompletePopoverElement, type AutocompletePopoverEvents, type AutocompletePopoverProps, autocompleteEmptyEvents, autocompleteEmptyProps, autocompleteItemEvents, autocompleteItemProps, autocompleteListEvents, autocompleteListProps, autocompletePopoverEvents, autocompletePopoverProps, useAutocompleteEmpty, useAutocompleteItem, useAutocompleteList, useAutocompletePopover };
@@ -1,5 +1,6 @@
1
- import { getSafeEditorView, getStateWithDefaults } from "./get-safe-editor-view-CqJWgxo1.js";
1
+ import { getStateWithDefaults } from "./get-default-state-CIEy7xrl.js";
2
2
  import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
3
+ import { getSafeEditorView } from "./get-safe-editor-view-DENm4avv.js";
3
4
  import { createComputed, createContext, createSignal, defineCustomElement, registerCustomElement, useAnimationFrame, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
4
5
  import { listboxProps, useListbox, useListboxEmpty, useListboxItem } from "@aria-ui/listbox/elements";
5
6
  import { listboxEvents, listboxItemEvents, listboxProps as listboxProps$1 } from "@aria-ui/listbox";
@@ -67,7 +67,7 @@ declare function useBlockHandleDraggable(host: ConnectableElement, {
67
67
  }): void;
68
68
  //#endregion
69
69
  //#region src/components/block-handle/block-handle-popover/types.d.ts
70
- interface BlockHandlePopoverProps extends Omit<OverlayPositionerProps, "placement" | "hoist"> {
70
+ interface BlockHandlePopoverProps extends Omit<OverlayPositionerProps, "placement" | "hoist" | "flip" | "shift" | "hide"> {
71
71
  /**
72
72
  * The ProseKit editor instance.
73
73
  *
@@ -88,6 +88,21 @@ interface BlockHandlePopoverProps extends Omit<OverlayPositionerProps, "placemen
88
88
  * @default false
89
89
  */
90
90
  hoist: boolean;
91
+ /**
92
+ * @default false
93
+ * @hidden
94
+ */
95
+ flip: boolean;
96
+ /**
97
+ * @default false
98
+ * @hidden
99
+ */
100
+ shift: boolean;
101
+ /**
102
+ * @default true
103
+ * @hidden
104
+ */
105
+ hide: boolean;
91
106
  }
92
107
  /** @internal */
93
108
  declare const blockHandlePopoverProps: PropDeclarations<BlockHandlePopoverProps>;
@@ -116,4 +131,4 @@ declare function useBlockHandlePopover(host: ConnectableElement, {
116
131
  emit
117
132
  }: SetupOptions<BlockHandlePopoverProps, BlockHandlePopoverEvents>): void;
118
133
  //#endregion
119
- export { BlockHandleAddElement, BlockHandleAddEvents, BlockHandleAddProps, BlockHandleDraggableElement, BlockHandleDraggableEvents, BlockHandleDraggableProps, BlockHandlePopoverElement, BlockHandlePopoverEvents, BlockHandlePopoverProps, blockHandleAddEvents, blockHandleAddProps, blockHandleDraggableEvents, blockHandleDraggableProps, blockHandlePopoverEvents, blockHandlePopoverProps, useBlockHandleAdd, useBlockHandleDraggable, useBlockHandlePopover };
134
+ export { BlockHandleAddElement, type BlockHandleAddEvents, type BlockHandleAddProps, BlockHandleDraggableElement, type BlockHandleDraggableEvents, type BlockHandleDraggableProps, BlockHandlePopoverElement, type BlockHandlePopoverEvents, type BlockHandlePopoverProps, blockHandleAddEvents, blockHandleAddProps, blockHandleDraggableEvents, blockHandleDraggableProps, blockHandlePopoverEvents, blockHandlePopoverProps, useBlockHandleAdd, useBlockHandleDraggable, useBlockHandlePopover };
@@ -1,6 +1,8 @@
1
1
  import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
2
- import { assignStyles, deepCloneElement } from "./clone-element-B55UD54E.js";
3
- import { createContext, createSignal, defineCustomElement, registerCustomElement, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
2
+ import { getSafeEditorView } from "./get-safe-editor-view-DENm4avv.js";
3
+ import { assignStyles, useScrolling } from "./use-scrolling-BNfsQs3S.js";
4
+ import { deepCloneElement } from "./clone-element-CwLKm7c_.js";
5
+ import { createComputed, createContext, createSignal, defineCustomElement, registerCustomElement, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
4
6
  import { defineDOMEventHandler, insertDefaultBlock, union } from "@prosekit/core";
5
7
  import { overlayPositionerEvents, overlayPositionerProps, useOverlayPositionerState } from "@aria-ui/overlay/elements";
6
8
  import { usePresence } from "@aria-ui/presence";
@@ -13,6 +15,10 @@ import { NodeSelection } from "@prosekit/pm/state";
13
15
  * @internal
14
16
  */
15
17
  const blockPopoverContext = createContext("prosekit-block-popover-context", null);
18
+ /**
19
+ * @internal
20
+ */
21
+ const draggingContext = createContext("prosekit-block-handle-dragging-context", false);
16
22
 
17
23
  //#endregion
18
24
  //#region src/components/block-handle/block-handle-add/setup.ts
@@ -50,6 +56,38 @@ const BlockHandleAddElementBase = defineCustomElement({
50
56
  var BlockHandleAddElement = class extends BlockHandleAddElementBase {};
51
57
  registerCustomElement("prosekit-block-handle-add", BlockHandleAddElement);
52
58
 
59
+ //#endregion
60
+ //#region src/utils/get-client-rect.ts
61
+ /**
62
+ * Similar to `element.getBoundingClientRect`, but handles `display: contents` elements.
63
+ */
64
+ function getClientRect(element) {
65
+ const rect = element.getBoundingClientRect();
66
+ if (rect.width === 0 && rect.height === 0 && rect.x === 0 && rect.y === 0) {
67
+ if (element.getClientRects().length === 0) {
68
+ const children = Array.from(element.children);
69
+ const rects = children.map((child) => getClientRect(child));
70
+ if (rects.length === 0) return rect;
71
+ if (rects.length === 1) return rects[0];
72
+ let { top, bottom, left, right } = rects[0];
73
+ for (let i = 1; i < rects.length; i++) {
74
+ const r = rects[i];
75
+ if (r.top < top) top = r.top;
76
+ if (r.bottom > bottom) bottom = r.bottom;
77
+ if (r.left < left) left = r.left;
78
+ if (r.right > right) right = r.right;
79
+ }
80
+ return {
81
+ top,
82
+ bottom,
83
+ left,
84
+ right
85
+ };
86
+ }
87
+ }
88
+ return rect;
89
+ }
90
+
53
91
  //#endregion
54
92
  //#region src/utils/max-z-index.ts
55
93
  const maxZIndex = "2147483647";
@@ -68,8 +106,11 @@ const maxZIndex = "2147483647";
68
106
  * - Removes the container from the document body after the next frame.
69
107
  */
70
108
  function setDragPreview(event, element) {
71
- const rect = element.getBoundingClientRect();
72
- const { width, height, x: elementX, y: elementY } = rect;
109
+ const { top, bottom, left, right } = getClientRect(element);
110
+ const width = right - left;
111
+ const height = bottom - top;
112
+ const elementX = left;
113
+ const elementY = top;
73
114
  const { clientX, clientY } = event;
74
115
  const document = element.ownerDocument;
75
116
  const container = document.createElement("div");
@@ -90,8 +131,8 @@ function setDragPreview(event, element) {
90
131
  });
91
132
  const clonedElement = deepCloneElement(element);
92
133
  assignStyles(clonedElement, {
93
- outline: "none",
94
- opacity: "0.5"
134
+ opacity: "0.5",
135
+ margin: "0"
95
136
  });
96
137
  document.body.appendChild(container);
97
138
  container.appendChild(clonedElement);
@@ -108,12 +149,27 @@ function setDragPreview(event, element) {
108
149
  */
109
150
  function useBlockHandleDraggable(host, { state }) {
110
151
  const context = blockPopoverContext.consume(host);
152
+ const dragging = draggingContext.consume(host);
111
153
  useEffect(host, () => {
112
154
  host.draggable = true;
113
155
  });
114
156
  usePointerDownHandler(host, context, state.editor);
115
- useDraggingPreview(host, context, state.editor);
116
- useDataDraggingAttribute(host);
157
+ useEventListener(host, "dragstart", (event) => {
158
+ dragging.set(true);
159
+ const view = getSafeEditorView(state.editor.get());
160
+ const hoverState = context.get();
161
+ if (view && hoverState) {
162
+ view.dom.classList.add("prosekit-dragging");
163
+ createDraggingPreview(view, hoverState, event);
164
+ setViewDragging(view, hoverState);
165
+ }
166
+ });
167
+ useEventListener(host, "dragend", () => {
168
+ dragging.set(false);
169
+ const view = getSafeEditorView(state.editor.get());
170
+ if (view) view.dom.classList.remove("prosekit-dragging");
171
+ });
172
+ useAttribute(host, "data-dragging", () => dragging.get() ? "" : void 0);
117
173
  }
118
174
  function usePointerDownHandler(host, context, editor) {
119
175
  useEventListener(host, "pointerdown", () => {
@@ -126,39 +182,24 @@ function usePointerDownHandler(host, context, editor) {
126
182
  });
127
183
  });
128
184
  }
129
- function useDraggingPreview(host, context, editor) {
130
- useEventListener(host, "dragstart", (event) => {
131
- const hoverState = context.get();
132
- const { view } = editor.get() ?? {};
133
- if (!hoverState || !view || !event.dataTransfer) return;
134
- const { node, pos } = hoverState;
135
- const element = view.nodeDOM(pos);
136
- if (!element || !isHTMLElement(element)) return;
137
- event.dataTransfer.clearData();
138
- event.dataTransfer.setData("text/html", element.outerHTML);
139
- event.dataTransfer.effectAllowed = "copyMove";
140
- setDragPreview(event, element);
141
- const dragging = {
142
- slice: new Slice(Fragment.from(node), 0, 0),
143
- move: true,
144
- node: NodeSelection.create(view.state.doc, pos)
145
- };
146
- view.dragging = dragging;
147
- });
185
+ function createDraggingPreview(view, hoverState, event) {
186
+ if (!event.dataTransfer) return;
187
+ const { pos } = hoverState;
188
+ const element = view.nodeDOM(pos);
189
+ if (!element || !isHTMLElement(element)) return;
190
+ event.dataTransfer.clearData();
191
+ event.dataTransfer.setData("text/html", element.outerHTML);
192
+ event.dataTransfer.effectAllowed = "copyMove";
193
+ setDragPreview(event, element);
148
194
  }
149
- function useDataDraggingAttribute(host) {
150
- const dragging = useDragging(host);
151
- useAttribute(host, "data-dragging", () => dragging.get() ? "" : void 0);
152
- }
153
- function useDragging(host) {
154
- const dragging = createSignal(false);
155
- useEventListener(host, "dragstart", () => {
156
- dragging.set(true);
157
- });
158
- useEventListener(host, "dragend", () => {
159
- dragging.set(false);
160
- });
161
- return dragging;
195
+ function setViewDragging(view, hoverState) {
196
+ const { node, pos } = hoverState;
197
+ const dragging = {
198
+ slice: new Slice(Fragment.from(node), 0, 0),
199
+ move: true,
200
+ node: NodeSelection.create(view.state.doc, pos)
201
+ };
202
+ view.dragging = dragging;
162
203
  }
163
204
 
164
205
  //#endregion
@@ -178,30 +219,6 @@ const BlockHandleDraggableElementBase = defineCustomElement({
178
219
  var BlockHandleDraggableElement = class extends BlockHandleDraggableElementBase {};
179
220
  registerCustomElement("prosekit-block-handle-draggable", BlockHandleDraggableElement);
180
221
 
181
- //#endregion
182
- //#region src/utils/get-client-rect.ts
183
- /**
184
- * Similar to `element.getBoundingClientRect`, but handles `display: contents` elements.
185
- */
186
- function getClientRect(element) {
187
- const rect = element.getBoundingClientRect();
188
- if (rect.width === 0 && rect.height === 0 && rect.x === 0 && rect.y === 0) {
189
- if (element.getClientRects().length === 0) {
190
- const children = Array.from(element.children);
191
- const rects = children.map((child) => getClientRect(child)).filter((x) => !!x);
192
- if (rects.length === 0) return rect;
193
- if (rects.length === 1) return rects[0];
194
- return {
195
- top: Math.min(...rects.map((rect$1) => rect$1.top)),
196
- right: Math.max(...rects.map((rect$1) => rect$1.right)),
197
- bottom: Math.max(...rects.map((rect$1) => rect$1.bottom)),
198
- left: Math.min(...rects.map((rect$1) => rect$1.left))
199
- };
200
- }
201
- }
202
- return rect;
203
- }
204
-
205
222
  //#endregion
206
223
  //#region src/utils/throttle.ts
207
224
  /**
@@ -236,7 +253,7 @@ function defineElementHoverHandler(handler) {
236
253
  };
237
254
  const handlePointerEvent = (view, event) => {
238
255
  const { x, y } = event;
239
- const block = findBlockByCoordinate(view, x, y);
256
+ const block = findBlockByCoords(view, x, y);
240
257
  if (!block) {
241
258
  handler(null, null);
242
259
  return;
@@ -257,9 +274,8 @@ function defineElementHoverHandler(handler) {
257
274
  };
258
275
  return union(defineDOMEventHandler("pointermove", throttle(handlePointerEvent, 200)), defineDOMEventHandler("pointerout", handlePointerEvent), defineDOMEventHandler("keypress", () => handler(null, null)));
259
276
  }
260
- function findBlockByCoordinate(view, x, y) {
261
- const dom = view.dom;
262
- const rect = getClientRect(dom);
277
+ function findBlockByCoords(view, x, y) {
278
+ const rect = getClientRect(view.dom);
263
279
  if (!isWithinRect(rect, x, y)) return;
264
280
  let parent = view.state.doc;
265
281
  let pos = -1;
@@ -281,7 +297,7 @@ function findBlockByCoordinate(view, x, y) {
281
297
  const childDOM = view.nodeDOM(positions[i]);
282
298
  const childRect = getNodeRect(childDOM);
283
299
  if (!childRect) {
284
- console.warn("[prosekit] Unable to get rect at position", positions[i]);
300
+ console.warn(`[prosekit] Unable to get rect at position: ${positions[i]}`);
285
301
  return;
286
302
  }
287
303
  if (childRect.top > y) hi = i - 1;
@@ -403,9 +419,11 @@ function useBlockHandlePopover(host, { state, emit }) {
403
419
  useOverlayPositionerState(host, overlayState, { reference });
404
420
  const context = createSignal(null);
405
421
  blockPopoverContext.provide(host, context);
406
- const open = createSignal(false);
407
- useEffect(host, () => {
408
- open.set(!!context.get());
422
+ const dragging = createSignal(false);
423
+ draggingContext.provide(host, dragging);
424
+ const scrolling = useScrolling(host);
425
+ const open = createComputed(() => {
426
+ return !!context.get() && !scrolling.get();
409
427
  });
410
428
  useHoverExtension(host, editor, (referenceValue, hoverState) => {
411
429
  reference.set(referenceValue);
@@ -441,7 +459,10 @@ const blockHandlePopoverProps = {
441
459
  ...overlayPositionerProps,
442
460
  editor: { default: null },
443
461
  placement: { default: "left" },
444
- hoist: { default: false }
462
+ hoist: { default: false },
463
+ flip: { default: false },
464
+ shift: { default: false },
465
+ hide: { default: true }
445
466
  };
446
467
  /** @internal */
447
468
  const blockHandlePopoverEvents = {
@@ -0,0 +1,38 @@
1
+ import { BaseElementConstructor, ConnectableElement, EventDeclarations, PropDeclarations, SetupOptions } from "@aria-ui/core";
2
+ import { Editor } from "@prosekit/core";
3
+
4
+ //#region src/components/drop-indicator/drop-indicator/types.d.ts
5
+ interface DropIndicatorProps {
6
+ /**
7
+ * The ProseKit editor instance.
8
+ *
9
+ * @default null
10
+ * @hidden
11
+ */
12
+ editor: Editor | null;
13
+ /**
14
+ * The line width in pixels.
15
+ *
16
+ * @default 2
17
+ */
18
+ width: number;
19
+ }
20
+ /** @internal */
21
+ declare const dropIndicatorProps: PropDeclarations<DropIndicatorProps>;
22
+ interface DropIndicatorEvents {}
23
+ /** @internal */
24
+ declare const dropIndicatorEvents: EventDeclarations<DropIndicatorEvents>;
25
+ //#endregion
26
+ //#region src/components/drop-indicator/drop-indicator/element.gen.d.ts
27
+ declare const DropIndicatorElementBase: BaseElementConstructor<DropIndicatorProps>;
28
+ declare class DropIndicatorElement extends DropIndicatorElementBase {}
29
+ //#endregion
30
+ //#region src/components/drop-indicator/drop-indicator/setup.d.ts
31
+ /**
32
+ * @internal
33
+ */
34
+ declare function useDropIndicator(host: ConnectableElement, {
35
+ state
36
+ }: SetupOptions<DropIndicatorProps, DropIndicatorEvents>): void;
37
+ //#endregion
38
+ export { DropIndicatorElement, type DropIndicatorEvents, type DropIndicatorProps, dropIndicatorEvents, dropIndicatorProps, useDropIndicator };
@@ -0,0 +1,78 @@
1
+ import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
2
+ import { assignStyles, useScrolling } from "./use-scrolling-BNfsQs3S.js";
3
+ import { createComputed, createSignal, defineCustomElement, registerCustomElement, useEffect } from "@aria-ui/core";
4
+ import { usePresence } from "@aria-ui/presence";
5
+ import { defineDropIndicator } from "@prosekit/extensions/drop-indicator";
6
+
7
+ //#region src/components/drop-indicator/drop-indicator/setup.ts
8
+ /**
9
+ * @internal
10
+ */
11
+ function useDropIndicator(host, { state }) {
12
+ const context = createSignal(null);
13
+ const extension = defineDropIndicator({
14
+ onShow: (options) => context.set(options),
15
+ onHide: () => context.set(null)
16
+ });
17
+ useEditorExtension(host, state.editor, extension);
18
+ const line = createComputed(() => context.get()?.line);
19
+ const scrolling = useScrolling(host);
20
+ const presence = createComputed(() => {
21
+ return !!context.get() && !scrolling.get();
22
+ });
23
+ usePresence(host, presence);
24
+ useEffect(host, () => {
25
+ const lineValue = line.get();
26
+ const lineWidth = state.width.get();
27
+ if (!lineValue) return;
28
+ const { p1: { x: x1, y: y1 }, p2: { x: x2, y: y2 } } = lineValue;
29
+ const horizontal = y1 === y2;
30
+ let width;
31
+ let height;
32
+ let top = y1;
33
+ let left = x1;
34
+ if (horizontal) {
35
+ width = x2 - x1;
36
+ height = lineWidth;
37
+ top -= lineWidth / 2;
38
+ } else {
39
+ width = lineWidth;
40
+ height = y2 - y1;
41
+ left -= lineWidth / 2;
42
+ }
43
+ top = Math.round(top);
44
+ left = Math.round(left);
45
+ assignStyles(host, {
46
+ position: "fixed",
47
+ pointerEvents: "none",
48
+ width: `${width}px`,
49
+ height: `${height}px`,
50
+ transform: `translate(${left}px, ${top}px)`,
51
+ left: "0px",
52
+ top: "0px"
53
+ });
54
+ });
55
+ }
56
+
57
+ //#endregion
58
+ //#region src/components/drop-indicator/drop-indicator/types.ts
59
+ /** @internal */
60
+ const dropIndicatorProps = Object.freeze({
61
+ editor: { default: null },
62
+ width: { default: 2 }
63
+ });
64
+ /** @internal */
65
+ const dropIndicatorEvents = {};
66
+
67
+ //#endregion
68
+ //#region src/components/drop-indicator/drop-indicator/element.gen.ts
69
+ const DropIndicatorElementBase = defineCustomElement({
70
+ props: dropIndicatorProps,
71
+ events: dropIndicatorEvents,
72
+ setup: useDropIndicator
73
+ });
74
+ var DropIndicatorElement = class extends DropIndicatorElementBase {};
75
+ registerCustomElement("prosekit-drop-indicator", DropIndicatorElement);
76
+
77
+ //#endregion
78
+ export { DropIndicatorElement, dropIndicatorEvents, dropIndicatorProps, useDropIndicator };
@@ -87,4 +87,4 @@ declare function useInlinePopover(host: ConnectableElement, {
87
87
  emit
88
88
  }: SetupOptions<InlinePopoverProps, InlinePopoverEvents>): void;
89
89
  //#endregion
90
- export { InlinePopoverElement, InlinePopoverEvents, InlinePopoverProps, inlinePopoverEvents, inlinePopoverProps, useInlinePopover };
90
+ export { InlinePopoverElement, type InlinePopoverEvents, type InlinePopoverProps, inlinePopoverEvents, inlinePopoverProps, useInlinePopover };
@@ -25,4 +25,4 @@ interface PopoverTriggerEvents extends PopoverTriggerEvents$1 {}
25
25
  declare const PopoverTriggerElementBase: BaseElementConstructor<PopoverTriggerProps>;
26
26
  declare class PopoverTriggerElement extends PopoverTriggerElementBase {}
27
27
  //#endregion
28
- export { PopoverContentElement, PopoverContentEvents, PopoverContentProps, PopoverRootElement, PopoverRootEvents, PopoverRootProps, PopoverTriggerElement, PopoverTriggerEvents, PopoverTriggerProps, popoverContentEvents, popoverContentProps, popoverRootEvents, popoverRootProps, popoverTriggerEvents, popoverTriggerProps, usePopoverContent, usePopoverRoot, usePopoverTrigger };
28
+ export { PopoverContentElement, type PopoverContentEvents, type PopoverContentProps, PopoverRootElement, type PopoverRootEvents, type PopoverRootProps, PopoverTriggerElement, type PopoverTriggerEvents, type PopoverTriggerProps, popoverContentEvents, popoverContentProps, popoverRootEvents, popoverRootProps, popoverTriggerEvents, popoverTriggerProps, usePopoverContent, usePopoverRoot, usePopoverTrigger };
@@ -64,4 +64,4 @@ declare function useResizableRoot(host: ConnectableElement, {
64
64
  emit
65
65
  }: SetupOptions<ResizableRootProps, ResizableRootEvents>): void;
66
66
  //#endregion
67
- export { ResizableHandleElement, ResizableHandleEvents, ResizableHandleProps, ResizableRootElement, ResizableRootEvents, ResizableRootProps, resizableHandleEvents, resizableHandleProps, resizableRootEvents, resizableRootProps, useResizableHandle, useResizableRoot };
67
+ export { ResizableHandleElement, type ResizableHandleEvents, type ResizableHandleProps, ResizableRootElement, type ResizableRootEvents, type ResizableRootProps, resizableHandleEvents, resizableHandleProps, resizableRootEvents, resizableRootProps, useResizableHandle, useResizableRoot };
@@ -7,7 +7,7 @@ import { Placement } from "@floating-ui/dom";
7
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
- interface TableHandleColumnRootProps extends Omit<OverlayPositionerProps, "placement"> {
10
+ interface TableHandleColumnRootProps extends Omit<OverlayPositionerProps, "placement" | "hoist" | "flip" | "shift" | "hide"> {
11
11
  /**
12
12
  * The ProseKit editor instance.
13
13
  *
@@ -21,6 +21,28 @@ interface TableHandleColumnRootProps extends Omit<OverlayPositionerProps, "place
21
21
  * @default "top"
22
22
  */
23
23
  placement: Placement;
24
+ /**
25
+ * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
26
+ * to place the floating element on top of other page content.
27
+ *
28
+ * @default false
29
+ */
30
+ hoist: boolean;
31
+ /**
32
+ * @default false
33
+ * @hidden
34
+ */
35
+ flip: boolean;
36
+ /**
37
+ * @default false
38
+ * @hidden
39
+ */
40
+ shift: boolean;
41
+ /**
42
+ * @default true
43
+ * @hidden
44
+ */
45
+ hide: boolean;
24
46
  }
25
47
  /** @internal */
26
48
  declare const tableHandleColumnRootProps: PropDeclarations<TableHandleColumnRootProps>;
@@ -195,7 +217,7 @@ declare function useTableHandleRoot(host: ConnectableElement, {
195
217
  }): void;
196
218
  //#endregion
197
219
  //#region src/components/table-handle/table-handle-row-root/types.d.ts
198
- interface TableHandleRowRootProps extends Omit<OverlayPositionerProps, "placement"> {
220
+ interface TableHandleRowRootProps extends Omit<OverlayPositionerProps, "placement" | "hoist" | "flip" | "shift" | "hide"> {
199
221
  /**
200
222
  * The ProseKit editor instance.
201
223
  *
@@ -209,6 +231,28 @@ interface TableHandleRowRootProps extends Omit<OverlayPositionerProps, "placemen
209
231
  * @default "left"
210
232
  */
211
233
  placement: Placement;
234
+ /**
235
+ * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
236
+ * to place the floating element on top of other page content.
237
+ *
238
+ * @default false
239
+ */
240
+ hoist: boolean;
241
+ /**
242
+ * @default false
243
+ * @hidden
244
+ */
245
+ flip: boolean;
246
+ /**
247
+ * @default false
248
+ * @hidden
249
+ */
250
+ shift: boolean;
251
+ /**
252
+ * @default true
253
+ * @hidden
254
+ */
255
+ hide: boolean;
212
256
  }
213
257
  /** @internal */
214
258
  declare const tableHandleRowRootProps: PropDeclarations<TableHandleRowRootProps>;
@@ -254,4 +298,4 @@ declare function useTableHandleRowTrigger(host: ConnectableElement, {
254
298
  state
255
299
  }: SetupOptions<TableHandleRowTriggerProps, TableHandleRowTriggerEvents>): void;
256
300
  //#endregion
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 };
301
+ export { TableHandleColumnRootElement, type TableHandleColumnRootEvents, type TableHandleColumnRootProps, TableHandleColumnTriggerElement, type TableHandleColumnTriggerEvents, type TableHandleColumnTriggerProps, TableHandleDragPreviewElement, type TableHandleDragPreviewEvents, type TableHandleDragPreviewProps, TableHandleDropIndicatorElement, type TableHandleDropIndicatorEvents, type TableHandleDropIndicatorProps, TableHandlePopoverContentElement, type TableHandlePopoverContentEvents, type TableHandlePopoverContentProps, TableHandlePopoverItemElement, type TableHandlePopoverItemEvents, type TableHandlePopoverItemProps, TableHandleRootElement, type TableHandleRootEvents, type TableHandleRootProps, TableHandleRowRootElement, type TableHandleRowRootEvents, type TableHandleRowRootProps, TableHandleRowTriggerElement, type TableHandleRowTriggerEvents, type 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,6 +1,8 @@
1
- import { getSafeEditorView, getStateWithDefaults } from "./get-safe-editor-view-CqJWgxo1.js";
1
+ import { getStateWithDefaults } from "./get-default-state-CIEy7xrl.js";
2
2
  import { useEditorExtension } from "./use-editor-extension-Cc7ZG7uj.js";
3
- import { assignStyles, cloneElement, deepCloneElement } from "./clone-element-B55UD54E.js";
3
+ import { getSafeEditorView } from "./get-safe-editor-view-DENm4avv.js";
4
+ import { assignStyles, useScrolling } from "./use-scrolling-BNfsQs3S.js";
5
+ import { cloneElement, deepCloneElement } from "./clone-element-CwLKm7c_.js";
4
6
  import { createComputed, createContext, createSignal, defineCustomElement, defineEmit, registerCustomElement, useAttribute, useEffect, useEventListener } from "@aria-ui/core";
5
7
  import { defineDOMEventHandler, union } from "@prosekit/core";
6
8
  import { useOverlayPositionerState } from "@aria-ui/overlay/elements";
@@ -75,7 +77,11 @@ function useTableHandleColumnRoot(host, { state }) {
75
77
  const tableHandleColumnRootProps = Object.freeze({
76
78
  ...overlayPositionerProps$1,
77
79
  editor: { default: null },
78
- placement: { default: "top" }
80
+ placement: { default: "top" },
81
+ hoist: { default: false },
82
+ flip: { default: false },
83
+ shift: { default: false },
84
+ hide: { default: true }
79
85
  });
80
86
  /** @internal */
81
87
  const tableHandleColumnRootEvents = overlayPositionerEvents$1;
@@ -704,6 +710,43 @@ function useEditorTyping(host, editor) {
704
710
  return typing;
705
711
  }
706
712
 
713
+ //#endregion
714
+ //#region src/hooks/use-selecting.ts
715
+ /**
716
+ * Detect if the user is selecting text inside the editor, in which case some
717
+ * components should be disabled or hidden.
718
+ */
719
+ function useSelecting(host, editor, enabled) {
720
+ const selecting = createSignal(false);
721
+ const isPointerDown = createSignal(false);
722
+ useEffect(host, () => {
723
+ if (!enabled.get()) return;
724
+ const view = getSafeEditorView(editor.peek());
725
+ if (!view) return;
726
+ const { dom, root } = view;
727
+ if (!root) return;
728
+ const handlePointerDown = () => {
729
+ selecting.set(true);
730
+ isPointerDown.set(true);
731
+ };
732
+ const handlePointerUp = () => {
733
+ isPointerDown.set(false);
734
+ };
735
+ const handleMouseMove = () => {
736
+ if (!isPointerDown.get()) selecting.set(false);
737
+ };
738
+ dom.addEventListener("pointerdown", handlePointerDown);
739
+ root.addEventListener("pointerup", handlePointerUp);
740
+ root.addEventListener("pointermove", handleMouseMove);
741
+ return () => {
742
+ dom.removeEventListener("pointerdown", handlePointerDown);
743
+ root.removeEventListener("pointerup", handlePointerUp);
744
+ root.removeEventListener("pointermove", handleMouseMove);
745
+ };
746
+ });
747
+ return selecting;
748
+ }
749
+
707
750
  //#endregion
708
751
  //#region src/components/table-handle/hooks/use-drop.ts
709
752
  function useDrop(host, editor, dndContext) {
@@ -814,11 +857,12 @@ function useTableHandleRoot(host, { state }) {
814
857
  const typing = useEditorTyping(host, editor);
815
858
  const isInTable = createComputed(() => !!hoveringCell.get());
816
859
  const selecting = useSelecting(host, editor, isInTable);
860
+ const scrolling = useScrolling(host);
861
+ const canShow = createComputed(() => {
862
+ return !typing.get() && !selecting.get() && !scrolling.get();
863
+ });
817
864
  useEffect(host, () => {
818
- const typingValue = typing.get();
819
- const selectingValue = selecting.get();
820
- const hoveringCellValue = hoveringCell.get();
821
- context.set(typingValue || selectingValue ? null : hoveringCellValue);
865
+ context.set(canShow.get() ? hoveringCell.get() : null);
822
866
  });
823
867
  tableHandleRootContext.provide(host, context);
824
868
  tableHandleDndContext.provide(host, dndContext);
@@ -840,33 +884,6 @@ function defineCellHoverHandler(handler) {
840
884
  };
841
885
  return defineDOMEventHandler("pointerover", pointerHandler);
842
886
  }
843
- /**
844
- * Detect if the user is selecting text by dragging.
845
- */
846
- function useSelecting(host, editor, isInTable) {
847
- const selecting = createSignal(false);
848
- useEffect(host, () => {
849
- if (!isInTable.get()) return;
850
- const view = getSafeEditorView(editor.peek());
851
- const root = view?.root;
852
- if (!root) return;
853
- const pointerDownHandler = (event) => {
854
- const target = event.target;
855
- if (!target || host.contains(event.target)) return;
856
- selecting.set(true);
857
- };
858
- const pointerUpHandler = () => {
859
- selecting.set(false);
860
- };
861
- root.addEventListener("pointerdown", pointerDownHandler);
862
- root.addEventListener("pointerup", pointerUpHandler);
863
- return () => {
864
- root.removeEventListener("pointerdown", pointerDownHandler);
865
- root.removeEventListener("pointerup", pointerUpHandler);
866
- };
867
- });
868
- return selecting;
869
- }
870
887
 
871
888
  //#endregion
872
889
  //#region src/components/table-handle/table-handle-root/types.ts
@@ -924,7 +941,11 @@ function useTableHandleRowRoot(host, { state }) {
924
941
  const tableHandleRowRootProps = {
925
942
  ...overlayPositionerProps$1,
926
943
  editor: { default: null },
927
- placement: { default: "left" }
944
+ placement: { default: "left" },
945
+ hoist: { default: false },
946
+ flip: { default: false },
947
+ shift: { default: false },
948
+ hide: { default: true }
928
949
  };
929
950
  /** @internal */
930
951
  const tableHandleRowRootEvents = {};
@@ -25,4 +25,4 @@ interface TooltipTriggerEvents extends TooltipTriggerEvents$1 {}
25
25
  declare const TooltipTriggerElementBase: BaseElementConstructor<TooltipTriggerProps>;
26
26
  declare class TooltipTriggerElement extends TooltipTriggerElementBase {}
27
27
  //#endregion
28
- export { TooltipContentElement, TooltipContentEvents, TooltipContentProps, TooltipRootElement, TooltipRootEvents, TooltipRootProps, TooltipTriggerElement, TooltipTriggerEvents, TooltipTriggerProps, tooltipContentEvents, tooltipContentProps, tooltipRootEvents, tooltipRootProps, tooltipTriggerEvents, tooltipTriggerProps, useTooltipContent, useTooltipRoot, useTooltipTrigger };
28
+ export { TooltipContentElement, type TooltipContentEvents, type TooltipContentProps, TooltipRootElement, type TooltipRootEvents, type TooltipRootProps, TooltipTriggerElement, type TooltipTriggerEvents, type TooltipTriggerProps, tooltipContentEvents, tooltipContentProps, tooltipRootEvents, tooltipRootProps, tooltipTriggerEvents, tooltipTriggerProps, useTooltipContent, useTooltipRoot, useTooltipTrigger };
@@ -0,0 +1,35 @@
1
+ import { createSignal, useEffect } from "@aria-ui/core";
2
+ import { getNearestOverflowAncestor } from "@zag-js/dom-query";
3
+
4
+ //#region src/utils/assign-styles.ts
5
+ /**
6
+ * A type-safe version of `Object.assign` for `element.style`.
7
+ */
8
+ function assignStyles(element, styles) {
9
+ Object.assign(element.style, styles);
10
+ }
11
+
12
+ //#endregion
13
+ //#region src/hooks/use-scrolling.ts
14
+ function useScrolling(host) {
15
+ const scrolling = createSignal(false);
16
+ useEffect(host, () => {
17
+ const scrollableParent = getNearestOverflowAncestor(host);
18
+ const handleScroll = () => {
19
+ scrolling.set(true);
20
+ };
21
+ const handleMouseMove = () => {
22
+ scrolling.set(false);
23
+ };
24
+ scrollableParent.addEventListener("scroll", handleScroll, { passive: true });
25
+ window.addEventListener("mousemove", handleMouseMove, { passive: true });
26
+ return () => {
27
+ scrollableParent.removeEventListener("scroll", handleScroll);
28
+ window.removeEventListener("mousemove", handleMouseMove);
29
+ };
30
+ });
31
+ return scrolling;
32
+ }
33
+
34
+ //#endregion
35
+ export { assignStyles, useScrolling };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/web",
3
3
  "type": "module",
4
- "version": "0.6.1",
4
+ "version": "0.7.1",
5
5
  "private": false,
6
6
  "description": "A collection of web components for ProseKit",
7
7
  "author": {
@@ -10,14 +10,14 @@
10
10
  },
11
11
  "license": "MIT",
12
12
  "funding": "https://github.com/sponsors/ocavue",
13
- "homepage": "https://github.com/ocavue/prosekit#readme",
13
+ "homepage": "https://github.com/prosekit/prosekit#readme",
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "git+https://github.com/ocavue/prosekit.git",
16
+ "url": "git+https://github.com/prosekit/prosekit.git",
17
17
  "directory": "packages/web"
18
18
  },
19
19
  "bugs": {
20
- "url": "https://github.com/ocavue/prosekit/issues"
20
+ "url": "https://github.com/prosekit/prosekit/issues"
21
21
  },
22
22
  "keywords": [
23
23
  "ProseMirror"
@@ -38,6 +38,10 @@
38
38
  "types": "./dist/prosekit-web-block-handle.d.ts",
39
39
  "default": "./dist/prosekit-web-block-handle.js"
40
40
  },
41
+ "./drop-indicator": {
42
+ "types": "./dist/prosekit-web-drop-indicator.d.ts",
43
+ "default": "./dist/prosekit-web-drop-indicator.js"
44
+ },
41
45
  "./inline-popover": {
42
46
  "types": "./dist/prosekit-web-inline-popover.d.ts",
43
47
  "default": "./dist/prosekit-web-inline-popover.js"
@@ -71,15 +75,16 @@
71
75
  "@aria-ui/popover": "^0.0.27",
72
76
  "@aria-ui/presence": "^0.0.19",
73
77
  "@aria-ui/tooltip": "^0.0.29",
74
- "@floating-ui/dom": "^1.7.2",
75
- "@ocavue/utils": "^0.5.0",
78
+ "@floating-ui/dom": "^1.7.3",
79
+ "@ocavue/utils": "^0.6.0",
80
+ "@zag-js/dom-query": "^1.21.1",
76
81
  "prosemirror-tables": "^1.7.1",
77
82
  "@prosekit/core": "^0.8.3",
78
- "@prosekit/extensions": "^0.10.0",
83
+ "@prosekit/extensions": "^0.11.1",
79
84
  "@prosekit/pm": "^0.1.11"
80
85
  },
81
86
  "devDependencies": {
82
- "tsdown": "^0.12.9",
87
+ "tsdown": "^0.13.1",
83
88
  "typescript": "~5.8.3",
84
89
  "vitest": "^3.2.4",
85
90
  "@prosekit/config-tsdown": "0.0.0",
@@ -93,6 +98,7 @@
93
98
  "prosekit-web": "./src/index.ts",
94
99
  "prosekit-web-autocomplete": "./src/components/autocomplete/index.gen.ts",
95
100
  "prosekit-web-block-handle": "./src/components/block-handle/index.gen.ts",
101
+ "prosekit-web-drop-indicator": "./src/components/drop-indicator/index.gen.ts",
96
102
  "prosekit-web-inline-popover": "./src/components/inline-popover/index.gen.ts",
97
103
  "prosekit-web-popover": "./src/components/popover/index.gen.ts",
98
104
  "prosekit-web-resizable": "./src/components/resizable/index.gen.ts",
@@ -116,6 +122,9 @@
116
122
  "block-handle": [
117
123
  "./dist/prosekit-web-block-handle.d.ts"
118
124
  ],
125
+ "drop-indicator": [
126
+ "./dist/prosekit-web-drop-indicator.d.ts"
127
+ ],
119
128
  "inline-popover": [
120
129
  "./dist/prosekit-web-inline-popover.d.ts"
121
130
  ],