@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,49 @@
1
+ import {
2
+ createContext,
3
+ type Context,
4
+ } from '@aria-ui/core'
5
+
6
+ import type {
7
+ DndInfo,
8
+ HoveringCellInfo,
9
+ } from './utils'
10
+
11
+ /**
12
+ * @internal
13
+ */
14
+ export type TableHandleRootContext = HoveringCellInfo | null
15
+
16
+ /**
17
+ * @internal
18
+ */
19
+ export const tableHandleRootContext: Context<TableHandleRootContext> = createContext(
20
+ 'prosekit-table-handle-root-context',
21
+ null,
22
+ )
23
+
24
+ /**
25
+ * @internal
26
+ */
27
+ export type TableHandleDndContext = DndInfo
28
+
29
+ /**
30
+ * @internal
31
+ */
32
+ export const defaultTableHandleDndContext: TableHandleDndContext = {
33
+ dragging: false,
34
+ direction: 'row',
35
+ draggingIndex: -1,
36
+ droppingIndex: -1,
37
+ x: -1,
38
+ y: -1,
39
+ startX: -1,
40
+ startY: -1,
41
+ }
42
+
43
+ /**
44
+ * @internal
45
+ */
46
+ export const tableHandleDndContext: Context<TableHandleDndContext> = createContext(
47
+ 'prosekit-table-handle-dnd-context',
48
+ defaultTableHandleDndContext,
49
+ )
@@ -0,0 +1,135 @@
1
+ import {
2
+ createComputed,
3
+ useEffect,
4
+ type ConnectableElement,
5
+ type ReadonlySignal,
6
+ } from '@aria-ui/core'
7
+ import {
8
+ computePosition,
9
+ offset,
10
+ } from '@floating-ui/dom'
11
+ import { isHTMLElement } from '@ocavue/utils'
12
+ import type { Editor } from '@prosekit/core'
13
+ import type { EditorView } from '@prosekit/pm/view'
14
+
15
+ import { assignStyles } from '../../utils/assign-styles'
16
+ import { getSafeEditorView } from '../../utils/get-safe-editor-view'
17
+
18
+ import {
19
+ tableHandleDndContext,
20
+ tableHandleRootContext,
21
+ } from './context'
22
+
23
+ export type OnInitParams = {
24
+ host: ConnectableElement
25
+ direction: 'row' | 'col'
26
+ dragging: boolean
27
+ draggingIndex: number
28
+ table: HTMLTableElement
29
+ cell: HTMLTableCellElement
30
+ }
31
+
32
+ export function useInitDndPosition(
33
+ host: ConnectableElement,
34
+ editor: ReadonlySignal<Editor | null>,
35
+ onInit: (params: OnInitParams) => void,
36
+ ): void {
37
+ const dndContext = tableHandleDndContext.consume(host)
38
+ const rootContext = tableHandleRootContext.consume(host)
39
+
40
+ const draggingSignal = createComputed(() => {
41
+ const context = dndContext.get()
42
+ return context.dragging
43
+ })
44
+
45
+ const directionSignal = createComputed(() => {
46
+ const context = dndContext.get()
47
+ return context.direction
48
+ })
49
+
50
+ const draggingIndexSignal = createComputed(() => {
51
+ const context = dndContext.get()
52
+ return context.draggingIndex
53
+ })
54
+
55
+ useEffect(host, () => {
56
+ const view = getSafeEditorView(editor.get())
57
+ if (!view) return
58
+
59
+ const dragging = draggingSignal.get()
60
+ const direction = directionSignal.get()
61
+
62
+ host.dataset.direction = direction
63
+ host.dataset.dragging = dragging.toString()
64
+
65
+ const draggingIndex = draggingIndexSignal.get()
66
+
67
+ const relatedDOMs = getDndRelatedDOMs(view, rootContext.peek()?.cellPos, draggingIndex, direction)
68
+ if (!relatedDOMs) return
69
+ const { table, cell } = relatedDOMs
70
+
71
+ onInit({
72
+ host,
73
+ direction,
74
+ dragging,
75
+ draggingIndex,
76
+ table,
77
+ cell,
78
+ })
79
+
80
+ if (!dragging) return
81
+
82
+ let cancelled = false
83
+
84
+ void computePosition(cell, host, {
85
+ placement: direction === 'row' ? 'right' : 'bottom',
86
+ middleware: [
87
+ offset(({ rects }) => {
88
+ if (direction === 'col') {
89
+ return -rects.reference.height
90
+ }
91
+ return -rects.reference.width
92
+ }),
93
+ ],
94
+ }).then(({ x, y }) => {
95
+ if (cancelled) return
96
+ assignStyles(host, {
97
+ left: `${x}px`,
98
+ top: `${y}px`,
99
+ })
100
+ })
101
+
102
+ return () => {
103
+ cancelled = true
104
+ }
105
+ })
106
+ }
107
+
108
+ function getTableDOMByPos(view: EditorView, pos: number): HTMLTableElement | undefined {
109
+ const dom = view.domAtPos(pos).node
110
+ if (!dom) return
111
+ const element = isHTMLElement(dom) ? dom : dom.parentElement
112
+ const table = element?.closest('table')
113
+ return table ?? undefined
114
+ }
115
+
116
+ function getTargetFirstCellDOM(table: HTMLTableElement, index: number, direction: 'row' | 'col'): HTMLTableCellElement | undefined {
117
+ if (direction === 'row') {
118
+ const row = table.querySelectorAll('tr')[index]
119
+ const cell = row?.querySelector('td')
120
+ return cell ?? undefined
121
+ } else {
122
+ const row = table.querySelector('tr')
123
+ const cell = row?.querySelectorAll('td')[index]
124
+ return cell ?? undefined
125
+ }
126
+ }
127
+
128
+ export function getDndRelatedDOMs(view: EditorView, cellPos: number | undefined, draggingIndex: number, direction: 'row' | 'col'): { table: HTMLTableElement; cell: HTMLTableCellElement } | undefined {
129
+ if (cellPos == null) return
130
+ const table = getTableDOMByPos(view, cellPos)
131
+ if (!table) return
132
+ const cell = getTargetFirstCellDOM(table, draggingIndex, direction)
133
+ if (!cell) return
134
+ return { table, cell }
135
+ }
@@ -0,0 +1,94 @@
1
+ import {
2
+ createComputed,
3
+ useEffect,
4
+ type ConnectableElement,
5
+ type ReadonlySignal,
6
+ type Signal,
7
+ } from '@aria-ui/core'
8
+ import type { Editor } from '@prosekit/core'
9
+ import {
10
+ moveTableColumn,
11
+ moveTableRow,
12
+ } from '@prosekit/extensions/table'
13
+
14
+ import { getSafeEditorView } from '../../../utils/get-safe-editor-view'
15
+ import type { TableHandleDndContext } from '../context'
16
+
17
+ export function useDrop(
18
+ host: ConnectableElement,
19
+ editor: ReadonlySignal<Editor | null>,
20
+ dndContext: Signal<TableHandleDndContext>,
21
+ ): void {
22
+ const dragging = createComputed(() => dndContext.get().dragging)
23
+
24
+ useEffect(host, () => {
25
+ const view = getSafeEditorView(editor.get())
26
+ if (!view || !view.editable) return
27
+
28
+ const ownerDocument = view.dom?.ownerDocument
29
+ if (!ownerDocument) return
30
+
31
+ const handleDrop = () => {
32
+ if (!dragging.peek()) return
33
+ const editorValue = editor.peek()
34
+ if (!editorValue) return
35
+ const { droppingIndex, draggingIndex, direction } = dndContext.peek()
36
+
37
+ // Validate indices
38
+ if (draggingIndex < 0 || droppingIndex < 0) {
39
+ console.warn('[prosekit] Invalid drag indices:', { draggingIndex, droppingIndex })
40
+ return
41
+ }
42
+
43
+ if (direction === 'row') {
44
+ editorValue.exec(moveTableRow({
45
+ from: draggingIndex,
46
+ to: droppingIndex,
47
+ }))
48
+ return
49
+ }
50
+ if (direction === 'col') {
51
+ editorValue.exec(moveTableColumn({
52
+ from: draggingIndex,
53
+ to: droppingIndex,
54
+ }))
55
+ return
56
+ }
57
+ }
58
+
59
+ // To make `drop` event work, we need to prevent the default behavior of the
60
+ // `dragover` event for drop zone. Here we set the whole document as the
61
+ // drop zone so that even the mouse moves outside the editor, the `drop`
62
+ // event will still be triggered.
63
+ const handleDragOver = (event: DragEvent) => {
64
+ if (!dragging.peek()) return
65
+ event.preventDefault()
66
+ const prev = dndContext.peek()
67
+
68
+ dndContext.set({
69
+ ...prev,
70
+ dragging: true,
71
+ x: event.clientX,
72
+ y: event.clientY,
73
+ })
74
+ }
75
+
76
+ const handleDragEnd = () => {
77
+ if (!dragging.peek()) return
78
+ const prev = dndContext.peek()
79
+ dndContext.set({
80
+ ...prev,
81
+ dragging: false,
82
+ })
83
+ }
84
+
85
+ ownerDocument.addEventListener('dragover', handleDragOver)
86
+ ownerDocument.addEventListener('drop', handleDrop)
87
+ ownerDocument.addEventListener('dragend', handleDragEnd)
88
+ return () => {
89
+ ownerDocument.removeEventListener('dragover', handleDragOver)
90
+ ownerDocument.removeEventListener('drop', handleDrop)
91
+ ownerDocument.removeEventListener('dragend', handleDragEnd)
92
+ }
93
+ })
94
+ }
@@ -0,0 +1,30 @@
1
+ import type { ConnectableElement } from '@aria-ui/core'
2
+ import { useEffect } from '@aria-ui/core'
3
+
4
+ /**
5
+ * Returns a function that returns a 1x1 transparent image. This is used to
6
+ * prevent the browser from showing the default drag image. An earth icon in
7
+ * chrome is used as the default drag image. This image must be loaded before
8
+ * the dragStart event triggers.
9
+ *
10
+ * See https://stackoverflow.com/a/40923520
11
+ *
12
+ * @internal
13
+ */
14
+ export function useEmptyImage(
15
+ host: ConnectableElement,
16
+ ): () => HTMLImageElement | undefined {
17
+ let image: HTMLImageElement | undefined
18
+
19
+ useEffect(host, () => {
20
+ image = new Image(1, 1)
21
+ image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
22
+
23
+ return () => {
24
+ image?.remove()
25
+ image = undefined
26
+ }
27
+ })
28
+
29
+ return () => image
30
+ }
@@ -0,0 +1,37 @@
1
+ // This file is generated by packages/dev/src/gen-components.ts
2
+
3
+ export { TableHandleColumnRootElement } from './table-handle-column-root/element.gen'
4
+ export { tableHandleColumnRootEvents, tableHandleColumnRootProps, type TableHandleColumnRootEvents, type TableHandleColumnRootProps } from './table-handle-column-root/types'
5
+ export { useTableHandleColumnRoot } from './table-handle-column-root/setup'
6
+
7
+ export { TableHandleColumnTriggerElement } from './table-handle-column-trigger/element.gen'
8
+ export { tableHandleColumnTriggerEvents, tableHandleColumnTriggerProps, type TableHandleColumnTriggerEvents, type TableHandleColumnTriggerProps } from './table-handle-column-trigger/types'
9
+ export { useTableHandleColumnTrigger } from './table-handle-column-trigger/setup'
10
+
11
+ export { TableHandleDragPreviewElement } from './table-handle-drag-preview/element.gen'
12
+ export { tableHandleDragPreviewEvents, tableHandleDragPreviewProps, type TableHandleDragPreviewEvents, type TableHandleDragPreviewProps } from './table-handle-drag-preview/types'
13
+ export { useTableHandleDragPreview } from './table-handle-drag-preview/setup'
14
+
15
+ export { TableHandleDropIndicatorElement } from './table-handle-drop-indicator/element.gen'
16
+ export { tableHandleDropIndicatorEvents, tableHandleDropIndicatorProps, type TableHandleDropIndicatorEvents, type TableHandleDropIndicatorProps } from './table-handle-drop-indicator/types'
17
+ export { useTableHandleDropIndicator } from './table-handle-drop-indicator/setup'
18
+
19
+ export { TableHandlePopoverContentElement } from './table-handle-popover-content/element.gen'
20
+ export { tableHandlePopoverContentEvents, tableHandlePopoverContentProps, type TableHandlePopoverContentEvents, type TableHandlePopoverContentProps } from './table-handle-popover-content/types'
21
+ export { useTableHandlePopoverContent } from './table-handle-popover-content/setup'
22
+
23
+ export { TableHandlePopoverItemElement } from './table-handle-popover-item/element.gen'
24
+ export { tableHandlePopoverItemEvents, tableHandlePopoverItemProps, type TableHandlePopoverItemEvents, type TableHandlePopoverItemProps } from './table-handle-popover-item/types'
25
+ export { useTableHandlePopoverItem } from './table-handle-popover-item/setup'
26
+
27
+ export { TableHandleRootElement } from './table-handle-root/element.gen'
28
+ export { tableHandleRootEvents, tableHandleRootProps, type TableHandleRootEvents, type TableHandleRootProps } from './table-handle-root/types'
29
+ export { useTableHandleRoot } from './table-handle-root/setup'
30
+
31
+ export { TableHandleRowRootElement } from './table-handle-row-root/element.gen'
32
+ export { tableHandleRowRootEvents, tableHandleRowRootProps, type TableHandleRowRootEvents, type TableHandleRowRootProps } from './table-handle-row-root/types'
33
+ export { useTableHandleRowRoot } from './table-handle-row-root/setup'
34
+
35
+ export { TableHandleRowTriggerElement } from './table-handle-row-trigger/element.gen'
36
+ export { tableHandleRowTriggerEvents, tableHandleRowTriggerProps, type TableHandleRowTriggerEvents, type TableHandleRowTriggerProps } from './table-handle-row-trigger/types'
37
+ export { useTableHandleRowTrigger } from './table-handle-row-trigger/setup'
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useTableHandleColumnRoot } from "./setup"
4
+ import { tableHandleColumnRootEvents, tableHandleColumnRootProps, type TableHandleColumnRootEvents, type TableHandleColumnRootProps } from "./types"
5
+
6
+ const TableHandleColumnRootElementBase: BaseElementConstructor<TableHandleColumnRootProps> = defineCustomElement<
7
+ TableHandleColumnRootProps,
8
+ TableHandleColumnRootEvents
9
+ >({
10
+ props: tableHandleColumnRootProps,
11
+ events: tableHandleColumnRootEvents,
12
+ setup: useTableHandleColumnRoot,
13
+ })
14
+ class TableHandleColumnRootElement extends TableHandleColumnRootElementBase {}
15
+
16
+ registerCustomElement('prosekit-table-handle-column-root', TableHandleColumnRootElement)
17
+
18
+ export { TableHandleColumnRootElement }
@@ -0,0 +1,71 @@
1
+ import {
2
+ createComputed,
3
+ createSignal,
4
+ useAttribute,
5
+ useEffect,
6
+ type ConnectableElement,
7
+ type SignalState,
8
+ } from '@aria-ui/core'
9
+ import {
10
+ menuRootProps,
11
+ useMenuRoot,
12
+ type MenuRootProps,
13
+ } from '@aria-ui/menu/elements'
14
+ import { useOverlayPositionerState } from '@aria-ui/overlay/elements'
15
+ import { usePresence } from '@aria-ui/presence'
16
+
17
+ import { getStateWithDefaults } from '../../../utils/get-default-state'
18
+ import { getSafeEditorView } from '../../../utils/get-safe-editor-view'
19
+ import { tableHandleRootContext } from '../context'
20
+
21
+ import type { TableHandleColumnRootProps } from './types'
22
+
23
+ /**
24
+ * @internal
25
+ */
26
+ export function useTableHandleColumnRoot(
27
+ host: ConnectableElement,
28
+ { state }: { state: SignalState<TableHandleColumnRootProps> },
29
+ ): void {
30
+ const { editor, ...overlayState } = state
31
+
32
+ const rootContext = tableHandleRootContext.consume(host)
33
+
34
+ const colFirstCellPos = createComputed<number | undefined>(() => {
35
+ return rootContext.get()?.colFirstCellPos
36
+ })
37
+
38
+ const referenceCell = createComputed<HTMLElement | null>(() => {
39
+ const pos = colFirstCellPos.get()
40
+ const view = getSafeEditorView(editor.get())
41
+ if (!pos || !view) return null
42
+ return view.nodeDOM(pos) as HTMLElement | null
43
+ })
44
+
45
+ const contentOpen = createSignal(false)
46
+
47
+ // Close the menu when the hovering element is changed
48
+ // TODO: add a delay
49
+ useEffect(host, () => {
50
+ colFirstCellPos.get()
51
+ contentOpen.set(false)
52
+ })
53
+
54
+ useOverlayPositionerState(host, overlayState, {
55
+ reference: referenceCell,
56
+ })
57
+
58
+ const presence = createComputed(() => !!referenceCell.get())
59
+ useAttribute(host, 'data-state', () => (presence.get() ? 'open' : 'closed'))
60
+ usePresence(host, presence)
61
+
62
+ const menuRootState: SignalState<MenuRootProps> = getStateWithDefaults(
63
+ { open: contentOpen },
64
+ menuRootProps,
65
+ )
66
+
67
+ useMenuRoot(host, {
68
+ state: menuRootState,
69
+ emit: () => void 0,
70
+ })
71
+ }
@@ -0,0 +1,76 @@
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'
11
+ import type { Placement } from '@floating-ui/dom'
12
+ import type { Editor } from '@prosekit/core'
13
+
14
+ export interface TableHandleColumnRootProps extends Omit<OverlayPositionerProps, 'placement' | 'hoist' | 'flip' | 'shift' | 'hide'> {
15
+ /**
16
+ * The ProseKit editor instance.
17
+ *
18
+ * @default null
19
+ * @hidden
20
+ */
21
+ editor: Editor | null
22
+
23
+ /**
24
+ * The placement of the popover, relative to the hovered table cell.
25
+ *
26
+ * @default "top"
27
+ */
28
+ placement: Placement
29
+
30
+ /**
31
+ * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
32
+ * to place the floating element on top of other page content.
33
+ *
34
+ * @default false
35
+ */
36
+ hoist: boolean
37
+
38
+ /**
39
+ * @default false
40
+ * @hidden
41
+ */
42
+ flip: boolean
43
+
44
+ /**
45
+ * @default false
46
+ * @hidden
47
+ */
48
+ shift: boolean
49
+
50
+ /**
51
+ * @default true
52
+ * @hidden
53
+ */
54
+ hide: boolean
55
+ }
56
+
57
+ /** @internal */
58
+ export const tableHandleColumnRootProps: PropDeclarations<TableHandleColumnRootProps> = Object.freeze({
59
+ ...overlayPositionerProps,
60
+ editor: { default: null },
61
+ placement: { default: 'top' },
62
+
63
+ // Enabling `hoist` will cause the popover to have a small delay when
64
+ // scrolling the page.
65
+ hoist: { default: false },
66
+
67
+ flip: { default: false },
68
+ shift: { default: false },
69
+ hide: { default: true },
70
+ })
71
+
72
+ /** @internal */
73
+ export interface TableHandleColumnRootEvents extends OverlayPositionerEvents {}
74
+
75
+ /** @internal */
76
+ export const tableHandleColumnRootEvents: EventDeclarations<TableHandleColumnRootEvents> = overlayPositionerEvents
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useTableHandleColumnTrigger } from "./setup"
4
+ import { tableHandleColumnTriggerEvents, tableHandleColumnTriggerProps, type TableHandleColumnTriggerEvents, type TableHandleColumnTriggerProps } from "./types"
5
+
6
+ const TableHandleColumnTriggerElementBase: BaseElementConstructor<TableHandleColumnTriggerProps> = defineCustomElement<
7
+ TableHandleColumnTriggerProps,
8
+ TableHandleColumnTriggerEvents
9
+ >({
10
+ props: tableHandleColumnTriggerProps,
11
+ events: tableHandleColumnTriggerEvents,
12
+ setup: useTableHandleColumnTrigger,
13
+ })
14
+ class TableHandleColumnTriggerElement extends TableHandleColumnTriggerElementBase {}
15
+
16
+ registerCustomElement('prosekit-table-handle-column-trigger', TableHandleColumnTriggerElement)
17
+
18
+ export { TableHandleColumnTriggerElement }
@@ -0,0 +1,75 @@
1
+ import {
2
+ useEffect,
3
+ useEventListener,
4
+ type ConnectableElement,
5
+ type SetupOptions,
6
+ } from '@aria-ui/core'
7
+ import { useMenuTrigger } from '@aria-ui/menu/elements'
8
+ import { selectTableColumn } from '@prosekit/extensions/table'
9
+
10
+ import {
11
+ tableHandleDndContext,
12
+ tableHandleRootContext,
13
+ } from '../context'
14
+ import { useEmptyImage } from '../hooks/use-empty-image'
15
+
16
+ import type {
17
+ TableHandleColumnTriggerEvents,
18
+ TableHandleColumnTriggerProps,
19
+ } from './types'
20
+
21
+ /**
22
+ * @internal
23
+ */
24
+ export function useTableHandleColumnTrigger(
25
+ host: ConnectableElement,
26
+ { state }: SetupOptions<TableHandleColumnTriggerProps, TableHandleColumnTriggerEvents>,
27
+ ): void {
28
+ useMenuTrigger(host)
29
+
30
+ const context = tableHandleRootContext.consume(host)
31
+
32
+ const dndContext = tableHandleDndContext.consume(host)
33
+
34
+ useEventListener(host, 'pointerdown', () => {
35
+ const editor = state.editor.peek()
36
+ const cellPos = context.peek()?.cellPos
37
+ if (!editor || !cellPos) return
38
+ editor.exec(selectTableColumn({ head: cellPos }))
39
+ })
40
+
41
+ useEffect(host, () => {
42
+ host.draggable = true
43
+ })
44
+
45
+ const getEmptyImage = useEmptyImage(host)
46
+
47
+ useEventListener(host, 'dragstart', (event: DragEvent) => {
48
+ const dataTransfer = event.dataTransfer
49
+ if (dataTransfer) {
50
+ dataTransfer.effectAllowed = 'move'
51
+ const emptyImage = getEmptyImage()
52
+ if (emptyImage) {
53
+ dataTransfer.setDragImage(emptyImage, 0, 0)
54
+ }
55
+ dataTransfer.setData('application/x-prosekit-table-handle-drag', '')
56
+ }
57
+ const prev = dndContext.peek()
58
+ const index = context.peek()?.colIndex
59
+
60
+ if (index == null || index < 0) {
61
+ console.warn('[prosekit] Invalid column index for drag operation:', index)
62
+ event.preventDefault()
63
+ return
64
+ }
65
+
66
+ dndContext.set({
67
+ ...prev,
68
+ direction: 'col',
69
+ dragging: true,
70
+ draggingIndex: index,
71
+ startX: event.clientX,
72
+ startY: event.clientY,
73
+ })
74
+ })
75
+ }
@@ -0,0 +1,23 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import type { Editor } from '@prosekit/core'
6
+ import type { defineTableCommands } from '@prosekit/extensions/table'
7
+
8
+ type TableCommandsExtension = ReturnType<typeof defineTableCommands>
9
+
10
+ export interface TableHandleColumnTriggerProps {
11
+ editor: Editor<TableCommandsExtension> | null
12
+ }
13
+
14
+ /** @internal */
15
+ export const tableHandleColumnTriggerProps: PropDeclarations<TableHandleColumnTriggerProps> = {
16
+ editor: { default: null },
17
+ }
18
+
19
+ /** @internal */
20
+ export interface TableHandleColumnTriggerEvents {}
21
+
22
+ /** @internal */
23
+ export const tableHandleColumnTriggerEvents: EventDeclarations<TableHandleColumnTriggerEvents> = {}
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useTableHandleDragPreview } from "./setup"
4
+ import { tableHandleDragPreviewEvents, tableHandleDragPreviewProps, type TableHandleDragPreviewEvents, type TableHandleDragPreviewProps } from "./types"
5
+
6
+ const TableHandleDragPreviewElementBase: BaseElementConstructor<TableHandleDragPreviewProps> = defineCustomElement<
7
+ TableHandleDragPreviewProps,
8
+ TableHandleDragPreviewEvents
9
+ >({
10
+ props: tableHandleDragPreviewProps,
11
+ events: tableHandleDragPreviewEvents,
12
+ setup: useTableHandleDragPreview,
13
+ })
14
+ class TableHandleDragPreviewElement extends TableHandleDragPreviewElementBase {}
15
+
16
+ registerCustomElement('prosekit-table-handle-drag-preview', TableHandleDragPreviewElement)
17
+
18
+ export { TableHandleDragPreviewElement }