@prosekit/web 0.7.3 → 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-D5jj7cme.js → inject-style-BJQNFufI.js} +4 -5
  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 +9 -13
  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 +17 -37
  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 +17 -17
  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,80 @@
1
+ import { assignStyles } from '../../../utils/assign-styles'
2
+ import {
3
+ cloneElement,
4
+ deepCloneElement,
5
+ } from '../../../utils/clone-element'
6
+ import { fadeColor } from '../../../utils/fade-color'
7
+ import { getEffectiveBackgroundColor } from '../../../utils/get-effective-background-color'
8
+ import { injectStyle } from '../../../utils/inject-style'
9
+
10
+ export function clearPreviewDOM(previewRoot: HTMLElement): void {
11
+ while (previewRoot.firstChild) {
12
+ previewRoot.removeChild(previewRoot.firstChild)
13
+ }
14
+ }
15
+
16
+ export function createPreviewDOM(
17
+ table: HTMLTableElement,
18
+ previewRoot: HTMLElement,
19
+ index: number,
20
+ direction: 'row' | 'col',
21
+ ): void {
22
+ clearPreviewDOM(previewRoot)
23
+
24
+ const [previewTable, previewTableStyle] = cloneElement(table)
25
+ injectStyle(previewRoot, previewTableStyle)
26
+ unsetSize(previewTable)
27
+
28
+ const tableBody = table.querySelector('tbody')
29
+ const [previewTableBody, previewTableBodyStyle] = tableBody
30
+ ? cloneElement(tableBody)
31
+ : [table.ownerDocument.createElement('tbody'), '']
32
+ injectStyle(previewRoot, previewTableBodyStyle)
33
+ unsetSize(previewTableBody)
34
+
35
+ // Get effective background color and apply it with some opacity
36
+ const backgroundColor = getEffectiveBackgroundColor(table)
37
+ if (backgroundColor) {
38
+ const backgroundColorWithOpacity = fadeColor(backgroundColor, 0.8)
39
+ if (backgroundColorWithOpacity) {
40
+ assignStyles(previewTable, { backgroundColor: backgroundColorWithOpacity })
41
+ }
42
+ }
43
+
44
+ previewTable.appendChild(previewTableBody)
45
+ previewRoot.appendChild(previewTable)
46
+
47
+ const rows = table.querySelectorAll('tr')
48
+
49
+ if (direction === 'row') {
50
+ const row = rows[index]
51
+ const [previewRow, previewRowStyle] = deepCloneElement(row)
52
+ injectStyle(previewRoot, previewRowStyle)
53
+ previewTableBody.appendChild(previewRow)
54
+ } else {
55
+ rows.forEach((row) => {
56
+ const [previewRow, previewRowStyle] = cloneElement(row)
57
+ injectStyle(previewRoot, previewRowStyle)
58
+ unsetSize(previewRow)
59
+ const cells = row.querySelectorAll('td')
60
+ const cell = cells[index]
61
+ if (cell) {
62
+ const [previewCell, previewCellStyle] = deepCloneElement(cell)
63
+ injectStyle(previewRoot, previewCellStyle)
64
+ previewRow.appendChild(previewCell)
65
+ previewTableBody.appendChild(previewRow)
66
+ }
67
+ })
68
+ }
69
+ }
70
+
71
+ function unsetSize(element: HTMLElement) {
72
+ assignStyles(element, {
73
+ width: 'unset',
74
+ height: 'unset',
75
+ minWidth: 'unset',
76
+ minHeight: 'unset',
77
+ maxWidth: 'unset',
78
+ maxHeight: 'unset',
79
+ })
80
+ }
@@ -0,0 +1,67 @@
1
+ import {
2
+ useEffect,
3
+ type ConnectableElement,
4
+ type SignalState,
5
+ } from '@aria-ui/core'
6
+
7
+ import { assignStyles } from '../../../utils/assign-styles'
8
+ import {
9
+ useInitDndPosition,
10
+ type OnInitParams,
11
+ } from '../dnd'
12
+
13
+ import {
14
+ clearPreviewDOM,
15
+ createPreviewDOM,
16
+ } from './render-preview'
17
+ import type { TableHandleDragPreviewProps } from './types'
18
+ import { useUpdatePreviewPosition } from './updater'
19
+
20
+ /**
21
+ * @internal
22
+ */
23
+ export function useTableHandleDragPreview(host: ConnectableElement, { state }: { state: SignalState<TableHandleDragPreviewProps> }): void {
24
+ const { editor } = state
25
+
26
+ useEffect(host, () => {
27
+ assignStyles(host, {
28
+ position: 'absolute',
29
+ // Make sure drop on preview will trigger drop event on the host
30
+ pointerEvents: 'none',
31
+ })
32
+ })
33
+
34
+ useInitDndPosition(host, editor, onInitPreviewPosition)
35
+
36
+ useUpdatePreviewPosition(host, editor)
37
+ }
38
+
39
+ function onInitPreviewPosition({ host, direction, dragging, table, cell, draggingIndex }: OnInitParams): void {
40
+ assignStyles(host, {
41
+ display: dragging ? 'block' : 'none',
42
+ })
43
+
44
+ if (!dragging) {
45
+ clearPreviewDOM(host)
46
+ return
47
+ }
48
+
49
+ createPreviewDOM(table, host, draggingIndex, direction)
50
+
51
+ const tableRect = table.getBoundingClientRect()
52
+ const cellRect = cell.getBoundingClientRect()
53
+
54
+ if (direction === 'col') {
55
+ assignStyles(host, {
56
+ width: `${cellRect.width}px`,
57
+ height: `${tableRect.height}px`,
58
+ })
59
+ }
60
+
61
+ if (direction === 'row') {
62
+ assignStyles(host, {
63
+ width: `${tableRect.width}px`,
64
+ height: `${cellRect.height}px`,
65
+ })
66
+ }
67
+ }
@@ -0,0 +1,17 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import type { Editor } from '@prosekit/core'
6
+
7
+ export interface TableHandleDragPreviewProps {
8
+ editor: Editor | null
9
+ }
10
+
11
+ export const tableHandleDragPreviewProps: PropDeclarations<TableHandleDragPreviewProps> = {
12
+ editor: { default: null },
13
+ }
14
+
15
+ export interface TableHandleDragPreviewEvents {}
16
+
17
+ export const tableHandleDragPreviewEvents: EventDeclarations<TableHandleDragPreviewEvents> = {}
@@ -0,0 +1,101 @@
1
+ import {
2
+ createComputed,
3
+ useEffect,
4
+ type ConnectableElement,
5
+ type ReadonlySignal,
6
+ } from '@aria-ui/core'
7
+ import {
8
+ computePosition,
9
+ type ReferenceElement,
10
+ } from '@floating-ui/dom'
11
+ import type { Editor } from '@prosekit/core'
12
+
13
+ import { assignStyles } from '../../../utils/assign-styles'
14
+ import { getSafeEditorView } from '../../../utils/get-safe-editor-view'
15
+ import {
16
+ tableHandleDndContext,
17
+ tableHandleRootContext,
18
+ } from '../context'
19
+ import { getDndRelatedDOMs } from '../dnd'
20
+
21
+ export function useUpdatePreviewPosition(host: ConnectableElement, editor: ReadonlySignal<Editor | null>): void {
22
+ const dndContext = tableHandleDndContext.consume(host)
23
+ const rootContext = tableHandleRootContext.consume(host)
24
+
25
+ const draggingSignal = createComputed(() => {
26
+ const context = dndContext.get()
27
+ return context.dragging
28
+ })
29
+
30
+ const clientXSignal = createComputed(() => {
31
+ const context = dndContext.get()
32
+ return context.x
33
+ })
34
+
35
+ const clientYSignal = createComputed(() => {
36
+ const context = dndContext.get()
37
+ return context.y
38
+ })
39
+
40
+ useEffect(host, () => {
41
+ const view = getSafeEditorView(editor.get())
42
+ if (!view) return
43
+
44
+ if (!draggingSignal.get()) return
45
+
46
+ const { draggingIndex, direction } = dndContext.peek()
47
+ const x = clientXSignal.get()
48
+ const y = clientYSignal.get()
49
+
50
+ const relatedDOMs = getDndRelatedDOMs(view, rootContext.peek()?.cellPos, draggingIndex, direction)
51
+ if (!relatedDOMs) return
52
+ const { cell } = relatedDOMs
53
+
54
+ let cancelled = false
55
+
56
+ void computePosition(
57
+ getVirtualElement(cell, x, y),
58
+ host,
59
+ { placement: direction === 'row' ? 'right' : 'bottom' },
60
+ ).then(({ x, y }) => {
61
+ if (cancelled) return
62
+
63
+ if (direction === 'row') {
64
+ assignStyles(host, {
65
+ top: `${y}px`,
66
+ })
67
+ return
68
+ }
69
+
70
+ if (direction === 'col') {
71
+ assignStyles(host, {
72
+ left: `${x}px`,
73
+ })
74
+ return
75
+ }
76
+ })
77
+
78
+ return () => {
79
+ cancelled = true
80
+ }
81
+ })
82
+ }
83
+
84
+ function getVirtualElement(cell: HTMLTableCellElement, x: number, y: number): ReferenceElement {
85
+ return {
86
+ contextElement: cell,
87
+ getBoundingClientRect: () => {
88
+ const rect = cell.getBoundingClientRect()
89
+ return {
90
+ width: rect.width,
91
+ height: rect.height,
92
+ right: x + rect.width / 2,
93
+ bottom: y + rect.height / 2,
94
+ top: y - rect.height / 2,
95
+ left: x - rect.width / 2,
96
+ x: x - rect.width / 2,
97
+ y: y - rect.height / 2,
98
+ }
99
+ },
100
+ }
101
+ }
@@ -0,0 +1,44 @@
1
+ function findDragOverElement(
2
+ elements: Element[],
3
+ pointer: number,
4
+ axis: 'x' | 'y',
5
+ ): [Element, number] | undefined {
6
+ const startProp = axis === 'x' ? 'left' : 'top'
7
+ const endProp = axis === 'x' ? 'right' : 'bottom'
8
+ const lastIndex = elements.length - 1
9
+
10
+ const index = elements.findIndex((el, index) => {
11
+ const rect = el.getBoundingClientRect()
12
+ const boundaryStart = rect[startProp]
13
+ const boundaryEnd = rect[endProp]
14
+
15
+ // The pointer is within the boundary of the current element.
16
+ if (boundaryStart <= pointer && pointer <= boundaryEnd) return true
17
+ // The pointer is beyond the last element.
18
+ if (index === lastIndex && pointer > boundaryEnd) return true
19
+ // The pointer is before the first element.
20
+ if (index === 0 && pointer < boundaryStart) return true
21
+
22
+ return false
23
+ })
24
+
25
+ return index >= 0 ? [elements[index], index] : undefined
26
+ }
27
+
28
+ export function getDragOverColumn(
29
+ table: HTMLTableElement,
30
+ pointerX: number,
31
+ ): [element: Element, index: number] | undefined {
32
+ const firstRow = table.querySelector('tr')
33
+ if (!firstRow) return
34
+ const cells = Array.from(firstRow.children)
35
+ return findDragOverElement(cells, pointerX, 'x')
36
+ }
37
+
38
+ export function getDragOverRow(
39
+ table: HTMLTableElement,
40
+ pointerY: number,
41
+ ): [element: Element, index: number] | undefined {
42
+ const rows = Array.from(table.querySelectorAll('tr'))
43
+ return findDragOverElement(rows, pointerY, 'y')
44
+ }
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useTableHandleDropIndicator } from "./setup"
4
+ import { tableHandleDropIndicatorEvents, tableHandleDropIndicatorProps, type TableHandleDropIndicatorEvents, type TableHandleDropIndicatorProps } from "./types"
5
+
6
+ const TableHandleDropIndicatorElementBase: BaseElementConstructor<TableHandleDropIndicatorProps> = defineCustomElement<
7
+ TableHandleDropIndicatorProps,
8
+ TableHandleDropIndicatorEvents
9
+ >({
10
+ props: tableHandleDropIndicatorProps,
11
+ events: tableHandleDropIndicatorEvents,
12
+ setup: useTableHandleDropIndicator,
13
+ })
14
+ class TableHandleDropIndicatorElement extends TableHandleDropIndicatorElementBase {}
15
+
16
+ registerCustomElement('prosekit-table-handle-drop-indicator', TableHandleDropIndicatorElement)
17
+
18
+ export { TableHandleDropIndicatorElement }
@@ -0,0 +1,56 @@
1
+ import {
2
+ useEffect,
3
+ type ConnectableElement,
4
+ type SignalState,
5
+ } from '@aria-ui/core'
6
+
7
+ import { assignStyles } from '../../../utils/assign-styles'
8
+ import {
9
+ useInitDndPosition,
10
+ type OnInitParams,
11
+ } from '../dnd'
12
+
13
+ import type { TableHandleDropIndicatorProps } from './types'
14
+ import { useUpdateIndicatorPosition } from './updater'
15
+
16
+ const HANDLE_WIDTH = 2
17
+
18
+ /**
19
+ * @internal
20
+ */
21
+ export function useTableHandleDropIndicator(host: ConnectableElement, { state }: { state: SignalState<TableHandleDropIndicatorProps> }): void {
22
+ const { editor } = state
23
+
24
+ useEffect(host, () => {
25
+ assignStyles(host, {
26
+ pointerEvents: 'none',
27
+ position: 'absolute',
28
+ })
29
+ })
30
+
31
+ useInitDndPosition(host, editor, onInitIndicatorPosition)
32
+
33
+ useUpdateIndicatorPosition(host, editor, HANDLE_WIDTH)
34
+ }
35
+
36
+ function onInitIndicatorPosition({ host, direction, dragging, table }: OnInitParams): void {
37
+ assignStyles(host, {
38
+ display: dragging ? 'block' : 'none',
39
+ })
40
+
41
+ const tableRect = table.getBoundingClientRect()
42
+
43
+ if (direction === 'col') {
44
+ assignStyles(host, {
45
+ width: `${HANDLE_WIDTH}px`,
46
+ height: `${tableRect.height}px`,
47
+ })
48
+ }
49
+
50
+ if (direction === 'row') {
51
+ assignStyles(host, {
52
+ width: `${tableRect.width}px`,
53
+ height: `${HANDLE_WIDTH}px`,
54
+ })
55
+ }
56
+ }
@@ -0,0 +1,18 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import type { Editor } from '@prosekit/core'
6
+ import type { TableCommandsExtension } from '@prosekit/extensions/table'
7
+
8
+ export interface TableHandleDropIndicatorProps {
9
+ editor: Editor<TableCommandsExtension> | null
10
+ }
11
+
12
+ export const tableHandleDropIndicatorProps: PropDeclarations<TableHandleDropIndicatorProps> = {
13
+ editor: { default: null },
14
+ }
15
+
16
+ export interface TableHandleDropIndicatorEvents {}
17
+
18
+ export const tableHandleDropIndicatorEvents: EventDeclarations<TableHandleDropIndicatorEvents> = {}
@@ -0,0 +1,110 @@
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 type { Editor } from '@prosekit/core'
12
+
13
+ import { assignStyles } from '../../../utils/assign-styles'
14
+ import { getSafeEditorView } from '../../../utils/get-safe-editor-view'
15
+ import {
16
+ tableHandleDndContext,
17
+ tableHandleRootContext,
18
+ } from '../context'
19
+ import { getDndRelatedDOMs } from '../dnd'
20
+
21
+ import {
22
+ getDragOverColumn,
23
+ getDragOverRow,
24
+ } from './calc-drag-over'
25
+
26
+ export function useUpdateIndicatorPosition(host: ConnectableElement, editor: ReadonlySignal<Editor | null>, handleWidth: number): void {
27
+ const dndContext = tableHandleDndContext.consume(host)
28
+ const rootContext = tableHandleRootContext.consume(host)
29
+
30
+ const draggingSignal = createComputed(() => {
31
+ const context = dndContext.get()
32
+ return context.dragging
33
+ })
34
+
35
+ const clientXSignal = createComputed(() => {
36
+ const context = dndContext.get()
37
+ return context.x
38
+ })
39
+
40
+ const clientYSignal = createComputed(() => {
41
+ const context = dndContext.get()
42
+ return context.y
43
+ })
44
+
45
+ const startXSignal = createComputed(() => {
46
+ return dndContext.get().startX
47
+ })
48
+
49
+ const startYSignal = createComputed(() => {
50
+ return dndContext.get().startY
51
+ })
52
+
53
+ useEffect(host, () => {
54
+ const view = getSafeEditorView(editor.get())
55
+ if (!view) return
56
+
57
+ if (!draggingSignal.get()) return
58
+
59
+ const { draggingIndex, direction } = dndContext.peek()
60
+ const x = clientXSignal.get()
61
+ const y = clientYSignal.get()
62
+
63
+ const relatedDOMs = getDndRelatedDOMs(view, rootContext.peek()?.cellPos, draggingIndex, direction)
64
+ if (!relatedDOMs) return
65
+ const { table } = relatedDOMs
66
+
67
+ let cancelled = false
68
+ let cleanup = () => {
69
+ cancelled = true
70
+ }
71
+
72
+ if (direction === 'col') {
73
+ const direction = startXSignal.get() > x ? 'left' : 'right'
74
+ const dragOverColumn = getDragOverColumn(table, x)
75
+
76
+ if (dragOverColumn) {
77
+ const [col, index] = dragOverColumn
78
+ dndContext.set({ ...dndContext.peek(), droppingIndex: index })
79
+ void computePosition(col, host, {
80
+ placement: direction === 'left' ? 'left' : 'right',
81
+ middleware: [offset(direction === 'left' ? -1 * handleWidth : 0)],
82
+ }).then(({ x }) => {
83
+ if (cancelled) return
84
+ assignStyles(host, { left: `${x}px` })
85
+ })
86
+ }
87
+
88
+ return cleanup
89
+ }
90
+
91
+ if (direction === 'row') {
92
+ const direction = startYSignal.get() > y ? 'up' : 'down'
93
+ const dragOverRow = getDragOverRow(table, y)
94
+
95
+ if (dragOverRow) {
96
+ const [row, index] = dragOverRow
97
+ dndContext.set({ ...dndContext.peek(), droppingIndex: index })
98
+ void computePosition(row, host, {
99
+ placement: direction === 'up' ? 'top' : 'bottom',
100
+ middleware: [offset(direction === 'up' ? -1 * handleWidth : 0)],
101
+ }).then(({ y }) => {
102
+ if (cancelled) return
103
+ assignStyles(host, { top: `${y}px` })
104
+ })
105
+ }
106
+
107
+ return cleanup
108
+ }
109
+ })
110
+ }
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useTableHandlePopoverContent } from "./setup"
4
+ import { tableHandlePopoverContentEvents, tableHandlePopoverContentProps, type TableHandlePopoverContentEvents, type TableHandlePopoverContentProps } from "./types"
5
+
6
+ const TableHandlePopoverContentElementBase: BaseElementConstructor<TableHandlePopoverContentProps> = defineCustomElement<
7
+ TableHandlePopoverContentProps,
8
+ TableHandlePopoverContentEvents
9
+ >({
10
+ props: tableHandlePopoverContentProps,
11
+ events: tableHandlePopoverContentEvents,
12
+ setup: useTableHandlePopoverContent,
13
+ })
14
+ class TableHandlePopoverContentElement extends TableHandlePopoverContentElementBase {}
15
+
16
+ registerCustomElement('prosekit-table-handle-popover-content', TableHandlePopoverContentElement)
17
+
18
+ export { TableHandlePopoverContentElement }
@@ -0,0 +1,90 @@
1
+ import {
2
+ createComputed,
3
+ createSignal,
4
+ useEffect,
5
+ type ConnectableElement,
6
+ type ReadonlySignal,
7
+ type SetupOptions,
8
+ type SignalState,
9
+ type TypedEventTarget,
10
+ } from '@aria-ui/core'
11
+ import {
12
+ menuContentProps,
13
+ useMenuContent,
14
+ type MenuContentProps,
15
+ } from '@aria-ui/menu/elements'
16
+
17
+ import { getStateWithDefaults } from '../../../utils/get-default-state'
18
+ import { tableHandleRootContext } from '../context'
19
+
20
+ import type {
21
+ TableHandlePopoverContentEvents,
22
+ TableHandlePopoverContentProps,
23
+ } from './types'
24
+
25
+ /**
26
+ * @internal
27
+ */
28
+ export function useTableHandlePopoverContent(
29
+ host: ConnectableElement,
30
+ {
31
+ state,
32
+ emit,
33
+ }: SetupOptions<
34
+ TableHandlePopoverContentProps,
35
+ TableHandlePopoverContentEvents
36
+ >,
37
+ ): void {
38
+ const rootContext = tableHandleRootContext.consume(host)
39
+ const open = createComputed(() => !!rootContext.get())
40
+ const keyDownTarget = useKeyDownTarget(host, open)
41
+
42
+ const menuContentState: SignalState<MenuContentProps> = getStateWithDefaults(
43
+ {
44
+ placement: state.placement,
45
+ offset: state.offset,
46
+ eventTarget: createSignal(keyDownTarget),
47
+ },
48
+ menuContentProps,
49
+ )
50
+
51
+ useMenuContent(host, { state: menuContentState, emit })
52
+ }
53
+
54
+ function useKeyDownTarget(
55
+ element: ConnectableElement,
56
+ open: ReadonlySignal<boolean>,
57
+ ): TypedEventTarget<'keydown'> {
58
+ const keydownHandlers: Array<(event: KeyboardEvent) => void> = []
59
+
60
+ useEffect(element, () => {
61
+ const handleKeydown = (event: KeyboardEvent) => {
62
+ if (event.isComposing || event.defaultPrevented || !open.get()) {
63
+ return false
64
+ }
65
+ keydownHandlers.forEach((handler) => handler(event))
66
+ }
67
+
68
+ document.addEventListener('keydown', handleKeydown)
69
+
70
+ return () => {
71
+ document.removeEventListener('keydown', handleKeydown)
72
+ }
73
+ })
74
+
75
+ return {
76
+ addEventListener: (type, listener) => {
77
+ if (type === 'keydown') {
78
+ keydownHandlers.push(listener)
79
+ }
80
+ },
81
+ removeEventListener: (type, listener) => {
82
+ if (type === 'keydown') {
83
+ const index = keydownHandlers.indexOf(listener)
84
+ if (index !== -1) {
85
+ keydownHandlers.splice(index, 1)
86
+ }
87
+ }
88
+ },
89
+ }
90
+ }
@@ -0,0 +1,40 @@
1
+ import type {
2
+ EventDeclarations,
3
+ PropDeclarations,
4
+ } from '@aria-ui/core'
5
+ import {
6
+ menuContentEvents,
7
+ menuContentProps,
8
+ type MenuContentEvents,
9
+ type MenuContentProps,
10
+ } from '@aria-ui/menu/elements'
11
+ import type { Editor } from '@prosekit/core'
12
+
13
+ export interface TableHandlePopoverContentProps extends Omit<MenuContentProps, 'placement' | 'offset'> {
14
+ /**
15
+ * @default 'bottom-start'
16
+ */
17
+ placement: MenuContentProps['placement']
18
+
19
+ /**
20
+ * @default {mainAxis: -4, crossAxis: 4}
21
+ */
22
+ offset: MenuContentProps['offset']
23
+
24
+ editor: Editor | null
25
+ }
26
+
27
+ /** @internal */
28
+ export const tableHandlePopoverContentProps: PropDeclarations<TableHandlePopoverContentProps> = Object.freeze({
29
+ ...menuContentProps,
30
+ placement: { default: 'right-start' },
31
+ offset: { default: { mainAxis: -4, crossAxis: 4 } },
32
+ editor: { default: null },
33
+ })
34
+
35
+ export interface TableHandlePopoverContentEvents extends MenuContentEvents {}
36
+
37
+ /** @internal */
38
+ export const tableHandlePopoverContentEvents: EventDeclarations<TableHandlePopoverContentEvents> = Object.freeze({
39
+ ...menuContentEvents,
40
+ })
@@ -0,0 +1,18 @@
1
+ import { defineCustomElement, registerCustomElement, type BaseElementConstructor } from "@aria-ui/core"
2
+
3
+ import { useTableHandlePopoverItem } from "./setup"
4
+ import { tableHandlePopoverItemEvents, tableHandlePopoverItemProps, type TableHandlePopoverItemEvents, type TableHandlePopoverItemProps } from "./types"
5
+
6
+ const TableHandlePopoverItemElementBase: BaseElementConstructor<TableHandlePopoverItemProps> = defineCustomElement<
7
+ TableHandlePopoverItemProps,
8
+ TableHandlePopoverItemEvents
9
+ >({
10
+ props: tableHandlePopoverItemProps,
11
+ events: tableHandlePopoverItemEvents,
12
+ setup: useTableHandlePopoverItem,
13
+ })
14
+ class TableHandlePopoverItemElement extends TableHandlePopoverItemElementBase {}
15
+
16
+ registerCustomElement('prosekit-table-handle-popover-item', TableHandlePopoverItemElement)
17
+
18
+ export { TableHandlePopoverItemElement }