@prosekit/web 0.7.13 → 0.8.0-beta.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.
Files changed (207) hide show
  1. package/dist/prosekit-web-autocomplete.d.ts +112 -90
  2. package/dist/prosekit-web-autocomplete.d.ts.map +1 -1
  3. package/dist/prosekit-web-autocomplete.js +292 -217
  4. package/dist/prosekit-web-autocomplete.js.map +1 -1
  5. package/dist/prosekit-web-block-handle.d.ts +95 -62
  6. package/dist/prosekit-web-block-handle.d.ts.map +1 -1
  7. package/dist/prosekit-web-block-handle.js +219 -114
  8. package/dist/prosekit-web-block-handle.js.map +1 -1
  9. package/dist/prosekit-web-drop-indicator.d.ts +13 -15
  10. package/dist/prosekit-web-drop-indicator.d.ts.map +1 -1
  11. package/dist/prosekit-web-drop-indicator.js +34 -30
  12. package/dist/prosekit-web-drop-indicator.js.map +1 -1
  13. package/dist/prosekit-web-inline-popover.d.ts +88 -54
  14. package/dist/prosekit-web-inline-popover.d.ts.map +1 -1
  15. package/dist/prosekit-web-inline-popover.js +129 -79
  16. package/dist/prosekit-web-inline-popover.js.map +1 -1
  17. package/dist/prosekit-web-menu.d.ts +13 -0
  18. package/dist/prosekit-web-menu.d.ts.map +1 -0
  19. package/dist/prosekit-web-menu.js +53 -0
  20. package/dist/prosekit-web-menu.js.map +1 -0
  21. package/dist/prosekit-web-popover.d.ts +7 -26
  22. package/dist/prosekit-web-popover.d.ts.map +1 -1
  23. package/dist/prosekit-web-popover.js +31 -29
  24. package/dist/prosekit-web-popover.js.map +1 -1
  25. package/dist/prosekit-web-resizable.d.ts +92 -51
  26. package/dist/prosekit-web-resizable.d.ts.map +1 -1
  27. package/dist/prosekit-web-resizable.js +139 -131
  28. package/dist/prosekit-web-resizable.js.map +1 -1
  29. package/dist/prosekit-web-table-handle.d.ts +166 -199
  30. package/dist/prosekit-web-table-handle.d.ts.map +1 -1
  31. package/dist/prosekit-web-table-handle.js +495 -496
  32. package/dist/prosekit-web-table-handle.js.map +1 -1
  33. package/dist/prosekit-web-tooltip.d.ts +7 -26
  34. package/dist/prosekit-web-tooltip.d.ts.map +1 -1
  35. package/dist/prosekit-web-tooltip.js +31 -29
  36. package/dist/prosekit-web-tooltip.js.map +1 -1
  37. package/dist/use-editor-extension.js +2 -2
  38. package/dist/use-editor-extension.js.map +1 -1
  39. package/dist/use-scrolling.js +17 -8
  40. package/dist/use-scrolling.js.map +1 -1
  41. package/package.json +30 -25
  42. package/src/components/autocomplete/autocomplete-empty.ts +45 -0
  43. package/src/components/autocomplete/autocomplete-item.ts +65 -0
  44. package/src/components/autocomplete/autocomplete-popup.ts +95 -0
  45. package/src/components/autocomplete/autocomplete-positioner.ts +98 -0
  46. package/src/components/autocomplete/autocomplete-root.ts +280 -0
  47. package/src/components/autocomplete/context.ts +16 -14
  48. package/src/components/autocomplete/index.ts +65 -0
  49. package/src/components/block-handle/block-handle-add.ts +71 -0
  50. package/src/components/block-handle/block-handle-draggable.ts +158 -0
  51. package/src/components/block-handle/block-handle-popup.ts +43 -0
  52. package/src/components/block-handle/block-handle-positioner.ts +89 -0
  53. package/src/components/block-handle/block-handle-root.ts +116 -0
  54. package/src/components/block-handle/context.ts +9 -18
  55. package/src/components/block-handle/hover-state.ts +16 -0
  56. package/src/components/block-handle/index.ts +59 -0
  57. package/src/components/block-handle/{block-handle-popover/pointer-move.ts → pointer-move.ts} +8 -7
  58. package/src/components/block-handle/{block-handle-draggable/set-drag-preview.ts → set-drag-preview.ts} +4 -4
  59. package/src/components/block-handle/use-hover-extension.ts +65 -0
  60. package/src/components/drop-indicator/drop-indicator.ts +128 -0
  61. package/src/components/drop-indicator/index.ts +18 -0
  62. package/src/components/inline-popover/index.ts +41 -0
  63. package/src/components/inline-popover/inline-popover-popup.ts +52 -0
  64. package/src/components/inline-popover/inline-popover-positioner.ts +98 -0
  65. package/src/components/inline-popover/inline-popover-root.ts +122 -0
  66. package/src/components/inline-popover/store.ts +6 -0
  67. package/src/components/menu/index.ts +92 -0
  68. package/src/components/popover/index.ts +53 -0
  69. package/src/components/resizable/{resizable-handle/calc-resize.ts → calc-resize.ts} +1 -1
  70. package/src/components/resizable/context.ts +3 -6
  71. package/src/components/resizable/index.ts +32 -0
  72. package/src/components/resizable/resizable-handle.ts +134 -0
  73. package/src/components/resizable/resizable-root.ts +184 -0
  74. package/src/components/table-handle/dnd.ts +16 -27
  75. package/src/components/table-handle/index.ts +125 -0
  76. package/src/components/table-handle/{table-handle-drag-preview/render-preview.ts → render-preview.ts} +5 -5
  77. package/src/components/table-handle/shared.ts +61 -0
  78. package/src/components/table-handle/store.ts +117 -0
  79. package/src/components/table-handle/table-handle-column-menu-root.ts +51 -0
  80. package/src/components/table-handle/table-handle-column-menu-trigger.ts +107 -0
  81. package/src/components/table-handle/table-handle-column-popup.ts +44 -0
  82. package/src/components/table-handle/table-handle-column-positioner.ts +67 -0
  83. package/src/components/table-handle/table-handle-drag-preview.ts +169 -0
  84. package/src/components/table-handle/table-handle-drop-indicator.ts +166 -0
  85. package/src/components/table-handle/table-handle-root.ts +103 -0
  86. package/src/components/table-handle/table-handle-row-menu-root.ts +51 -0
  87. package/src/components/table-handle/table-handle-row-menu-trigger.ts +107 -0
  88. package/src/components/table-handle/table-handle-row-popup.ts +42 -0
  89. package/src/components/table-handle/table-handle-row-positioner.ts +67 -0
  90. package/src/components/table-handle/use-drop.ts +74 -0
  91. package/src/components/table-handle/{hooks/use-empty-image.ts → use-empty-image.ts} +2 -3
  92. package/src/components/table-handle/utils.ts +0 -11
  93. package/src/components/tooltip/index.ts +52 -0
  94. package/src/hooks/use-editor-extension.ts +4 -4
  95. package/src/hooks/use-editor-focus-event.ts +4 -4
  96. package/src/hooks/use-editor-typing.ts +12 -16
  97. package/src/hooks/use-editor-update-event.ts +4 -4
  98. package/src/hooks/use-keymap.ts +4 -4
  99. package/src/hooks/use-scrolling.ts +11 -10
  100. package/src/hooks/use-selecting.ts +8 -15
  101. package/src/utils/event.ts +28 -0
  102. package/src/utils/lazy-signal.spec.ts +68 -0
  103. package/src/utils/lazy-signal.ts +17 -0
  104. package/src/utils/prefers-reduced-motion.ts +6 -0
  105. package/src/utils/prevent-default.ts +3 -0
  106. package/src/utils/use-html-element-at.ts +17 -0
  107. package/src/utils/use-no-focus.ts +7 -0
  108. package/dist/get-default-state.js +0 -11
  109. package/dist/get-default-state.js.map +0 -1
  110. package/src/components/autocomplete/autocomplete-empty/element.gen.ts +0 -18
  111. package/src/components/autocomplete/autocomplete-empty/setup.ts +0 -6
  112. package/src/components/autocomplete/autocomplete-empty/types.ts +0 -13
  113. package/src/components/autocomplete/autocomplete-item/element.gen.ts +0 -18
  114. package/src/components/autocomplete/autocomplete-item/setup.ts +0 -30
  115. package/src/components/autocomplete/autocomplete-item/types.ts +0 -25
  116. package/src/components/autocomplete/autocomplete-list/element.gen.ts +0 -18
  117. package/src/components/autocomplete/autocomplete-list/setup.ts +0 -125
  118. package/src/components/autocomplete/autocomplete-list/types.ts +0 -22
  119. package/src/components/autocomplete/autocomplete-popover/element.gen.ts +0 -18
  120. package/src/components/autocomplete/autocomplete-popover/setup.ts +0 -169
  121. package/src/components/autocomplete/autocomplete-popover/types.ts +0 -100
  122. package/src/components/autocomplete/index.gen.ts +0 -17
  123. package/src/components/block-handle/block-handle-add/element.gen.ts +0 -18
  124. package/src/components/block-handle/block-handle-add/setup.ts +0 -33
  125. package/src/components/block-handle/block-handle-add/types.ts +0 -23
  126. package/src/components/block-handle/block-handle-draggable/element.gen.ts +0 -18
  127. package/src/components/block-handle/block-handle-draggable/setup.ts +0 -113
  128. package/src/components/block-handle/block-handle-draggable/types.ts +0 -23
  129. package/src/components/block-handle/block-handle-popover/element.gen.ts +0 -18
  130. package/src/components/block-handle/block-handle-popover/setup.ts +0 -68
  131. package/src/components/block-handle/block-handle-popover/types.ts +0 -81
  132. package/src/components/block-handle/index.gen.ts +0 -13
  133. package/src/components/drop-indicator/drop-indicator/element.gen.ts +0 -18
  134. package/src/components/drop-indicator/drop-indicator/setup.ts +0 -75
  135. package/src/components/drop-indicator/drop-indicator/types.ts +0 -31
  136. package/src/components/drop-indicator/index.gen.ts +0 -5
  137. package/src/components/inline-popover/index.gen.ts +0 -5
  138. package/src/components/inline-popover/inline-popover/element.gen.ts +0 -18
  139. package/src/components/inline-popover/inline-popover/setup.ts +0 -111
  140. package/src/components/inline-popover/inline-popover/types.ts +0 -112
  141. package/src/components/popover/index.gen.ts +0 -13
  142. package/src/components/popover/popover-content/element.gen.ts +0 -18
  143. package/src/components/popover/popover-content/setup.ts +0 -1
  144. package/src/components/popover/popover-content/types.ts +0 -6
  145. package/src/components/popover/popover-root/element.gen.ts +0 -18
  146. package/src/components/popover/popover-root/setup.ts +0 -1
  147. package/src/components/popover/popover-root/types.ts +0 -6
  148. package/src/components/popover/popover-trigger/element.gen.ts +0 -18
  149. package/src/components/popover/popover-trigger/setup.ts +0 -1
  150. package/src/components/popover/popover-trigger/types.ts +0 -6
  151. package/src/components/resizable/index.gen.ts +0 -9
  152. package/src/components/resizable/resizable-handle/element.gen.ts +0 -18
  153. package/src/components/resizable/resizable-handle/setup.ts +0 -106
  154. package/src/components/resizable/resizable-handle/types.ts +0 -29
  155. package/src/components/resizable/resizable-root/element.gen.ts +0 -18
  156. package/src/components/resizable/resizable-root/setup.ts +0 -84
  157. package/src/components/resizable/resizable-root/types.ts +0 -59
  158. package/src/components/table-handle/context.ts +0 -43
  159. package/src/components/table-handle/hooks/use-drop.ts +0 -85
  160. package/src/components/table-handle/index.gen.ts +0 -37
  161. package/src/components/table-handle/table-handle-column-root/element.gen.ts +0 -18
  162. package/src/components/table-handle/table-handle-column-root/setup.ts +0 -60
  163. package/src/components/table-handle/table-handle-column-root/types.ts +0 -73
  164. package/src/components/table-handle/table-handle-column-trigger/element.gen.ts +0 -18
  165. package/src/components/table-handle/table-handle-column-trigger/setup.ts +0 -64
  166. package/src/components/table-handle/table-handle-column-trigger/types.ts +0 -20
  167. package/src/components/table-handle/table-handle-drag-preview/element.gen.ts +0 -18
  168. package/src/components/table-handle/table-handle-drag-preview/setup.ts +0 -57
  169. package/src/components/table-handle/table-handle-drag-preview/types.ts +0 -14
  170. package/src/components/table-handle/table-handle-drag-preview/updater.ts +0 -90
  171. package/src/components/table-handle/table-handle-drop-indicator/element.gen.ts +0 -18
  172. package/src/components/table-handle/table-handle-drop-indicator/setup.ts +0 -52
  173. package/src/components/table-handle/table-handle-drop-indicator/types.ts +0 -15
  174. package/src/components/table-handle/table-handle-drop-indicator/updater.ts +0 -96
  175. package/src/components/table-handle/table-handle-popover-content/element.gen.ts +0 -18
  176. package/src/components/table-handle/table-handle-popover-content/setup.ts +0 -83
  177. package/src/components/table-handle/table-handle-popover-content/types.ts +0 -32
  178. package/src/components/table-handle/table-handle-popover-item/element.gen.ts +0 -18
  179. package/src/components/table-handle/table-handle-popover-item/setup.ts +0 -17
  180. package/src/components/table-handle/table-handle-popover-item/types.ts +0 -16
  181. package/src/components/table-handle/table-handle-root/element.gen.ts +0 -18
  182. package/src/components/table-handle/table-handle-root/setup.ts +0 -86
  183. package/src/components/table-handle/table-handle-root/types.ts +0 -23
  184. package/src/components/table-handle/table-handle-row-root/element.gen.ts +0 -18
  185. package/src/components/table-handle/table-handle-row-root/setup.ts +0 -70
  186. package/src/components/table-handle/table-handle-row-root/types.ts +0 -68
  187. package/src/components/table-handle/table-handle-row-trigger/element.gen.ts +0 -18
  188. package/src/components/table-handle/table-handle-row-trigger/setup.ts +0 -63
  189. package/src/components/table-handle/table-handle-row-trigger/types.ts +0 -23
  190. package/src/components/tooltip/index.gen.ts +0 -13
  191. package/src/components/tooltip/tooltip-content/element.gen.ts +0 -18
  192. package/src/components/tooltip/tooltip-content/setup.ts +0 -1
  193. package/src/components/tooltip/tooltip-content/types.ts +0 -6
  194. package/src/components/tooltip/tooltip-root/element.gen.ts +0 -18
  195. package/src/components/tooltip/tooltip-root/setup.ts +0 -1
  196. package/src/components/tooltip/tooltip-root/types.ts +0 -6
  197. package/src/components/tooltip/tooltip-trigger/element.gen.ts +0 -18
  198. package/src/components/tooltip/tooltip-trigger/setup.ts +0 -1
  199. package/src/components/tooltip/tooltip-trigger/types.ts +0 -6
  200. package/src/hooks/use-first-rendering.ts +0 -15
  201. package/src/utils/get-default-state.spec.ts +0 -42
  202. package/src/utils/get-default-state.ts +0 -18
  203. /package/src/components/autocomplete/{autocomplete-popover/helpers.spec.ts → helpers.spec.ts} +0 -0
  204. /package/src/components/autocomplete/{autocomplete-popover/helpers.ts → helpers.ts} +0 -0
  205. /package/src/components/inline-popover/{inline-popover/virtual-selection-element.ts → virtual-selection-element.ts} +0 -0
  206. /package/src/components/resizable/{resizable-handle/calc-resize.spec.ts → calc-resize.spec.ts} +0 -0
  207. /package/src/components/table-handle/{table-handle-drop-indicator/calc-drag-over.ts → calc-drag-over.ts} +0 -0
