@meta-1/editor 0.0.28 → 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,182 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import type { Editor } from "@tiptap/react";
5
+
6
+ type Orientation = "horizontal" | "vertical" | "both";
7
+
8
+ interface MenuNavigationOptions<T> {
9
+ /**
10
+ * The Tiptap editor instance, if using with a Tiptap editor.
11
+ */
12
+ editor?: Editor | null;
13
+ /**
14
+ * Reference to the container element for handling keyboard events.
15
+ */
16
+ containerRef?: React.RefObject<HTMLElement | null>;
17
+ /**
18
+ * Search query that affects the selected item.
19
+ */
20
+ query?: string;
21
+ /**
22
+ * Array of items to navigate through.
23
+ */
24
+ items: T[];
25
+ /**
26
+ * Callback fired when an item is selected.
27
+ */
28
+ onSelect?: (item: T) => void;
29
+ /**
30
+ * Callback fired when the menu should close.
31
+ */
32
+ onClose?: () => void;
33
+ /**
34
+ * The navigation orientation of the menu.
35
+ * @default "vertical"
36
+ */
37
+ orientation?: Orientation;
38
+ /**
39
+ * Whether to automatically select the first item when the menu opens.
40
+ * @default true
41
+ */
42
+ autoSelectFirstItem?: boolean;
43
+ }
44
+
45
+ /**
46
+ * Hook that implements keyboard navigation for dropdown menus and command palettes.
47
+ *
48
+ * Handles arrow keys, tab, home/end, enter for selection, and escape to close.
49
+ * Works with both Tiptap editors and regular DOM elements.
50
+ *
51
+ * @param options - Configuration options for the menu navigation
52
+ * @returns Object containing the selected index and a setter function
53
+ */
54
+ export function useMenuNavigation<T>({
55
+ editor,
56
+ containerRef,
57
+ query,
58
+ items,
59
+ onSelect,
60
+ onClose,
61
+ orientation = "vertical",
62
+ autoSelectFirstItem = true,
63
+ }: MenuNavigationOptions<T>) {
64
+ const [selectedIndex, setSelectedIndex] = useState<number>(autoSelectFirstItem ? 0 : -1);
65
+
66
+ useEffect(() => {
67
+ const handleKeyboardNavigation = (event: KeyboardEvent) => {
68
+ if (!items.length) return false;
69
+
70
+ const moveNext = () =>
71
+ setSelectedIndex((currentIndex) => {
72
+ if (currentIndex === -1) return 0;
73
+ return (currentIndex + 1) % items.length;
74
+ });
75
+
76
+ const movePrev = () =>
77
+ setSelectedIndex((currentIndex) => {
78
+ if (currentIndex === -1) return items.length - 1;
79
+ return (currentIndex - 1 + items.length) % items.length;
80
+ });
81
+
82
+ switch (event.key) {
83
+ case "ArrowUp": {
84
+ if (orientation === "horizontal") return false;
85
+ event.preventDefault();
86
+ movePrev();
87
+ return true;
88
+ }
89
+
90
+ case "ArrowDown": {
91
+ if (orientation === "horizontal") return false;
92
+ event.preventDefault();
93
+ moveNext();
94
+ return true;
95
+ }
96
+
97
+ case "ArrowLeft": {
98
+ if (orientation === "vertical") return false;
99
+ event.preventDefault();
100
+ movePrev();
101
+ return true;
102
+ }
103
+
104
+ case "ArrowRight": {
105
+ if (orientation === "vertical") return false;
106
+ event.preventDefault();
107
+ moveNext();
108
+ return true;
109
+ }
110
+
111
+ case "Tab": {
112
+ event.preventDefault();
113
+ if (event.shiftKey) {
114
+ movePrev();
115
+ } else {
116
+ moveNext();
117
+ }
118
+ return true;
119
+ }
120
+
121
+ case "Home": {
122
+ event.preventDefault();
123
+ setSelectedIndex(0);
124
+ return true;
125
+ }
126
+
127
+ case "End": {
128
+ event.preventDefault();
129
+ setSelectedIndex(items.length - 1);
130
+ return true;
131
+ }
132
+
133
+ case "Enter": {
134
+ if (event.isComposing) return false;
135
+ event.preventDefault();
136
+ if (selectedIndex !== -1 && items[selectedIndex]) {
137
+ onSelect?.(items[selectedIndex]);
138
+ }
139
+ return true;
140
+ }
141
+
142
+ case "Escape": {
143
+ event.preventDefault();
144
+ onClose?.();
145
+ return true;
146
+ }
147
+
148
+ default:
149
+ return false;
150
+ }
151
+ };
152
+
153
+ let targetElement: HTMLElement | null = null;
154
+
155
+ if (editor) {
156
+ targetElement = editor.view.dom;
157
+ } else if (containerRef?.current) {
158
+ targetElement = containerRef.current;
159
+ }
160
+
161
+ if (targetElement) {
162
+ targetElement.addEventListener("keydown", handleKeyboardNavigation, true);
163
+
164
+ return () => {
165
+ targetElement?.removeEventListener("keydown", handleKeyboardNavigation, true);
166
+ };
167
+ }
168
+
169
+ return undefined;
170
+ }, [editor, containerRef, items, selectedIndex, onSelect, onClose, orientation]);
171
+
172
+ useEffect(() => {
173
+ if (query) {
174
+ setSelectedIndex(autoSelectFirstItem ? 0 : -1);
175
+ }
176
+ }, [query, autoSelectFirstItem]);
177
+
178
+ return {
179
+ selectedIndex: items.length ? selectedIndex : undefined,
180
+ setSelectedIndex,
181
+ };
182
+ }
@@ -0,0 +1,135 @@
1
+ "use client";
2
+
3
+ import type { RefObject } from "react";
4
+ import { useEffect, useRef } from "react";
5
+
6
+ import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect";
7
+
8
+ // MediaQueryList Event based useEventListener interface
9
+ function useEventListener<K extends keyof MediaQueryListEventMap>(
10
+ eventName: K,
11
+ handler: (event: MediaQueryListEventMap[K]) => void,
12
+ element: RefObject<MediaQueryList>,
13
+ options?: boolean | AddEventListenerOptions,
14
+ ): void;
15
+
16
+ // Window Event based useEventListener interface
17
+ function useEventListener<K extends keyof WindowEventMap>(
18
+ eventName: K,
19
+ handler: (event: WindowEventMap[K]) => void,
20
+ element?: undefined,
21
+ options?: boolean | AddEventListenerOptions,
22
+ ): void;
23
+
24
+ // Element Event based useEventListener interface
25
+ function useEventListener<
26
+ K extends keyof HTMLElementEventMap & keyof SVGElementEventMap,
27
+ T extends Element = K extends keyof HTMLElementEventMap ? HTMLDivElement : SVGElement,
28
+ >(
29
+ eventName: K,
30
+ handler: ((event: HTMLElementEventMap[K]) => void) | ((event: SVGElementEventMap[K]) => void),
31
+ element: RefObject<T>,
32
+ options?: boolean | AddEventListenerOptions,
33
+ ): void;
34
+
35
+ // Document Event based useEventListener interface
36
+ function useEventListener<K extends keyof DocumentEventMap>(
37
+ eventName: K,
38
+ handler: (event: DocumentEventMap[K]) => void,
39
+ element: RefObject<Document>,
40
+ options?: boolean | AddEventListenerOptions,
41
+ ): void;
42
+
43
+ /**
44
+ * Custom hook that attaches event listeners to DOM elements, the window, or media query lists.
45
+ * @template KW - The type of event for window events.
46
+ * @template KH - The type of event for HTML or SVG element events.
47
+ * @template KM - The type of event for media query list events.
48
+ * @template T - The type of the DOM element (default is `HTMLElement`).
49
+ * @param {KW | KH | KM} eventName - The name of the event to listen for.
50
+ * @param {(event: WindowEventMap[KW] | HTMLElementEventMap[KH] | SVGElementEventMap[KH] | MediaQueryListEventMap[KM] | Event) => void} handler - The event handler function.
51
+ * @param {RefObject<T>} [element] - The DOM element or media query list to attach the event listener to (optional).
52
+ * @param {boolean | AddEventListenerOptions} [options] - An options object that specifies characteristics about the event listener (optional).
53
+ */
54
+ function useEventListener<
55
+ KW extends keyof WindowEventMap,
56
+ KH extends keyof HTMLElementEventMap & keyof SVGElementEventMap,
57
+ KM extends keyof MediaQueryListEventMap,
58
+ T extends HTMLElement | SVGAElement | MediaQueryList = HTMLElement,
59
+ >(
60
+ eventName: KW | KH | KM,
61
+ handler: (
62
+ event: WindowEventMap[KW] | HTMLElementEventMap[KH] | SVGElementEventMap[KH] | MediaQueryListEventMap[KM] | Event,
63
+ ) => void,
64
+ element?: RefObject<T>,
65
+ options?: boolean | AddEventListenerOptions,
66
+ ) {
67
+ // Create a ref that stores handler
68
+ const savedHandler = useRef(handler);
69
+
70
+ useIsomorphicLayoutEffect(() => {
71
+ savedHandler.current = handler;
72
+ }, [handler]);
73
+
74
+ useEffect(() => {
75
+ // Define the listening target
76
+ const targetElement: T | Window = element?.current ?? window;
77
+
78
+ if (!(targetElement && targetElement.addEventListener)) return;
79
+
80
+ // Create event listener that calls handler function stored in ref
81
+ const listener: typeof handler = (event) => {
82
+ savedHandler.current(event);
83
+ };
84
+
85
+ targetElement.addEventListener(eventName, listener, options);
86
+
87
+ // Remove event listener on cleanup
88
+ return () => {
89
+ targetElement.removeEventListener(eventName, listener, options);
90
+ };
91
+ }, [eventName, element, options]);
92
+ }
93
+
94
+ export { useEventListener };
95
+
96
+ /** Supported event types. */
97
+ type EventType = "mousedown" | "mouseup" | "touchstart" | "touchend" | "focusin" | "focusout";
98
+
99
+ /**
100
+ * Custom hook that handles clicks outside a specified element.
101
+ * @template T - The type of the element's reference.
102
+ * @param {RefObject<T> | RefObject<T>[]} ref - The React ref object(s) representing the element(s) to watch for outside clicks.
103
+ * @param {(event: MouseEvent | TouchEvent | FocusEvent) => void} handler - The callback function to be executed when a click outside the element occurs.
104
+ * @param {EventType} [eventType] - The mouse event type to listen for (optional, default is 'mousedown').
105
+ * @param {?AddEventListenerOptions} [eventListenerOptions] - The options object to be passed to the `addEventListener` method (optional).
106
+ * @returns {void}
107
+ */
108
+ export function useOnClickOutside<T extends HTMLElement | null = HTMLElement>(
109
+ ref: RefObject<T> | RefObject<T>[],
110
+ handler: (event: MouseEvent | TouchEvent | FocusEvent) => void,
111
+ eventType: EventType = "mousedown",
112
+ eventListenerOptions: AddEventListenerOptions = {},
113
+ ): void {
114
+ useEventListener(
115
+ eventType,
116
+ (event) => {
117
+ const target = event.target as Node;
118
+
119
+ // Do nothing if the target is not connected element with document
120
+ if (!target || !target.isConnected) {
121
+ return;
122
+ }
123
+
124
+ const isOutside = Array.isArray(ref)
125
+ ? ref.filter((r) => Boolean(r.current)).every((r) => r.current && !r.current.contains(target))
126
+ : ref.current && !ref.current.contains(target);
127
+
128
+ if (isOutside) {
129
+ handler(event);
130
+ }
131
+ },
132
+ undefined,
133
+ eventListenerOptions,
134
+ );
135
+ }
@@ -0,0 +1,75 @@
1
+ import type { RefObject } from "react"
2
+ import { useEffect, useState } from "react"
3
+
4
+ type ScrollTarget = RefObject<HTMLElement> | Window | null | undefined
5
+ type EventTargetWithScroll = Window | HTMLElement | Document
6
+
7
+ interface UseScrollingOptions {
8
+ debounce?: number
9
+ fallbackToDocument?: boolean
10
+ }
11
+
12
+ export function useScrolling(
13
+ target?: ScrollTarget,
14
+ options: UseScrollingOptions = {}
15
+ ): boolean {
16
+ const { debounce = 150, fallbackToDocument = true } = options
17
+ const [isScrolling, setIsScrolling] = useState(false)
18
+
19
+ useEffect(() => {
20
+ // Resolve element or window
21
+ const element: EventTargetWithScroll =
22
+ target && typeof Window !== "undefined" && target instanceof Window
23
+ ? target
24
+ : ((target as RefObject<HTMLElement>)?.current ?? window)
25
+
26
+ // Mobile: fallback to document when using window
27
+ const eventTarget: EventTargetWithScroll =
28
+ fallbackToDocument &&
29
+ element === window &&
30
+ typeof document !== "undefined"
31
+ ? document
32
+ : element
33
+
34
+ const on = (
35
+ el: EventTargetWithScroll,
36
+ event: string,
37
+ handler: EventListener
38
+ ) => el.addEventListener(event, handler, true)
39
+
40
+ const off = (
41
+ el: EventTargetWithScroll,
42
+ event: string,
43
+ handler: EventListener
44
+ ) => el.removeEventListener(event, handler)
45
+
46
+ let timeout: ReturnType<typeof setTimeout>
47
+ const supportsScrollEnd = element === window && "onscrollend" in window
48
+
49
+ const handleScroll: EventListener = () => {
50
+ if (!isScrolling) setIsScrolling(true)
51
+
52
+ if (!supportsScrollEnd) {
53
+ clearTimeout(timeout)
54
+ timeout = setTimeout(() => setIsScrolling(false), debounce)
55
+ }
56
+ }
57
+
58
+ const handleScrollEnd: EventListener = () => setIsScrolling(false)
59
+
60
+ on(eventTarget, "scroll", handleScroll)
61
+ if (supportsScrollEnd) {
62
+ on(eventTarget, "scrollend", handleScrollEnd)
63
+ }
64
+
65
+ return () => {
66
+ off(eventTarget, "scroll", handleScroll)
67
+ if (supportsScrollEnd) {
68
+ off(eventTarget, "scrollend", handleScrollEnd)
69
+ }
70
+ clearTimeout(timeout)
71
+ }
72
+ }, [target, debounce, fallbackToDocument, isScrolling])
73
+
74
+ return isScrolling
75
+ }
@@ -0,0 +1,48 @@
1
+ import { useMemo } from "react";
2
+ import throttle from "lodash.throttle";
3
+
4
+ import { useUnmount } from "./use-unmount";
5
+
6
+ interface ThrottleSettings {
7
+ leading?: boolean | undefined;
8
+ trailing?: boolean | undefined;
9
+ }
10
+
11
+ const defaultOptions: ThrottleSettings = {
12
+ leading: false,
13
+ trailing: true,
14
+ };
15
+
16
+ /**
17
+ * A hook that returns a throttled callback function.
18
+ *
19
+ * @param fn The function to throttle
20
+ * @param wait The time in ms to wait before calling the function
21
+ * @param dependencies The dependencies to watch for changes
22
+ * @param options The throttle options
23
+ */
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ export function useThrottledCallback<T extends (...args: any[]) => any>(
26
+ fn: T,
27
+ wait = 250,
28
+ dependencies: React.DependencyList = [],
29
+ options: ThrottleSettings = defaultOptions,
30
+ ): {
31
+ (this: ThisParameterType<T>, ...args: Parameters<T>): ReturnType<T>;
32
+ cancel: () => void;
33
+ flush: () => void;
34
+ } {
35
+ const handler = useMemo(
36
+ () => throttle<T>(fn, wait, options),
37
+ // eslint-disable-next-line react-hooks/exhaustive-deps
38
+ dependencies,
39
+ );
40
+
41
+ useUnmount(() => {
42
+ handler.cancel();
43
+ });
44
+
45
+ return handler;
46
+ }
47
+
48
+ export default useThrottledCallback;
@@ -0,0 +1,49 @@
1
+ "use client"
2
+
3
+ import type { Editor } from "@tiptap/react"
4
+ import { useCurrentEditor, useEditorState } from "@tiptap/react"
5
+ import { useMemo } from "react"
6
+
7
+ /**
8
+ * Hook that provides access to a Tiptap editor instance.
9
+ *
10
+ * Accepts an optional editor instance directly, or falls back to retrieving
11
+ * the editor from the Tiptap context if available. This allows components
12
+ * to work both when given an editor directly and when used within a Tiptap
13
+ * editor context.
14
+ *
15
+ * @param providedEditor - Optional editor instance to use instead of the context editor
16
+ * @returns The provided editor or the editor from context, whichever is available
17
+ */
18
+ export function useTiptapEditor(providedEditor?: Editor | null): {
19
+ editor: Editor | null
20
+ editorState?: Editor["state"]
21
+ canCommand?: Editor["can"]
22
+ } {
23
+ const { editor: coreEditor } = useCurrentEditor()
24
+ const mainEditor = useMemo(
25
+ () => providedEditor || coreEditor,
26
+ [providedEditor, coreEditor]
27
+ )
28
+
29
+ const editorState = useEditorState({
30
+ editor: mainEditor,
31
+ selector(context) {
32
+ if (!context.editor) {
33
+ return {
34
+ editor: null,
35
+ editorState: undefined,
36
+ canCommand: undefined,
37
+ }
38
+ }
39
+
40
+ return {
41
+ editor: context.editor,
42
+ editorState: context.editor.state,
43
+ canCommand: context.editor.can,
44
+ }
45
+ },
46
+ })
47
+
48
+ return editorState || { editor: null }
49
+ }
@@ -0,0 +1,29 @@
1
+ "use client";
2
+
3
+ import type { Editor } from "@tiptap/react";
4
+ import { useEditorState } from "@tiptap/react";
5
+
6
+ import { defaultUiState, type UiState } from "../components/tiptap-extension/ui-state-extension";
7
+
8
+ export function useUiEditorState(editor: Editor | null): UiState {
9
+ return (
10
+ useEditorState({
11
+ editor,
12
+ selector: ({ editor }) => {
13
+ if (!editor) return defaultUiState;
14
+
15
+ const state = editor.storage.uiState;
16
+ if (!state) {
17
+ console.warn(
18
+ "Editor storage uiState is not initialized. Ensure you have the uiState extension added to your editor.",
19
+ );
20
+ return defaultUiState;
21
+ }
22
+
23
+ return { ...defaultUiState, ...state };
24
+ },
25
+ }) ?? defaultUiState
26
+ );
27
+ }
28
+
29
+ export default useUiEditorState;
@@ -0,0 +1,21 @@
1
+ import { useRef, useEffect } from "react"
2
+
3
+ /**
4
+ * Hook that executes a callback when the component unmounts.
5
+ *
6
+ * @param callback Function to be called on component unmount
7
+ */
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export const useUnmount = (callback: (...args: Array<any>) => any) => {
10
+ const ref = useRef(callback)
11
+ ref.current = callback
12
+
13
+ useEffect(
14
+ () => () => {
15
+ ref.current()
16
+ },
17
+ []
18
+ )
19
+ }
20
+
21
+ export default useUnmount
@@ -0,0 +1,88 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+
5
+ import { useThrottledCallback } from "./use-throttled-callback";
6
+
7
+ export interface WindowSizeState {
8
+ /**
9
+ * The width of the window's visual viewport in pixels.
10
+ */
11
+ width: number;
12
+ /**
13
+ * The height of the window's visual viewport in pixels.
14
+ */
15
+ height: number;
16
+ /**
17
+ * The distance from the top of the visual viewport to the top of the layout viewport.
18
+ * Particularly useful for handling mobile keyboard appearance.
19
+ */
20
+ offsetTop: number;
21
+ /**
22
+ * The distance from the left of the visual viewport to the left of the layout viewport.
23
+ */
24
+ offsetLeft: number;
25
+ /**
26
+ * The scale factor of the visual viewport.
27
+ * This is useful for scaling elements based on the current zoom level.
28
+ */
29
+ scale: number;
30
+ }
31
+
32
+ /**
33
+ * Hook that tracks the window's visual viewport dimensions, position, and provides
34
+ * a CSS transform for positioning elements.
35
+ *
36
+ * Uses the Visual Viewport API to get accurate measurements, especially important
37
+ * for mobile devices where virtual keyboards can change the visible area.
38
+ * Only updates state when values actually change to optimize performance.
39
+ *
40
+ * @returns An object containing viewport properties and a CSS transform string
41
+ */
42
+ export function useWindowSize(): WindowSizeState {
43
+ const [windowSize, setWindowSize] = useState<WindowSizeState>({
44
+ width: 0,
45
+ height: 0,
46
+ offsetTop: 0,
47
+ offsetLeft: 0,
48
+ scale: 0,
49
+ });
50
+
51
+ const handleViewportChange = useThrottledCallback(() => {
52
+ if (typeof window === "undefined") return;
53
+
54
+ const vp = window.visualViewport;
55
+ if (!vp) return;
56
+
57
+ const { width = 0, height = 0, offsetTop = 0, offsetLeft = 0, scale = 0 } = vp;
58
+
59
+ setWindowSize((prevState) => {
60
+ if (
61
+ width === prevState.width &&
62
+ height === prevState.height &&
63
+ offsetTop === prevState.offsetTop &&
64
+ offsetLeft === prevState.offsetLeft &&
65
+ scale === prevState.scale
66
+ ) {
67
+ return prevState;
68
+ }
69
+
70
+ return { width, height, offsetTop, offsetLeft, scale };
71
+ });
72
+ }, 200);
73
+
74
+ useEffect(() => {
75
+ const visualViewport = window.visualViewport;
76
+ if (!visualViewport) return;
77
+
78
+ visualViewport.addEventListener("resize", handleViewportChange);
79
+
80
+ handleViewportChange();
81
+
82
+ return () => {
83
+ visualViewport.removeEventListener("resize", handleViewportChange);
84
+ };
85
+ }, [handleViewportChange]);
86
+
87
+ return windowSize;
88
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,4 @@
1
- export type { EditorEvents } from "@tiptap/core";
2
-
3
- export type { EditorProps, EditorRef } from "./editor";
4
- export { Editor } from "./editor";
5
- export * from "./editor/hooks";
6
- export type { ContentViewerProps } from "./editor/viewer";
7
- export { ContentViewer } from "./editor/viewer";
1
+ export * from "./content";
2
+ export * from "./editor";
3
+ export * from "./editor/collaboration";
4
+ export * from "./hooks/use-editor";