@prosekit/web 0.7.2 → 0.7.4

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 (173) hide show
  1. package/dist/get-default-state-CIEy7xrl.js +2 -1
  2. package/dist/get-default-state-CIEy7xrl.js.map +1 -0
  3. package/dist/get-safe-editor-view-DENm4avv.js +2 -1
  4. package/dist/get-safe-editor-view-DENm4avv.js.map +1 -0
  5. package/dist/{inject-style-RwRNoINh.js → inject-style-BJQNFufI.js} +12 -13
  6. package/dist/inject-style-BJQNFufI.js.map +1 -0
  7. package/dist/prosekit-web-autocomplete.d.ts +2 -1
  8. package/dist/prosekit-web-autocomplete.d.ts.map +1 -0
  9. package/dist/prosekit-web-autocomplete.js +5 -7
  10. package/dist/prosekit-web-autocomplete.js.map +1 -0
  11. package/dist/prosekit-web-block-handle.d.ts +2 -1
  12. package/dist/prosekit-web-block-handle.d.ts.map +1 -0
  13. package/dist/prosekit-web-block-handle.js +33 -20
  14. package/dist/prosekit-web-block-handle.js.map +1 -0
  15. package/dist/prosekit-web-drop-indicator.d.ts +2 -1
  16. package/dist/prosekit-web-drop-indicator.d.ts.map +1 -0
  17. package/dist/prosekit-web-drop-indicator.js +2 -1
  18. package/dist/prosekit-web-drop-indicator.js.map +1 -0
  19. package/dist/prosekit-web-inline-popover.d.ts +2 -1
  20. package/dist/prosekit-web-inline-popover.d.ts.map +1 -0
  21. package/dist/prosekit-web-inline-popover.js +4 -5
  22. package/dist/prosekit-web-inline-popover.js.map +1 -0
  23. package/dist/prosekit-web-popover.d.ts +2 -1
  24. package/dist/prosekit-web-popover.d.ts.map +1 -0
  25. package/dist/prosekit-web-popover.js +2 -1
  26. package/dist/prosekit-web-popover.js.map +1 -0
  27. package/dist/prosekit-web-resizable.d.ts +2 -1
  28. package/dist/prosekit-web-resizable.d.ts.map +1 -0
  29. package/dist/prosekit-web-resizable.js +2 -1
  30. package/dist/prosekit-web-resizable.js.map +1 -0
  31. package/dist/prosekit-web-table-handle.d.ts +2 -1
  32. package/dist/prosekit-web-table-handle.d.ts.map +1 -0
  33. package/dist/prosekit-web-table-handle.js +38 -75
  34. package/dist/prosekit-web-table-handle.js.map +1 -0
  35. package/dist/prosekit-web-tooltip.d.ts +2 -1
  36. package/dist/prosekit-web-tooltip.d.ts.map +1 -0
  37. package/dist/prosekit-web-tooltip.js +2 -1
  38. package/dist/prosekit-web-tooltip.js.map +1 -0
  39. package/dist/prosekit-web.d.ts +1 -1
  40. package/dist/prosekit-web.js +1 -0
  41. package/dist/use-editor-extension-Cc7ZG7uj.js +2 -1
  42. package/dist/use-editor-extension-Cc7ZG7uj.js.map +1 -0
  43. package/dist/use-scrolling-BNfsQs3S.js +2 -1
  44. package/dist/use-scrolling-BNfsQs3S.js.map +1 -0
  45. package/package.json +21 -20
  46. package/src/components/autocomplete/autocomplete-empty/element.gen.ts +18 -0
  47. package/src/components/autocomplete/autocomplete-empty/setup.ts +6 -0
  48. package/src/components/autocomplete/autocomplete-empty/types.ts +16 -0
  49. package/src/components/autocomplete/autocomplete-item/element.gen.ts +18 -0
  50. package/src/components/autocomplete/autocomplete-item/setup.ts +38 -0
  51. package/src/components/autocomplete/autocomplete-item/types.ts +31 -0
  52. package/src/components/autocomplete/autocomplete-list/element.gen.ts +18 -0
  53. package/src/components/autocomplete/autocomplete-list/setup.ts +140 -0
  54. package/src/components/autocomplete/autocomplete-list/types.ts +30 -0
  55. package/src/components/autocomplete/autocomplete-popover/element.gen.ts +18 -0
  56. package/src/components/autocomplete/autocomplete-popover/helpers.spec.ts +21 -0
  57. package/src/components/autocomplete/autocomplete-popover/helpers.ts +7 -0
  58. package/src/components/autocomplete/autocomplete-popover/setup.ts +185 -0
  59. package/src/components/autocomplete/autocomplete-popover/types.ts +103 -0
  60. package/src/components/autocomplete/context.ts +19 -0
  61. package/src/components/autocomplete/index.gen.ts +17 -0
  62. package/src/components/block-handle/block-handle-add/element.gen.ts +18 -0
  63. package/src/components/block-handle/block-handle-add/setup.ts +37 -0
  64. package/src/components/block-handle/block-handle-add/types.ts +26 -0
  65. package/src/components/block-handle/block-handle-draggable/element.gen.ts +18 -0
  66. package/src/components/block-handle/block-handle-draggable/set-drag-preview.ts +88 -0
  67. package/src/components/block-handle/block-handle-draggable/setup.ts +133 -0
  68. package/src/components/block-handle/block-handle-draggable/types.ts +26 -0
  69. package/src/components/block-handle/block-handle-popover/element.gen.ts +18 -0
  70. package/src/components/block-handle/block-handle-popover/pointer-move.ts +243 -0
  71. package/src/components/block-handle/block-handle-popover/setup.ts +88 -0
  72. package/src/components/block-handle/block-handle-popover/types.ts +84 -0
  73. package/src/components/block-handle/context.ts +34 -0
  74. package/src/components/block-handle/index.gen.ts +13 -0
  75. package/src/components/drop-indicator/drop-indicator/element.gen.ts +18 -0
  76. package/src/components/drop-indicator/drop-indicator/setup.ts +87 -0
  77. package/src/components/drop-indicator/drop-indicator/types.ts +34 -0
  78. package/src/components/drop-indicator/index.gen.ts +5 -0
  79. package/src/components/inline-popover/index.gen.ts +5 -0
  80. package/src/components/inline-popover/inline-popover/element.gen.ts +18 -0
  81. package/src/components/inline-popover/inline-popover/setup.ts +97 -0
  82. package/src/components/inline-popover/inline-popover/types.ts +115 -0
  83. package/src/components/inline-popover/inline-popover/virtual-selection-element.ts +75 -0
  84. package/src/components/popover/index.gen.ts +13 -0
  85. package/src/components/popover/popover-content/element.gen.ts +18 -0
  86. package/src/components/popover/popover-content/setup.ts +1 -0
  87. package/src/components/popover/popover-content/types.ts +12 -0
  88. package/src/components/popover/popover-root/element.gen.ts +18 -0
  89. package/src/components/popover/popover-root/setup.ts +1 -0
  90. package/src/components/popover/popover-root/types.ts +12 -0
  91. package/src/components/popover/popover-trigger/element.gen.ts +18 -0
  92. package/src/components/popover/popover-trigger/setup.ts +1 -0
  93. package/src/components/popover/popover-trigger/types.ts +12 -0
  94. package/src/components/resizable/context.ts +45 -0
  95. package/src/components/resizable/index.gen.ts +9 -0
  96. package/src/components/resizable/resizable-handle/calc-resize.spec.ts +280 -0
  97. package/src/components/resizable/resizable-handle/calc-resize.ts +121 -0
  98. package/src/components/resizable/resizable-handle/element.gen.ts +18 -0
  99. package/src/components/resizable/resizable-handle/setup.ts +112 -0
  100. package/src/components/resizable/resizable-handle/types.ts +32 -0
  101. package/src/components/resizable/resizable-root/element.gen.ts +18 -0
  102. package/src/components/resizable/resizable-root/setup.ts +93 -0
  103. package/src/components/resizable/resizable-root/types.ts +28 -0
  104. package/src/components/table-handle/context.ts +49 -0
  105. package/src/components/table-handle/dnd.ts +135 -0
  106. package/src/components/table-handle/hooks/use-drop.ts +94 -0
  107. package/src/components/table-handle/hooks/use-empty-image.ts +30 -0
  108. package/src/components/table-handle/index.gen.ts +37 -0
  109. package/src/components/table-handle/table-handle-column-root/element.gen.ts +18 -0
  110. package/src/components/table-handle/table-handle-column-root/setup.ts +71 -0
  111. package/src/components/table-handle/table-handle-column-root/types.ts +76 -0
  112. package/src/components/table-handle/table-handle-column-trigger/element.gen.ts +18 -0
  113. package/src/components/table-handle/table-handle-column-trigger/setup.ts +75 -0
  114. package/src/components/table-handle/table-handle-column-trigger/types.ts +23 -0
  115. package/src/components/table-handle/table-handle-drag-preview/element.gen.ts +18 -0
  116. package/src/components/table-handle/table-handle-drag-preview/render-preview.ts +80 -0
  117. package/src/components/table-handle/table-handle-drag-preview/setup.ts +67 -0
  118. package/src/components/table-handle/table-handle-drag-preview/types.ts +17 -0
  119. package/src/components/table-handle/table-handle-drag-preview/updater.ts +101 -0
  120. package/src/components/table-handle/table-handle-drop-indicator/calc-drag-over.ts +44 -0
  121. package/src/components/table-handle/table-handle-drop-indicator/element.gen.ts +18 -0
  122. package/src/components/table-handle/table-handle-drop-indicator/setup.ts +56 -0
  123. package/src/components/table-handle/table-handle-drop-indicator/types.ts +18 -0
  124. package/src/components/table-handle/table-handle-drop-indicator/updater.ts +110 -0
  125. package/src/components/table-handle/table-handle-popover-content/element.gen.ts +18 -0
  126. package/src/components/table-handle/table-handle-popover-content/setup.ts +90 -0
  127. package/src/components/table-handle/table-handle-popover-content/types.ts +40 -0
  128. package/src/components/table-handle/table-handle-popover-item/element.gen.ts +18 -0
  129. package/src/components/table-handle/table-handle-popover-item/setup.ts +23 -0
  130. package/src/components/table-handle/table-handle-popover-item/types.ts +24 -0
  131. package/src/components/table-handle/table-handle-root/element.gen.ts +18 -0
  132. package/src/components/table-handle/table-handle-root/setup.ts +93 -0
  133. package/src/components/table-handle/table-handle-root/types.ts +26 -0
  134. package/src/components/table-handle/table-handle-row-root/element.gen.ts +18 -0
  135. package/src/components/table-handle/table-handle-row-root/setup.ts +77 -0
  136. package/src/components/table-handle/table-handle-row-root/types.ts +75 -0
  137. package/src/components/table-handle/table-handle-row-trigger/element.gen.ts +18 -0
  138. package/src/components/table-handle/table-handle-row-trigger/setup.ts +74 -0
  139. package/src/components/table-handle/table-handle-row-trigger/types.ts +26 -0
  140. package/src/components/table-handle/utils.ts +107 -0
  141. package/src/components/tooltip/index.gen.ts +13 -0
  142. package/src/components/tooltip/tooltip-content/element.gen.ts +18 -0
  143. package/src/components/tooltip/tooltip-content/setup.ts +1 -0
  144. package/src/components/tooltip/tooltip-content/types.ts +12 -0
  145. package/src/components/tooltip/tooltip-root/element.gen.ts +18 -0
  146. package/src/components/tooltip/tooltip-root/setup.ts +1 -0
  147. package/src/components/tooltip/tooltip-root/types.ts +12 -0
  148. package/src/components/tooltip/tooltip-trigger/element.gen.ts +18 -0
  149. package/src/components/tooltip/tooltip-trigger/setup.ts +1 -0
  150. package/src/components/tooltip/tooltip-trigger/types.ts +12 -0
  151. package/src/hooks/use-editor-extension.ts +19 -0
  152. package/src/hooks/use-editor-focus-event.ts +23 -0
  153. package/src/hooks/use-editor-typing.ts +36 -0
  154. package/src/hooks/use-editor-update-event.ts +23 -0
  155. package/src/hooks/use-first-rendering.ts +20 -0
  156. package/src/hooks/use-keymap.ts +20 -0
  157. package/src/hooks/use-scrolling.ts +33 -0
  158. package/src/hooks/use-selecting.ts +63 -0
  159. package/src/index.ts +1 -0
  160. package/src/utils/assign-styles.ts +14 -0
  161. package/src/utils/clone-element.ts +110 -0
  162. package/src/utils/css-feature-detection.ts +9 -0
  163. package/src/utils/fade-color.ts +15 -0
  164. package/src/utils/get-box-element.ts +20 -0
  165. package/src/utils/get-client-rect.ts +35 -0
  166. package/src/utils/get-default-state.spec.ts +50 -0
  167. package/src/utils/get-default-state.ts +22 -0
  168. package/src/utils/get-effective-background-color.ts +21 -0
  169. package/src/utils/get-safe-editor-view.ts +10 -0
  170. package/src/utils/inject-style.ts +11 -0
  171. package/src/utils/is-finite-positive-number.ts +3 -0
  172. package/src/utils/max-z-index.ts +3 -0
  173. package/src/utils/throttle.ts +17 -0