@@ -0,0 +1,89 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ type HostElement,
6
+ type HostElementConstructor,
7
+ type PropsDeclaration,
8
+ type State,
9
+ } from '@aria-ui/core'
10
+ import { OverlayPositionerPropsDeclaration, setupOverlayPositioner, type OverlayPositionerProps } from '@aria-ui/elements/overlay'
11
+ import type { Placement } from '@floating-ui/dom'
12
+
13
+ import { blockHandleOverlayStoreContext } from './context.ts'
14
+
15
+ /**
16
+ * @public
17
+ */
18
+ export interface BlockHandlePositionerProps extends Omit<OverlayPositionerProps, 'placement' | 'hoist' | 'flip' | 'shift' | 'hide'> {
19
+ /**
20
+ * The placement of the popover, relative to the hovered block.
21
+ *
22
+ * @default "left"
23
+ */
24
+ placement: Placement
25
+
26
+ /**
27
+ * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
28
+ * to place the floating element on top of other page content.
29
+ *
30
+ * @default false
31
+ */
32
+ hoist: boolean
33
+
34
+ /**
35
+ * @default false
36
+ * @hidden
37
+ */
38
+ flip: boolean
39
+
40
+ /**
41
+ * @default false
42
+ * @hidden
43
+ */
44
+ shift: boolean
45
+
46
+ /**
47
+ * @default true
48
+ * @hidden
49
+ */
50
+ hide: boolean
51
+ }
52
+
53
+ /** @internal */
54
+ export const BlockHandlePositionerPropsDeclaration: PropsDeclaration<BlockHandlePositionerProps> = /* @__PURE__ */ defineProps<
55
+ BlockHandlePositionerProps
56
+ >({
57
+ ...OverlayPositionerPropsDeclaration,
58
+ placement: { default: 'left', attribute: 'placement', type: 'string' },
59
+ // Enabling `hoist` will cause the popover to have a small delay when
60
+ // scrolling the page.
61
+ hoist: { default: false, attribute: 'hoist', type: 'boolean' },
62
+ flip: { default: false, attribute: false, type: 'json' },
63
+ shift: { default: false, attribute: 'shift', type: 'boolean' },
64
+ hide: { default: true, attribute: 'hide', type: 'boolean' },
65
+ })
66
+
67
+ /** @internal */
68
+ export function setupBlockHandlePositioner(
69
+ host: HostElement,
70
+ props: State<BlockHandlePositionerProps>,
71
+ ): void {
72
+ const getOverlayStore = blockHandleOverlayStoreContext.consume(host)
73
+ setupOverlayPositioner(host, props as unknown as State<OverlayPositionerProps>, getOverlayStore)
74
+ }
75
+
76
+ const BlockHandlePositionerElementBase: HostElementConstructor<BlockHandlePositionerProps> = defineCustomElement(
77
+ setupBlockHandlePositioner,
78
+ BlockHandlePositionerPropsDeclaration,
79
+ )
80
+
81
+ /**
82
+ * @public
83
+ */
84
+ export class BlockHandlePositionerElement extends BlockHandlePositionerElementBase {}
85
+
86
+ /** @internal */
87
+ export function registerBlockHandlePositionerElement(): void {
88
+ registerCustomElement('prosekit-block-handle-positioner', BlockHandlePositionerElement)
89
+ }
@@ -0,0 +1,116 @@
1
+ import {
2
+ computed,
3
+ createSignal,
4
+ defineCustomElement,
5
+ defineProps,
6
+ registerCustomElement,
7
+ useEffect,
8
+ type HostElement,
9
+ type HostElementConstructor,
10
+ type PropsDeclaration,
11
+ type State,
12
+ } from '@aria-ui/core'
13
+ import { createOverlayStore } from '@aria-ui/elements/overlay'
14
+ import type { VirtualElement } from '@floating-ui/dom'
15
+ import type { Editor } from '@prosekit/core'
16
+ import type { ProseMirrorNode } from '@prosekit/pm/model'
17
+
18
+ import { useScrolling } from '../../hooks/use-scrolling.ts'
19
+
20
+ import { blockHandleOverlayStoreContext, BlockHandleStore, blockHandleStoreContext } from './context.ts'
21
+ import { useHoverExtension } from './use-hover-extension.ts'
22
+
23
+ export interface BlockHandleRootProps {
24
+ /**
25
+ * The ProseKit editor instance.
26
+ *
27
+ * @default null
28
+ * @hidden
29
+ */
30
+ editor: Editor | null
31
+ }
32
+
33
+ /** @internal */
34
+ export const BlockHandleRootPropsDeclaration: PropsDeclaration<BlockHandleRootProps> = /* @__PURE__ */ defineProps<
35
+ BlockHandleRootProps
36
+ >({
37
+ editor: { default: null, attribute: false, type: 'json' },
38
+ })
39
+
40
+ /**
41
+ * @public
42
+ */
43
+ export class BlockHandleStateChangeEvent extends Event {
44
+ /**
45
+ * The currently hovered block's node and position, or `null` if no block is hovered.
46
+ */
47
+ detail: { node: ProseMirrorNode; pos: number } | null
48
+ constructor(state: { node: ProseMirrorNode; pos: number } | null) {
49
+ super('stateChange', { bubbles: true })
50
+ this.detail = state
51
+ }
52
+ }
53
+
54
+ /**
55
+ * @public
56
+ */
57
+ export interface BlockHandleRootEvents {
58
+ /**
59
+ * Fired when the hovered block changes.
60
+ */
61
+ stateChange: BlockHandleStateChangeEvent
62
+ }
63
+
64
+ /**
65
+ * @internal
66
+ */
67
+ export function setupBlockHandleRoot(
68
+ host: HostElement,
69
+ props: State<BlockHandleRootProps>,
70
+ ): void {
71
+ const getEditor = props.editor.get
72
+
73
+ const store = new BlockHandleStore()
74
+ blockHandleStoreContext.provide(host, store)
75
+
76
+ const reference = createSignal<VirtualElement | undefined>(undefined)
77
+ const getScrolling = useScrolling(host)
78
+
79
+ const getOpen = computed(() => !!store.hoverState.get() && !getScrolling())
80
+
81
+ const overlayStore = createOverlayStore(
82
+ getOpen,
83
+ () => {},
84
+ () => true,
85
+ () => false,
86
+ (event) => host.dispatchEvent(event),
87
+ )
88
+
89
+ useHoverExtension(host, getEditor, (ref, hoverState) => {
90
+ reference.set(ref ?? undefined)
91
+ store.hoverState.set(hoverState)
92
+ const state = hoverState ? { node: hoverState.node, pos: hoverState.pos } : null
93
+ host.dispatchEvent(new BlockHandleStateChangeEvent(state))
94
+ })
95
+
96
+ useEffect(host, () => {
97
+ overlayStore.setAnchorElement(reference.get())
98
+ })
99
+
100
+ blockHandleOverlayStoreContext.provide(host, overlayStore)
101
+ }
102
+
103
+ const BlockHandleRootElementBase: HostElementConstructor<BlockHandleRootProps> = defineCustomElement(
104
+ setupBlockHandleRoot,
105
+ BlockHandleRootPropsDeclaration,
106
+ )
107
+
108
+ /**
109
+ * @public
110
+ */
111
+ export class BlockHandleRootElement extends BlockHandleRootElementBase {}
112
+
113
+ /** @internal */
114
+ export function registerBlockHandleRootElement(): void {
115
+ registerCustomElement('prosekit-block-handle-root', BlockHandleRootElement)
116
+ }
@@ -1,31 +1,22 @@
1
- import { createContext, type Context } from '@aria-ui/core'
2
- import type { ProseMirrorNode } from '@prosekit/pm/model'
1
+ import { createContext, createSignal, type Context, type Signal } from '@aria-ui/core'
2
+ import type { OverlayStore } from '@aria-ui/elements/overlay'
3
3
 
