@meta-1/editor 0.0.29 → 1.0.0

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 (502) hide show
  1. package/package.json +52 -67
  2. package/src/components/notion-like/notion-like-editor-toolbar-floating.tsx +181 -0
  3. package/src/components/tiptap-extension/list-normalization-extension.ts +112 -0
  4. package/src/components/tiptap-extension/node-alignment-extension.ts +285 -0
  5. package/src/components/tiptap-extension/node-background-extension.ts +150 -0
  6. package/src/components/tiptap-extension/ui-state-extension.ts +97 -0
  7. package/src/components/tiptap-icons/add-col-left-icon.tsx +30 -0
  8. package/src/components/tiptap-icons/add-col-right-icon.tsx +30 -0
  9. package/src/components/tiptap-icons/add-row-bottom-icon.tsx +30 -0
  10. package/src/components/tiptap-icons/add-row-top-icon.tsx +30 -0
  11. package/src/components/tiptap-icons/ai-sparkles-icon.tsx +32 -0
  12. package/src/components/tiptap-icons/align-bottom-icon.tsx +28 -0
  13. package/src/components/tiptap-icons/align-center-icon.tsx +38 -0
  14. package/src/components/tiptap-icons/align-center-vertical-icon.tsx +34 -0
  15. package/src/components/tiptap-icons/align-end-vertical-icon.tsx +34 -0
  16. package/src/components/tiptap-icons/align-justify-icon.tsx +38 -0
  17. package/src/components/tiptap-icons/align-left-icon.tsx +38 -0
  18. package/src/components/tiptap-icons/align-middle-icon.tsx +55 -0
  19. package/src/components/tiptap-icons/align-right-icon.tsx +38 -0
  20. package/src/components/tiptap-icons/align-start-vertical-icon.tsx +32 -0
  21. package/src/components/tiptap-icons/align-top-icon.tsx +28 -0
  22. package/src/components/tiptap-icons/alignment-icon.tsx +72 -0
  23. package/src/components/tiptap-icons/arrow-down-a-z-icon.tsx +34 -0
  24. package/src/components/tiptap-icons/arrow-down-icon.tsx +24 -0
  25. package/src/components/tiptap-icons/arrow-down-to-line-icon.tsx +28 -0
  26. package/src/components/tiptap-icons/arrow-down-z-a-icon.tsx +34 -0
  27. package/src/components/tiptap-icons/arrow-left-icon.tsx +24 -0
  28. package/src/components/tiptap-icons/arrow-right-icon.tsx +26 -0
  29. package/src/components/tiptap-icons/arrow-up-icon.tsx +26 -0
  30. package/src/components/tiptap-icons/at-sign-icon.tsx +26 -0
  31. package/src/components/tiptap-icons/ban-icon.tsx +26 -0
  32. package/src/components/tiptap-icons/blockquote-icon.tsx +44 -0
  33. package/src/components/tiptap-icons/bold-icon.tsx +26 -0
  34. package/src/components/tiptap-icons/check-ai-icon.tsx +32 -0
  35. package/src/components/tiptap-icons/check-icon.tsx +26 -0
  36. package/src/components/tiptap-icons/chevron-down-icon.tsx +26 -0
  37. package/src/components/tiptap-icons/chevron-right-icon.tsx +26 -0
  38. package/src/components/tiptap-icons/clipboard-icon.tsx +24 -0
  39. package/src/components/tiptap-icons/close-icon.tsx +24 -0
  40. package/src/components/tiptap-icons/code-block-icon.tsx +38 -0
  41. package/src/components/tiptap-icons/code2-icon.tsx +32 -0
  42. package/src/components/tiptap-icons/complete-sentence-icon.tsx +44 -0
  43. package/src/components/tiptap-icons/copy-icon.tsx +32 -0
  44. package/src/components/tiptap-icons/corner-down-left-icon.tsx +26 -0
  45. package/src/components/tiptap-icons/external-link-icon.tsx +28 -0
  46. package/src/components/tiptap-icons/grip-4-icon.tsx +24 -0
  47. package/src/components/tiptap-icons/grip-vertical-icon.tsx +44 -0
  48. package/src/components/tiptap-icons/heading-five-icon.tsx +28 -0
  49. package/src/components/tiptap-icons/heading-four-icon.tsx +28 -0
  50. package/src/components/tiptap-icons/heading-one-icon.tsx +28 -0
  51. package/src/components/tiptap-icons/heading-six-icon.tsx +30 -0
  52. package/src/components/tiptap-icons/heading-three-icon.tsx +36 -0
  53. package/src/components/tiptap-icons/heading-two-icon.tsx +28 -0
  54. package/src/components/tiptap-icons/highlighter-icon.tsx +26 -0
  55. package/src/components/tiptap-icons/image-caption-icon.tsx +38 -0
  56. package/src/components/tiptap-icons/image-icon.tsx +26 -0
  57. package/src/components/tiptap-icons/image-plus-icon.tsx +26 -0
  58. package/src/components/tiptap-icons/italic-icon.tsx +24 -0
  59. package/src/components/tiptap-icons/languages-icon.tsx +34 -0
  60. package/src/components/tiptap-icons/link-icon.tsx +28 -0
  61. package/src/components/tiptap-icons/list-icon.tsx +56 -0
  62. package/src/components/tiptap-icons/list-ordered-icon.tsx +56 -0
  63. package/src/components/tiptap-icons/list-todo-icon.tsx +50 -0
  64. package/src/components/tiptap-icons/message-square-icon.tsx +26 -0
  65. package/src/components/tiptap-icons/message-square-plus-icon.tsx +32 -0
  66. package/src/components/tiptap-icons/mic-ai-icon.tsx +34 -0
  67. package/src/components/tiptap-icons/minus-icon.tsx +26 -0
  68. package/src/components/tiptap-icons/moon-star-icon.tsx +30 -0
  69. package/src/components/tiptap-icons/more-vertical-icon.tsx +38 -0
  70. package/src/components/tiptap-icons/move-horizontal-icon.tsx +24 -0
  71. package/src/components/tiptap-icons/paint-bucket-icon.tsx +32 -0
  72. package/src/components/tiptap-icons/plus-icon.tsx +24 -0
  73. package/src/components/tiptap-icons/plus-small-icon.tsx +24 -0
  74. package/src/components/tiptap-icons/redo2-icon.tsx +26 -0
  75. package/src/components/tiptap-icons/refresh-ai-icon.tsx +34 -0
  76. package/src/components/tiptap-icons/refresh-ccw-icon.tsx +28 -0
  77. package/src/components/tiptap-icons/repeat-2-icon.tsx +26 -0
  78. package/src/components/tiptap-icons/rotate-ccw-icon.tsx +24 -0
  79. package/src/components/tiptap-icons/simplify-2-icon.tsx +24 -0
  80. package/src/components/tiptap-icons/smile-ai-icon.tsx +38 -0
  81. package/src/components/tiptap-icons/smile-plus-icon.tsx +26 -0
  82. package/src/components/tiptap-icons/square-x-icon.tsx +26 -0
  83. package/src/components/tiptap-icons/stop-circle-2-icon.tsx +26 -0
  84. package/src/components/tiptap-icons/strike-icon.tsx +28 -0
  85. package/src/components/tiptap-icons/subscript-icon.tsx +38 -0
  86. package/src/components/tiptap-icons/summarize-text-icon.tsx +36 -0
  87. package/src/components/tiptap-icons/sun-icon.tsx +58 -0
  88. package/src/components/tiptap-icons/superscript-icon.tsx +38 -0
  89. package/src/components/tiptap-icons/table-cell-merge-icon.tsx +44 -0
  90. package/src/components/tiptap-icons/table-cell-split-icon.tsx +44 -0
  91. package/src/components/tiptap-icons/table-column-icon.tsx +26 -0
  92. package/src/components/tiptap-icons/table-header-column-icon.tsx +28 -0
  93. package/src/components/tiptap-icons/table-header-row-icon.tsx +26 -0
  94. package/src/components/tiptap-icons/table-icon.tsx +26 -0
  95. package/src/components/tiptap-icons/table-row-icon.tsx +26 -0
  96. package/src/components/tiptap-icons/text-color-small-icon.tsx +26 -0
  97. package/src/components/tiptap-icons/text-extend-icon.tsx +36 -0
  98. package/src/components/tiptap-icons/text-reduce-icon.tsx +32 -0
  99. package/src/components/tiptap-icons/trash-icon.tsx +26 -0
  100. package/src/components/tiptap-icons/type-icon.tsx +24 -0
  101. package/src/components/tiptap-icons/underline-icon.tsx +26 -0
  102. package/src/components/tiptap-icons/undo2-icon.tsx +26 -0
  103. package/src/components/tiptap-icons/x-icon.tsx +24 -0
  104. package/src/components/tiptap-node/blockquote-node/blockquote-node.css +18 -0
  105. package/src/components/tiptap-node/code-block-node/code-block-node.css +24 -0
  106. package/src/components/tiptap-node/heading-node/heading-node.css +33 -0
  107. package/src/components/tiptap-node/horizontal-rule-node/horizontal-rule-node-extension.ts +11 -0
  108. package/src/components/tiptap-node/horizontal-rule-node/horizontal-rule-node.css +12 -0
  109. package/src/components/tiptap-node/image-node/image-node-extension.ts +169 -0
  110. package/src/components/tiptap-node/image-node/image-node-floating.tsx +41 -0
  111. package/src/components/tiptap-node/image-node/image-node-view.css +60 -0
  112. package/src/components/tiptap-node/image-node/image-node-view.tsx +316 -0
  113. package/src/components/tiptap-node/image-node/image-node.css +28 -0
  114. package/src/components/tiptap-node/image-upload-node/image-upload-node-extension.ts +155 -0
  115. package/src/components/tiptap-node/image-upload-node/image-upload-node.css +141 -0
  116. package/src/components/tiptap-node/image-upload-node/image-upload-node.tsx +513 -0
  117. package/src/components/tiptap-node/image-upload-node/index.tsx +1 -0
  118. package/src/components/tiptap-node/list-node/list-node.css +127 -0
  119. package/src/components/tiptap-node/paragraph-node/paragraph-node.css +198 -0
  120. package/src/components/tiptap-node/table-node/extensions/table-handle/helpers/create-image.ts +273 -0
  121. package/src/components/tiptap-node/table-node/extensions/table-handle/index.ts +2 -0
  122. package/src/components/tiptap-node/table-node/extensions/table-handle/table-handle-plugin.ts +718 -0
  123. package/src/components/tiptap-node/table-node/extensions/table-handle/table-handle.ts +48 -0
  124. package/src/components/tiptap-node/table-node/extensions/table-node-extension.ts +226 -0
  125. package/src/components/tiptap-node/table-node/hooks/use-table-handle-state.ts +66 -0
  126. package/src/components/tiptap-node/table-node/lib/tiptap-table-utils.ts +1289 -0
  127. package/src/components/tiptap-node/table-node/styles/prosemirror-table.css +35 -0
  128. package/src/components/tiptap-node/table-node/styles/table-node.css +158 -0
  129. package/src/components/tiptap-node/table-node/ui/table-add-row-column-button/index.tsx +2 -0
  130. package/src/components/tiptap-node/table-node/ui/table-add-row-column-button/table-add-row-column-button.tsx +94 -0
  131. package/src/components/tiptap-node/table-node/ui/table-add-row-column-button/use-table-add-row-column.ts +325 -0
  132. package/src/components/tiptap-node/table-node/ui/table-align-cell-button/index.tsx +2 -0
  133. package/src/components/tiptap-node/table-node/ui/table-align-cell-button/table-align-cell-button.tsx +129 -0
  134. package/src/components/tiptap-node/table-node/ui/table-align-cell-button/use-table-align-cell.ts +528 -0
  135. package/src/components/tiptap-node/table-node/ui/table-alignment-menu/index.tsx +1 -0
  136. package/src/components/tiptap-node/table-node/ui/table-alignment-menu/table-alignment-menu.tsx +154 -0
  137. package/src/components/tiptap-node/table-node/ui/table-cell-handle-menu/index.tsx +1 -0
  138. package/src/components/tiptap-node/table-node/ui/table-cell-handle-menu/table-cell-handle-menu.css +62 -0
  139. package/src/components/tiptap-node/table-node/ui/table-cell-handle-menu/table-cell-handle-menu.tsx +212 -0
  140. package/src/components/tiptap-node/table-node/ui/table-clear-row-column-content-button/index.tsx +2 -0
  141. package/src/components/tiptap-node/table-node/ui/table-clear-row-column-content-button/table-clear-row-column-content-button.tsx +101 -0
  142. package/src/components/tiptap-node/table-node/ui/table-clear-row-column-content-button/use-table-clear-row-column-content.ts +423 -0
  143. package/src/components/tiptap-node/table-node/ui/table-delete-row-column-button/index.tsx +2 -0
  144. package/src/components/tiptap-node/table-node/ui/table-delete-row-column-button/table-delete-row-column-button.tsx +100 -0
  145. package/src/components/tiptap-node/table-node/ui/table-delete-row-column-button/use-table-delete-row-column.ts +243 -0
  146. package/src/components/tiptap-node/table-node/ui/table-duplicate-row-column-button/index.tsx +2 -0
  147. package/src/components/tiptap-node/table-node/ui/table-duplicate-row-column-button/table-duplicate-row-column-button.tsx +92 -0
  148. package/src/components/tiptap-node/table-node/ui/table-duplicate-row-column-button/use-table-duplicate-row-column.ts +357 -0
  149. package/src/components/tiptap-node/table-node/ui/table-extend-row-column-button/index.tsx +2 -0
  150. package/src/components/tiptap-node/table-node/ui/table-extend-row-column-button/table-extend-row-column-button.css +17 -0
  151. package/src/components/tiptap-node/table-node/ui/table-extend-row-column-button/table-extend-row-column-button.tsx +240 -0
  152. package/src/components/tiptap-node/table-node/ui/table-extend-row-column-button/use-table-extend-row-column.ts +118 -0
  153. package/src/components/tiptap-node/table-node/ui/table-fit-to-width-button/index.tsx +2 -0
  154. package/src/components/tiptap-node/table-node/ui/table-fit-to-width-button/table-fit-to-width-button.tsx +98 -0
  155. package/src/components/tiptap-node/table-node/ui/table-fit-to-width-button/use-table-fit-to-width.ts +223 -0
  156. package/src/components/tiptap-node/table-node/ui/table-handle/index.tsx +2 -0
  157. package/src/components/tiptap-node/table-node/ui/table-handle/table-handle.tsx +163 -0
  158. package/src/components/tiptap-node/table-node/ui/table-handle/use-table-handle-positioning.ts +255 -0
  159. package/src/components/tiptap-node/table-node/ui/table-handle-menu/index.tsx +1 -0
  160. package/src/components/tiptap-node/table-node/ui/table-handle-menu/table-handle-menu.css +39 -0
  161. package/src/components/tiptap-node/table-node/ui/table-handle-menu/table-handle-menu.tsx +681 -0
  162. package/src/components/tiptap-node/table-node/ui/table-header-row-column-button/index.tsx +2 -0
  163. package/src/components/tiptap-node/table-node/ui/table-header-row-column-button/table-header-row-column-button.tsx +99 -0
  164. package/src/components/tiptap-node/table-node/ui/table-header-row-column-button/use-table-header-row-column.ts +227 -0
  165. package/src/components/tiptap-node/table-node/ui/table-merge-split-cell-button/index.tsx +2 -0
  166. package/src/components/tiptap-node/table-node/ui/table-merge-split-cell-button/table-merge-split-cell-button.tsx +125 -0
  167. package/src/components/tiptap-node/table-node/ui/table-merge-split-cell-button/use-table-merge-split-cell.ts +267 -0
  168. package/src/components/tiptap-node/table-node/ui/table-move-row-column-button/index.tsx +2 -0
  169. package/src/components/tiptap-node/table-node/ui/table-move-row-column-button/table-move-row-column-button.tsx +123 -0
  170. package/src/components/tiptap-node/table-node/ui/table-move-row-column-button/use-table-move-row-column.ts +431 -0
  171. package/src/components/tiptap-node/table-node/ui/table-selection-overlay/index.tsx +1 -0
  172. package/src/components/tiptap-node/table-node/ui/table-selection-overlay/table-selection-overlay.tsx +483 -0
  173. package/src/components/tiptap-node/table-node/ui/table-selection-overlay/use-resize-overlay.ts +78 -0
  174. package/src/components/tiptap-node/table-node/ui/table-sort-row-column-button/index.tsx +2 -0
  175. package/src/components/tiptap-node/table-node/ui/table-sort-row-column-button/table-sort-row-column-button.tsx +100 -0
  176. package/src/components/tiptap-node/table-node/ui/table-sort-row-column-button/use-table-sort-row-column.ts +444 -0
  177. package/src/components/tiptap-node/table-node/ui/table-trigger-button/index.tsx +3 -0
  178. package/src/components/tiptap-node/table-node/ui/table-trigger-button/table-grid-selector.css +39 -0
  179. package/src/components/tiptap-node/table-node/ui/table-trigger-button/table-grid-selector.tsx +219 -0
  180. package/src/components/tiptap-node/table-node/ui/table-trigger-button/table-trigger-button.tsx +132 -0
  181. package/src/components/tiptap-node/table-node/ui/table-trigger-button/use-table-trigger.ts +166 -0
  182. package/src/components/tiptap-ui/blockquote-button/blockquote-button.tsx +125 -0
  183. package/src/components/tiptap-ui/blockquote-button/index.tsx +2 -0
  184. package/src/components/tiptap-ui/blockquote-button/use-blockquote.ts +246 -0
  185. package/src/components/tiptap-ui/code-block-button/code-block-button.tsx +100 -0
  186. package/src/components/tiptap-ui/code-block-button/index.tsx +2 -0
  187. package/src/components/tiptap-ui/code-block-button/use-code-block.ts +256 -0
  188. package/src/components/tiptap-ui/color-highlight-button/color-highlight-button.css +32 -0
  189. package/src/components/tiptap-ui/color-highlight-button/color-highlight-button.tsx +171 -0
  190. package/src/components/tiptap-ui/color-highlight-button/index.tsx +2 -0
  191. package/src/components/tiptap-ui/color-highlight-button/use-color-highlight.ts +296 -0
  192. package/src/components/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx +211 -0
  193. package/src/components/tiptap-ui/color-highlight-popover/index.tsx +1 -0
  194. package/src/components/tiptap-ui/color-menu/color-menu.tsx +178 -0
  195. package/src/components/tiptap-ui/color-menu/index.tsx +1 -0
  196. package/src/components/tiptap-ui/color-text-button/color-text-button.css +31 -0
  197. package/src/components/tiptap-ui/color-text-button/color-text-button.tsx +150 -0
  198. package/src/components/tiptap-ui/color-text-button/index.tsx +2 -0
  199. package/src/components/tiptap-ui/color-text-button/use-color-text.ts +251 -0
  200. package/src/components/tiptap-ui/color-text-popover/color-text-popover.css +25 -0
  201. package/src/components/tiptap-ui/color-text-popover/color-text-popover.tsx +360 -0
  202. package/src/components/tiptap-ui/color-text-popover/index.tsx +2 -0
  203. package/src/components/tiptap-ui/color-text-popover/use-color-text-popover.ts +229 -0
  204. package/src/components/tiptap-ui/copy-anchor-link-button/copy-anchor-link-button.tsx +118 -0
  205. package/src/components/tiptap-ui/copy-anchor-link-button/index.tsx +3 -0
  206. package/src/components/tiptap-ui/copy-anchor-link-button/use-copy-anchor-link.ts +252 -0
  207. package/src/components/tiptap-ui/copy-anchor-link-button/use-scroll-to-hash.ts +128 -0
  208. package/src/components/tiptap-ui/copy-to-clipboard-button/copy-to-clipboard-button.tsx +116 -0
  209. package/src/components/tiptap-ui/copy-to-clipboard-button/index.tsx +2 -0
  210. package/src/components/tiptap-ui/copy-to-clipboard-button/use-copy-to-clipboard.ts +234 -0
  211. package/src/components/tiptap-ui/delete-node-button/delete-node-button.tsx +98 -0
  212. package/src/components/tiptap-ui/delete-node-button/index.tsx +2 -0
  213. package/src/components/tiptap-ui/delete-node-button/use-delete-node.ts +236 -0
  214. package/src/components/tiptap-ui/drag-context-menu/drag-context-menu-types.ts +28 -0
  215. package/src/components/tiptap-ui/drag-context-menu/drag-context-menu.css +17 -0
  216. package/src/components/tiptap-ui/drag-context-menu/drag-context-menu.tsx +413 -0
  217. package/src/components/tiptap-ui/drag-context-menu/index.tsx +2 -0
  218. package/src/components/tiptap-ui/duplicate-button/duplicate-button.tsx +114 -0
  219. package/src/components/tiptap-ui/duplicate-button/index.tsx +2 -0
  220. package/src/components/tiptap-ui/duplicate-button/use-duplicate.ts +208 -0
  221. package/src/components/tiptap-ui/emoji-dropdown-menu/emoji-dropdown-menu.tsx +103 -0
  222. package/src/components/tiptap-ui/emoji-dropdown-menu/index.tsx +1 -0
  223. package/src/components/tiptap-ui/emoji-menu/emoji-menu-utils.ts +36 -0
  224. package/src/components/tiptap-ui/emoji-menu/emoji-menu.css +30 -0
  225. package/src/components/tiptap-ui/emoji-menu/emoji-menu.tsx +142 -0
  226. package/src/components/tiptap-ui/emoji-menu/index.tsx +2 -0
  227. package/src/components/tiptap-ui/emoji-trigger-button/emoji-trigger-button.tsx +128 -0
  228. package/src/components/tiptap-ui/emoji-trigger-button/index.tsx +2 -0
  229. package/src/components/tiptap-ui/emoji-trigger-button/use-emoji-trigger.ts +315 -0
  230. package/src/components/tiptap-ui/heading-button/heading-button.tsx +127 -0
  231. package/src/components/tiptap-ui/heading-button/index.tsx +2 -0
  232. package/src/components/tiptap-ui/heading-button/use-heading.ts +321 -0
  233. package/src/components/tiptap-ui/image-align-button/image-align-button.tsx +114 -0
  234. package/src/components/tiptap-ui/image-align-button/index.tsx +2 -0
  235. package/src/components/tiptap-ui/image-align-button/use-image-align.ts +295 -0
  236. package/src/components/tiptap-ui/image-caption-button/image-caption-button.tsx +77 -0
  237. package/src/components/tiptap-ui/image-caption-button/index.tsx +2 -0
  238. package/src/components/tiptap-ui/image-caption-button/use-image-caption.ts +212 -0
  239. package/src/components/tiptap-ui/image-download-button/image-download-button.tsx +104 -0
  240. package/src/components/tiptap-ui/image-download-button/index.tsx +2 -0
  241. package/src/components/tiptap-ui/image-download-button/use-image-download.ts +364 -0
  242. package/src/components/tiptap-ui/image-upload-button/image-upload-button.tsx +133 -0
  243. package/src/components/tiptap-ui/image-upload-button/index.tsx +2 -0
  244. package/src/components/tiptap-ui/image-upload-button/use-image-upload.ts +192 -0
  245. package/src/components/tiptap-ui/link-popover/index.tsx +2 -0
  246. package/src/components/tiptap-ui/link-popover/link-popover.tsx +271 -0
  247. package/src/components/tiptap-ui/link-popover/use-link-popover.ts +286 -0
  248. package/src/components/tiptap-ui/list-button/index.tsx +2 -0
  249. package/src/components/tiptap-ui/list-button/list-button.tsx +123 -0
  250. package/src/components/tiptap-ui/list-button/use-list.ts +326 -0
  251. package/src/components/tiptap-ui/mark-button/index.tsx +2 -0
  252. package/src/components/tiptap-ui/mark-button/mark-button.tsx +110 -0
  253. package/src/components/tiptap-ui/mark-button/use-mark.ts +195 -0
  254. package/src/components/tiptap-ui/mention-dropdown-menu/index.tsx +1 -0
  255. package/src/components/tiptap-ui/mention-dropdown-menu/mention-dropdown-menu.tsx +212 -0
  256. package/src/components/tiptap-ui/mention-trigger-button/index.tsx +2 -0
  257. package/src/components/tiptap-ui/mention-trigger-button/mention-trigger-button.tsx +122 -0
  258. package/src/components/tiptap-ui/mention-trigger-button/use-mention-trigger.ts +339 -0
  259. package/src/components/tiptap-ui/move-node-button/index.tsx +2 -0
  260. package/src/components/tiptap-ui/move-node-button/move-node-button.tsx +120 -0
  261. package/src/components/tiptap-ui/move-node-button/use-move-node.ts +207 -0
  262. package/src/components/tiptap-ui/reset-all-formatting-button/index.tsx +2 -0
  263. package/src/components/tiptap-ui/reset-all-formatting-button/reset-all-formatting-button.tsx +126 -0
  264. package/src/components/tiptap-ui/reset-all-formatting-button/use-reset-all-formatting.ts +250 -0
  265. package/src/components/tiptap-ui/slash-command-trigger-button/index.tsx +2 -0
  266. package/src/components/tiptap-ui/slash-command-trigger-button/slash-command-trigger-button.tsx +128 -0
  267. package/src/components/tiptap-ui/slash-command-trigger-button/use-slash-command-trigger.ts +255 -0
  268. package/src/components/tiptap-ui/slash-dropdown-menu/index.tsx +2 -0
  269. package/src/components/tiptap-ui/slash-dropdown-menu/slash-dropdown-menu.css +33 -0
  270. package/src/components/tiptap-ui/slash-dropdown-menu/slash-dropdown-menu.tsx +159 -0
  271. package/src/components/tiptap-ui/slash-dropdown-menu/use-slash-dropdown-menu.ts +317 -0
  272. package/src/components/tiptap-ui/text-align-button/index.tsx +2 -0
  273. package/src/components/tiptap-ui/text-align-button/text-align-button.tsx +120 -0
  274. package/src/components/tiptap-ui/text-align-button/use-text-align.ts +224 -0
  275. package/src/components/tiptap-ui/text-button/index.tsx +2 -0
  276. package/src/components/tiptap-ui/text-button/text-button.tsx +117 -0
  277. package/src/components/tiptap-ui/text-button/use-text.ts +264 -0
  278. package/src/components/tiptap-ui/turn-into-dropdown/index.tsx +2 -0
  279. package/src/components/tiptap-ui/turn-into-dropdown/turn-into-dropdown.tsx +192 -0
  280. package/src/components/tiptap-ui/turn-into-dropdown/use-turn-into-dropdown.ts +260 -0
  281. package/src/components/tiptap-ui/undo-redo-button/index.tsx +2 -0
  282. package/src/components/tiptap-ui/undo-redo-button/undo-redo-button.tsx +126 -0
  283. package/src/components/tiptap-ui/undo-redo-button/use-undo-redo.ts +184 -0
  284. package/src/components/tiptap-ui-primitive/avatar/avatar.css +83 -0
  285. package/src/components/tiptap-ui-primitive/avatar/avatar.tsx +239 -0
  286. package/src/components/tiptap-ui-primitive/avatar/index.tsx +1 -0
  287. package/src/components/tiptap-ui-primitive/badge/badge-colors.css +358 -0
  288. package/src/components/tiptap-ui-primitive/badge/badge-group.css +18 -0
  289. package/src/components/tiptap-ui-primitive/badge/badge.css +93 -0
  290. package/src/components/tiptap-ui-primitive/badge/badge.tsx +46 -0
  291. package/src/components/tiptap-ui-primitive/badge/index.tsx +1 -0
  292. package/src/components/tiptap-ui-primitive/button/button-colors.css +6 -0
  293. package/src/components/tiptap-ui-primitive/button/button-group.css +17 -0
  294. package/src/components/tiptap-ui-primitive/button/button.css +428 -0
  295. package/src/components/tiptap-ui-primitive/button/button.tsx +116 -0
  296. package/src/components/tiptap-ui-primitive/button/index.tsx +1 -0
  297. package/src/components/tiptap-ui-primitive/card/card.css +42 -0
  298. package/src/components/tiptap-ui-primitive/card/card.tsx +79 -0
  299. package/src/components/tiptap-ui-primitive/card/index.tsx +1 -0
  300. package/src/components/tiptap-ui-primitive/combobox/combobox.css +15 -0
  301. package/src/components/tiptap-ui-primitive/combobox/combobox.tsx +73 -0
  302. package/src/components/tiptap-ui-primitive/combobox/index.tsx +1 -0
  303. package/src/components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.css +49 -0
  304. package/src/components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.tsx +98 -0
  305. package/src/components/tiptap-ui-primitive/dropdown-menu/index.tsx +1 -0
  306. package/src/components/tiptap-ui-primitive/input/index.tsx +1 -0
  307. package/src/components/tiptap-ui-primitive/input/input.css +26 -0
  308. package/src/components/tiptap-ui-primitive/input/input.tsx +24 -0
  309. package/src/components/tiptap-ui-primitive/label/index.tsx +1 -0
  310. package/src/components/tiptap-ui-primitive/label/label.css +9 -0
  311. package/src/components/tiptap-ui-primitive/label/label.tsx +42 -0
  312. package/src/components/tiptap-ui-primitive/menu/index.tsx +5 -0
  313. package/src/components/tiptap-ui-primitive/menu/menu-context.ts +19 -0
  314. package/src/components/tiptap-ui-primitive/menu/menu-hooks.ts +102 -0
  315. package/src/components/tiptap-ui-primitive/menu/menu-types.ts +56 -0
  316. package/src/components/tiptap-ui-primitive/menu/menu-utils.ts +64 -0
  317. package/src/components/tiptap-ui-primitive/menu/menu.css +49 -0
  318. package/src/components/tiptap-ui-primitive/menu/menu.tsx +235 -0
  319. package/src/components/tiptap-ui-primitive/popover/index.tsx +1 -0
  320. package/src/components/tiptap-ui-primitive/popover/popover.css +49 -0
  321. package/src/components/tiptap-ui-primitive/popover/popover.tsx +37 -0
  322. package/src/components/tiptap-ui-primitive/separator/index.tsx +1 -0
  323. package/src/components/tiptap-ui-primitive/separator/separator.css +19 -0
  324. package/src/components/tiptap-ui-primitive/separator/separator.tsx +33 -0
  325. package/src/components/tiptap-ui-primitive/sidebar/index.tsx +1 -0
  326. package/src/components/tiptap-ui-primitive/sidebar/sidebar.css +140 -0
  327. package/src/components/tiptap-ui-primitive/sidebar/sidebar.tsx +299 -0
  328. package/src/components/tiptap-ui-primitive/spacer/index.tsx +1 -0
  329. package/src/components/tiptap-ui-primitive/spacer/spacer.tsx +26 -0
  330. package/src/components/tiptap-ui-primitive/textarea-autosize/index.tsx +1 -0
  331. package/src/components/tiptap-ui-primitive/textarea-autosize/textarea-autosize.tsx +18 -0
  332. package/src/components/tiptap-ui-primitive/toolbar/index.tsx +1 -0
  333. package/src/components/tiptap-ui-primitive/toolbar/toolbar.css +65 -0
  334. package/src/components/tiptap-ui-primitive/toolbar/toolbar.tsx +123 -0
  335. package/src/components/tiptap-ui-primitive/tooltip/index.tsx +1 -0
  336. package/src/components/tiptap-ui-primitive/tooltip/tooltip.css +21 -0
  337. package/src/components/tiptap-ui-primitive/tooltip/tooltip.tsx +237 -0
  338. package/src/components/tiptap-ui-utils/floating-element/floating-element-utils.ts +23 -0
  339. package/src/components/tiptap-ui-utils/floating-element/floating-element.tsx +343 -0
  340. package/src/components/tiptap-ui-utils/floating-element/index.tsx +2 -0
  341. package/src/components/tiptap-ui-utils/suggestion-menu/index.tsx +3 -0
  342. package/src/components/tiptap-ui-utils/suggestion-menu/suggestion-menu-types.ts +91 -0
  343. package/src/components/tiptap-ui-utils/suggestion-menu/suggestion-menu-utils.ts +87 -0
  344. package/src/components/tiptap-ui-utils/suggestion-menu/suggestion-menu.tsx +240 -0
  345. package/src/content/index.tsx +27 -0
  346. package/src/content/style.css +12 -0
  347. package/src/contexts/ai-context.tsx +65 -0
  348. package/src/contexts/app-context.tsx +159 -0
  349. package/src/contexts/user-context.tsx +138 -0
  350. package/src/editor/collaboration/index.tsx +64 -0
  351. package/src/editor/index.tsx +144 -42
  352. package/src/hooks/use-composed-ref.ts +47 -0
  353. package/src/hooks/use-cursor-visibility.ts +69 -0
  354. package/src/hooks/use-editor.ts +237 -0
  355. package/src/hooks/use-element-rect.ts +165 -0
  356. package/src/hooks/use-floating-element.ts +101 -0
  357. package/src/hooks/use-floating-toolbar-visibility.ts +123 -0
  358. package/src/hooks/use-is-breakpoint.ts +37 -0
  359. package/src/hooks/use-isomorphic-layout-effect.ts +11 -0
  360. package/src/hooks/use-menu-navigation.ts +182 -0
  361. package/src/hooks/use-on-click-outside.ts +135 -0
  362. package/src/hooks/use-scrolling.ts +75 -0
  363. package/src/hooks/use-throttled-callback.ts +48 -0
  364. package/src/hooks/use-tiptap-editor.ts +49 -0
  365. package/src/hooks/use-ui-editor-state.ts +29 -0
  366. package/src/hooks/use-unmount.ts +21 -0
  367. package/src/hooks/use-window-size.ts +88 -0
  368. package/src/index.ts +4 -7
  369. package/src/lib/tiptap-advanced-utils.ts +362 -0
  370. package/src/lib/tiptap-collab-utils.ts +289 -0
  371. package/src/lib/tiptap-utils.ts +612 -0
  372. package/src/locales/en.json +123 -0
  373. package/src/locales/zh-CN.json +123 -0
  374. package/src/locales/zh-TW.json +123 -0
  375. package/src/styles/variables.css +92 -0
  376. package/README.md +0 -458
  377. package/src/editor/constants.tsx +0 -66
  378. package/src/editor/container.css +0 -46
  379. package/src/editor/control/character-count/index.tsx +0 -39
  380. package/src/editor/control/drag-handle/index.tsx +0 -85
  381. package/src/editor/control/drag-handle/use.content.actions.ts +0 -71
  382. package/src/editor/control/drag-handle/use.data.ts +0 -29
  383. package/src/editor/control/drag-handle/use.handle.id.ts +0 -6
  384. package/src/editor/control/index.tsx +0 -35
  385. package/src/editor/editor.css +0 -626
  386. package/src/editor/extension/block-quote-figure/BlockquoteFigure.ts +0 -73
  387. package/src/editor/extension/block-quote-figure/Quote/Quote.ts +0 -31
  388. package/src/editor/extension/block-quote-figure/Quote/index.ts +0 -1
  389. package/src/editor/extension/block-quote-figure/QuoteCaption/QuoteCaption.ts +0 -54
  390. package/src/editor/extension/block-quote-figure/QuoteCaption/index.ts +0 -1
  391. package/src/editor/extension/block-quote-figure/index.ts +0 -1
  392. package/src/editor/extension/document/index.ts +0 -5
  393. package/src/editor/extension/figcaption/Figcaption.ts +0 -90
  394. package/src/editor/extension/figcaption/index.ts +0 -1
  395. package/src/editor/extension/figure/Figure.ts +0 -62
  396. package/src/editor/extension/figure/index.ts +0 -1
  397. package/src/editor/extension/font-size/FontSize.ts +0 -64
  398. package/src/editor/extension/font-size/index.ts +0 -1
  399. package/src/editor/extension/global-drag-handle/clipboard-serializer.ts +0 -28
  400. package/src/editor/extension/global-drag-handle/index.ts +0 -377
  401. package/src/editor/extension/heading/index.ts +0 -13
  402. package/src/editor/extension/horizontal-rule/HorizontalRule.ts +0 -10
  403. package/src/editor/extension/horizontal-rule/index.ts +0 -1
  404. package/src/editor/extension/image/index.ts +0 -5
  405. package/src/editor/extension/image-block/ImageBlock.ts +0 -103
  406. package/src/editor/extension/image-block/components/ImageBlockMenu.tsx +0 -100
  407. package/src/editor/extension/image-block/components/ImageBlockView.tsx +0 -47
  408. package/src/editor/extension/image-block/components/ImageBlockWidth.tsx +0 -40
  409. package/src/editor/extension/image-block/index.ts +0 -1
  410. package/src/editor/extension/image-upload/ImageUpload.ts +0 -58
  411. package/src/editor/extension/image-upload/index.ts +0 -1
  412. package/src/editor/extension/image-upload/view/ImageUpload.tsx +0 -27
  413. package/src/editor/extension/image-upload/view/ImageUploader.tsx +0 -64
  414. package/src/editor/extension/image-upload/view/hooks.ts +0 -109
  415. package/src/editor/extension/image-upload/view/index.tsx +0 -1
  416. package/src/editor/extension/index.ts +0 -30
  417. package/src/editor/extension/link/Link.ts +0 -39
  418. package/src/editor/extension/link/index.ts +0 -1
  419. package/src/editor/extension/multi-column/Column.ts +0 -33
  420. package/src/editor/extension/multi-column/Columns.ts +0 -65
  421. package/src/editor/extension/multi-column/index.ts +0 -2
  422. package/src/editor/extension/multi-column/menus/ColumnsMenu.tsx +0 -82
  423. package/src/editor/extension/multi-column/menus/index.ts +0 -1
  424. package/src/editor/extension/selection/Selection.ts +0 -36
  425. package/src/editor/extension/selection/index.ts +0 -1
  426. package/src/editor/extension/slash-command/MenuList.tsx +0 -145
  427. package/src/editor/extension/slash-command/groups.ts +0 -153
  428. package/src/editor/extension/slash-command/index.ts +0 -277
  429. package/src/editor/extension/slash-command/types.ts +0 -25
  430. package/src/editor/extension/table/Cell.ts +0 -126
  431. package/src/editor/extension/table/Header.ts +0 -89
  432. package/src/editor/extension/table/Row.ts +0 -8
  433. package/src/editor/extension/table/Table.ts +0 -9
  434. package/src/editor/extension/table/index.ts +0 -4
  435. package/src/editor/extension/table/menus/TableColumn/index.tsx +0 -73
  436. package/src/editor/extension/table/menus/TableColumn/utils.ts +0 -38
  437. package/src/editor/extension/table/menus/TableRow/index.tsx +0 -74
  438. package/src/editor/extension/table/menus/TableRow/utils.ts +0 -38
  439. package/src/editor/extension/table/menus/index.tsx +0 -2
  440. package/src/editor/extension/table/utils.ts +0 -258
  441. package/src/editor/extension/task-item/index.ts +0 -1
  442. package/src/editor/extension/task-item/task-item.ts +0 -225
  443. package/src/editor/extension/task-list/index.ts +0 -1
  444. package/src/editor/extension/task-list/task-list.ts +0 -81
  445. package/src/editor/extension/trailing-node/index.ts +0 -1
  446. package/src/editor/extension/trailing-node/trailing-node.ts +0 -70
  447. package/src/editor/extension/unique-id/index.ts +0 -1
  448. package/src/editor/extension/unique-id/uniqueId.ts +0 -123
  449. package/src/editor/hooks.ts +0 -264
  450. package/src/editor/menus/LinkMenu/LinkMenu.tsx +0 -75
  451. package/src/editor/menus/LinkMenu/index.tsx +0 -1
  452. package/src/editor/menus/TextMenu/TextMenu.tsx +0 -193
  453. package/src/editor/menus/TextMenu/components/AIDropdown.tsx +0 -140
  454. package/src/editor/menus/TextMenu/components/ContentTypePicker.tsx +0 -76
  455. package/src/editor/menus/TextMenu/components/EditLinkPopover.tsx +0 -25
  456. package/src/editor/menus/TextMenu/components/FontFamilyPicker.tsx +0 -84
  457. package/src/editor/menus/TextMenu/components/FontSizePicker.tsx +0 -56
  458. package/src/editor/menus/TextMenu/hooks/useTextmenuCommands.ts +0 -96
  459. package/src/editor/menus/TextMenu/hooks/useTextmenuContentTypes.ts +0 -86
  460. package/src/editor/menus/TextMenu/hooks/useTextmenuStates.ts +0 -50
  461. package/src/editor/menus/TextMenu/index.tsx +0 -2
  462. package/src/editor/menus/types.ts +0 -21
  463. package/src/editor/panels/Colorpicker/ColorButton.tsx +0 -35
  464. package/src/editor/panels/Colorpicker/Colorpicker.tsx +0 -67
  465. package/src/editor/panels/Colorpicker/index.tsx +0 -2
  466. package/src/editor/panels/LinkEditorPanel/LinkEditorPanel.tsx +0 -76
  467. package/src/editor/panels/LinkEditorPanel/index.tsx +0 -1
  468. package/src/editor/panels/LinkPreviewPanel/LinkPreviewPanel.tsx +0 -32
  469. package/src/editor/panels/LinkPreviewPanel/index.tsx +0 -1
  470. package/src/editor/panels/index.tsx +0 -3
  471. package/src/editor/types.tsx +0 -38
  472. package/src/editor/ui/Button/Button.tsx +0 -70
  473. package/src/editor/ui/Button/index.tsx +0 -2
  474. package/src/editor/ui/Dropdown/Dropdown.tsx +0 -39
  475. package/src/editor/ui/Dropdown/index.tsx +0 -1
  476. package/src/editor/ui/Icon.tsx +0 -21
  477. package/src/editor/ui/Loader/Loader.tsx +0 -39
  478. package/src/editor/ui/Loader/index.ts +0 -1
  479. package/src/editor/ui/Loader/types.ts +0 -7
  480. package/src/editor/ui/Panel/index.tsx +0 -109
  481. package/src/editor/ui/PopoverMenu.tsx +0 -127
  482. package/src/editor/ui/Spinner/Spinner.tsx +0 -10
  483. package/src/editor/ui/Spinner/index.tsx +0 -1
  484. package/src/editor/ui/Surface.tsx +0 -27
  485. package/src/editor/ui/Textarea/Textarea.tsx +0 -20
  486. package/src/editor/ui/Textarea/index.tsx +0 -1
  487. package/src/editor/ui/Toggle/Toggle.tsx +0 -39
  488. package/src/editor/ui/Toggle/index.tsx +0 -1
  489. package/src/editor/ui/Toolbar.tsx +0 -107
  490. package/src/editor/ui/Tooltip/index.tsx +0 -77
  491. package/src/editor/ui/Tooltip/types.ts +0 -17
  492. package/src/editor/utils/cssVar.ts +0 -14
  493. package/src/editor/utils/getRenderContainer.ts +0 -39
  494. package/src/editor/utils/index.ts +0 -16
  495. package/src/editor/utils/isCustomNodeSelected.ts +0 -47
  496. package/src/editor/utils/isTextSelected.ts +0 -25
  497. package/src/editor/utils/locale.ts +0 -5
  498. package/src/editor/viewer/index.tsx +0 -26
  499. package/src/globals.css +0 -1
  500. package/src/locales/en-us.ts +0 -133
  501. package/src/locales/zh-cn.ts +0 -133
  502. package/src/locales/zh-tw.ts +0 -133
