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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/dist/prosekit-web-autocomplete.d.ts +112 -90
  2. package/dist/prosekit-web-autocomplete.d.ts.map +1 -1
  3. package/dist/prosekit-web-autocomplete.js +292 -217
  4. package/dist/prosekit-web-autocomplete.js.map +1 -1
  5. package/dist/prosekit-web-block-handle.d.ts +95 -62
  6. package/dist/prosekit-web-block-handle.d.ts.map +1 -1
  7. package/dist/prosekit-web-block-handle.js +219 -114
  8. package/dist/prosekit-web-block-handle.js.map +1 -1
  9. package/dist/prosekit-web-drop-indicator.d.ts +13 -15
  10. package/dist/prosekit-web-drop-indicator.d.ts.map +1 -1
  11. package/dist/prosekit-web-drop-indicator.js +34 -30
  12. package/dist/prosekit-web-drop-indicator.js.map +1 -1
  13. package/dist/prosekit-web-inline-popover.d.ts +88 -54
  14. package/dist/prosekit-web-inline-popover.d.ts.map +1 -1
  15. package/dist/prosekit-web-inline-popover.js +129 -79
  16. package/dist/prosekit-web-inline-popover.js.map +1 -1
  17. package/dist/prosekit-web-menu.d.ts +13 -0
  18. package/dist/prosekit-web-menu.d.ts.map +1 -0
  19. package/dist/prosekit-web-menu.js +53 -0
  20. package/dist/prosekit-web-menu.js.map +1 -0
  21. package/dist/prosekit-web-popover.d.ts +7 -26
  22. package/dist/prosekit-web-popover.d.ts.map +1 -1
  23. package/dist/prosekit-web-popover.js +31 -29
  24. package/dist/prosekit-web-popover.js.map +1 -1
  25. package/dist/prosekit-web-resizable.d.ts +92 -51
  26. package/dist/prosekit-web-resizable.d.ts.map +1 -1
  27. package/dist/prosekit-web-resizable.js +139 -131
  28. package/dist/prosekit-web-resizable.js.map +1 -1
  29. package/dist/prosekit-web-table-handle.d.ts +166 -199
  30. package/dist/prosekit-web-table-handle.d.ts.map +1 -1
  31. package/dist/prosekit-web-table-handle.js +495 -496
  32. package/dist/prosekit-web-table-handle.js.map +1 -1
  33. package/dist/prosekit-web-tooltip.d.ts +7 -26
  34. package/dist/prosekit-web-tooltip.d.ts.map +1 -1
  35. package/dist/prosekit-web-tooltip.js +31 -29
  36. package/dist/prosekit-web-tooltip.js.map +1 -1
  37. package/dist/use-editor-extension.js +2 -2
  38. package/dist/use-editor-extension.js.map +1 -1
  39. package/dist/use-scrolling.js +17 -8
  40. package/dist/use-scrolling.js.map +1 -1
  41. package/package.json +28 -23
  42. package/src/components/autocomplete/autocomplete-empty.ts +45 -0
  43. package/src/components/autocomplete/autocomplete-item.ts +65 -0
  44. package/src/components/autocomplete/autocomplete-popup.ts +95 -0
  45. package/src/components/autocomplete/autocomplete-positioner.ts +98 -0
  46. package/src/components/autocomplete/autocomplete-root.ts +280 -0
  47. package/src/components/autocomplete/context.ts +16 -14
  48. package/src/components/autocomplete/index.ts +65 -0
  49. package/src/components/block-handle/block-handle-add.ts +71 -0
  50. package/src/components/block-handle/block-handle-draggable.ts +158 -0
  51. package/src/components/block-handle/block-handle-popup.ts +43 -0
  52. package/src/components/block-handle/block-handle-positioner.ts +89 -0
  53. package/src/components/block-handle/block-handle-root.ts +116 -0
  54. package/src/components/block-handle/context.ts +9 -18
  55. package/src/components/block-handle/hover-state.ts +16 -0
  56. package/src/components/block-handle/index.ts +59 -0
  57. package/src/components/block-handle/{block-handle-popover/pointer-move.ts → pointer-move.ts} +8 -7
  58. package/src/components/block-handle/{block-handle-draggable/set-drag-preview.ts → set-drag-preview.ts} +4 -4
  59. package/src/components/block-handle/use-hover-extension.ts +65 -0
  60. package/src/components/drop-indicator/drop-indicator.ts +128 -0
  61. package/src/components/drop-indicator/index.ts +18 -0
  62. package/src/components/inline-popover/index.ts +41 -0
  63. package/src/components/inline-popover/inline-popover-popup.ts +52 -0
  64. package/src/components/inline-popover/inline-popover-positioner.ts +98 -0
  65. package/src/components/inline-popover/inline-popover-root.ts +122 -0
  66. package/src/components/inline-popover/store.ts +6 -0
  67. package/src/components/menu/index.ts +92 -0
  68. package/src/components/popover/index.ts +53 -0
  69. package/src/components/resizable/{resizable-handle/calc-resize.ts → calc-resize.ts} +1 -1
  70. package/src/components/resizable/context.ts +3 -6
  71. package/src/components/resizable/index.ts +32 -0
  72. package/src/components/resizable/resizable-handle.ts +134 -0
  73. package/src/components/resizable/resizable-root.ts +184 -0
  74. package/src/components/table-handle/dnd.ts +16 -27
  75. package/src/components/table-handle/index.ts +125 -0
  76. package/src/components/table-handle/{table-handle-drag-preview/render-preview.ts → render-preview.ts} +5 -5
  77. package/src/components/table-handle/shared.ts +61 -0
  78. package/src/components/table-handle/store.ts +117 -0
  79. package/src/components/table-handle/table-handle-column-menu-root.ts +51 -0
  80. package/src/components/table-handle/table-handle-column-menu-trigger.ts +107 -0
  81. package/src/components/table-handle/table-handle-column-popup.ts +44 -0
  82. package/src/components/table-handle/table-handle-column-positioner.ts +67 -0
  83. package/src/components/table-handle/table-handle-drag-preview.ts +169 -0
  84. package/src/components/table-handle/table-handle-drop-indicator.ts +166 -0
  85. package/src/components/table-handle/table-handle-root.ts +103 -0
  86. package/src/components/table-handle/table-handle-row-menu-root.ts +51 -0
  87. package/src/components/table-handle/table-handle-row-menu-trigger.ts +107 -0
  88. package/src/components/table-handle/table-handle-row-popup.ts +42 -0
  89. package/src/components/table-handle/table-handle-row-positioner.ts +67 -0
  90. package/src/components/table-handle/use-drop.ts +74 -0
  91. package/src/components/table-handle/{hooks/use-empty-image.ts → use-empty-image.ts} +2 -3
  92. package/src/components/table-handle/utils.ts +0 -11
  93. package/src/components/tooltip/index.ts +52 -0
  94. package/src/hooks/use-editor-extension.ts +4 -4
  95. package/src/hooks/use-editor-focus-event.ts +4 -4
  96. package/src/hooks/use-editor-typing.ts +12 -16
  97. package/src/hooks/use-editor-update-event.ts +4 -4
  98. package/src/hooks/use-keymap.ts +4 -4
  99. package/src/hooks/use-scrolling.ts +11 -10
  100. package/src/hooks/use-selecting.ts +8 -15
  101. package/src/utils/event.ts +28 -0
  102. package/src/utils/lazy-signal.spec.ts +68 -0
  103. package/src/utils/lazy-signal.ts +17 -0
  104. package/src/utils/prefers-reduced-motion.ts +6 -0
  105. package/src/utils/prevent-default.ts +3 -0
  106. package/src/utils/use-html-element-at.ts +17 -0
  107. package/src/utils/use-no-focus.ts +7 -0
  108. package/dist/get-default-state.js +0 -11
  109. package/dist/get-default-state.js.map +0 -1
  110. package/src/components/autocomplete/autocomplete-empty/element.gen.ts +0 -18
  111. package/src/components/autocomplete/autocomplete-empty/setup.ts +0 -6
  112. package/src/components/autocomplete/autocomplete-empty/types.ts +0 -13
  113. package/src/components/autocomplete/autocomplete-item/element.gen.ts +0 -18
  114. package/src/components/autocomplete/autocomplete-item/setup.ts +0 -30
  115. package/src/components/autocomplete/autocomplete-item/types.ts +0 -25
  116. package/src/components/autocomplete/autocomplete-list/element.gen.ts +0 -18
  117. package/src/components/autocomplete/autocomplete-list/setup.ts +0 -125
  118. package/src/components/autocomplete/autocomplete-list/types.ts +0 -22
  119. package/src/components/autocomplete/autocomplete-popover/element.gen.ts +0 -18
  120. package/src/components/autocomplete/autocomplete-popover/setup.ts +0 -169
  121. package/src/components/autocomplete/autocomplete-popover/types.ts +0 -100
  122. package/src/components/autocomplete/index.gen.ts +0 -17
  123. package/src/components/block-handle/block-handle-add/element.gen.ts +0 -18
  124. package/src/components/block-handle/block-handle-add/setup.ts +0 -33
  125. package/src/components/block-handle/block-handle-add/types.ts +0 -23
  126. package/src/components/block-handle/block-handle-draggable/element.gen.ts +0 -18
  127. package/src/components/block-handle/block-handle-draggable/setup.ts +0 -113
  128. package/src/components/block-handle/block-handle-draggable/types.ts +0 -23
  129. package/src/components/block-handle/block-handle-popover/element.gen.ts +0 -18
  130. package/src/components/block-handle/block-handle-popover/setup.ts +0 -68
  131. package/src/components/block-handle/block-handle-popover/types.ts +0 -81
  132. package/src/components/block-handle/index.gen.ts +0 -13
  133. package/src/components/drop-indicator/drop-indicator/element.gen.ts +0 -18
  134. package/src/components/drop-indicator/drop-indicator/setup.ts +0 -75
  135. package/src/components/drop-indicator/drop-indicator/types.ts +0 -31
  136. package/src/components/drop-indicator/index.gen.ts +0 -5
  137. package/src/components/inline-popover/index.gen.ts +0 -5
  138. package/src/components/inline-popover/inline-popover/element.gen.ts +0 -18
  139. package/src/components/inline-popover/inline-popover/setup.ts +0 -111
  140. package/src/components/inline-popover/inline-popover/types.ts +0 -112
  141. package/src/components/popover/index.gen.ts +0 -13
  142. package/src/components/popover/popover-content/element.gen.ts +0 -18
  143. package/src/components/popover/popover-content/setup.ts +0 -1
  144. package/src/components/popover/popover-content/types.ts +0 -6
  145. package/src/components/popover/popover-root/element.gen.ts +0 -18
  146. package/src/components/popover/popover-root/setup.ts +0 -1
  147. package/src/components/popover/popover-root/types.ts +0 -6
  148. package/src/components/popover/popover-trigger/element.gen.ts +0 -18
  149. package/src/components/popover/popover-trigger/setup.ts +0 -1
  150. package/src/components/popover/popover-trigger/types.ts +0 -6
  151. package/src/components/resizable/index.gen.ts +0 -9
  152. package/src/components/resizable/resizable-handle/element.gen.ts +0 -18
  153. package/src/components/resizable/resizable-handle/setup.ts +0 -106
  154. package/src/components/resizable/resizable-handle/types.ts +0 -29
  155. package/src/components/resizable/resizable-root/element.gen.ts +0 -18
  156. package/src/components/resizable/resizable-root/setup.ts +0 -84
  157. package/src/components/resizable/resizable-root/types.ts +0 -59
  158. package/src/components/table-handle/context.ts +0 -43
  159. package/src/components/table-handle/hooks/use-drop.ts +0 -85
  160. package/src/components/table-handle/index.gen.ts +0 -37
  161. package/src/components/table-handle/table-handle-column-root/element.gen.ts +0 -18
  162. package/src/components/table-handle/table-handle-column-root/setup.ts +0 -60
  163. package/src/components/table-handle/table-handle-column-root/types.ts +0 -73
  164. package/src/components/table-handle/table-handle-column-trigger/element.gen.ts +0 -18
  165. package/src/components/table-handle/table-handle-column-trigger/setup.ts +0 -64
  166. package/src/components/table-handle/table-handle-column-trigger/types.ts +0 -20
  167. package/src/components/table-handle/table-handle-drag-preview/element.gen.ts +0 -18
  168. package/src/components/table-handle/table-handle-drag-preview/setup.ts +0 -57
  169. package/src/components/table-handle/table-handle-drag-preview/types.ts +0 -14
  170. package/src/components/table-handle/table-handle-drag-preview/updater.ts +0 -90
  171. package/src/components/table-handle/table-handle-drop-indicator/element.gen.ts +0 -18
  172. package/src/components/table-handle/table-handle-drop-indicator/setup.ts +0 -52
  173. package/src/components/table-handle/table-handle-drop-indicator/types.ts +0 -15
  174. package/src/components/table-handle/table-handle-drop-indicator/updater.ts +0 -96
  175. package/src/components/table-handle/table-handle-popover-content/element.gen.ts +0 -18
  176. package/src/components/table-handle/table-handle-popover-content/setup.ts +0 -83
  177. package/src/components/table-handle/table-handle-popover-content/types.ts +0 -32
  178. package/src/components/table-handle/table-handle-popover-item/element.gen.ts +0 -18
  179. package/src/components/table-handle/table-handle-popover-item/setup.ts +0 -17
  180. package/src/components/table-handle/table-handle-popover-item/types.ts +0 -16
  181. package/src/components/table-handle/table-handle-root/element.gen.ts +0 -18
  182. package/src/components/table-handle/table-handle-root/setup.ts +0 -86
  183. package/src/components/table-handle/table-handle-root/types.ts +0 -23
  184. package/src/components/table-handle/table-handle-row-root/element.gen.ts +0 -18
  185. package/src/components/table-handle/table-handle-row-root/setup.ts +0 -70
  186. package/src/components/table-handle/table-handle-row-root/types.ts +0 -68
  187. package/src/components/table-handle/table-handle-row-trigger/element.gen.ts +0 -18
  188. package/src/components/table-handle/table-handle-row-trigger/setup.ts +0 -63
  189. package/src/components/table-handle/table-handle-row-trigger/types.ts +0 -23
  190. package/src/components/tooltip/index.gen.ts +0 -13
  191. package/src/components/tooltip/tooltip-content/element.gen.ts +0 -18
  192. package/src/components/tooltip/tooltip-content/setup.ts +0 -1
  193. package/src/components/tooltip/tooltip-content/types.ts +0 -6
  194. package/src/components/tooltip/tooltip-root/element.gen.ts +0 -18
  195. package/src/components/tooltip/tooltip-root/setup.ts +0 -1
  196. package/src/components/tooltip/tooltip-root/types.ts +0 -6
  197. package/src/components/tooltip/tooltip-trigger/element.gen.ts +0 -18
  198. package/src/components/tooltip/tooltip-trigger/setup.ts +0 -1
  199. package/src/components/tooltip/tooltip-trigger/types.ts +0 -6
  200. package/src/hooks/use-first-rendering.ts +0 -15
  201. package/src/utils/get-default-state.spec.ts +0 -42
  202. package/src/utils/get-default-state.ts +0 -18
  203. /package/src/components/autocomplete/{autocomplete-popover/helpers.spec.ts → helpers.spec.ts} +0 -0
  204. /package/src/components/autocomplete/{autocomplete-popover/helpers.ts → helpers.ts} +0 -0
  205. /package/src/components/inline-popover/{inline-popover/virtual-selection-element.ts → virtual-selection-element.ts} +0 -0
  206. /package/src/components/resizable/{resizable-handle/calc-resize.spec.ts → calc-resize.spec.ts} +0 -0
  207. /package/src/components/table-handle/{table-handle-drop-indicator/calc-drag-over.ts → calc-drag-over.ts} +0 -0