@@ -0,0 +1,103 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import {
6
+ overlayPositionerEvents,
7
+ overlayPositionerProps,
8
+ type OverlayPositionerEvents,
9
+ type OverlayPositionerProps,
10
+ } from '@aria-ui/overlay/elements'
11
+ import type { Editor } from '@prosekit/core'
12
+
13
+ export interface AutocompletePopoverProps extends OverlayPositionerProps {
14
+ /**
15
+ * The ProseKit editor instance.
16
+ *
17
+ * @default null
18
+ * @hidden
19
+ */
20
+ editor: Editor | null
21
+
22
+ /**
23
+ * The regular expression to match the query text to autocomplete.
24
+ *
25
+ * @default null
26
+ */
27
+ regex: RegExp | null
28
+
29
+ /**
30
+ * The placement of the popover, relative to the text cursor.
31
+ *
32
+ * @default "bottom-start"
33
+ */
34
+ placement: OverlayPositionerProps['placement']
35
+
36
+ /**
37
+ * The distance between the popover and the hovered block.
38
+ *
39
+ * @default 4
40
+ */
41
+ offset: OverlayPositionerProps['offset']
42
+
43
+ /**
44
+ * @default true
45
+ */
46
+ inline: OverlayPositionerProps['inline']
47
+
48
+ /**
49
+ * @default true
50
+ */
51
+ hoist: OverlayPositionerProps['hoist']
52
+
53
+ /**
54
+ * @default true
55
+ */
56
+ fitViewport: OverlayPositionerProps['fitViewport']
57
+
58
+ /**
59
+ * @default "The body element"
60
+ */
61
+ boundary: OverlayPositionerProps['boundary']
62
+
63
+ /**
64
+ * @default 8
65
+ */
66
+ overflowPadding: OverlayPositionerProps['overflowPadding']
67
+ }
68
+
69
+ const body = typeof document !== 'undefined' && document.querySelector('body')
70
+ const defaultBoundary = body || 'clippingAncestors'
71
+
72
+ /** @internal */
73
+ export const autocompletePopoverProps: PropDeclarations<AutocompletePopoverProps> = {
74
+ ...overlayPositionerProps,
75
+ editor: { default: null },
76
+ regex: { default: null },
77
+ placement: { default: 'bottom-start' },
78
+ offset: { default: 4 },
79
+ inline: { default: true },
80
+ hoist: { default: true },
81
+ fitViewport: { default: true },
82
+ boundary: { default: defaultBoundary },
83
+ overflowPadding: { default: 8 },
84
+ }
85
+
86
+ export interface AutocompletePopoverEvents extends OverlayPositionerEvents {
87
+ /**
88
+ * Fired when the open state changes.
89
+ */
90
+ openChange: CustomEvent<boolean>
91
+
92
+ /**
93
+ * Fired when the query changes.
94
+ */
95
+ queryChange: CustomEvent<string>
96
+ }
97
+
98
+ /** @internal */
99
+ export const autocompletePopoverEvents: EventDeclarations<AutocompletePopoverEvents> = {
100
+ ...overlayPositionerEvents,
101
+ openChange: {},
102
+ queryChange: {},
103
+ }
@@ -0,0 +1,19 @@
1
+ import {
2
+ createContext,
3
+ type Context,
4
+ } from '@aria-ui/core'
5
+
6
+ export const queryContext: Context<string> = createContext(
7
+ 'prosekit/autocomplete-popover/query',
8
+ '',
9
+ )
10
+
11
+ export const onSubmitContext: Context<VoidFunction | null> = createContext(
12
+ 'prosekit/autocomplete-popover/onSubmit',
13
+ null,
14
+ )
15
+
16
+ export const openContext: Context<boolean> = createContext(
17
+ 'prosekit/autocomplete-popover/open',
18
+ false,
19
+ )
@@ -0,0 +1,17 @@
1
+ // This file is generated by packages/dev/src/gen-components.ts
2
+
3
+ export { AutocompleteEmptyElement } from './autocomplete-empty/element.gen'
4
+ export { autocompleteEmptyEvents, autocompleteEmptyProps, type AutocompleteEmptyEvents, type AutocompleteEmptyProps } from './autocomplete-empty/types'
5
+ export { useAutocompleteEmpty } from './autocomplete-empty/setup'
6
+
7
+ export { AutocompleteItemElement } from './autocomplete-item/element.gen'
8
+ export { autocompleteItemEvents, autocompleteItemProps, type AutocompleteItemEvents, type AutocompleteItemProps } from './autocomplete-item/types'
9
+ export { useAutocompleteItem } from './autocomplete-item/setup'
10
+
11
+ export { AutocompleteListElement } from './autocomplete-list/element.gen'
12
+ export { autocompleteListEvents, autocompleteListProps, type AutocompleteListEvents, type AutocompleteListProps } from './autocomplete-list/types'
13
+ export { useAutocompleteList } from './autocomplete-list/setup'
14
+
15
+ export { AutocompletePopoverElement } from './autocomplete-popover/element.gen'
16
+ export { autocompletePopoverEvents, autocompletePopoverProps, type AutocompletePopoverEvents, type AutocompletePopoverProps } from './autocomplete-popover/types'
17
+ export { useAutocompletePopover } from './autocomplete-popover/setup'
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useBlockHandleAdd } from "./setup"
4
+ import { blockHandleAddEvents, blockHandleAddProps, type BlockHandleAddEvents, type BlockHandleAddProps } from "./types"
5
+
6
+ const BlockHandleAddElementBase: BaseElementConstructor<BlockHandleAddProps> = defineCustomElement<
7
+ BlockHandleAddProps,
8
+ BlockHandleAddEvents
9
+ >({
10
+ props: blockHandleAddProps,
11
+ events: blockHandleAddEvents,
12
+ setup: useBlockHandleAdd,
13
+ })
14
+ class BlockHandleAddElement extends BlockHandleAddElementBase {}
15
+
16
+ registerCustomElement('prosekit-block-handle-add', BlockHandleAddElement)
17
+
18
+ export { BlockHandleAddElement }
@@ -0,0 +1,37 @@
1
+ import {
2
+ useEventListener,
3
+ type ConnectableElement,
4
+ type SignalState,
5
+ } from '@aria-ui/core'
6
+ import { insertDefaultBlock } from '@prosekit/core'
7
+
8
+ import { blockPopoverContext } from '../context'
9
+
10
+ import type { BlockHandleAddProps } from './types'
11
+
12
+ /**
13
+ * @internal
14
+ */
15
+ export function useBlockHandleAdd(
16
+ host: ConnectableElement,
17
+ { state }: { state: SignalState<BlockHandleAddProps> },
18
+ ): void {
19
+ const context = blockPopoverContext.consume(host)
20
+
21
+ useEventListener(host, 'pointerdown', (event) => {
22
+ event.preventDefault()
23
+
24
+ const editor = state.editor.get()
25
+ const hoverState = context.get()
26
+ if (!editor || !hoverState) {
27
+ return
28
+ }
29
+
30
+ const { node, pos } = hoverState
31
+ editor.exec(insertDefaultBlock({ pos: pos + node.nodeSize }))
32
+ editor.focus()
33
+
34
+ // Hide the drag handle
35
+ context.set(null)
36
+ })
37
+ }
@@ -0,0 +1,26 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import type { Editor } from '@prosekit/core'
6
+
7
+ export interface BlockHandleAddProps {
8
+ /**
9
+ * The ProseKit editor instance.
10
+ *
11
+ * @default null
12
+ * @hidden
13
+ */
14
+ editor: Editor | null
15
+ }
16
+
17
+ /** @internal */
18
+ export const blockHandleAddProps: PropDeclarations<BlockHandleAddProps> = {
19
+ editor: { default: null },
20
+ }
21
+
22
+ /** @internal */
23
+ export interface BlockHandleAddEvents {}
24
+
25
+ /** @internal */
26
+ export const blockHandleAddEvents: EventDeclarations<BlockHandleAddEvents> = {}
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useBlockHandleDraggable } from "./setup"
4
+ import { blockHandleDraggableEvents, blockHandleDraggableProps, type BlockHandleDraggableEvents, type BlockHandleDraggableProps } from "./types"
5
+
6
+ const BlockHandleDraggableElementBase: BaseElementConstructor<BlockHandleDraggableProps> = defineCustomElement<
7
+ BlockHandleDraggableProps,
8
+ BlockHandleDraggableEvents
9
+ >({
10
+ props: blockHandleDraggableProps,
11
+ events: blockHandleDraggableEvents,
12
+ setup: useBlockHandleDraggable,
13
+ })
14
+ class BlockHandleDraggableElement extends BlockHandleDraggableElementBase {}
15
+
16
+ registerCustomElement('prosekit-block-handle-draggable', BlockHandleDraggableElement)
17
+
18
+ export { BlockHandleDraggableElement }
@@ -0,0 +1,88 @@
1
+ import { assignStyles } from '../../../utils/assign-styles'
2
+ import { deepCloneElement } from '../../../utils/clone-element'
3
+ import { getClientRect } from '../../../utils/get-client-rect'
4
+ import { injectStyle } from '../../../utils/inject-style'
5
+ import { maxZIndex } from '../../../utils/max-z-index'
6
+
7
+ /**
8
+ * Sets a drag preview image for the given element and ensures the preview position
9
+ * relative to the pointer is correct.
10
+ *
11
+ * This function does the following:
12
+ *
13
+ * - Creates a temporary container element.
14
+ * - Puts the container at the end of the document body.
15
+ * - Sets event's drag image.
16
+ * - Removes the container from the document body after the next frame.
17
+ */
18
+ export function setDragPreview(event: DragEvent, element: HTMLElement): void {
19
+ const { top, bottom, left, right } = getClientRect(element)
20
+ const width = right - left
21
+ const height = bottom - top
22
+ const elementX = left
23
+ const elementY = top
24
+
25
+ const { clientX, clientY } = event
26
+
27
+ const document = element.ownerDocument
28
+
29
+ const container = document.createElement('div')
30
+
31
+ // If outsideX is positive, the point is at the left side of the element.
32
+ const outsideX = Math.round(elementX - clientX)
33
+ // If outsideY is positive, the point is above the element.
34
+ const outsideY = Math.round(elementY - clientY)
35
+
36
+ const borderX = Math.max(outsideX, 0)
37
+ const borderY = Math.max(outsideY, 0)
38
+ assignStyles(container, {
39
+ // Ensuring we don't cause reflow when adding the element to the page using
40
+ // `position:fixed` rather than `position:absolute` so we are positioned on
41
+ // the current viewport. `position:fixed` also creates a new stacking
42
+ // context, so we don't need to do that here.
43
+ // https://github.com/atlassian/pragmatic-drag-and-drop/blob/56276552/packages/core/src/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.ts#L60
44
+ position: 'fixed',
45
+
46
+ // The element is positioned off-screen to avoid capturing the content of
47
+ // the page on Safari when the dragging element has a transparent background
48
+ // on Safari. See https://github.com/prosekit/prosekit/issues/1153 for more
49
+ // details.
50
+ top: '-1000vh',
51
+ left: '-1000vw',
52
+
53
+ // The element should not be interactive.
54
+ pointerEvents: 'none',
55
+
56
+ zIndex: maxZIndex,
57
+
58
+ // Only reliable cross browser technique found to push a drag preview away
59
+ // from the cursor is to use transparent borders on the container.
60
+ // https://github.com/atlassian/pragmatic-drag-and-drop/blob/56276552/packages/core/src/public-utils/element/custom-native-drag-preview/pointer-outside-of-preview.ts#L13-L18
61
+ borderLeft: `${borderX}px solid transparent`,
62
+ borderTop: `${borderY}px solid transparent`,
63
+
64
+ boxSizing: 'border-box',
65
+ width: `${width + borderX}px`,
66
+ height: `${height + borderY}px`,
67
+ })
68
+
69
+ const [clonedElement, styleText] = deepCloneElement(element, true)
70
+
71
+ // A hardcoded opacity.
72
+ clonedElement.style.setProperty('opacity', '0.5', 'important')
73
+ // The bounding client rect doesn't include the margin, so we need to remove
74
+ // the margin too from the cloned element so that it can fit the container.
75
+ clonedElement.style.setProperty('margin', '0', 'important')
76
+ // Hide the outline of the cloned element.
77
+ clonedElement.style.setProperty('outline-color', 'transparent', 'important')
78
+
79
+ document.body.appendChild(container)
80
+ container.appendChild(clonedElement)
81
+ injectStyle(container, styleText)
82
+
83
+ event.dataTransfer?.setDragImage(container, Math.max(-outsideX, 0), Math.max(-outsideY, 0))
84
+
85
+ requestAnimationFrame(() => {
86
+ container.remove()
87
+ })
88
+ }
@@ -0,0 +1,133 @@
1
+ import {
2
+ useAttribute,
3
+ useEffect,
4
+ useEventListener,
5
+ type ConnectableElement,
6
+ type ReadonlySignal,
7
+ type SignalState,
8
+ } from '@aria-ui/core'
9
+ import { isHTMLElement } from '@ocavue/utils'
10
+ import type { Editor } from '@prosekit/core'
11
+ import type { ViewDragging } from '@prosekit/extensions/drop-indicator'
12
+ import {
13
+ Fragment,
14
+ Slice,
15
+ } from '@prosekit/pm/model'
16
+ import { NodeSelection } from '@prosekit/pm/state'
17
+ import type { EditorView } from '@prosekit/pm/view'
18
+
19
+ import { getBoxElement } from '../../../utils/get-box-element'
20
+ import { getSafeEditorView } from '../../../utils/get-safe-editor-view'
21
+ import {
22
+ blockPopoverContext,
23
+ draggingContext,
24
+ type BlockPopoverContext,
25
+ type HoverState,
26
+ } from '../context'
27
+
28
+ import { setDragPreview } from './set-drag-preview'
29
+ import type { BlockHandleDraggableProps } from './types'
30
+
31
+ /**
32
+ * @internal
33
+ */
34
+ export function useBlockHandleDraggable(
35
+ host: ConnectableElement,
36
+ { state }: { state: SignalState<BlockHandleDraggableProps> },
37
+ ): void {
38
+ const context = blockPopoverContext.consume(host)
39
+ const dragging = draggingContext.consume(host)
40
+
41
+ useEffect(host, () => {
42
+ host.draggable = true
43
+ })
44
+
45
+ usePointerDownHandler(host, context, state.editor)
46
+
47
+ useEventListener(host, 'dragstart', (event) => {
48
+ dragging.set(true)
49
+
50
+ const view = getSafeEditorView(state.editor.get())
51
+ const hoverState = context.get()
52
+
53
+ if (view && hoverState) {
54
+ view.dom.classList.add('prosekit-dragging')
55
+ createDraggingPreview(view, hoverState, event)
56
+ setViewDragging(view, hoverState)
57
+ }
58
+ })
59
+
60
+ useEventListener(host, 'dragend', () => {
61
+ dragging.set(false)
62
+
63
+ const view = getSafeEditorView(state.editor.get())
64
+ if (view) {
65
+ view.dom.classList.remove('prosekit-dragging')
66
+ }
67
+ })
68
+
69
+ useAttribute(host, 'data-dragging', () => (dragging.get() ? '' : undefined))
70
+ }
71
+
72
+ function usePointerDownHandler(
73
+ host: ConnectableElement,
74
+ context: ReadonlySignal<BlockPopoverContext>,
75
+ editor: ReadonlySignal<Editor | null>,
76
+ ) {
77
+ useEventListener(host, 'pointerdown', () => {
78
+ const { pos } = context.get() ?? {}
79
+ const { view } = editor.get() ?? {}
80
+
81
+ if (pos == null || view == null) {
82
+ return
83
+ }
84
+
85
+ view.dispatch(
86
+ view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos)),
87
+ )
88
+
89
+ // Clicking the handle will blur the editor, so we need to focus it again.
90
+ // We cannot call `event.preventDefault()` here to prevent the blur
91
+ // because it will prevent the drag event from firing.
92
+ requestAnimationFrame(() => {
93
+ view.focus()
94
+ })
95
+ })
96
+ }
97
+
98
+ function createDraggingPreview(view: EditorView, hoverState: HoverState, event: DragEvent): void {
99
+ if (!event.dataTransfer) {
100
+ return
101
+ }
102
+
103
+ const { pos } = hoverState
104
+
105
+ const element = view.nodeDOM(pos)
106
+ if (!element || !isHTMLElement(element)) {
107
+ return
108
+ }
109
+
110
+ const boxElement = getBoxElement(element)
111
+ if (!boxElement || !isHTMLElement(boxElement)) {
112
+ return
113
+ }
114
+
115
+ event.dataTransfer.clearData()
116
+ event.dataTransfer.setData('text/html', boxElement.outerHTML)
117
+ event.dataTransfer.effectAllowed = 'copyMove'
118
+ setDragPreview(event, boxElement)
119
+
120
+ return
121
+ }
122
+
123
+ function setViewDragging(view: EditorView, hoverState: HoverState): void {
124
+ const { node, pos } = hoverState
125
+
126
+ const dragging: ViewDragging = {
127
+ slice: new Slice(Fragment.from(node), 0, 0),
128
+ move: true,
129
+ node: NodeSelection.create(view.state.doc, pos),
130
+ }
131
+
132
+ view.dragging = dragging
133
+ }
@@ -0,0 +1,26 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import type { Editor } from '@prosekit/core'
6
+
7
+ export interface BlockHandleDraggableProps {
8
+ /**
9
+ * The ProseKit editor instance.
10
+ *
11
+ * @default null
12
+ * @hidden
13
+ */
14
+ editor: Editor | null
15
+ }
16
+
17
+ /** @internal */
18
+ export const blockHandleDraggableProps: PropDeclarations<BlockHandleDraggableProps> = {
19
+ editor: { default: null },
20
+ }
21
+
22
+ /** @internal */
23
+ export interface BlockHandleDraggableEvents {}
24
+
25
+ /** @internal */
26
+ export const blockHandleDraggableEvents: EventDeclarations<BlockHandleDraggableEvents> = {}
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useBlockHandlePopover } from "./setup"
4
+ import { blockHandlePopoverEvents, blockHandlePopoverProps, type BlockHandlePopoverEvents, type BlockHandlePopoverProps } from "./types"
5
+
6
+ const BlockHandlePopoverElementBase: BaseElementConstructor<BlockHandlePopoverProps> = defineCustomElement<
7
+ BlockHandlePopoverProps,
8
+ BlockHandlePopoverEvents
9
+ >({
10
+ props: blockHandlePopoverProps,
11
+ events: blockHandlePopoverEvents,
12
+ setup: useBlockHandlePopover,
13
+ })
14
+ class BlockHandlePopoverElement extends BlockHandlePopoverElementBase {}
15
+
16
+ registerCustomElement('prosekit-block-handle-popover', BlockHandlePopoverElement)
17
+
18
+ export { BlockHandlePopoverElement }