@prosekit/web 0.8.0-beta.0 → 0.8.0-beta.2

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 +94 -53
  14. package/dist/prosekit-web-inline-popover.d.ts.map +1 -1
  15. package/dist/prosekit-web-inline-popover.js +134 -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 +26 -21
  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 +118 -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,169 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ useEffect,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type State,
10
+ } from '@aria-ui/core'
11
+ import { computePosition, type ReferenceElement } from '@floating-ui/dom'
12
+ import type { Editor } from '@prosekit/core'
13
+
14
+ import { assignStyles } from '../../utils/assign-styles.ts'
15
+ import { getSafeEditorView } from '../../utils/get-safe-editor-view.ts'
16
+
17
+ import { getDndRelatedDOMs, useInitDndPosition, type OnInitParams } from './dnd.ts'
18
+ import { clearPreviewDOM, createPreviewDOM } from './render-preview.ts'
19
+ import { tableHandleStoreContext } from './store.ts'
20
+
21
+ export interface TableHandleDragPreviewProps {
22
+ /**
23
+ * @default null
24
+ * @hidden
25
+ */
26
+ editor: Editor | null
27
+ }
28
+
29
+ /** @internal */
30
+ export const TableHandleDragPreviewPropsDeclaration: PropsDeclaration<TableHandleDragPreviewProps> = defineProps<
31
+ TableHandleDragPreviewProps
32
+ >({
33
+ editor: { default: null, attribute: false, type: 'json' },
34
+ })
35
+
36
+ /**
37
+ * @internal
38
+ */
39
+ export function setupTableHandleDragPreview(
40
+ host: HostElement,
41
+ props: State<TableHandleDragPreviewProps>,
42
+ ): void {
43
+ const getEditor = props.editor.get
44
+
45
+ useEffect(host, () => {
46
+ assignStyles(host, {
47
+ position: 'absolute',
48
+ pointerEvents: 'none',
49
+ })
50
+ })
51
+
52
+ useInitDndPosition(host, getEditor, onInitPreviewPosition)
53
+
54
+ useUpdatePreviewPosition(host, getEditor)
55
+ }
56
+
57
+ function onInitPreviewPosition({ host, direction, dragging, table, cell, draggingIndex }: OnInitParams): void {
58
+ assignStyles(host, {
59
+ display: dragging ? 'block' : 'none',
60
+ })
61
+
62
+ if (!dragging) {
63
+ clearPreviewDOM(host)
64
+ return
65
+ }
66
+
67
+ createPreviewDOM(table, host, draggingIndex, direction)
68
+
69
+ const tableRect = table.getBoundingClientRect()
70
+ const cellRect = cell.getBoundingClientRect()
71
+
72
+ if (direction === 'col') {
73
+ assignStyles(host, {
74
+ width: `${cellRect.width}px`,
75
+ height: `${tableRect.height}px`,
76
+ })
77
+ }
78
+
79
+ if (direction === 'row') {
80
+ assignStyles(host, {
81
+ width: `${tableRect.width}px`,
82
+ height: `${cellRect.height}px`,
83
+ })
84
+ }
85
+ }
86
+
87
+ function useUpdatePreviewPosition(host: HostElement, getEditor: () => Editor | null): void {
88
+ const getStore = tableHandleStoreContext.consume(host)
89
+
90
+ useEffect(host, () => {
91
+ const view = getSafeEditorView(getEditor())
92
+ if (!view) return
93
+
94
+ const store = getStore()
95
+ if (!store) return
96
+ const dndStore = store.dndStore
97
+
98
+ if (!dndStore.dragging.get()) return
99
+
100
+ const draggingIndex = dndStore.draggingIndex.get()
101
+ const direction = dndStore.direction.get()
102
+ const x = dndStore.x.get()
103
+ const y = dndStore.y.get()
104
+
105
+ const relatedDOMs = getDndRelatedDOMs(view, store.getReferenceCell()?.cellPos, draggingIndex, direction)
106
+ if (!relatedDOMs) return
107
+ const { cell } = relatedDOMs
108
+
109
+ let cancelled = false
110
+
111
+ void computePosition(
112
+ getVirtualElement(cell, x, y),
113
+ host,
114
+ { placement: direction === 'row' ? 'right' : 'bottom' },
115
+ ).then(({ x, y }) => {
116
+ if (cancelled) return
117
+
118
+ if (direction === 'row') {
119
+ assignStyles(host, { top: `${y}px` })
120
+ return
121
+ }
122
+
123
+ if (direction === 'col') {
124
+ assignStyles(host, { left: `${x}px` })
125
+ return
126
+ }
127
+ })
128
+
129
+ return () => {
130
+ cancelled = true
131
+ }
132
+ })
133
+ }
134
+
135
+ function getVirtualElement(cell: HTMLTableCellElement, x: number, y: number): ReferenceElement {
136
+ return {
137
+ contextElement: cell,
138
+ getBoundingClientRect: () => {
139
+ const rect = cell.getBoundingClientRect()
140
+ return {
141
+ width: rect.width,
142
+ height: rect.height,
143
+ right: x + rect.width / 2,
144
+ bottom: y + rect.height / 2,
145
+ top: y - rect.height / 2,
146
+ left: x - rect.width / 2,
147
+ x: x - rect.width / 2,
148
+ y: y - rect.height / 2,
149
+ }
150
+ },
151
+ }
152
+ }
153
+
154
+ const TableHandleDragPreviewElementBase: HostElementConstructor<TableHandleDragPreviewProps> = defineCustomElement(
155
+ setupTableHandleDragPreview,
156
+ TableHandleDragPreviewPropsDeclaration,
157
+ )
158
+
159
+ /**
160
+ * @public
161
+ */
162
+ export class TableHandleDragPreviewElement extends TableHandleDragPreviewElementBase {}
163
+
164
+ /**
165
+ * @internal
166
+ */
167
+ export function registerTableHandleDragPreviewElement(): void {
168
+ registerCustomElement('prosekit-table-handle-drag-preview', TableHandleDragPreviewElement)
169
+ }
@@ -0,0 +1,166 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ useEffect,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type State,
10
+ } from '@aria-ui/core'
11
+ import { computePosition, offset } from '@floating-ui/dom'
12
+ import type { Editor } from '@prosekit/core'
13
+ import type { defineTableCommands } from '@prosekit/extensions/table'
14
+
15
+ import { assignStyles } from '../../utils/assign-styles.ts'
16
+ import { getSafeEditorView } from '../../utils/get-safe-editor-view.ts'
17
+
18
+ import { getDragOverColumn, getDragOverRow } from './calc-drag-over.ts'
19
+ import { getDndRelatedDOMs, useInitDndPosition, type OnInitParams } from './dnd.ts'
20
+ import { tableHandleStoreContext } from './store.ts'
21
+
22
+ type TableCommandsExtension = ReturnType<typeof defineTableCommands>
23
+
24
+ const HANDLE_WIDTH = 2
25
+
26
+ export interface TableHandleDropIndicatorProps {
27
+ /**
28
+ * @default null
29
+ * @hidden
30
+ */
31
+ editor: Editor<TableCommandsExtension> | null
32
+ }
33
+
34
+ /** @internal */
35
+ export const TableHandleDropIndicatorPropsDeclaration: PropsDeclaration<TableHandleDropIndicatorProps> = defineProps<
36
+ TableHandleDropIndicatorProps
37
+ >({
38
+ editor: { default: null, attribute: false, type: 'json' },
39
+ })
40
+
41
+ /**
42
+ * @internal
43
+ */
44
+ export function setupTableHandleDropIndicator(
45
+ host: HostElement,
46
+ props: State<TableHandleDropIndicatorProps>,
47
+ ): void {
48
+ const getEditor = props.editor.get
49
+
50
+ useEffect(host, () => {
51
+ assignStyles(host, {
52
+ pointerEvents: 'none',
53
+ position: 'absolute',
54
+ })
55
+ })
56
+
57
+ useInitDndPosition(host, getEditor, onInitIndicatorPosition)
58
+
59
+ useUpdateIndicatorPosition(host, getEditor, HANDLE_WIDTH)
60
+ }
61
+
62
+ function onInitIndicatorPosition({ host, direction, dragging, table }: OnInitParams): void {
63
+ assignStyles(host, {
64
+ display: dragging ? 'block' : 'none',
65
+ })
66
+
67
+ const tableRect = table.getBoundingClientRect()
68
+
69
+ if (direction === 'col') {
70
+ assignStyles(host, {
71
+ width: `${HANDLE_WIDTH}px`,
72
+ height: `${tableRect.height}px`,
73
+ })
74
+ }
75
+
76
+ if (direction === 'row') {
77
+ assignStyles(host, {
78
+ width: `${tableRect.width}px`,
79
+ height: `${HANDLE_WIDTH}px`,
80
+ })
81
+ }
82
+ }
83
+
84
+ function useUpdateIndicatorPosition(host: HostElement, getEditor: () => Editor | null, handleWidth: number): void {
85
+ const getStore = tableHandleStoreContext.consume(host)
86
+
87
+ useEffect(host, () => {
88
+ const view = getSafeEditorView(getEditor())
89
+ if (!view) return
90
+
91
+ const store = getStore()
92
+ if (!store) return
93
+
94
+ const dndStore = store.dndStore
95
+ if (!dndStore.dragging.get()) return
96
+
97
+ const draggingIndex = dndStore.draggingIndex.get()
98
+ const direction = dndStore.direction.get()
99
+ const x = dndStore.x.get()
100
+ const y = dndStore.y.get()
101
+
102
+ const relatedDOMs = getDndRelatedDOMs(view, store.getReferenceCell()?.cellPos, draggingIndex, direction)
103
+ if (!relatedDOMs) return
104
+ const { table } = relatedDOMs
105
+
106
+ let cancelled = false
107
+ const cleanup = () => {
108
+ cancelled = true
109
+ }
110
+
111
+ if (direction === 'col') {
112
+ const dir = dndStore.startX.get() > x ? 'left' : 'right'
113
+ const dragOverColumn = getDragOverColumn(table, x)
114
+
115
+ if (dragOverColumn) {
116
+ const [col, index] = dragOverColumn
117
+ dndStore.droppingIndex.set(index)
118
+ void computePosition(col, host, {
119
+ placement: dir === 'left' ? 'left' : 'right',
120
+ middleware: [offset(dir === 'left' ? -1 * handleWidth : 0)],
121
+ }).then(({ x }) => {
122
+ if (cancelled) return
123
+ assignStyles(host, { left: `${x}px` })
124
+ })
125
+ }
126
+
127
+ return cleanup
128
+ }
129
+
130
+ if (direction === 'row') {
131
+ const dir = dndStore.startY.get() > y ? 'up' : 'down'
132
+ const dragOverRow = getDragOverRow(table, y)
133
+
134
+ if (dragOverRow) {
135
+ const [row, index] = dragOverRow
136
+ dndStore.droppingIndex.set(index)
137
+ void computePosition(row, host, {
138
+ placement: dir === 'up' ? 'top' : 'bottom',
139
+ middleware: [offset(dir === 'up' ? -1 * handleWidth : 0)],
140
+ }).then(({ y }) => {
141
+ if (cancelled) return
142
+ assignStyles(host, { top: `${y}px` })
143
+ })
144
+ }
145
+
146
+ return cleanup
147
+ }
148
+ })
149
+ }
150
+
151
+ const TableHandleDropIndicatorElementBase: HostElementConstructor<TableHandleDropIndicatorProps> = defineCustomElement(
152
+ setupTableHandleDropIndicator,
153
+ TableHandleDropIndicatorPropsDeclaration,
154
+ )
155
+
156
+ /**
157
+ * @public
158
+ */
159
+ export class TableHandleDropIndicatorElement extends TableHandleDropIndicatorElementBase {}
160
+
161
+ /**
162
+ * @internal
163
+ */
164
+ export function registerTableHandleDropIndicatorElement(): void {
165
+ registerCustomElement('prosekit-table-handle-drop-indicator', TableHandleDropIndicatorElement)
166
+ }
@@ -0,0 +1,103 @@
1
+ import {
2
+ computed,
3
+ createSignal,
4
+ defineCustomElement,
5
+ defineProps,
6
+ registerCustomElement,
7
+ type HostElement,
8
+ type HostElementConstructor,
9
+ type PropsDeclaration,
10
+ type State,
11
+ } from '@aria-ui/core'
12
+ import { defineDOMEventHandler, type Editor } from '@prosekit/core'
13
+ import type { EditorView } from '@prosekit/pm/view'
14
+
15
+ import { useEditorExtension } from '../../hooks/use-editor-extension.ts'
16
+ import { useEditorTyping } from '../../hooks/use-editor-typing.ts'
17
+ import { useScrolling } from '../../hooks/use-scrolling.ts'
18
+ import { useSelecting } from '../../hooks/use-selecting.ts'
19
+
20
+ import { createTableHandleStore, tableHandleStoreContext } from './store.ts'
21
+ import { useDrop } from './use-drop.ts'
22
+ import { getHoveringCell, isHoveringCellInfoEqual, type HoveringCellInfo } from './utils.ts'
23
+
24
+ export interface TableHandleRootProps {
25
+ /**
26
+ * The ProseKit editor instance.
27
+ *
28
+ * @default null
29
+ * @hidden
30
+ */
31
+ editor: Editor | null
32
+ }
33
+
34
+ /** @internal */
35
+ export const TableHandleRootPropsDeclaration: PropsDeclaration<TableHandleRootProps> = defineProps<TableHandleRootProps>({
36
+ editor: { default: null, attribute: false, type: 'json' },
37
+ })
38
+
39
+ /**
40
+ * @internal
41
+ */
42
+ export function setupTableHandleRoot(
43
+ host: HostElement,
44
+ props: State<TableHandleRootProps>,
45
+ ): void {
46
+ const getEditor = props.editor.get
47
+
48
+ const getHoveringCellInfo = useHoveringCell(host, getEditor)
49
+ const getTyping = useEditorTyping(host, getEditor)
50
+ const getIsInTable = computed(() => !!getHoveringCellInfo())
51
+ const getSelecting = useSelecting(host, getEditor, getIsInTable)
52
+ const getScrolling = useScrolling(host)
53
+ const getCanShow = computed(() => !getTyping() && !getSelecting() && !getScrolling())
54
+
55
+ const store = createTableHandleStore(getHoveringCellInfo, getCanShow)
56
+ tableHandleStoreContext.provide(host, store)
57
+
58
+ useDrop(host, getEditor, store)
59
+ }
60
+
61
+ function useHoveringCell(
62
+ host: HostElement,
63
+ getEditor: () => Editor | null,
64
+ ): () => HoveringCellInfo | undefined {
65
+ const hoveringCell = createSignal<HoveringCellInfo | undefined>(undefined)
66
+
67
+ const extension = defineCellHoverHandler((curr: HoveringCellInfo | undefined) => {
68
+ const prev = hoveringCell.get()
69
+ if (isHoveringCellInfoEqual(prev, curr)) return
70
+ hoveringCell.set(curr)
71
+ })
72
+
73
+ useEditorExtension(host, getEditor, extension)
74
+
75
+ return hoveringCell.get
76
+ }
77
+
78
+ function defineCellHoverHandler(
79
+ handler: (hoveringCell: HoveringCellInfo | undefined) => void,
80
+ ) {
81
+ const pointerHandler = (view: EditorView, event: PointerEvent) => {
82
+ const hoveringCell = getHoveringCell(view, event)
83
+ return handler(hoveringCell)
84
+ }
85
+ return defineDOMEventHandler('pointerover', pointerHandler)
86
+ }
87
+
88
+ const TableHandleRootElementBase: HostElementConstructor<TableHandleRootProps> = defineCustomElement(
89
+ setupTableHandleRoot,
90
+ TableHandleRootPropsDeclaration,
91
+ )
92
+
93
+ /**
94
+ * @public
95
+ */
96
+ export class TableHandleRootElement extends TableHandleRootElementBase {}
97
+
98
+ /**
99
+ * @internal
100
+ */
101
+ export function registerTableHandleRootElement(): void {
102
+ registerCustomElement('prosekit-table-handle-root', TableHandleRootElement)
103
+ }
@@ -0,0 +1,51 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ useEffect,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type State,
10
+ } from '@aria-ui/core'
11
+ import { MenuRootPropsDeclaration, setupMenuRoot, type MenuRootProps } from '@aria-ui/elements/menu'
12
+
13
+ import { tableHandleStoreContext } from './store.ts'
14
+
15
+ export interface TableHandleRowMenuRootProps extends MenuRootProps {}
16
+
17
+ /** @internal */
18
+ export const TableHandleRowMenuRootPropsDeclaration: PropsDeclaration<TableHandleRowMenuRootProps> = defineProps<
19
+ TableHandleRowMenuRootProps
20
+ >(MenuRootPropsDeclaration)
21
+
22
+ /** @internal */
23
+ export function setupTableHandleRowMenuRoot(
24
+ host: HostElement,
25
+ props: State<TableHandleRowMenuRootProps>,
26
+ ): void {
27
+ setupMenuRoot(host, props)
28
+ const getStore = tableHandleStoreContext.consume(host)
29
+
30
+ useEffect(host, () => {
31
+ const open = props.open.get() || false
32
+ const store = getStore?.()
33
+ if (!store) return
34
+ store.setIsRowMenuOpen(open)
35
+ })
36
+ }
37
+
38
+ const TableHandleRowMenuRootElementBase: HostElementConstructor<TableHandleRowMenuRootProps> = defineCustomElement(
39
+ setupTableHandleRowMenuRoot,
40
+ TableHandleRowMenuRootPropsDeclaration,
41
+ )
42
+
43
+ /**
44
+ * @public
45
+ */
46
+ export class TableHandleRowMenuRootElement extends TableHandleRowMenuRootElementBase {}
47
+
48
+ /** @internal */
49
+ export function registerTableHandleRowMenuRootElement(): void {
50
+ registerCustomElement('prosekit-table-handle-row-menu-root', TableHandleRowMenuRootElement)
51
+ }
@@ -0,0 +1,107 @@
1
+ import {
2
+ createSignal,
3
+ defineCustomElement,
4
+ defineProps,
5
+ onMount,
6
+ registerCustomElement,
7
+ useEventListener,
8
+ type HostElement,
9
+ type HostElementConstructor,
10
+ type PropsDeclaration,
11
+ type State,
12
+ } from '@aria-ui/core'
13
+ import { setupMenuTrigger, type MenuTriggerProps } from '@aria-ui/elements/menu'
14
+ import type { Editor } from '@prosekit/core'
15
+ import { selectTableRow, type defineTableCommands } from '@prosekit/extensions/table'
16
+
17
+ import { tableHandleStoreContext } from './store.ts'
18
+ import { useEmptyImage } from './use-empty-image.ts'
19
+
20
+ type TableCommandsExtension = ReturnType<typeof defineTableCommands>
21
+
22
+ export interface TableHandleRowMenuTriggerProps {
23
+ /**
24
+ * @default null
25
+ * @hidden
26
+ */
27
+ editor: Editor<TableCommandsExtension> | null
28
+ }
29
+
30
+ /** @internal */
31
+ export const TableHandleRowMenuTriggerPropsDeclaration: PropsDeclaration<TableHandleRowMenuTriggerProps> = defineProps<
32
+ TableHandleRowMenuTriggerProps
33
+ >({
34
+ editor: { default: null, attribute: false, type: 'json' },
35
+ })
36
+
37
+ /** @internal */
38
+ export function setupTableHandleRowMenuTrigger(
39
+ host: HostElement,
40
+ props: State<TableHandleRowMenuTriggerProps>,
41
+ ): void {
42
+ const getEditor = props.editor.get
43
+ const getStore = tableHandleStoreContext.consume(host)
44
+
45
+ const triggerProps: State<MenuTriggerProps> = {
46
+ disabled: createSignal(false),
47
+ }
48
+ setupMenuTrigger(host, triggerProps)
49
+
50
+ useEventListener(host, 'pointerdown', () => {
51
+ const editor = getEditor()
52
+ const cellPos = getStore()?.getReferenceCell()?.cellPos
53
+ if (!editor || !cellPos) return
54
+ editor.exec(selectTableRow({ head: cellPos }))
55
+ })
56
+
57
+ onMount(host, () => {
58
+ host.draggable = true
59
+ })
60
+
61
+ const getEmptyImage = useEmptyImage(host)
62
+
63
+ useEventListener(host, 'dragstart', (event: DragEvent) => {
64
+ const dataTransfer = event.dataTransfer
65
+ if (dataTransfer) {
66
+ dataTransfer.effectAllowed = 'move'
67
+ const emptyImage = getEmptyImage()
68
+ if (emptyImage) {
69
+ dataTransfer.setDragImage(emptyImage, 0, 0)
70
+ }
71
+ }
72
+ const store = getStore()
73
+ if (!store) return
74
+ const index = store.getReferenceCell()?.rowIndex
75
+
76
+ if (index == null || index < 0) {
77
+ console.warn('[prosekit] Invalid row index for drag operation:', index)
78
+ event.preventDefault()
79
+ return
80
+ }
81
+
82
+ const dndStore = store.dndStore
83
+
84
+ dndStore.direction.set('row')
85
+ dndStore.dragging.set(true)
86
+ dndStore.draggingIndex.set(index)
87
+ dndStore.startX.set(event.clientX)
88
+ dndStore.startY.set(event.clientY)
89
+ })
90
+ }
91
+
92
+ const TableHandleRowMenuTriggerElementBase: HostElementConstructor<TableHandleRowMenuTriggerProps> = defineCustomElement(
93
+ setupTableHandleRowMenuTrigger,
94
+ TableHandleRowMenuTriggerPropsDeclaration,
95
+ )
96
+
97
+ /**
98
+ * @public
99
+ */
100
+ export class TableHandleRowMenuTriggerElement extends TableHandleRowMenuTriggerElementBase {}
101
+
102
+ /**
103
+ * @internal
104
+ */
105
+ export function registerTableHandleRowMenuTriggerElement(): void {
106
+ registerCustomElement('prosekit-table-handle-row-menu-trigger', TableHandleRowMenuTriggerElement)
107
+ }
@@ -0,0 +1,42 @@
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 { setupOverlayPopup } from '@aria-ui/elements/overlay'
11
+
12
+ import { tableHandleStoreContext } from './store.ts'
13
+
14
+ export interface TableHandleRowPopupProps {}
15
+
16
+ /** @internal */
17
+ export const TableHandleRowPopupPropsDeclaration: PropsDeclaration<TableHandleRowPopupProps> = defineProps<TableHandleRowPopupProps>({})
18
+
19
+ /** @internal */
20
+ export function setupTableHandleRowPopup(
21
+ host: HostElement,
22
+ _props: State<TableHandleRowPopupProps>,
23
+ ): void {
24
+ const getStore = tableHandleStoreContext.consume(host)
25
+ const getOverlayStore = () => getStore()?.rowOverlayStore
26
+ setupOverlayPopup(host, getOverlayStore)
27
+ }
28
+
29
+ const TableHandleRowPopupElementBase: HostElementConstructor<TableHandleRowPopupProps> = defineCustomElement(
30
+ setupTableHandleRowPopup,
31
+ TableHandleRowPopupPropsDeclaration,
32
+ )
33
+
34
+ /**
35
+ * @public
36
+ */
37
+ export class TableHandleRowPopupElement extends TableHandleRowPopupElementBase {}
38
+
39
+ /** @internal */
40
+ export function registerTableHandleRowPopupElement(): void {
41
+ registerCustomElement('prosekit-table-handle-row-popup', TableHandleRowPopupElement)
42
+ }
@@ -0,0 +1,67 @@
1
+ import {
2
+ computed,
3
+ defineCustomElement,
4
+ defineProps,
5
+ registerCustomElement,
6
+ useEffect,
7
+ type HostElement,
8
+ type HostElementConstructor,
9
+ type PropsDeclaration,
10
+ type State,
11
+ } from '@aria-ui/core'
12
+ import { setupOverlayPositioner } from '@aria-ui/elements/overlay'
13
+ import type { Placement } from '@floating-ui/dom'
14
+
15
+ import { useHTMLElementAt } from '../../utils/use-html-element-at.ts'
16
+
17
+ import { SharedTableHandlePositionerPropsDeclaration, type SharedTableHandlePositionerProps } from './shared.ts'
18
+ import { tableHandleStoreContext } from './store.ts'
19
+
20
+ export interface TableHandleRowPositionerProps extends Omit<SharedTableHandlePositionerProps, 'placement'> {
21
+ /**
22
+ * The placement of the popover, relative to the hovered table cell.
23
+ *
24
+ * @default "left"
25
+ */
26
+ placement: Placement
27
+ }
28
+
29
+ /** @internal */
30
+ export const TableHandleRowPositionerPropsDeclaration: PropsDeclaration<TableHandleRowPositionerProps> = defineProps<
31
+ TableHandleRowPositionerProps
32
+ >({
33
+ ...SharedTableHandlePositionerPropsDeclaration,
34
+ placement: { default: 'left', attribute: 'placement', type: 'string' },
35
+ })
36
+
37
+ /** @internal */
38
+ export function setupTableHandleRowPositioner(
39
+ host: HostElement,
40
+ props: State<TableHandleRowPositionerProps>,
41
+ ): void {
42
+ const getStore = tableHandleStoreContext.consume(host)
43
+ const getOverlayStore = () => getStore()?.rowOverlayStore
44
+ setupOverlayPositioner(host, props, getOverlayStore)
45
+
46
+ const getEditor = props.editor.get
47
+ const getRowFirstCellPos = computed(() => getStore()?.getReferenceCell()?.rowFirstCellPos)
48
+ const getReferenceCell = useHTMLElementAt(getEditor, getRowFirstCellPos)
49
+ useEffect(host, () => {
50
+ getOverlayStore()?.setAnchorElement(getReferenceCell())
51
+ })
52
+ }
53
+
54
+ const TableHandleRowPositionerElementBase: HostElementConstructor<TableHandleRowPositionerProps> = defineCustomElement(
55
+ setupTableHandleRowPositioner,
56
+ TableHandleRowPositionerPropsDeclaration,
57
+ )
58
+
59
+ /**
60
+ * @public
61
+ */
62
+ export class TableHandleRowPositionerElement extends TableHandleRowPositionerElementBase {}
63
+
64
+ /** @internal */
65
+ export function registerTableHandleRowPositionerElement(): void {
66
+ registerCustomElement('prosekit-table-handle-row-positioner', TableHandleRowPositionerElement)
67
+ }