@@ -0,0 +1,61 @@
1
+ import { defineProps, type PropsDeclaration } from '@aria-ui/core'
2
+ import { OverlayPositionerPropsDeclaration, type OverlayPositionerProps } from '@aria-ui/elements/overlay'
3
+ import type { Editor } from '@prosekit/core'
4
+
5
+ /**
6
+ * @internal
7
+ */
8
+ export interface SharedTableHandlePositionerProps extends Omit<OverlayPositionerProps, 'hoist' | 'flip' | 'shift' | 'hide' | 'offset'> {
9
+ /**
10
+ * The ProseKit editor instance.
11
+ *
12
+ * @default null
13
+ * @hidden
14
+ */
15
+ editor: Editor | null
16
+
17
+ /**
18
+ * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
19
+ * to place the floating element on top of other page content.
20
+ *
21
+ * @default false
22
+ */
23
+ hoist: OverlayPositionerProps['hoist']
24
+
25
+ /**
26
+ * @default false
27
+ * @hidden
28
+ */
29
+ flip: OverlayPositionerProps['flip']
30
+
31
+ /**
32
+ * @default false
33
+ * @hidden
34
+ */
35
+ shift: OverlayPositionerProps['shift']
36
+
37
+ /**
38
+ * @default true
39
+ * @hidden
40
+ */
41
+ hide: OverlayPositionerProps['hide']
42
+
43
+ /**
44
+ * @default 0
45
+ * @hidden
46
+ */
47
+ offset: OverlayPositionerProps['offset']
48
+ }
49
+
50
+ /** @internal */
51
+ export const SharedTableHandlePositionerPropsDeclaration: PropsDeclaration<SharedTableHandlePositionerProps> = defineProps<
52
+ SharedTableHandlePositionerProps
53
+ >({
54
+ ...OverlayPositionerPropsDeclaration,
55
+ editor: { default: null, attribute: false, type: 'json' },
56
+ hoist: { default: false, attribute: false, type: 'boolean' },
57
+ flip: { default: false, attribute: false, type: 'json' },
58
+ shift: { default: false, attribute: false, type: 'boolean' },
59
+ hide: { default: true, attribute: false, type: 'boolean' },
60
+ offset: { default: 0, attribute: false, type: 'json' },
61
+ })
@@ -0,0 +1,117 @@
1
+ import { computed, createContext, createSignal, type Context, type Signal } from '@aria-ui/core'
2
+ import type { OpenChangeEvent } from '@aria-ui/elements/overlay'
3
+ import { createOverlayStore, type OverlayStore } from '@aria-ui/elements/overlay'
4
+
5
+ import type { HoveringCellInfo } from './utils.ts'
6
+
7
+ function noop(): void {}
8
+ function returnTrue(): boolean {
9
+ return true
10
+ }
11
+ function returnFalse(): boolean {
12
+ return false
13
+ }
14
+
15
+ class DndStore {
16
+ readonly dragging: Signal<boolean> = createSignal(false)
17
+ readonly direction: Signal<'row' | 'col'> = createSignal<'row' | 'col'>('row')
18
+ readonly draggingIndex: Signal<number> = createSignal(-1)
19
+ readonly droppingIndex: Signal<number> = createSignal(-1)
20
+ readonly x: Signal<number> = createSignal(-1)
21
+ readonly y: Signal<number> = createSignal(-1)
22
+ readonly startX: Signal<number> = createSignal(-1)
23
+ readonly startY: Signal<number> = createSignal(-1)
24
+ }
25
+
26
+ /**
27
+ * @internal
28
+ */
29
+ export interface TableHandleStore {
30
+ readonly dndStore: DndStore
31
+ readonly setIsColumnMenuOpen: (open: boolean) => void
32
+ readonly setIsRowMenuOpen: (open: boolean) => void
33
+ readonly columnOverlayStore: OverlayStore
34
+ readonly rowOverlayStore: OverlayStore
35
+ readonly getReferenceCell: () => HoveringCellInfo | undefined
36
+ }
37
+
38
+ /**
39
+ * @internal
40
+ */
41
+ export function createTableHandleStore(
42
+ getHoveringCellInfo: () => HoveringCellInfo | undefined,
43
+ getCanShow: () => boolean,
44
+ ): TableHandleStore {
45
+ const isColumnMenuOpen = createSignal(false)
46
+ const isRowMenuOpen = createSignal(false)
47
+
48
+ const getHasMenuOpen = (): boolean => {
49
+ return isColumnMenuOpen.get() || isRowMenuOpen.get()
50
+ }
51
+
52
+ const setIsRowMenuOpen = (open: boolean): void => {
53
+ isRowMenuOpen.set(open)
54
+ }
55
+
56
+ const setIsColumnMenuOpen = (open: boolean): void => {
57
+ isColumnMenuOpen.set(open)
58
+ }
59
+
60
+ const referenceCellInfo = createSignal<HoveringCellInfo | undefined>(undefined)
61
+
62
+ let prevHoveringCellInfo: HoveringCellInfo | undefined = undefined
63
+
64
+ const getReferenceCell = computed((): HoveringCellInfo | undefined => {
65
+ if (!getCanShow()) {
66
+ referenceCellInfo.set(undefined)
67
+ return
68
+ }
69
+
70
+ // Do not toggle/update the menu when hovering another cell if the menu is already open
71
+ if (getHasMenuOpen()) {
72
+ return prevHoveringCellInfo
73
+ }
74
+
75
+ prevHoveringCellInfo = getHoveringCellInfo()
76
+ return prevHoveringCellInfo
77
+ })
78
+
79
+ const getOpen = computed((): boolean => {
80
+ return !!getReferenceCell()
81
+ })
82
+
83
+ const handleOpenChange = (event: OpenChangeEvent) => {
84
+ if (getHasMenuOpen()) {
85
+ event.preventDefault()
86
+ }
87
+ }
88
+
89
+ const columnOverlayStore = createOverlayStore(
90
+ getOpen,
91
+ noop,
92
+ returnTrue,
93
+ returnFalse,
94
+ handleOpenChange,
95
+ )
96
+ const rowOverlayStore = createOverlayStore(
97
+ getOpen,
98
+ noop,
99
+ returnTrue,
100
+ returnFalse,
101
+ handleOpenChange,
102
+ )
103
+
104
+ return {
105
+ dndStore: new DndStore(),
106
+ setIsRowMenuOpen,
107
+ setIsColumnMenuOpen,
108
+ columnOverlayStore,
109
+ rowOverlayStore,
110
+ getReferenceCell,
111
+ }
112
+ }
113
+
114
+ /**
115
+ * @internal
116
+ */
117
+ export const tableHandleStoreContext: Context<TableHandleStore> = createContext<TableHandleStore>('prosekit-table-handle-store')
@@ -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 TableHandleColumnMenuRootProps extends MenuRootProps {}
16
+
17
+ /** @internal */
18
+ export const TableHandleColumnMenuRootPropsDeclaration: PropsDeclaration<TableHandleColumnMenuRootProps> = defineProps<
19
+ TableHandleColumnMenuRootProps
20
+ >(MenuRootPropsDeclaration)
21
+
22
+ /** @internal */
23
+ export function setupTableHandleColumnMenuRoot(
24
+ host: HostElement,
25
+ props: State<TableHandleColumnMenuRootProps>,
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.setIsColumnMenuOpen(open)
35
+ })
36
+ }
37
+
38
+ const TableHandleColumnMenuRootElementBase: HostElementConstructor<TableHandleColumnMenuRootProps> = defineCustomElement(
39
+ setupTableHandleColumnMenuRoot,
40
+ TableHandleColumnMenuRootPropsDeclaration,
41
+ )
42
+
43
+ /**
44
+ * @public
45
+ */
46
+ export class TableHandleColumnMenuRootElement extends TableHandleColumnMenuRootElementBase {}
47
+
48
+ /** @internal */
49
+ export function registerTableHandleColumnMenuRootElement(): void {
50
+ registerCustomElement('prosekit-table-handle-column-menu-root', TableHandleColumnMenuRootElement)
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 { selectTableColumn, 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 TableHandleColumnMenuTriggerProps {
23
+ /**
24
+ * @default null
25
+ * @hidden
26
+ */
27
+ editor: Editor<TableCommandsExtension> | null
28
+ }
29
+
30
+ /** @internal */
31
+ export const TableHandleColumnMenuTriggerPropsDeclaration: PropsDeclaration<TableHandleColumnMenuTriggerProps> = defineProps<
32
+ TableHandleColumnMenuTriggerProps
33
+ >({
34
+ editor: { default: null, attribute: false, type: 'json' },
35
+ })
36
+
37
+ /** @internal */
38
+ export function setupTableHandleColumnMenuTrigger(
39
+ host: HostElement,
40
+ props: State<TableHandleColumnMenuTriggerProps>,
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(selectTableColumn({ 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
+ dataTransfer.setData('application/x-prosekit-table-handle-drag', '')
72
+ }
73
+ const store = getStore()
74
+ if (!store) return
75
+ const index = store.getReferenceCell()?.colIndex
76
+
77
+ if (index == null || index < 0) {
78
+ console.warn('[prosekit] Invalid column index for drag operation:', index)
79
+ event.preventDefault()
80
+ return
81
+ }
82
+
83
+ const dndStore = store.dndStore
84
+ dndStore.direction.set('col')
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 TableHandleColumnMenuTriggerElementBase: HostElementConstructor<TableHandleColumnMenuTriggerProps> = defineCustomElement(
93
+ setupTableHandleColumnMenuTrigger,
94
+ TableHandleColumnMenuTriggerPropsDeclaration,
95
+ )
96
+
97
+ /**
98
+ * @public
99
+ */
100
+ export class TableHandleColumnMenuTriggerElement extends TableHandleColumnMenuTriggerElementBase {}
101
+
102
+ /**
103
+ * @internal
104
+ */
105
+ export function registerTableHandleColumnMenuTriggerElement(): void {
106
+ registerCustomElement('prosekit-table-handle-column-menu-trigger', TableHandleColumnMenuTriggerElement)
107
+ }
@@ -0,0 +1,44 @@
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 TableHandleColumnPopupProps {}
15
+
16
+ /** @internal */
17
+ export const TableHandleColumnPopupPropsDeclaration: PropsDeclaration<TableHandleColumnPopupProps> = defineProps<
18
+ TableHandleColumnPopupProps
19
+ >({})
20
+
21
+ /** @internal */
22
+ export function setupTableHandleColumnPopup(
23
+ host: HostElement,
24
+ _props: State<TableHandleColumnPopupProps>,
25
+ ): void {
26
+ const getStore = tableHandleStoreContext.consume(host)
27
+ const getOverlayStore = () => getStore()?.columnOverlayStore
28
+ setupOverlayPopup(host, getOverlayStore)
29
+ }
30
+
31
+ const TableHandleColumnPopupElementBase: HostElementConstructor<TableHandleColumnPopupProps> = defineCustomElement(
32
+ setupTableHandleColumnPopup,
33
+ TableHandleColumnPopupPropsDeclaration,
34
+ )
35
+
36
+ /**
37
+ * @public
38
+ */
39
+ export class TableHandleColumnPopupElement extends TableHandleColumnPopupElementBase {}
40
+
41
+ /** @internal */
42
+ export function registerTableHandleColumnPopupElement(): void {
43
+ registerCustomElement('prosekit-table-handle-column-popup', TableHandleColumnPopupElement)
44
+ }
@@ -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 TableHandleColumnPositionerProps extends Omit<SharedTableHandlePositionerProps, 'placement'> {
21
+ /**
22
+ * The placement of the popover, relative to the hovered table cell.
23
+ *
24
+ * @default "top"
25
+ */
26
+ placement: Placement
27
+ }
28
+
29
+ /** @internal */
30
+ export const TableHandleColumnPositionerPropsDeclaration: PropsDeclaration<TableHandleColumnPositionerProps> = defineProps<
31
+ TableHandleColumnPositionerProps
32
+ >({
33
+ ...SharedTableHandlePositionerPropsDeclaration,
34
+ placement: { default: 'top', attribute: 'placement', type: 'string' },
35
+ })
36
+
37
+ /** @internal */
38
+ export function setupTableHandleColumnPositioner(
39
+ host: HostElement,
40
+ props: State<TableHandleColumnPositionerProps>,
41
+ ): void {
42
+ const getStore = tableHandleStoreContext.consume(host)
43
+ const getOverlayStore = () => getStore()?.columnOverlayStore
44
+ setupOverlayPositioner(host, props, getOverlayStore)
45
+
46
+ const getEditor = props.editor.get
47
+ const getColumnFirstCellPos = computed(() => getStore()?.getReferenceCell()?.colFirstCellPos)
48
+ const getReferenceCell = useHTMLElementAt(getEditor, getColumnFirstCellPos)
49
+ useEffect(host, () => {
50
+ getOverlayStore()?.setAnchorElement(getReferenceCell())
51
+ })
52
+ }
53
+
54
+ const TableHandleColumnPositionerElementBase: HostElementConstructor<TableHandleColumnPositionerProps> = defineCustomElement(
55
+ setupTableHandleColumnPositioner,
56
+ TableHandleColumnPositionerPropsDeclaration,
57
+ )
58
+
59
+ /**
60
+ * @public
61
+ */
62
+ export class TableHandleColumnPositionerElement extends TableHandleColumnPositionerElementBase {}
63
+
64
+ /** @internal */
65
+ export function registerTableHandleColumnPositionerElement(): void {
66
+ registerCustomElement('prosekit-table-handle-column-positioner', TableHandleColumnPositionerElement)
67
+ }
@@ -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
+ }