4
- /**
5
- * @internal
6
- */
7
- export interface HoverState {
8
- node: ProseMirrorNode
9
- pos: number
10
- }
4
+ import type { HoverState } from './hover-state.ts'
11
5
 
12
6
  /**
13
7
  * @internal
14
8
  */
15
- export type BlockPopoverContext = HoverState | null
9
+ export class BlockHandleStore {
10
+ readonly hoverState: Signal<HoverState | undefined> = createSignal<HoverState | undefined>(undefined)
11
+ readonly dragging: Signal<boolean> = createSignal(false)
12
+ }
16
13
 
17
14
  /**
18
15
  * @internal
19
16
  */
20
- export const blockPopoverContext: Context<BlockPopoverContext> = createContext(
21
- 'prosekit-block-popover-context',
22
- null,
23
- )
17
+ export const blockHandleStoreContext: Context<BlockHandleStore> = createContext<BlockHandleStore>('prosekit-block-handle-store')
24
18
 
25
19
  /**
26
20
  * @internal
27
21
  */
28
- export const draggingContext: Context<boolean> = createContext(
29
- 'prosekit-block-handle-dragging-context',
30
- false,
31
- )
22
+ export const blockHandleOverlayStoreContext: Context<OverlayStore> = createContext<OverlayStore>('prosekit-block-handle-overlay-store')
@@ -0,0 +1,16 @@
1
+ import type { ProseMirrorNode } from '@prosekit/pm/model'
2
+
3
+ /**
4
+ * @internal
5
+ */
6
+ export interface HoverState {
7
+ node: ProseMirrorNode
8
+ pos: number
9
+ }
10
+
11
+ /**
12
+ * @internal
13
+ */
14
+ export function isHoverStateEqual(a: HoverState, b: HoverState): boolean {
15
+ return a.pos === b.pos && a.node.eq(b.node)
16
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+
3
+ @module
4
+
5
+ ## Anatomy
6
+
7
+ ```html
8
+ <prosekit-block-handle-root>
9
+ <prosekit-block-handle-positioner>
10
+ <prosekit-block-handle-popup>
11
+ <prosekit-block-handle-add>...</prosekit-block-handle-add>
12
+ <prosekit-block-handle-draggable>...</prosekit-block-handle-draggable>
13
+ </prosekit-block-handle-popup>
14
+ </prosekit-block-handle-positioner>
15
+ </prosekit-block-handle-root>
16
+ ```
17
+ */
18
+
19
+ export {
20
+ BlockHandleAddElement,
21
+ BlockHandleAddPropsDeclaration,
22
+ registerBlockHandleAddElement,
23
+ setupBlockHandleAdd,
24
+ type BlockHandleAddProps,
25
+ } from './block-handle-add.ts'
26
+
27
+ export {
28
+ BlockHandleDraggableElement,
29
+ BlockHandleDraggablePropsDeclaration,
30
+ registerBlockHandleDraggableElement,
31
+ setupBlockHandleDraggable,
32
+ type BlockHandleDraggableProps,
33
+ } from './block-handle-draggable.ts'
34
+
35
+ export {
36
+ BlockHandlePopupElement,
37
+ BlockHandlePopupPropsDeclaration,
38
+ registerBlockHandlePopupElement,
39
+ setupBlockHandlePopup,
40
+ type BlockHandlePopupProps,
41
+ } from './block-handle-popup.ts'
42
+
43
+ export {
44
+ BlockHandlePositionerElement,
45
+ BlockHandlePositionerPropsDeclaration,
46
+ registerBlockHandlePositionerElement,
47
+ setupBlockHandlePositioner,
48
+ type BlockHandlePositionerProps,
49
+ } from './block-handle-positioner.ts'
50
+
51
+ export {
52
+ BlockHandleRootElement,
53
+ BlockHandleRootPropsDeclaration,
54
+ BlockHandleStateChangeEvent,
55
+ registerBlockHandleRootElement,
56
+ setupBlockHandleRoot,
57
+ type BlockHandleRootEvents,
58
+ type BlockHandleRootProps,
59
+ } from './block-handle-root.ts'
@@ -4,12 +4,13 @@ import { defineDOMEventHandler, union, type PlainExtension } from '@prosekit/cor
4
4
  import type { ProseMirrorNode } from '@prosekit/pm/model'
5
5
  import type { EditorView } from '@prosekit/pm/view'
6
6
 
7
- import { getClientRect } from '../../../utils/get-client-rect.ts'
8
- import type { HoverState } from '../context.ts'
7
+ import { getClientRect } from '../../utils/get-client-rect.ts'
8
+
9
+ import type { HoverState } from './hover-state.ts'
9
10
 
10
11
  export type ElementHoverHandler = (
11
- reference: VirtualElement | null,
12
- hoverState: HoverState | null,
12
+ reference?: VirtualElement,
13
+ hoverState?: HoverState,
13
14
  ) => void
14
15
 
15
16
  export function defineElementHoverHandler(handler: ElementHoverHandler): PlainExtension {
@@ -53,14 +54,14 @@ export function defineElementHoverHandler(handler: ElementHoverHandler): PlainEx
53
54
 
54
55
  const block = findBlockByCoords(view, x, y)
55
56
  if (!block) {
56
- handler(null, null)
57
+ handler()
57
58
  return
58
59
  }
59
60
 
60
61
  const { node, pos } = block
61
62
  const element = view.nodeDOM(pos)
62
63
  if (!element || !isHTMLElement(element)) {
63
- handler(null, null)
64
+ handler()
64
65
  return
65
66
  }
66
67
 
@@ -82,7 +83,7 @@ export function defineElementHoverHandler(handler: ElementHoverHandler): PlainEx
82
83
  defineDOMEventHandler('pointermove', throttle(handlePointerEvent, 200)),
83
84
  defineDOMEventHandler('pointerenter', handlePointerEvent),
84
85
  defineDOMEventHandler('pointerout', handlePointerEvent),
85
- defineDOMEventHandler('keypress', () => handler(null, null)),
86
+ defineDOMEventHandler('keypress', () => handler()),
86
87
  )
87
88
  }