@@ -0,0 +1,718 @@
1
+ import type { Editor } from "@tiptap/core";
2
+ import type { Node as TiptapNode } from "@tiptap/pm/model";
3
+ import type { PluginView, Transaction } from "@tiptap/pm/state";
4
+ import { Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
5
+ import { CellSelection, moveTableColumn, moveTableRow, TableMap } from "@tiptap/pm/tables";
6
+ import { Decoration, DecorationSet, type EditorView } from "@tiptap/pm/view";
7
+
8
+ import { isValidPosition } from "../../../../../lib/tiptap-utils";
9
+ import {
10
+ clamp,
11
+ domCellAround,
12
+ getCellIndicesFromDOM,
13
+ getColumnCells,
14
+ getIndexCoordinates,
15
+ getRowCells,
16
+ getTableFromDOM,
17
+ isHTMLElement,
18
+ isTableNode,
19
+ safeClosest,
20
+ selectCellsByCoords,
21
+ } from "../../lib/tiptap-table-utils";
22
+ import { createTableDragImage } from "./helpers/create-image";
23
+
24
+ export type TableHandlesState = {
25
+ show: boolean;
26
+ showAddOrRemoveRowsButton: boolean;
27
+ showAddOrRemoveColumnsButton: boolean;
28
+ referencePosCell?: DOMRect;
29
+ referencePosTable: DOMRect;
30
+ block: TiptapNode;
31
+ blockPos: number;
32
+ colIndex: number | undefined;
33
+ rowIndex: number | undefined;
34
+ draggingState?:
35
+ | {
36
+ draggedCellOrientation: "row" | "col";
37
+ originalIndex: number;
38
+ mousePos: number;
39
+ initialOffset: number;
40
+ }
41
+ | undefined;
42
+ widgetContainer: HTMLElement | undefined;
43
+ };
44
+
45
+ function hideElements(selector: string, rootEl: Document | ShadowRoot) {
46
+ rootEl.querySelectorAll<HTMLElement>(selector).forEach((el) => {
47
+ el.style.visibility = "hidden";
48
+ });
49
+ }
50
+
51
+ export const tableHandlePluginKey = new PluginKey("tableHandlePlugin");
52
+
53
+ class TableHandleView implements PluginView {
54
+ public editor: Editor;
55
+ public editorView: EditorView;
56
+
57
+ public state: TableHandlesState | undefined = undefined;
58
+ public menuFrozen = false;
59
+ public mouseState: "up" | "down" | "selecting" = "up";
60
+ public tableId: string | undefined;
61
+ public tablePos: number | undefined;
62
+ public tableElement: HTMLElement | undefined;
63
+
64
+ public emitUpdate: () => void;
65
+
66
+ constructor(editor: Editor, editorView: EditorView, emitUpdate: (state: TableHandlesState) => void) {
67
+ this.editor = editor;
68
+ this.editorView = editorView;
69
+ this.emitUpdate = () => this.state && emitUpdate(this.state);
70
+
71
+ this.editorView.dom.addEventListener("mousemove", this.mouseMoveHandler);
72
+ this.editorView.dom.addEventListener("mousedown", this.viewMousedownHandler);
73
+ window.addEventListener("mouseup", this.mouseUpHandler);
74
+
75
+ this.editorView.root.addEventListener("dragover", this.dragOverHandler as EventListener);
76
+ this.editorView.root.addEventListener("drop", this.dropHandler as unknown as EventListener);
77
+ }
78
+
79
+ private viewMousedownHandler = (event: MouseEvent) => {
80
+ this.mouseState = "down";
81
+
82
+ const { state, view } = this.editor;
83
+ if (!(state.selection instanceof CellSelection) || this.editor.isFocused) return;
84
+
85
+ const posInfo = view.posAtCoords({
86
+ left: event.clientX,
87
+ top: event.clientY,
88
+ });
89
+ if (!posInfo) return;
90
+
91
+ const $pos = state.doc.resolve(posInfo.pos);
92
+ const { nodes } = state.schema;
93
+ let paraDepth = -1;
94
+ let inTableCell = false;
95
+
96
+ for (let d = $pos.depth; d >= 0; d--) {
97
+ const node = $pos.node(d);
98
+ if (!inTableCell && (node.type === nodes.tableCell || node.type === nodes.tableHeader)) {
99
+ inTableCell = true;
100
+ }
101
+ if (paraDepth === -1 && node.type === nodes.paragraph) {
102
+ paraDepth = d;
103
+ }
104
+ if (inTableCell && paraDepth !== -1) break;
105
+ }
106
+
107
+ if (!inTableCell || paraDepth === -1) return;
108
+
109
+ const from = $pos.start(paraDepth);
110
+ const to = $pos.end(paraDepth);
111
+ const nextSel = TextSelection.create(state.doc, from, to);
112
+ if (state.selection.eq(nextSel)) return;
113
+
114
+ view.dispatch(state.tr.setSelection(nextSel));
115
+ view.focus();
116
+ };
117
+
118
+ private mouseUpHandler = (event: MouseEvent) => {
119
+ this.mouseState = "up";
120
+ this.mouseMoveHandler(event);
121
+ };
122
+
123
+ private mouseMoveHandler = (event: MouseEvent) => {
124
+ if (this.menuFrozen || this.mouseState === "selecting") return;
125
+
126
+ const target = event.target;
127
+ if (!isHTMLElement(target) || !this.editorView.dom.contains(target)) return;
128
+
129
+ this._handleMouseMoveNow(event);
130
+ };
131
+
132
+ private hideHandles() {
133
+ if (!this.state?.show) return;
134
+
135
+ this.state = {
136
+ ...this.state,
137
+ show: false,
138
+ showAddOrRemoveRowsButton: false,
139
+ showAddOrRemoveColumnsButton: false,
140
+ colIndex: undefined,
141
+ rowIndex: undefined,
142
+ referencePosCell: undefined,
143
+ };
144
+ this.emitUpdate();
145
+ }
146
+
147
+ private _handleMouseMoveNow(event: MouseEvent) {
148
+ const around = domCellAround(event.target as Element);
149
+
150
+ // Hide handles while selecting inside a cell
151
+ if (around?.type === "cell" && this.mouseState === "down" && !this.state?.draggingState) {
152
+ this.mouseState = "selecting";
153
+ this.hideHandles();
154
+ return;
155
+ }
156
+
157
+ if (!around || !this.editor.isEditable) {
158
+ this.hideHandles();
159
+ return;
160
+ }
161
+
162
+ const tbody = around.tbodyNode;
163
+ if (!tbody) return;
164
+
165
+ const tableRect = tbody.getBoundingClientRect();
166
+ const coords = this.editor.view.posAtCoords({
167
+ left: event.clientX,
168
+ top: event.clientY,
169
+ });
170
+ if (!coords) return;
171
+
172
+ // Find the table node at this position
173
+ const $pos = this.editor.view.state.doc.resolve(coords.pos);
174
+ let blockInfo: { node: TiptapNode; pos: number } | undefined;
175
+ for (let d = $pos.depth; d >= 0; d--) {
176
+ const node = $pos.node(d);
177
+ if (isTableNode(node)) {
178
+ blockInfo = { node, pos: d === 0 ? 0 : $pos.before(d) };
179
+ break;
180
+ }
181
+ }
182
+ if (!blockInfo || blockInfo.node.type.name !== "table") return;
183
+
184
+ this.tableElement = this.editor.view.nodeDOM(blockInfo.pos) as HTMLElement | undefined;
185
+ this.tablePos = blockInfo.pos;
186
+ this.tableId = blockInfo.node.attrs.id;
187
+
188
+ const wrapper = safeClosest<HTMLElement>(around.domNode, ".tableWrapper");
189
+ const widgetContainer = wrapper?.querySelector(".table-controls") as HTMLElement | undefined;
190
+
191
+ // Hovering around the table (outside cells)
192
+ if (around.type === "wrapper") {
193
+ const below = event.clientY >= tableRect.bottom - 1 && event.clientY < tableRect.bottom + 20;
194
+ const right = event.clientX >= tableRect.right - 1 && event.clientX < tableRect.right + 20;
195
+ const cursorBeyondRightOrBottom = event.clientX > tableRect.right || event.clientY > tableRect.bottom;
196
+
197
+ this.state = {
198
+ ...this.state,
199
+ show: true,
200
+ showAddOrRemoveRowsButton: below,
201
+ showAddOrRemoveColumnsButton: right,
202
+ referencePosTable: tableRect,
203
+ block: blockInfo.node,
204
+ blockPos: blockInfo.pos,
205
+ widgetContainer,
206
+ colIndex: cursorBeyondRightOrBottom ? undefined : this.state?.colIndex,
207
+ rowIndex: cursorBeyondRightOrBottom ? undefined : this.state?.rowIndex,
208
+ referencePosCell: cursorBeyondRightOrBottom ? undefined : this.state?.referencePosCell,
209
+ };
210
+ } else {
211
+ // Hovering over a cell
212
+ const cellPosition = getCellIndicesFromDOM(around.domNode as HTMLTableCellElement, blockInfo.node, this.editor);
213
+ if (!cellPosition) return;
214
+
215
+ const { rowIndex, colIndex } = cellPosition;
216
+ const cellRect = (around.domNode as HTMLElement).getBoundingClientRect();
217
+ const lastRowIndex = blockInfo.node.content.childCount - 1;
218
+ const lastColIndex = (blockInfo.node.content.firstChild?.content.childCount ?? 0) - 1;
219
+
220
+ // Skip update if same cell
221
+ if (
222
+ this.state?.show &&
223
+ this.tableId === blockInfo.node.attrs.id &&
224
+ this.state.rowIndex === rowIndex &&
225
+ this.state.colIndex === colIndex
226
+ ) {
227
+ return;
228
+ }
229
+
230
+ this.state = {
231
+ show: true,
232
+ showAddOrRemoveColumnsButton: colIndex === lastColIndex,
233
+ showAddOrRemoveRowsButton: rowIndex === lastRowIndex,
234
+ referencePosTable: tableRect,
235
+ block: blockInfo.node,
236
+ blockPos: blockInfo.pos,
237
+ draggingState: undefined,
238
+ referencePosCell: cellRect,
239
+ colIndex,
240
+ rowIndex,
241
+ widgetContainer,
242
+ };
243
+ }
244
+
245
+ this.emitUpdate();
246
+ return false;
247
+ }
248
+
249
+ dragOverHandler = (event: DragEvent) => {
250
+ if (this.state?.draggingState === undefined) {
251
+ return;
252
+ }
253
+
254
+ event.preventDefault();
255
+ event.dataTransfer!.dropEffect = "move";
256
+
257
+ hideElements(".prosemirror-dropcursor-block, .prosemirror-dropcursor-inline", this.editorView.root);
258
+
259
+ // The mouse cursor coordinates, bounded to the table's bounding box.
260
+ const { left: tableLeft, right: tableRight, top: tableTop, bottom: tableBottom } = this.state.referencePosTable;
261
+
262
+ const boundedMouseCoords = {
263
+ left: clamp(event.clientX, tableLeft + 1, tableRight - 1),
264
+ top: clamp(event.clientY, tableTop + 1, tableBottom - 1),
265
+ };
266
+
267
+ // Gets the table cell element
268
+ const tableCellElements = this.editorView.root
269
+ .elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top)
270
+ .filter((element) => element.tagName === "TD" || element.tagName === "TH");
271
+ if (tableCellElements.length === 0) {
272
+ return;
273
+ }
274
+ const tableCellElement = tableCellElements[0];
275
+ if (!isHTMLElement(tableCellElement)) {
276
+ return;
277
+ }
278
+
279
+ const cellPosition = getCellIndicesFromDOM(tableCellElement as HTMLTableCellElement, this.state.block, this.editor);
280
+ if (!cellPosition) return;
281
+
282
+ const { rowIndex, colIndex } = cellPosition;
283
+
284
+ // Check what changed
285
+ const oldIndex =
286
+ this.state.draggingState.draggedCellOrientation === "row" ? this.state.rowIndex : this.state.colIndex;
287
+ const newIndex = this.state.draggingState.draggedCellOrientation === "row" ? rowIndex : colIndex;
288
+ const dispatchDecorationsTransaction = newIndex !== oldIndex;
289
+
290
+ const mousePos =
291
+ this.state.draggingState.draggedCellOrientation === "row" ? boundedMouseCoords.top : boundedMouseCoords.left;
292
+
293
+ // Check if anything needs updating
294
+ const cellChanged = this.state.rowIndex !== rowIndex || this.state.colIndex !== colIndex;
295
+ const mousePosChanged = this.state.draggingState.mousePos !== mousePos;
296
+
297
+ if (cellChanged || mousePosChanged) {
298
+ this.state = {
299
+ ...this.state,
300
+ rowIndex: rowIndex,
301
+ colIndex: colIndex,
302
+ referencePosCell: tableCellElement.getBoundingClientRect(),
303
+ draggingState: {
304
+ ...this.state.draggingState,
305
+ mousePos: mousePos,
306
+ },
307
+ };
308
+
309
+ this.emitUpdate();
310
+ }
311
+
312
+ // Dispatch decorations transaction if needed
313
+ if (dispatchDecorationsTransaction) {
314
+ this.editor.view.dispatch(this.editor.state.tr.setMeta(tableHandlePluginKey, true));
315
+ }
316
+ };
317
+
318
+ dropHandler = () => {
319
+ this.mouseState = "up";
320
+
321
+ const st = this.state;
322
+ if (!st?.draggingState) return false;
323
+
324
+ const { draggingState, rowIndex, colIndex, blockPos } = st;
325
+ if (!isValidPosition(blockPos)) return false;
326
+
327
+ if (
328
+ (draggingState.draggedCellOrientation === "row" && rowIndex === undefined) ||
329
+ (draggingState.draggedCellOrientation === "col" && colIndex === undefined)
330
+ ) {
331
+ throw new Error("Attempted to drop table row or column, but no table block was hovered prior.");
332
+ }
333
+
334
+ const isRow = draggingState.draggedCellOrientation === "row";
335
+ const orientation = isRow ? "row" : "column";
336
+ const destIndex = isRow ? rowIndex! : colIndex!;
337
+
338
+ const cellCoords = getIndexCoordinates({
339
+ editor: this.editor,
340
+ index: draggingState.originalIndex,
341
+ orientation,
342
+ tablePos: blockPos,
343
+ });
344
+ if (!cellCoords) return false;
345
+
346
+ const stateWithCellSel = selectCellsByCoords(this.editor, blockPos, cellCoords, { mode: "state" });
347
+ if (!stateWithCellSel) return false;
348
+
349
+ const dispatch = (tr: Transaction) => this.editor.view.dispatch(tr);
350
+
351
+ if (isRow) {
352
+ moveTableRow({
353
+ from: draggingState.originalIndex,
354
+ to: destIndex,
355
+ select: true,
356
+ pos: blockPos + 1,
357
+ })(stateWithCellSel, dispatch);
358
+ } else {
359
+ moveTableColumn({
360
+ from: draggingState.originalIndex,
361
+ to: destIndex,
362
+ select: true,
363
+ pos: blockPos + 1,
364
+ })(stateWithCellSel, dispatch);
365
+ }
366
+
367
+ this.state = { ...st, draggingState: undefined };
368
+ this.emitUpdate();
369
+
370
+ this.editor.view.dispatch(this.editor.state.tr.setMeta(tableHandlePluginKey, null));
371
+
372
+ return true;
373
+ };
374
+
375
+ update(view: EditorView): void {
376
+ const pluginState = tableHandlePluginKey.getState(view.state);
377
+ if (pluginState !== undefined && pluginState !== this.menuFrozen) {
378
+ this.menuFrozen = pluginState;
379
+ }
380
+
381
+ if (!this.state?.show) return;
382
+
383
+ if (!this.tableElement?.isConnected) {
384
+ this.hideHandles();
385
+ return;
386
+ }
387
+
388
+ const tableInfo = getTableFromDOM(this.tableElement, this.editor);
389
+ if (!tableInfo) {
390
+ this.hideHandles();
391
+ return;
392
+ }
393
+
394
+ // Check if table changed
395
+ const blockChanged = this.state.block !== tableInfo.node || this.state.blockPos !== tableInfo.pos;
396
+
397
+ if (!tableInfo.node || tableInfo.node.type.name !== "table" || !this.tableElement?.isConnected) {
398
+ this.hideHandles();
399
+ return;
400
+ }
401
+
402
+ const { height: rowCount, width: colCount } = TableMap.get(tableInfo.node);
403
+
404
+ // Calculate new indices
405
+ let newRowIndex = this.state.rowIndex;
406
+ let newColIndex = this.state.colIndex;
407
+
408
+ // Clamp indices if rows/columns were deleted
409
+ if (newRowIndex !== undefined && newRowIndex >= rowCount) {
410
+ newRowIndex = rowCount ? rowCount - 1 : undefined;
411
+ }
412
+ if (newColIndex !== undefined && newColIndex >= colCount) {
413
+ newColIndex = colCount ? colCount - 1 : undefined;
414
+ }
415
+
416
+ const tableBody = this.tableElement.querySelector("tbody");
417
+ if (!tableBody) {
418
+ throw new Error("Table block does not contain a 'tbody' HTML element. This should never happen.");
419
+ }
420
+
421
+ // Calculate new reference positions
422
+ let newReferencePosCell = this.state.referencePosCell;
423
+ if (newRowIndex !== undefined && newColIndex !== undefined) {
424
+ const rowEl = tableBody.children[newRowIndex];
425
+ const cellEl = rowEl?.children[newColIndex];
426
+
427
+ if (cellEl) {
428
+ newReferencePosCell = cellEl.getBoundingClientRect();
429
+ } else {
430
+ newRowIndex = undefined;
431
+ newColIndex = undefined;
432
+ newReferencePosCell = undefined;
433
+ }
434
+ }
435
+
436
+ const newReferencePosTable = tableBody.getBoundingClientRect();
437
+
438
+ // Check if anything changed
439
+ const indicesChanged = newRowIndex !== this.state.rowIndex || newColIndex !== this.state.colIndex;
440
+ const refPosChanged =
441
+ newReferencePosCell !== this.state.referencePosCell || newReferencePosTable !== this.state.referencePosTable;
442
+
443
+ if (blockChanged || indicesChanged || refPosChanged) {
444
+ this.state = {
445
+ ...this.state,
446
+ block: tableInfo.node,
447
+ blockPos: tableInfo.pos,
448
+ rowIndex: newRowIndex,
449
+ colIndex: newColIndex,
450
+ referencePosCell: newReferencePosCell,
451
+ referencePosTable: newReferencePosTable,
452
+ };
453
+ this.emitUpdate();
454
+ }
455
+ }
456
+
457
+ destroy(): void {
458
+ this.editorView.dom.removeEventListener("mousemove", this.mouseMoveHandler as EventListener);
459
+ window.removeEventListener("mouseup", this.mouseUpHandler as EventListener);
460
+ this.editorView.dom.removeEventListener("mousedown", this.viewMousedownHandler as EventListener);
461
+ this.editorView.root.removeEventListener("dragover", this.dragOverHandler as EventListener);
462
+ this.editorView.root.removeEventListener("drop", this.dropHandler as unknown as EventListener);
463
+ }
464
+ }
465
+
466
+ let tableHandleView: TableHandleView | null = null;
467
+
468
+ export function TableHandlePlugin(editor: Editor, emitUpdate: (state: TableHandlesState) => void): Plugin {
469
+ return new Plugin({
470
+ key: tableHandlePluginKey,
471
+
472
+ state: {
473
+ init: () => false,
474
+ apply: (tr, frozen) => {
475
+ const meta = tr.getMeta(tableHandlePluginKey);
476
+ return meta !== undefined ? meta : frozen;
477
+ },
478
+ },
479
+
480
+ view: (editorView) => {
481
+ tableHandleView = new TableHandleView(editor, editorView, emitUpdate);
482
+
483
+ return tableHandleView;
484
+ },
485
+
486
+ props: {
487
+ decorations: (state) => {
488
+ if (!tableHandleView) return null;
489
+
490
+ if (
491
+ tableHandleView === undefined ||
492
+ tableHandleView.state === undefined ||
493
+ tableHandleView.state.draggingState === undefined ||
494
+ tableHandleView.tablePos === undefined
495
+ ) {
496
+ return;
497
+ }
498
+
499
+ const newIndex =
500
+ tableHandleView.state.draggingState.draggedCellOrientation === "row"
501
+ ? tableHandleView.state.rowIndex
502
+ : tableHandleView.state.colIndex;
503
+
504
+ if (newIndex === undefined) {
505
+ return;
506
+ }
507
+
508
+ const decorations: Decoration[] = [];
509
+ const { draggingState } = tableHandleView.state;
510
+ const { originalIndex } = draggingState;
511
+
512
+ if (tableHandleView.state.draggingState.draggedCellOrientation === "row") {
513
+ const originalCells = getRowCells(editor, originalIndex, tableHandleView.state.blockPos);
514
+ originalCells.cells.forEach((cell) => {
515
+ if (cell.node) {
516
+ decorations.push(
517
+ Decoration.node(cell.pos, cell.pos + cell.node.nodeSize, {
518
+ class: "table-cell-dragging-source",
519
+ }),
520
+ );
521
+ }
522
+ });
523
+ } else {
524
+ const originalCells = getColumnCells(editor, originalIndex, tableHandleView.state.blockPos);
525
+ originalCells.cells.forEach((cell) => {
526
+ if (cell.node) {
527
+ decorations.push(
528
+ Decoration.node(cell.pos, cell.pos + cell.node.nodeSize, {
529
+ class: "table-cell-dragging-source",
530
+ }),
531
+ );
532
+ }
533
+ });
534
+ }
535
+
536
+ // Return empty decorations if:
537
+ // - original index is same as new index (no change)
538
+ // - editor is not defined for some reason
539
+ if (newIndex === originalIndex || !editor) {
540
+ return DecorationSet.create(state.doc, decorations);
541
+ }
542
+
543
+ if (tableHandleView.state.draggingState.draggedCellOrientation === "row") {
544
+ const cellsInRow = getRowCells(editor, newIndex, tableHandleView.state.blockPos);
545
+
546
+ cellsInRow.cells.forEach((cell) => {
547
+ const cellNode = cell.node;
548
+ if (!cellNode) {
549
+ return;
550
+ }
551
+
552
+ // Creates a decoration at the start or end of each cell,
553
+ // depending on whether the new index is before or after the
554
+ // original index.
555
+ const decorationPos = cell.pos + (newIndex > originalIndex ? cellNode.nodeSize - 2 : 2);
556
+ decorations.push(
557
+ Decoration.widget(decorationPos, () => {
558
+ const widget = document.createElement("div");
559
+ widget.className = "tiptap-table-dropcursor";
560
+ widget.style.left = "0";
561
+ widget.style.right = "0";
562
+ // This is only necessary because the drop indicator's height
563
+ // is an even number of pixels, whereas the border between
564
+ // table cells is an odd number of pixels. So this makes the
565
+ // positioning slightly more consistent regardless of where
566
+ // the row is being dropped.
567
+ if (newIndex > originalIndex) {
568
+ widget.style.bottom = "-1px";
569
+ } else {
570
+ widget.style.top = "-1px";
571
+ }
572
+ widget.style.height = "3px";
573
+
574
+ return widget;
575
+ }),
576
+ );
577
+ });
578
+ } else {
579
+ const cellsInColumn = getColumnCells(editor, newIndex, tableHandleView.state.blockPos);
580
+ cellsInColumn.cells.forEach((cell) => {
581
+ const cellNode = cell.node;
582
+ if (!cellNode) {
583
+ return;
584
+ }
585
+ // Creates a decoration at the start or end of each cell,
586
+ // depending on whether the new index is before or after the
587
+ // original index.
588
+ const decorationPos = cell.pos + (newIndex > originalIndex ? cellNode.nodeSize - 2 : 2);
589
+ decorations.push(
590
+ Decoration.widget(decorationPos, () => {
591
+ const widget = document.createElement("div");
592
+ widget.className = "tiptap-table-dropcursor";
593
+ widget.style.top = "0";
594
+ widget.style.bottom = "0";
595
+ // This is only necessary because the drop indicator's width
596
+ // is an even number of pixels, whereas the border between
597
+ // table cells is an odd number of pixels. So this makes the
598
+ // positioning slightly more consistent regardless of where
599
+ // the column is being dropped.
600
+ if (newIndex > originalIndex) {
601
+ widget.style.right = "-1px";
602
+ } else {
603
+ widget.style.left = "-1px";
604
+ }
605
+ widget.style.width = "3px";
606
+ return widget;
607
+ }),
608
+ );
609
+ });
610
+ }
611
+
612
+ return DecorationSet.create(state.doc, decorations);
613
+ },
614
+ },
615
+ });
616
+ }
617
+
618
+ /**
619
+ * Shared drag start handler for table rows and columns
620
+ */
621
+ const tableDragStart = (
622
+ orientation: "col" | "row",
623
+ event: {
624
+ dataTransfer: DataTransfer | null;
625
+ currentTarget: EventTarget & Element;
626
+ clientX: number;
627
+ clientY: number;
628
+ },
629
+ ) => {
630
+ if (!tableHandleView?.state) {
631
+ throw new Error(`Attempted to drag table ${orientation}, but no table block was hovered prior.`);
632
+ }
633
+
634
+ const { state, editor } = tableHandleView;
635
+ const index = orientation === "col" ? state.colIndex : state.rowIndex;
636
+
637
+ if (index === undefined) {
638
+ throw new Error(`Attempted to drag table ${orientation}, but no table block was hovered prior.`);
639
+ }
640
+
641
+ const { blockPos, referencePosCell } = state;
642
+ const mousePos = orientation === "col" ? event.clientX : event.clientY;
643
+
644
+ // Clear cell selection to prevent table reference collapse
645
+ if (editor.state.selection instanceof CellSelection) {
646
+ const safeSel = TextSelection.near(editor.state.doc.resolve(blockPos), 1);
647
+ editor.view.dispatch(editor.state.tr.setSelection(safeSel));
648
+ }
649
+
650
+ const dragImage = createTableDragImage(editor, orientation, index, blockPos);
651
+
652
+ // Configure drag image
653
+ if (event.dataTransfer) {
654
+ const handleRect = (event.currentTarget as HTMLElement).getBoundingClientRect();
655
+ const offset = orientation === "col" ? { x: handleRect.width / 2, y: 0 } : { x: 0, y: handleRect.height / 2 };
656
+
657
+ event.dataTransfer.effectAllowed = orientation === "col" ? "move" : "copyMove";
658
+ event.dataTransfer.setDragImage(dragImage, offset.x, offset.y);
659
+ }
660
+
661
+ // Cleanup drag image
662
+ const cleanup = () => dragImage.parentNode?.removeChild(dragImage);
663
+ document.addEventListener("drop", cleanup, { once: true });
664
+ document.addEventListener("dragend", cleanup, { once: true });
665
+
666
+ const initialOffset = referencePosCell
667
+ ? (orientation === "col" ? referencePosCell.left : referencePosCell.top) - mousePos
668
+ : 0;
669
+
670
+ // Update dragging state
671
+ tableHandleView.state = {
672
+ ...state,
673
+ draggingState: {
674
+ draggedCellOrientation: orientation,
675
+ originalIndex: index,
676
+ mousePos,
677
+ initialOffset,
678
+ },
679
+ };
680
+ tableHandleView.emitUpdate();
681
+ editor.view.dispatch(editor.state.tr.setMeta(tableHandlePluginKey, true));
682
+ };
683
+
684
+ /**
685
+ * Callback for column drag handle
686
+ */
687
+ export const colDragStart = (event: {
688
+ dataTransfer: DataTransfer | null;
689
+ currentTarget: EventTarget & Element;
690
+ clientX: number;
691
+ }) => tableDragStart("col", { ...event, clientY: 0 });
692
+
693
+ /**
694
+ * Callback for row drag handle
695
+ */
696
+ export const rowDragStart = (event: {
697
+ dataTransfer: DataTransfer | null;
698
+ currentTarget: EventTarget & Element;
699
+ clientY: number;
700
+ }) => tableDragStart("row", { ...event, clientX: 0 });
701
+
702
+ /**
703
+ * Drag end cleanup
704
+ */
705
+ export const dragEnd = () => {
706
+ if (!tableHandleView || tableHandleView.state === undefined) {
707
+ return;
708
+ }
709
+
710
+ tableHandleView.state = {
711
+ ...tableHandleView.state,
712
+ draggingState: undefined,
713
+ };
714
+ tableHandleView.emitUpdate();
715
+
716
+ const editor = tableHandleView.editor;
717
+ editor.view.dispatch(editor.state.tr.setMeta(tableHandlePluginKey, null));
718
+ };