@prosekit/web 0.8.0-beta.0 → 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 +28 -23
  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
@@ -1,16 +1,18 @@
1
- import { createContext, type Context } from '@aria-ui/core'
1
+ import { createContext, type Context, type Signal } from '@aria-ui/core'
2
+ import type { ItemFilter } from '@aria-ui/elements/listbox'
3
+ import type { OverlayStore } from '@aria-ui/elements/overlay'
2
4
 
3
- export const queryContext: Context<string> = createContext(
4
- 'prosekit/autocomplete-popover/query',
5
- '',
6
- )
5
+ /**
6
+ * @internal
7
+ */
8
+ export interface AutocompleteStore {
9
+ overlayStore: OverlayStore
10
+ query: Signal<string>
11
+ eventTarget: Signal<EventTarget | null>
12
+ filter: Signal<ItemFilter | null>
13
+ }
7
14
 
8
- export const onSubmitContext: Context<VoidFunction | null> = createContext(
9
- 'prosekit/autocomplete-popover/onSubmit',
10
- null,
11
- )
12
-
13
- export const openContext: Context<boolean> = createContext(
14
- 'prosekit/autocomplete-popover/open',
15
- false,
16
- )
15
+ /**
16
+ * @internal
17
+ */
18
+ export const autocompleteStoreContext: Context<AutocompleteStore> = createContext<AutocompleteStore>('prosekit-autocomplete-store')
@@ -0,0 +1,65 @@
1
+ /**
2
+
3
+ @module
4
+
5
+ ## Anatomy
6
+
7
+ ```html
8
+ <prosekit-autocomplete-root>
9
+ <prosekit-autocomplete-positioner>
10
+ <prosekit-autocomplete-popup>
11
+ <prosekit-autocomplete-item>...</prosekit-autocomplete-item>
12
+ <prosekit-autocomplete-empty>...</prosekit-autocomplete-empty>
13
+ </prosekit-autocomplete-popup>
14
+ </prosekit-autocomplete-positioner>
15
+ </prosekit-autocomplete-root>
16
+ ```
17
+ */
18
+
19
+ export {
20
+ AutocompleteEmptyElement,
21
+ AutocompleteEmptyPropsDeclaration,
22
+ registerAutocompleteEmptyElement,
23
+ setupAutocompleteEmpty,
24
+ type AutocompleteEmptyProps,
25
+ } from './autocomplete-empty.ts'
26
+
27
+ export {
28
+ AutocompleteItemElement,
29
+ AutocompleteItemPropsDeclaration,
30
+ registerAutocompleteItemElement,
31
+ SelectEvent,
32
+ setupAutocompleteItem,
33
+ type AutocompleteItemEvents,
34
+ type AutocompleteItemProps,
35
+ } from './autocomplete-item.ts'
36
+
37
+ export {
38
+ AutocompletePopupElement,
39
+ AutocompletePopupPropsDeclaration,
40
+ registerAutocompletePopupElement,
41
+ setupAutocompletePopup,
42
+ type AutocompletePopupEvents,
43
+ type AutocompletePopupProps,
44
+ } from './autocomplete-popup.ts'
45
+
46
+ export {
47
+ AutocompletePositionerElement,
48
+ AutocompletePositionerPropsDeclaration,
49
+ registerAutocompletePositionerElement,
50
+ setupAutocompletePositioner,
51
+ type AutocompletePositionerProps,
52
+ } from './autocomplete-positioner.ts'
53
+
54
+ export {
55
+ AutocompleteRootElement,
56
+ AutocompleteRootPropsDeclaration,
57
+ OpenChangeEvent,
58
+ QueryChangeEvent,
59
+ registerAutocompleteRootElement,
60
+ setupAutocompleteRoot,
61
+ type AutocompleteRootEvents,
62
+ type AutocompleteRootProps,
63
+ } from './autocomplete-root.ts'
64
+
65
+ export { ValueChangeEvent, ValuesChangeEvent } from '@aria-ui/elements/listbox'
@@ -0,0 +1,71 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ useEventListener,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type State,
10
+ } from '@aria-ui/core'
11
+ import { insertDefaultBlock, type Editor } from '@prosekit/core'
12
+
13
+ import { blockHandleStoreContext } from './context.ts'
14
+
15
+ export interface BlockHandleAddProps {
16
+ /**
17
+ * The ProseKit editor instance.
18
+ *
19
+ * @default null
20
+ * @hidden
21
+ */
22
+ editor: Editor | null
23
+ }
24
+
25
+ /** @internal */
26
+ export const BlockHandleAddPropsDeclaration: PropsDeclaration<BlockHandleAddProps> = /* @__PURE__ */ defineProps<BlockHandleAddProps>({
27
+ editor: { default: null, attribute: false, type: 'json' },
28
+ })
29
+
30
+ /**
31
+ * @internal
32
+ */
33
+ export function setupBlockHandleAdd(
34
+ host: HostElement,
35
+ props: State<BlockHandleAddProps>,
36
+ ): void {
37
+ const getStore = blockHandleStoreContext.consume(host)
38
+
39
+ useEventListener(host, 'pointerdown', (event) => {
40
+ event.preventDefault()
41
+
42
+ const store = getStore()
43
+ const editor = props.editor.get()
44
+ const hoverState = store?.hoverState.get()
45
+ if (!editor || !hoverState) {
46
+ return
47
+ }
48
+
49
+ const { node, pos } = hoverState
50
+ editor.exec(insertDefaultBlock({ pos: pos + node.nodeSize }))
51
+ editor.focus()
52
+
53
+ // Hide the drag handle
54
+ store?.hoverState.set(undefined)
55
+ })
56
+ }
57
+
58
+ const BlockHandleAddElementBase: HostElementConstructor<BlockHandleAddProps> = defineCustomElement(
59
+ setupBlockHandleAdd,
60
+ BlockHandleAddPropsDeclaration,
61
+ )
62
+
63
+ /**
64
+ * @public
65
+ */
66
+ export class BlockHandleAddElement extends BlockHandleAddElementBase {}
67
+
68
+ /** @internal */
69
+ export function registerBlockHandleAddElement(): void {
70
+ registerCustomElement('prosekit-block-handle-add', BlockHandleAddElement)
71
+ }
@@ -0,0 +1,158 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ onMount,
5
+ registerCustomElement,
6
+ useEventListener,
7
+ type HostElement,
8
+ type HostElementConstructor,
9
+ type PropsDeclaration,
10
+ type State,
11
+ } from '@aria-ui/core'
12
+ import { useAttribute } from '@aria-ui/utils'
13
+ import { isHTMLElement } from '@ocavue/utils'
14
+ import type { Editor } from '@prosekit/core'
15
+ import type { ViewDragging } from '@prosekit/extensions/drop-indicator'
16
+ import { Fragment, Slice } from '@prosekit/pm/model'
17
+ import { NodeSelection } from '@prosekit/pm/state'
18
+ import type { EditorView } from '@prosekit/pm/view'
19
+
20
+ import { DRAGGING_CLASS_NAME } from '../../constants.ts'
21
+ import { getSafeEditorView } from '../../utils/get-safe-editor-view.ts'
22
+
23
+ import { blockHandleStoreContext } from './context.ts'
24
+ import type { HoverState } from './hover-state.ts'
25
+ import { setDragPreview } from './set-drag-preview.ts'
26
+
27
+ export interface BlockHandleDraggableProps {
28
+ /**
29
+ * The ProseKit editor instance.
30
+ *
31
+ * @default null
32
+ * @hidden
33
+ */
34
+ editor: Editor | null
35
+ }
36
+
37
+ /** @internal */
38
+ export const BlockHandleDraggablePropsDeclaration: PropsDeclaration<BlockHandleDraggableProps> = /* @__PURE__ */ defineProps<
39
+ BlockHandleDraggableProps
40
+ >({
41
+ editor: { default: null, attribute: false, type: 'json' },
42
+ })
43
+
44
+ /**
45
+ * @internal
46
+ */
47
+ export function setupBlockHandleDraggable(
48
+ host: HostElement,
49
+ props: State<BlockHandleDraggableProps>,
50
+ ): void {
51
+ const getStore = blockHandleStoreContext.consume(host)
52
+
53
+ onMount(host, () => {
54
+ host.draggable = true
55
+ })
56
+
57
+ usePointerDownHandler(host, () => getStore()?.hoverState.get() ?? null, props.editor.get)
58
+
59
+ useEventListener(host, 'dragstart', (event) => {
60
+ const store = getStore()
61
+ store?.dragging.set(true)
62
+
63
+ const view = getSafeEditorView(props.editor.get())
64
+ const hoverState = store?.hoverState.get()
65
+
66
+ if (view && hoverState) {
67
+ view.dom.classList.add(DRAGGING_CLASS_NAME)
68
+ createDraggingPreview(view, hoverState, event)
69
+ setViewDragging(view, hoverState)
70
+ }
71
+ })
72
+
73
+ useEventListener(host, 'dragend', () => {
74
+ const store = getStore()
75
+ store?.dragging.set(false)
76
+
77
+ const view = getSafeEditorView(props.editor.get())
78
+ if (view) {
79
+ view.dom.classList.remove(DRAGGING_CLASS_NAME)
80
+ }
81
+ })
82
+
83
+ useAttribute(host, 'data-dragging', () => (getStore()?.dragging.get() ? '' : undefined))
84
+ }
85
+
86
+ function usePointerDownHandler(
87
+ host: HostElement,
88
+ getHoverState: () => HoverState | null,
89
+ getEditor: () => Editor | null,
90
+ ) {
91
+ useEventListener(host, 'pointerdown', () => {
92
+ const hoverState = getHoverState()
93
+ const editor = getEditor()
94
+
95
+ if (hoverState?.pos == null || !editor?.view) {
96
+ return
97
+ }
98
+
99
+ const { view } = editor
100
+ view.dispatch(
101
+ view.state.tr.setSelection(NodeSelection.create(view.state.doc, hoverState.pos)),
102
+ )
103
+
104
+ // Clicking the handle will blur the editor, so we need to focus it again.
105
+ // We cannot call `event.preventDefault()` here to prevent the blur
106
+ // because it will prevent the drag event from firing.
107
+ requestAnimationFrame(() => {
108
+ view.focus()
109
+ })
110
+ })
111
+ }
112
+
113
+ function createDraggingPreview(view: EditorView, hoverState: HoverState, event: DragEvent): void {
114
+ if (!event.dataTransfer) {
115
+ return
116
+ }
117
+
118
+ const { pos } = hoverState
119
+
120
+ const element = view.nodeDOM(pos)
121
+ if (!element || !isHTMLElement(element)) {
122
+ return
123
+ }
124
+
125
+ event.dataTransfer.clearData()
126
+ event.dataTransfer.setData('text/html', element.outerHTML)
127
+ event.dataTransfer.effectAllowed = 'copyMove'
128
+ setDragPreview(event, element)
129
+
130
+ return
131
+ }
132
+
133
+ function setViewDragging(view: EditorView, hoverState: HoverState): void {
134
+ const { node, pos } = hoverState
135
+
136
+ const dragging: ViewDragging = {
137
+ slice: new Slice(Fragment.from(node), 0, 0),
138
+ move: true,
139
+ node: NodeSelection.create(view.state.doc, pos),
140
+ }
141
+
142
+ view.dragging = dragging
143
+ }
144
+
145
+ const BlockHandleDraggableElementBase: HostElementConstructor<BlockHandleDraggableProps> = defineCustomElement(
146
+ setupBlockHandleDraggable,
147
+ BlockHandleDraggablePropsDeclaration,
148
+ )
149
+
150
+ /**
151
+ * @public
152
+ */
153
+ export class BlockHandleDraggableElement extends BlockHandleDraggableElementBase {}
154
+
155
+ /** @internal */
156
+ export function registerBlockHandleDraggableElement(): void {
157
+ registerCustomElement('prosekit-block-handle-draggable', BlockHandleDraggableElement)
158
+ }
@@ -0,0 +1,43 @@
1
+ import {
2
+ defineCustomElement,
3
+ registerCustomElement,
4
+ type HostElement,
5
+ type HostElementConstructor,
6
+ type PropsDeclaration,
7
+ type State,
8
+ } from '@aria-ui/core'
9
+ import { OverlayPopupPropsDeclaration, setupOverlayPopup, type OverlayPopupProps } from '@aria-ui/elements/overlay'
10
+
11
+ import { blockHandleOverlayStoreContext } from './context.ts'
12
+
13
+ /**
14
+ * @public
15
+ */
16
+ export interface BlockHandlePopupProps extends OverlayPopupProps {}
17
+
18
+ /** @internal */
19
+ export const BlockHandlePopupPropsDeclaration: PropsDeclaration<BlockHandlePopupProps> = OverlayPopupPropsDeclaration
20
+
21
+ /** @internal */
22
+ export function setupBlockHandlePopup(
23
+ host: HostElement,
24
+ _props: State<BlockHandlePopupProps>,
25
+ ): void {
26
+ const getOverlayStore = blockHandleOverlayStoreContext.consume(host)
27
+ setupOverlayPopup(host, getOverlayStore)
28
+ }
29
+
30
+ const BlockHandlePopupElementBase: HostElementConstructor<BlockHandlePopupProps> = defineCustomElement(
31
+ setupBlockHandlePopup,
32
+ BlockHandlePopupPropsDeclaration,
33
+ )
34
+
35
+ /**
36
+ * @public
37
+ */
38
+ export class BlockHandlePopupElement extends BlockHandlePopupElementBase {}
39
+
40
+ /** @internal */
41
+ export function registerBlockHandlePopupElement(): void {
42
+ registerCustomElement('prosekit-block-handle-popup', BlockHandlePopupElement)
43
+ }
@@ -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'