88
89
 
@@ -1,7 +1,7 @@
1
- import { DRAGGING_CLASS_NAME } from '../../../constants.ts'
2
- import { assignStyles } from '../../../utils/assign-styles.ts'
3
- import { getClientRect } from '../../../utils/get-client-rect.ts'
4
- import { maxZIndex } from '../../../utils/max-z-index.ts'
1
+ import { DRAGGING_CLASS_NAME } from '../../constants.ts'
2
+ import { assignStyles } from '../../utils/assign-styles.ts'
3
+ import { getClientRect } from '../../utils/get-client-rect.ts'
4
+ import { maxZIndex } from '../../utils/max-z-index.ts'
5
5
 
6
6
  /**
7
7
  * Sets a drag preview image for the given element and ensures the preview position
@@ -0,0 +1,65 @@
1
+ import type { HostElement } from '@aria-ui/core'
2
+ import type { Editor } from '@prosekit/core'
3
+
4
+ import { useEditorExtension } from '../../hooks/use-editor-extension.ts'
5
+ import { prefersReducedMotion } from '../../utils/prefers-reduced-motion.ts'
6
+
7
+ import { isHoverStateEqual, type HoverState } from './hover-state.ts'
8
+ import { defineElementHoverHandler, type ElementHoverHandler } from './pointer-move.ts'
9
+
10
+ export function useHoverExtension(
11
+ host: HostElement,
12
+ getEditor: () => Editor | null,
13
+ handler: ElementHoverHandler,
14
+ ): void {
15
+ const invalidTimeoutMs = prefersReducedMotion() ? 0 : 180
16
+
17
+ let invalidTimeoutId: ReturnType<typeof setTimeout> | undefined
18
+
19
+ let prevHoverState: HoverState | undefined
20
+
21
+ const callHandler: ElementHoverHandler = (reference, hoverState) => {
22
+ prevHoverState = hoverState
23
+ handler(reference, hoverState)
24
+ }
25
+
26
+ const extension = defineElementHoverHandler((reference, hoverState) => {
27
+ if (hoverState && invalidTimeoutId != null) {
28
+ clearTimeout(invalidTimeoutId)
29
+ invalidTimeoutId = undefined
30
+ }
31
+
32
+ if (prevHoverState && hoverState) {
33
+ if (isHoverStateEqual(prevHoverState, hoverState)) {
34
+ return
35
+ }
36
+ callHandler(reference, hoverState)
37
+ return
38
+ }
39
+
40
+ if (!prevHoverState && !hoverState) {
41
+ return
42
+ }
43
+
44
+ if (!prevHoverState && hoverState) {
45
+ callHandler(reference, hoverState)
46
+ return
47
+ }
48
+
49
+ if (prevHoverState && !hoverState) {
50
+ if (invalidTimeoutId != null) {
51
+ return
52
+ }
53
+
54
+ // Wait for a short period of time before invalidating the hover state.
55
+ // This ensures smoother animation when the pointer moves between two
56
+ // blocks with a small gap.
57
+ invalidTimeoutId = setTimeout(() => {
58
+ callHandler(reference, undefined)
59
+ invalidTimeoutId = undefined
60
+ }, invalidTimeoutMs)
61
+ }
62
+ })
63
+
64
+ useEditorExtension(host, getEditor, extension)
65
+ }
@@ -0,0 +1,128 @@
1
+ import {
2
+ computed,
3
+ createSignal,
4
+ defineCustomElement,
5
+ defineProps,
6
+ registerCustomElement,
7
+ useEffect,
8
+ type HostElement,
9
+ type HostElementConstructor,
10
+ type PropsDeclaration,
11
+ type State,
12
+ } from '@aria-ui/core'
13
+ import { usePresence } from '@aria-ui/utils'
14
+ import type { Editor } from '@prosekit/core'
15
+ import { defineDropIndicator, type ShowHandlerOptions } from '@prosekit/extensions/drop-indicator'
16
+
17
+ import { useEditorExtension } from '../../hooks/use-editor-extension.ts'
18
+ import { useScrolling } from '../../hooks/use-scrolling.ts'
19
+ import { assignStyles } from '../../utils/assign-styles.ts'
20
+
21
+ export interface DropIndicatorProps {
22
+ /**
23
+ * The ProseKit editor instance.
24
+ *
25
+ * @default null
26
+ * @hidden
27
+ */
28
+ editor: Editor | null
29
+
30
+ /**
31
+ * The line width in pixels.
32
+ *
33
+ * @default 2
34
+ */
35
+ width: number
36
+ }
37
+
38
+ /** @internal */
39
+ export const DropIndicatorPropsDeclaration: PropsDeclaration<DropIndicatorProps> = /* @__PURE__ */ defineProps<DropIndicatorProps>({
40
+ editor: {
41
+ default: null,
42
+ attribute: false,
43
+ type: 'json',
44
+ },
45
+ width: {
46
+ default: 2,
47
+ attribute: 'width',
48
+ type: 'number',
49
+ },
50
+ })
51
+
52
+ /**
53
+ * @internal
54
+ */
55
+ export function setupDropIndicator(
56
+ host: HostElement,
57
+ props: State<DropIndicatorProps>,
58
+ ): void {
59
+ type DropIndicatorContext = ShowHandlerOptions | null
60
+ const context = createSignal<DropIndicatorContext>(null)
61
+
62
+ const extension = defineDropIndicator({
63
+ onShow: (options) => context.set(options),
64
+ onHide: () => context.set(null),
65
+ })
66
+
67
+ useEditorExtension(host, props.editor.get, extension)
68
+
69
+ const getLine = computed(() => context.get()?.line)
70
+ const getScrolling = useScrolling(host)
71
+ const getPresence = computed(() => !!context.get() && !getScrolling())
72
+ usePresence(host, getPresence)
73
+
74
+ useEffect(host, () => {
75
+ const lineValue = getLine()
76
+ const lineWidth = props.width.get()
77
+
78
+ if (!lineValue) return
79
+
80
+ const { p1: { x: x1, y: y1 }, p2: { x: x2, y: y2 } } = lineValue
81
+ const horizontal = y1 === y2
82
+
83
+ let width: number
84
+ let height: number
85
+ let top: number = y1
86
+ let left: number = x1
87
+
88
+ if (horizontal) {
89
+ width = x2 - x1
90
+ height = lineWidth
91
+ top -= lineWidth / 2
92
+ } else {
93
+ width = lineWidth
94
+ height = y2 - y1
95
+ left -= lineWidth / 2
96
+ }
97
+
98
+ top = Math.round(top)
99
+ left = Math.round(left)
100
+
101
+ assignStyles(host, {
102
+ position: 'fixed',
103
+ pointerEvents: 'none',
104
+ width: `${width}px`,
105
+ height: `${height}px`,
106
+ transform: `translate(${left}px, ${top}px)`,
107
+ left: '0px',
108
+ top: '0px',
109
+ })
110
+ })
111
+ }
112
+
113
+ const DropIndicatorElementBase: HostElementConstructor<DropIndicatorProps> = defineCustomElement(
114
+ setupDropIndicator,
115
+ DropIndicatorPropsDeclaration,
116
+ )
117
+
118
+ /**
119
+ * @public
120
+ */
121
+ export class DropIndicatorElement extends DropIndicatorElementBase {}
122
+
123
+ /**
124
+ * @internal
125
+ */
126
+ export function registerDropIndicatorElement(): void {
127
+ registerCustomElement('prosekit-drop-indicator', DropIndicatorElement)
128
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+
3
+ @module
4
+
5
+ ## Anatomy
6
+
7
+ ```html
8
+ <prosekit-drop-indicator></prosekit-drop-indicator>
9
+ ```
10
+ */
11
+
12
+ export {
13
+ DropIndicatorElement,
14
+ DropIndicatorPropsDeclaration,
15
+ registerDropIndicatorElement,
16
+ setupDropIndicator,
17
+ type DropIndicatorProps,
18
+ } from './drop-indicator.ts'
@@ -0,0 +1,41 @@
1
+ /**
2
+
3
+ @module
4
+
5
+ ## Anatomy
6
+
7
+ ```html
8
+ <prosekit-inline-popover-root>
9
+ <prosekit-inline-popover-positioner>
10
+ <prosekit-inline-popover-popup>...</prosekit-inline-popover-popup>
11
+ </prosekit-inline-popover-positioner>
12
+ </prosekit-inline-popover-root>
13
+ ```
14
+ */
15
+
16
+ export {
17
+ InlinePopoverPopupElement,
18
+ InlinePopoverPopupPropsDeclaration,
19
+ registerInlinePopoverPopupElement,
20
+ setupInlinePopoverPopup,
21
+ type InlinePopoverPopupProps,
22
+ } from './inline-popover-popup.ts'
23
+
24
+ export {
25
+ InlinePopoverPositionerElement,
26
+ InlinePopoverPositionerPropsDeclaration,
27
+ registerInlinePopoverPositionerElement,
28
+ setupInlinePopoverPositioner,
29
+ type InlinePopoverPositionerProps,
30
+ } from './inline-popover-positioner.ts'
31
+
32
+ export {
33
+ InlinePopoverRootElement,
34
+ InlinePopoverRootPropsDeclaration,
35
+ registerInlinePopoverRootElement,
36
+ setupInlinePopoverRoot,
37
+ type InlinePopoverRootEvents,
38
+ type InlinePopoverRootProps,
39
+ } from './inline-popover-root.ts'
40
+
41
+ export { OpenChangeEvent } from '@aria-ui/elements/overlay'
@@ -0,0 +1,52 @@
1
+ import {
2
+ computed,
3
+ defineCustomElement,
4
+ onMount,
5
+ registerCustomElement,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type State,
10
+ } from '@aria-ui/core'
11
+ import { OverlayPopupPropsDeclaration, setupOverlayPopup, type OverlayPopupProps } from '@aria-ui/elements/overlay'
12
+ import { usePresence } from '@aria-ui/utils'
13
+
14
+ import { InlinePopoverStoreContext } from './store.ts'
15
+
16
+ /**
17
+ * @public
18
+ */
19
+ export interface InlinePopoverPopupProps extends OverlayPopupProps {}
20
+
21
+ /** @internal */
22
+ export const InlinePopoverPopupPropsDeclaration: PropsDeclaration<InlinePopoverPopupProps> = OverlayPopupPropsDeclaration
23
+
24
+ /** @internal */
25
+ export function setupInlinePopoverPopup(
26
+ host: HostElement,
27
+ _props: State<InlinePopoverPopupProps>,
28
+ ): void {
29
+ const getStore = InlinePopoverStoreContext.consume(host)
30
+ setupOverlayPopup(host, getStore)
31
+ const getOpen = computed(() => getStore()?.getIsOpen() ?? false)
32
+ usePresence(host, getOpen)
33
+
34
+ onMount(host, () => {
35
+ host.role = 'dialog'
36
+ })
37
+ }
38
+
39
+ const InlinePopoverPopupElementBase: HostElementConstructor<InlinePopoverPopupProps> = defineCustomElement(
40
+ setupInlinePopoverPopup,
41
+ InlinePopoverPopupPropsDeclaration,
42
+ )
43
+
44
+ /**
45
+ * @public
46
+ */
47
+ export class InlinePopoverPopupElement extends InlinePopoverPopupElementBase {}
48
+
49
+ /** @internal */
50
+ export function registerInlinePopoverPopupElement(): void {
51
+ registerCustomElement('prosekit-inline-popover-popup', InlinePopoverPopupElement)
52
+ }