reactjs-tiptap-editor-pro 0.2.29 → 0.2.31

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 (333) hide show
  1. package/package.json +5 -58
  2. package/src/components/ActionButton.tsx +103 -0
  3. package/src/components/ActionMenuButton.tsx +76 -0
  4. package/src/components/BubbleMenu.tsx +93 -0
  5. package/src/components/CharactorCount.tsx +50 -0
  6. package/src/components/ColorPicker.tsx +272 -0
  7. package/src/components/RichTextEditor.tsx +212 -0
  8. package/src/components/SizeSetter/SizeSetter.tsx +102 -0
  9. package/src/components/Toolbar.tsx +108 -0
  10. package/src/components/icons/Activity.tsx +19 -0
  11. package/src/components/icons/Animas.tsx +24 -0
  12. package/src/components/icons/AspectRatio.tsx +13 -0
  13. package/src/components/icons/Blockquote.tsx +17 -0
  14. package/src/components/icons/ColumnAddLeft.tsx +7 -0
  15. package/src/components/icons/ColumnAddRight.tsx +7 -0
  16. package/src/components/icons/DeleteColumn.tsx +26 -0
  17. package/src/components/icons/DeleteRow.tsx +26 -0
  18. package/src/components/icons/Direction.tsx +7 -0
  19. package/src/components/icons/Excalidraw.tsx +7 -0
  20. package/src/components/icons/ExportPdf.tsx +8 -0
  21. package/src/components/icons/ExportWord.tsx +24 -0
  22. package/src/components/icons/FileWordOutline.tsx +13 -0
  23. package/src/components/icons/Flag.tsx +19 -0
  24. package/src/components/icons/Food.tsx +20 -0
  25. package/src/components/icons/GIfIcon.tsx +10 -0
  26. package/src/components/icons/Icon.tsx +30 -0
  27. package/src/components/icons/ImportWord.tsx +23 -0
  28. package/src/components/icons/LeftToRight.tsx +7 -0
  29. package/src/components/icons/LineHeight.tsx +13 -0
  30. package/src/components/icons/MenuDown.tsx +24 -0
  31. package/src/components/icons/Mermaid.tsx +13 -0
  32. package/src/components/icons/NoFill.tsx +7 -0
  33. package/src/components/icons/Object.tsx +24 -0
  34. package/src/components/icons/RightToLeft.tsx +7 -0
  35. package/src/components/icons/SizeL.tsx +9 -0
  36. package/src/components/icons/SizeM.tsx +13 -0
  37. package/src/components/icons/SizeS.tsx +13 -0
  38. package/src/components/icons/Symbol.tsx +19 -0
  39. package/src/components/icons/Travel.tsx +24 -0
  40. package/src/components/icons/Twitter.tsx +7 -0
  41. package/src/components/icons/icons.ts +212 -0
  42. package/src/components/icons/index.ts +12 -0
  43. package/src/components/index.ts +9 -0
  44. package/src/components/menus/bubble.ts +395 -0
  45. package/src/components/menus/components/BubbleMenuContent.tsx +15 -0
  46. package/src/components/menus/components/BubbleMenuDrawer.tsx +128 -0
  47. package/src/components/menus/components/BubbleMenuExcalidraw.tsx +91 -0
  48. package/src/components/menus/components/BubbleMenuIframe.tsx +143 -0
  49. package/src/components/menus/components/BubbleMenuKatex.tsx +136 -0
  50. package/src/components/menus/components/BubbleMenuLink.tsx +99 -0
  51. package/src/components/menus/components/BubbleMenuMedia.tsx +235 -0
  52. package/src/components/menus/components/BubbleMenuMermaid.tsx +128 -0
  53. package/src/components/menus/components/BubbleMenuText.tsx +102 -0
  54. package/src/components/menus/components/BubbleMenuTwitter.tsx +91 -0
  55. package/src/components/menus/components/ColumnsBubbleMenu.tsx +59 -0
  56. package/src/components/menus/components/ContentMenu.tsx +396 -0
  57. package/src/components/menus/components/TableBubbleMenu.tsx +362 -0
  58. package/src/components/menus/index.ts +7 -0
  59. package/src/components/ui/button.tsx +56 -0
  60. package/src/components/ui/checkbox.tsx +30 -0
  61. package/src/components/ui/dialog.tsx +128 -0
  62. package/src/components/ui/dropdown-menu.tsx +203 -0
  63. package/src/components/ui/emoji-picker.tsx +166 -0
  64. package/src/components/ui/index.ts +14 -0
  65. package/src/components/ui/input.tsx +25 -0
  66. package/src/components/ui/label.tsx +26 -0
  67. package/src/components/ui/popover.tsx +31 -0
  68. package/src/components/ui/select.tsx +162 -0
  69. package/src/components/ui/separator.tsx +31 -0
  70. package/src/components/ui/switch.tsx +29 -0
  71. package/src/components/ui/tabs.tsx +55 -0
  72. package/src/components/ui/textarea.tsx +24 -0
  73. package/src/components/ui/toast.tsx +129 -0
  74. package/src/components/ui/toaster.tsx +44 -0
  75. package/src/components/ui/toggle.tsx +45 -0
  76. package/src/components/ui/tooltip.tsx +30 -0
  77. package/src/components/ui/use-toast.ts +197 -0
  78. package/src/constants/index.ts +223 -0
  79. package/src/constants/resetCSS.ts +139 -0
  80. package/src/extension-bundle.ts +2 -0
  81. package/src/extensions/Attachment/Attachment.ts +144 -0
  82. package/src/extensions/Attachment/components/NodeViewAttachment/FileIcon.tsx +69 -0
  83. package/src/extensions/Attachment/components/NodeViewAttachment/FileIconString.ts +28 -0
  84. package/src/extensions/Attachment/components/NodeViewAttachment/NodeViewAttachment.tsx +155 -0
  85. package/src/extensions/Attachment/components/NodeViewAttachment/index.module.scss +23 -0
  86. package/src/extensions/Attachment/index.ts +1 -0
  87. package/src/extensions/BaseKit.ts +253 -0
  88. package/src/extensions/Blockquote/Blockquote.ts +31 -0
  89. package/src/extensions/Blockquote/index.ts +1 -0
  90. package/src/extensions/Bold/Bold.ts +26 -0
  91. package/src/extensions/Bold/index.ts +1 -0
  92. package/src/extensions/BulletList/BulletList.ts +28 -0
  93. package/src/extensions/BulletList/index.ts +1 -0
  94. package/src/extensions/Clear/Clear.ts +24 -0
  95. package/src/extensions/Clear/index.ts +1 -0
  96. package/src/extensions/Code/Code.ts +26 -0
  97. package/src/extensions/Code/index.ts +1 -0
  98. package/src/extensions/CodeBlock/CodeBlock.ts +54 -0
  99. package/src/extensions/CodeBlock/components/CodeBlockActiveButton.tsx +66 -0
  100. package/src/extensions/CodeBlock/components/NodeViewCodeBlock/NodeViewCodeBlock.tsx +89 -0
  101. package/src/extensions/CodeBlock/components/NodeViewCodeBlock/index.module.scss +81 -0
  102. package/src/extensions/CodeBlock/highlighter.ts +132 -0
  103. package/src/extensions/CodeBlock/index.ts +1 -0
  104. package/src/extensions/CodeBlock/shiki-plugin.ts +213 -0
  105. package/src/extensions/Color/Color.ts +52 -0
  106. package/src/extensions/Color/components/ColorActionButton.tsx +104 -0
  107. package/src/extensions/Color/index.ts +1 -0
  108. package/src/extensions/Document/Document.ts +8 -0
  109. package/src/extensions/Document/index.ts +1 -0
  110. package/src/extensions/Drawer/Drawer.ts +177 -0
  111. package/src/extensions/Drawer/components/ControlDrawer/ControlDrawer.module.scss +85 -0
  112. package/src/extensions/Drawer/components/ControlDrawer/ControlDrawer.tsx +598 -0
  113. package/src/extensions/Drawer/components/ControlDrawer/icon.tsx +500 -0
  114. package/src/extensions/Drawer/components/DrawerActiveButton.tsx +239 -0
  115. package/src/extensions/Drawer/components/EditDrawerBlock.tsx +238 -0
  116. package/src/extensions/Drawer/components/NodeViewDrawer/NodeViewDrawer.tsx +260 -0
  117. package/src/extensions/Drawer/index.ts +1 -0
  118. package/src/extensions/Emoji/Emoji.ts +146 -0
  119. package/src/extensions/Emoji/components/EmojiList/EmojiList.tsx +103 -0
  120. package/src/extensions/Emoji/components/EmojiList/emojis.ts +1858 -0
  121. package/src/extensions/Emoji/components/EmojiPicker/EmojiPicker.tsx +61 -0
  122. package/src/extensions/Emoji/index.ts +1 -0
  123. package/src/extensions/Excalidraw/Excalidraw.ts +123 -0
  124. package/src/extensions/Excalidraw/components/ExcalidrawActiveButton.tsx +138 -0
  125. package/src/extensions/Excalidraw/components/NodeViewExcalidraw/NodeViewExcalidraw.tsx +178 -0
  126. package/src/extensions/Excalidraw/components/NodeViewExcalidraw/index.module.scss +43 -0
  127. package/src/extensions/Excalidraw/index.ts +1 -0
  128. package/src/extensions/ExportPdf/ExportPdf.ts +25 -0
  129. package/src/extensions/ExportPdf/index.ts +1 -0
  130. package/src/extensions/ExportWord/ExportWord.ts +87 -0
  131. package/src/extensions/ExportWord/index.ts +1 -0
  132. package/src/extensions/FontFamily/FontFamily.ts +64 -0
  133. package/src/extensions/FontFamily/components/FontFamilyButton.tsx +97 -0
  134. package/src/extensions/FontFamily/index.ts +1 -0
  135. package/src/extensions/FontSize/FontSize.ts +119 -0
  136. package/src/extensions/FontSize/components/FontSizeMenuButton.tsx +84 -0
  137. package/src/extensions/FontSize/index.ts +1 -0
  138. package/src/extensions/FormatPainter/FormatPainter.ts +121 -0
  139. package/src/extensions/FormatPainter/index.ts +1 -0
  140. package/src/extensions/Heading/Heading.ts +57 -0
  141. package/src/extensions/Heading/components/HeadingButton.tsx +96 -0
  142. package/src/extensions/Heading/index.ts +1 -0
  143. package/src/extensions/Highlight/Highlight.ts +36 -0
  144. package/src/extensions/Highlight/components/HighlightActionButton.tsx +108 -0
  145. package/src/extensions/Highlight/index.ts +1 -0
  146. package/src/extensions/History/History.ts +39 -0
  147. package/src/extensions/History/components/HistoryActionButton.tsx +74 -0
  148. package/src/extensions/History/index.ts +1 -0
  149. package/src/extensions/HorizontalRule/HorizontalRule.ts +42 -0
  150. package/src/extensions/HorizontalRule/index.ts +1 -0
  151. package/src/extensions/Iframe/Iframe.ts +140 -0
  152. package/src/extensions/Iframe/components/IframeNodeView.tsx +92 -0
  153. package/src/extensions/Iframe/components/index.module.scss +40 -0
  154. package/src/extensions/Iframe/embed.ts +487 -0
  155. package/src/extensions/Iframe/index.ts +1 -0
  156. package/src/extensions/Image/Image.ts +303 -0
  157. package/src/extensions/Image/components/ActionImageButton.tsx +186 -0
  158. package/src/extensions/Image/components/ImageCropper.tsx +198 -0
  159. package/src/extensions/Image/components/ImageView.tsx +271 -0
  160. package/src/extensions/Image/index.ts +1 -0
  161. package/src/extensions/Image/store.ts +15 -0
  162. package/src/extensions/ImageGif/ImageGif.ts +176 -0
  163. package/src/extensions/ImageGif/components/ImageGifActionButton.tsx +138 -0
  164. package/src/extensions/ImageGif/components/ImageGifView.tsx +260 -0
  165. package/src/extensions/ImageGif/index.ts +1 -0
  166. package/src/extensions/ImportWord/ImportWord.ts +52 -0
  167. package/src/extensions/ImportWord/components/ImportWordButton.tsx +151 -0
  168. package/src/extensions/ImportWord/index.ts +1 -0
  169. package/src/extensions/Indent/Indent.ts +110 -0
  170. package/src/extensions/Indent/index.ts +1 -0
  171. package/src/extensions/Italic/Italic.ts +29 -0
  172. package/src/extensions/Italic/index.ts +1 -0
  173. package/src/extensions/Katex/Katex.ts +109 -0
  174. package/src/extensions/Katex/components/KatexActiveButton.tsx +117 -0
  175. package/src/extensions/Katex/components/KatexWrapper.tsx +53 -0
  176. package/src/extensions/Katex/index.ts +1 -0
  177. package/src/extensions/LineHeight/LineHeight.ts +76 -0
  178. package/src/extensions/LineHeight/components/LineHeightDropdown.tsx +93 -0
  179. package/src/extensions/LineHeight/index.ts +1 -0
  180. package/src/extensions/Link/Link.ts +92 -0
  181. package/src/extensions/Link/components/LinkEditBlock.tsx +110 -0
  182. package/src/extensions/Link/components/LinkEditPopover.tsx +46 -0
  183. package/src/extensions/Link/components/LinkViewBlock.tsx +54 -0
  184. package/src/extensions/Link/index.ts +1 -0
  185. package/src/extensions/ListItem/ListItem.ts +1 -0
  186. package/src/extensions/ListItem/index.ts +1 -0
  187. package/src/extensions/Mention/Mention.ts +100 -0
  188. package/src/extensions/Mention/components/NodeViewMentionList/NodeViewMentionList.tsx +94 -0
  189. package/src/extensions/Mention/components/NodeViewMentionList/index.module.scss +38 -0
  190. package/src/extensions/Mention/index.ts +1 -0
  191. package/src/extensions/Mermaid/Mermaid.ts +177 -0
  192. package/src/extensions/Mermaid/components/EditMermaidBlock.tsx +155 -0
  193. package/src/extensions/Mermaid/components/MermaidActiveButton.tsx +151 -0
  194. package/src/extensions/Mermaid/components/NodeViewMermaid/NodeViewMermaid.tsx +260 -0
  195. package/src/extensions/Mermaid/index.ts +1 -0
  196. package/src/extensions/MoreMark/MoreMark.ts +102 -0
  197. package/src/extensions/MoreMark/components/ActionMoreButton.tsx +97 -0
  198. package/src/extensions/MoreMark/index.ts +1 -0
  199. package/src/extensions/MultiColumn/Column.ts +36 -0
  200. package/src/extensions/MultiColumn/MultiColumn.ts +111 -0
  201. package/src/extensions/MultiColumn/components/ColumnActionButton.ts +22 -0
  202. package/src/extensions/MultiColumn/index.ts +3 -0
  203. package/src/extensions/OrderedList/OrderedList.ts +28 -0
  204. package/src/extensions/OrderedList/index.ts +1 -0
  205. package/src/extensions/SearchAndReplace/SearchAndReplace.ts +395 -0
  206. package/src/extensions/SearchAndReplace/components/SearchAndReplaceButton.tsx +190 -0
  207. package/src/extensions/SearchAndReplace/index.ts +1 -0
  208. package/src/extensions/Selection/Selection.ts +32 -0
  209. package/src/extensions/Selection/index.ts +1 -0
  210. package/src/extensions/SlashCommand/SlashCommand.ts +255 -0
  211. package/src/extensions/SlashCommand/components/CommandsList.tsx +180 -0
  212. package/src/extensions/SlashCommand/groups.ts +183 -0
  213. package/src/extensions/SlashCommand/index.ts +1 -0
  214. package/src/extensions/SlashCommand/types.ts +24 -0
  215. package/src/extensions/Strike/Strike.ts +26 -0
  216. package/src/extensions/Strike/index.ts +1 -0
  217. package/src/extensions/Subscript/Subscript.ts +88 -0
  218. package/src/extensions/Subscript/index.ts +1 -0
  219. package/src/extensions/Table/Cell.ts +131 -0
  220. package/src/extensions/Table/Header.ts +93 -0
  221. package/src/extensions/Table/Row.ts +8 -0
  222. package/src/extensions/Table/Table.ts +60 -0
  223. package/src/extensions/Table/cell-background.ts +112 -0
  224. package/src/extensions/Table/components/CreateTablePopover.tsx +132 -0
  225. package/src/extensions/Table/components/TableActionButton.tsx +42 -0
  226. package/src/extensions/Table/index.ts +6 -0
  227. package/src/extensions/Table/utils.ts +352 -0
  228. package/src/extensions/TableOfContent/TableOfContent.ts +124 -0
  229. package/src/extensions/TableOfContent/components/NodeViewTableOfContent.tsx +116 -0
  230. package/src/extensions/TableOfContent/components/TableOfContentActionButton.tsx +27 -0
  231. package/src/extensions/TableOfContent/components/index.module.scss +40 -0
  232. package/src/extensions/TableOfContent/index.ts +1 -0
  233. package/src/extensions/TaskList/TaskList.ts +46 -0
  234. package/src/extensions/TaskList/index.ts +1 -0
  235. package/src/extensions/TextAlign/TextAlign.ts +68 -0
  236. package/src/extensions/TextAlign/components/TextAlignMenuButton.tsx +103 -0
  237. package/src/extensions/TextAlign/index.ts +1 -0
  238. package/src/extensions/TextBubble/TextBubble.ts +22 -0
  239. package/src/extensions/TextBubble/components/TextDropdown.tsx +146 -0
  240. package/src/extensions/TextBubble/index.ts +1 -0
  241. package/src/extensions/TextDirection/TextDirection.ts +97 -0
  242. package/src/extensions/TextDirection/components/TextDirectionButton.tsx +103 -0
  243. package/src/extensions/TextDirection/index.ts +1 -0
  244. package/src/extensions/TrailingNode/TrailingNode.ts +71 -0
  245. package/src/extensions/TrailingNode/index.ts +1 -0
  246. package/src/extensions/Twitter/Twitter.ts +161 -0
  247. package/src/extensions/Twitter/components/FormEditLinkTwitter.tsx +68 -0
  248. package/src/extensions/Twitter/components/NodeViewTweet.tsx +30 -0
  249. package/src/extensions/Twitter/components/TwitterActiveButton.tsx +41 -0
  250. package/src/extensions/Twitter/index.ts +1 -0
  251. package/src/extensions/UnderLine/Underline.ts +30 -0
  252. package/src/extensions/UnderLine/index.ts +1 -0
  253. package/src/extensions/Video/Video.ts +204 -0
  254. package/src/extensions/Video/components/ActiveVideoButton.tsx +191 -0
  255. package/src/extensions/Video/index.ts +1 -0
  256. package/src/extensions/Video/store.ts +15 -0
  257. package/src/extensions/index.ts +122 -0
  258. package/src/hooks/useActive.tsx +24 -0
  259. package/src/hooks/useAttributes.tsx +45 -0
  260. package/src/hooks/useCopy.tsx +20 -0
  261. package/src/hooks/useEditorState.tsx +23 -0
  262. package/src/hooks/useExtension.tsx +29 -0
  263. package/src/index.ts +8 -0
  264. package/src/lib/utils.ts +7 -0
  265. package/src/locale-bundle.ts +3 -0
  266. package/src/locales/en.ts +173 -0
  267. package/src/locales/hu.ts +173 -0
  268. package/src/locales/index.tsx +163 -0
  269. package/src/locales/pt-br.ts +173 -0
  270. package/src/locales/vi.ts +173 -0
  271. package/src/locales/zh-cn.ts +173 -0
  272. package/src/plugins/DragHandle/index.ts +375 -0
  273. package/src/plugins/DragHandle/range.ts +114 -0
  274. package/src/plugins/DragHandle/utils.ts +80 -0
  275. package/src/plugins/image-upload.ts +160 -0
  276. package/src/store/ProviderRichText.tsx +53 -0
  277. package/src/store/editableEditor.ts +15 -0
  278. package/src/store/fast-context.tsx +70 -0
  279. package/src/store/store.ts +35 -0
  280. package/src/styles/ProseMirror.scss +176 -0
  281. package/src/styles/columns.scss +23 -0
  282. package/src/styles/editor.scss +411 -0
  283. package/src/styles/global.scss +87 -0
  284. package/src/styles/index.scss +5 -0
  285. package/src/styles/mention.scss +6 -0
  286. package/src/theme/theme.ts +15 -0
  287. package/src/types.ts +271 -0
  288. package/src/utils/_event.ts +55 -0
  289. package/src/utils/color.ts +67 -0
  290. package/src/utils/columns.ts +142 -0
  291. package/src/utils/customEvents/customEvents.ts +18 -0
  292. package/src/utils/customEvents/events.constant.ts +11 -0
  293. package/src/utils/delete-node.ts +46 -0
  294. package/src/utils/dom-dataset.ts +121 -0
  295. package/src/utils/download.ts +17 -0
  296. package/src/utils/dynamicCSS.ts +192 -0
  297. package/src/utils/editor-container-size.ts +28 -0
  298. package/src/utils/file.ts +112 -0
  299. package/src/utils/getRenderContainer.ts +41 -0
  300. package/src/utils/indent.ts +99 -0
  301. package/src/utils/is-mobile.ts +57 -0
  302. package/src/utils/json.ts +18 -0
  303. package/src/utils/line-height.ts +109 -0
  304. package/src/utils/lru-cache.ts +145 -0
  305. package/src/utils/mitt.ts +114 -0
  306. package/src/utils/node.ts +92 -0
  307. package/src/utils/pdf.ts +72 -0
  308. package/src/utils/plateform.ts +49 -0
  309. package/src/utils/shortId.ts +5 -0
  310. package/src/utils/storage.ts +18 -0
  311. package/src/utils/utils.ts +71 -0
  312. package/src/vite-env.d.ts +3 -0
  313. package/lib/RichTextEditor-BwbqJLnA.cjs +0 -141
  314. package/lib/RichTextEditor-iGJ6-rbq.js +0 -8833
  315. package/lib/extension-bundle.cjs +0 -33
  316. package/lib/extension-bundle.d.cts +0 -947
  317. package/lib/extension-bundle.d.ts +0 -947
  318. package/lib/extension-bundle.js +0 -5755
  319. package/lib/index-DV-nXpU1.cjs +0 -1
  320. package/lib/index-M6H3FoBi.js +0 -1147
  321. package/lib/index.cjs +0 -1
  322. package/lib/index.d.cts +0 -513
  323. package/lib/index.d.ts +0 -513
  324. package/lib/index.js +0 -16
  325. package/lib/locale-bundle.cjs +0 -1
  326. package/lib/locale-bundle.d.cts +0 -1140
  327. package/lib/locale-bundle.d.ts +0 -1140
  328. package/lib/locale-bundle.js +0 -9
  329. package/lib/style.css +0 -1
  330. package/lib/tiptap-DkWHMWDt.js +0 -6061
  331. package/lib/tiptap-gBG-1T-V.cjs +0 -116
  332. package/lib/vendor-BJ0Yf78E.cjs +0 -8114
  333. package/lib/vendor-Cpa6z-M0.js +0 -67575
@@ -0,0 +1,112 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ import type { Command } from '@tiptap/core';
3
+ import { Extension } from '@tiptap/core';
4
+ import type { Transaction } from '@tiptap/pm/state';
5
+ import { CellSelection } from '@tiptap/pm/tables';
6
+
7
+ export interface TableCellBackgroundOptions {
8
+ HTMLAttributes: Record<string, any>
9
+ types?: any
10
+ }
11
+
12
+ declare module '@tiptap/core' {
13
+ interface Commands<ReturnType> {
14
+ tableCellBackground: {
15
+ setTableCellBackground: (color: string) => ReturnType
16
+ unsetTableCellBackground: () => ReturnType
17
+ }
18
+ }
19
+ }
20
+
21
+ export function setCellBackgroundMarkup(tr: Transaction, pos: number, backgroundColor: string): Transaction {
22
+ if (!tr.doc) {
23
+ return tr;
24
+ }
25
+
26
+ const node = tr.doc.nodeAt(pos);
27
+ if (!node) {
28
+ return tr;
29
+ }
30
+
31
+ if (backgroundColor === node.attrs.backgroundColor) {
32
+ return tr;
33
+ }
34
+
35
+ const nodeAttrs = {
36
+ ...node.attrs,
37
+ backgroundColor,
38
+ };
39
+
40
+ return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
41
+ }
42
+
43
+ export function updateCellBackground(tr: Transaction, options: TableCellBackgroundOptions, backgroundColor: string): Transaction {
44
+ const { doc, selection } = tr;
45
+
46
+ if (!doc || !selection || !(selection instanceof CellSelection)) {
47
+ return tr;
48
+ }
49
+
50
+ selection.forEachCell((node, pos) => {
51
+ tr = setCellBackgroundMarkup(tr, pos, backgroundColor);
52
+ });
53
+
54
+ return tr;
55
+ }
56
+
57
+ export function createCellBackgroundCommand(backgroundColor: string, options: TableCellBackgroundOptions): Command {
58
+ return ({ tr, state, dispatch }) => {
59
+ const { selection } = state;
60
+ tr = tr.setSelection(selection);
61
+ tr = updateCellBackground(tr, options, backgroundColor);
62
+
63
+ if (tr.docChanged) {
64
+ dispatch?.(tr);
65
+ return true;
66
+ }
67
+
68
+ return false;
69
+ };
70
+ }
71
+
72
+ // @ts-ignore
73
+ export const TableCellBackground = Extension.create<TableCellBackgroundOptions>({
74
+ name: 'tableCellBackground',
75
+ addOptions() {
76
+ return {
77
+ types: ['tableCell'],
78
+ HTMLAttributes: {},
79
+ };
80
+ },
81
+
82
+ addGlobalAttributes() {
83
+ return [
84
+ {
85
+ types: this.options.types,
86
+ attributes: {
87
+ backgroundColor: {
88
+ parseHTML: (element) => {
89
+ return element.style.backgroundColor || '';
90
+ },
91
+ renderHTML: (attributes) => {
92
+ if (!attributes.backgroundColor || attributes.backgroundColor === '') {
93
+ return {};
94
+ } else {
95
+ return {
96
+ style: `background-color: ${attributes.backgroundColor}`,
97
+ };
98
+ }
99
+ },
100
+ },
101
+ },
102
+ },
103
+ ];
104
+ },
105
+ addCommands() {
106
+ return {
107
+ setTableCellBackground: (backgroundColor: string) =>
108
+ createCellBackgroundCommand(backgroundColor, this.options),
109
+ unsetTableCellBackground: () => createCellBackgroundCommand('', this.options),
110
+ };
111
+ },
112
+ });
@@ -0,0 +1,132 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { Popover, PopoverContent, PopoverTrigger } from 'reactjs-tiptap-editor-pro/components';
4
+ import {
5
+ TABLE_DEFAULT_SELECTED_GRID_SIZE,
6
+ TABLE_INIT_GRID_SIZE,
7
+ TABLE_MAX_GRID_SIZE,
8
+ } from 'reactjs-tiptap-editor-pro/constants';
9
+ import { isMobile } from 'reactjs-tiptap-editor-pro/utils/is-mobile';
10
+
11
+ const createArray = (length: number) => Array.from({ length }).map((_, index) => index + 1);
12
+
13
+ interface IPropsCreateTablePopover {
14
+ createTable: any
15
+ children: any
16
+ }
17
+
18
+ export interface GridSize {
19
+ rows: number
20
+ cols: number
21
+ }
22
+
23
+ export interface CreateTablePayload extends GridSize {
24
+ withHeaderRow: boolean
25
+ }
26
+
27
+ function CreateTablePopover(props: IPropsCreateTablePopover) {
28
+ const [withHeaderRow, setWithHeaderRow] = useState<boolean>(true);
29
+ const [tableGridSize, setTableGridSize] = useState<GridSize>({
30
+ rows: isMobile() ? TABLE_MAX_GRID_SIZE : TABLE_INIT_GRID_SIZE,
31
+ cols: isMobile() ? TABLE_MAX_GRID_SIZE : TABLE_INIT_GRID_SIZE,
32
+ });
33
+
34
+ const [selectedTableGridSize, setSelectedTableGridSize] = useState<GridSize>({
35
+ rows: TABLE_DEFAULT_SELECTED_GRID_SIZE,
36
+ cols: TABLE_DEFAULT_SELECTED_GRID_SIZE,
37
+ });
38
+
39
+ function selectTableGridSize(rows: number, cols: number): void {
40
+ if (rows === tableGridSize.rows) {
41
+ setTableGridSize((prev) => {
42
+ return {
43
+ ...prev,
44
+ rows: Math.min(rows + 1, TABLE_MAX_GRID_SIZE),
45
+ };
46
+ });
47
+ }
48
+
49
+ if (cols === tableGridSize.cols) {
50
+ setTableGridSize((prev) => {
51
+ return {
52
+ ...prev,
53
+ cols: Math.min(cols + 1, TABLE_MAX_GRID_SIZE),
54
+ };
55
+ });
56
+ }
57
+
58
+ setSelectedTableGridSize({
59
+ rows,
60
+ cols,
61
+ });
62
+ }
63
+
64
+ function onMouseDown(rows: number, cols: number) {
65
+ props?.createTable({ rows, cols, withHeaderRow });
66
+ resetTableGridSize();
67
+ }
68
+
69
+ function resetTableGridSize(): void {
70
+ setWithHeaderRow(false);
71
+
72
+ setTableGridSize({
73
+ rows: TABLE_INIT_GRID_SIZE,
74
+ cols: TABLE_INIT_GRID_SIZE,
75
+ });
76
+
77
+ setSelectedTableGridSize({
78
+ rows: TABLE_DEFAULT_SELECTED_GRID_SIZE,
79
+ cols: TABLE_DEFAULT_SELECTED_GRID_SIZE,
80
+ });
81
+ }
82
+
83
+ return (
84
+ <Popover modal>
85
+ <PopoverTrigger asChild>
86
+ {props?.children}
87
+ </PopoverTrigger>
88
+
89
+ <PopoverContent align="start"
90
+ className="w-full !p-2"
91
+ side="bottom"
92
+ >
93
+ <div className="table-grid-size-editor p-0">
94
+ <div className="flex flex-col flex-wrap justify-between gap-1">
95
+ {createArray(tableGridSize?.rows)?.map((row: any) => {
96
+ return (
97
+ <div className="flex gap-1"
98
+ key={`r-${row}`}
99
+ >
100
+ {createArray(tableGridSize?.cols)?.map((col: any) => {
101
+ return (
102
+ <div
103
+ key={`c-${col}`}
104
+ onMouseDown={() => onMouseDown(row, col)}
105
+ onMouseOver={() => selectTableGridSize(row, col)}
106
+ className={`cursor-pointer border-border ${
107
+ col <= selectedTableGridSize.cols
108
+ && row <= selectedTableGridSize.rows
109
+ && 'tableCellActive !bg-foreground'
110
+ }`}
111
+ >
112
+ <div className="box-border size-4 rounded-[2px] !border border-solid !border-border p-1"></div>
113
+ </div>
114
+ );
115
+ })}
116
+ </div>
117
+ );
118
+ })}
119
+ </div>
120
+
121
+ <div className="mt-2 text-center text-sm text-zinc-600">
122
+ {selectedTableGridSize.rows}
123
+ x
124
+ {selectedTableGridSize.cols}
125
+ </div>
126
+ </div>
127
+ </PopoverContent>
128
+ </Popover>
129
+ );
130
+ }
131
+
132
+ export default CreateTablePopover;
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+
3
+ import { ActionButton } from 'reactjs-tiptap-editor-pro/components';
4
+ import CreateTablePopover from 'reactjs-tiptap-editor-pro/extensions/Table/components/CreateTablePopover';
5
+ import type { ButtonViewReturnComponentProps } from 'reactjs-tiptap-editor-pro/types';
6
+
7
+ interface IPropsTableActionButton {
8
+ editor: any
9
+ icon?: any
10
+ tooltip?: string
11
+ disabled?: boolean
12
+ color?: string
13
+ action?: ButtonViewReturnComponentProps['action']
14
+ isActive?: ButtonViewReturnComponentProps['isActive']
15
+ }
16
+
17
+ function TableActionButton(props: IPropsTableActionButton) {
18
+ function createTable(options: any) {
19
+ if (!props.disabled) {
20
+ props.editor
21
+ .chain()
22
+ .focus()
23
+ .insertTable({ ...options, withHeaderRow: false })
24
+ .run();
25
+ }
26
+ }
27
+
28
+ return (
29
+ <CreateTablePopover createTable={createTable}>
30
+ <ActionButton
31
+ icon={props?.icon}
32
+ tooltip={props?.tooltip}
33
+ disabled={props?.disabled}
34
+ color={props?.color}
35
+ action={props?.action}
36
+ isActive={props?.isActive}
37
+ />
38
+ </CreateTablePopover>
39
+ );
40
+ }
41
+
42
+ export default TableActionButton;
@@ -0,0 +1,6 @@
1
+ export { type TableRowOptions, TableRow } from '@tiptap/extension-table-row';
2
+ export { Table, type TableOptions } from './Table';
3
+ export { TableCell, type TableCellOptions } from '@tiptap/extension-table-cell';
4
+ export { TableHeader, type TableHeaderOptions } from '@tiptap/extension-table-header';
5
+
6
+ export { TableCellBackground, type TableCellBackgroundOptions } from './cell-background';
@@ -0,0 +1,352 @@
1
+ import { type Editor, findParentNode } from '@tiptap/core';
2
+ import { type Node, type ResolvedPos } from '@tiptap/pm/model';
3
+ import { type EditorState, type Selection, type Transaction } from '@tiptap/pm/state';
4
+ import { CellSelection, TableMap } from '@tiptap/pm/tables';
5
+ import { type EditorView } from '@tiptap/pm/view';
6
+
7
+ import Table from './Table';
8
+
9
+ export function isRectSelected (rect: any) {
10
+ return (selection: CellSelection) => {
11
+ const map = TableMap.get(selection.$anchorCell.node(-1));
12
+ const start = selection.$anchorCell.start(-1);
13
+ const cells = map.cellsInRect(rect);
14
+ const selectedCells = map.cellsInRect(
15
+ map.rectBetween(
16
+ selection.$anchorCell.pos - start,
17
+ selection.$headCell.pos - start,
18
+ ),
19
+ );
20
+
21
+ for (let i = 0, count = cells.length; i < count; i += 1) {
22
+ if (!selectedCells.includes(cells[i])) {
23
+ return false;
24
+ }
25
+ }
26
+
27
+ return true;
28
+ };
29
+ }
30
+
31
+ export function findTable (selection: Selection) {
32
+ return findParentNode(
33
+ (node) => node.type.spec.tableRole && node.type.spec.tableRole === 'table',
34
+ )(selection);
35
+ }
36
+
37
+ export function isCellSelection (selection: any) {
38
+ return selection instanceof CellSelection;
39
+ }
40
+
41
+ export function isColumnSelected (columnIndex: number) {
42
+ return (selection: any) => {
43
+ if (isCellSelection(selection)) {
44
+ const map = TableMap.get(selection.$anchorCell.node(-1));
45
+
46
+ return isRectSelected({
47
+ left: columnIndex,
48
+ right: columnIndex + 1,
49
+ top: 0,
50
+ bottom: map.height,
51
+ })(selection);
52
+ }
53
+
54
+ return false;
55
+ };
56
+ }
57
+
58
+ export function isRowSelected (rowIndex: number) {
59
+ return (selection: any) => {
60
+ if (isCellSelection(selection)) {
61
+ const map = TableMap.get(selection.$anchorCell.node(-1));
62
+
63
+ return isRectSelected({
64
+ left: 0,
65
+ right: map.width,
66
+ top: rowIndex,
67
+ bottom: rowIndex + 1,
68
+ })(selection);
69
+ }
70
+
71
+ return false;
72
+ };
73
+ }
74
+
75
+ export function isTableSelected (selection: any) {
76
+ if (isCellSelection(selection)) {
77
+ const map = TableMap.get(selection.$anchorCell.node(-1));
78
+
79
+ return isRectSelected({
80
+ left: 0,
81
+ right: map.width,
82
+ top: 0,
83
+ bottom: map.height,
84
+ })(selection);
85
+ }
86
+
87
+ return false;
88
+ }
89
+
90
+ export function getCellsInColumn (columnIndex: number | number[]) {
91
+ return (selection: Selection) => {
92
+ const table = findTable(selection);
93
+ if (table) {
94
+ const map = TableMap.get(table.node);
95
+ const indexes = Array.isArray(columnIndex)
96
+ ? columnIndex
97
+ : Array.from([columnIndex]);
98
+
99
+ return indexes.reduce(
100
+ (acc, index) => {
101
+ if (index >= 0 && index <= map.width - 1) {
102
+ const cells = map.cellsInRect({
103
+ left: index,
104
+ right: index + 1,
105
+ top: 0,
106
+ bottom: map.height,
107
+ });
108
+
109
+ return acc.concat(
110
+ cells.map((nodePos) => {
111
+ const node = table.node.nodeAt(nodePos);
112
+ const pos = nodePos + table.start;
113
+
114
+ return { pos, start: pos + 1, node };
115
+ }),
116
+ );
117
+ }
118
+
119
+ return acc;
120
+ },
121
+ [] as { pos: number; start: number; node: Node | null | undefined }[],
122
+ );
123
+ }
124
+ return null;
125
+ };
126
+ }
127
+
128
+ export function getCellsInRow (rowIndex: number | number[]) {
129
+ return (selection: Selection) => {
130
+ const table = findTable(selection);
131
+
132
+ if (table) {
133
+ const map = TableMap.get(table.node);
134
+ const indexes = Array.isArray(rowIndex)
135
+ ? rowIndex
136
+ : Array.from([rowIndex]);
137
+
138
+ return indexes.reduce(
139
+ (acc, index) => {
140
+ if (index >= 0 && index <= map.height - 1) {
141
+ const cells = map.cellsInRect({
142
+ left: 0,
143
+ right: map.width,
144
+ top: index,
145
+ bottom: index + 1,
146
+ });
147
+
148
+ return acc.concat(
149
+ cells.map((nodePos) => {
150
+ const node = table.node.nodeAt(nodePos);
151
+ const pos = nodePos + table.start;
152
+ return { pos, start: pos + 1, node };
153
+ }),
154
+ );
155
+ }
156
+
157
+ return acc;
158
+ },
159
+ [] as { pos: number; start: number; node: Node | null | undefined }[],
160
+ );
161
+ }
162
+
163
+ return null;
164
+ };
165
+ }
166
+
167
+ export function getCellsInTable (selection: Selection) {
168
+ const table = findTable(selection);
169
+
170
+ if (table) {
171
+ const map = TableMap.get(table.node);
172
+ const cells = map.cellsInRect({
173
+ left: 0,
174
+ right: map.width,
175
+ top: 0,
176
+ bottom: map.height,
177
+ });
178
+
179
+ return cells.map((nodePos) => {
180
+ const node = table.node.nodeAt(nodePos);
181
+ const pos = nodePos + table.start;
182
+
183
+ return { pos, start: pos + 1, node };
184
+ });
185
+ }
186
+
187
+ return null;
188
+ }
189
+
190
+ export function findParentNodeClosestToPos ($pos: ResolvedPos,
191
+ predicate: (node: Node) => boolean) {
192
+ for (let i = $pos.depth; i > 0; i -= 1) {
193
+ const node = $pos.node(i);
194
+
195
+ if (predicate(node)) {
196
+ return {
197
+ pos: i > 0 ? $pos.before(i) : 0,
198
+ start: $pos.start(i),
199
+ depth: i,
200
+ node,
201
+ };
202
+ }
203
+ }
204
+
205
+ return null;
206
+ }
207
+
208
+ export function findCellClosestToPos ($pos: ResolvedPos) {
209
+ const predicate = (node: Node) =>
210
+ node.type.spec.tableRole && /cell/i.test(node.type.spec.tableRole);
211
+
212
+ return findParentNodeClosestToPos($pos, predicate);
213
+ }
214
+
215
+ function select (type: 'row' | 'column') {
216
+ return (index: number) => (tr: Transaction) => {
217
+ const table = findTable(tr.selection);
218
+ const isRowSelection = type === 'row';
219
+
220
+ if (table) {
221
+ const map = TableMap.get(table.node);
222
+
223
+ // Check if the index is valid
224
+ if (index >= 0 && index < (isRowSelection ? map.height : map.width)) {
225
+ const left = isRowSelection ? 0 : index;
226
+ const top = isRowSelection ? index : 0;
227
+ const right = isRowSelection ? map.width : index + 1;
228
+ const bottom = isRowSelection ? index + 1 : map.height;
229
+
230
+ const cellsInFirstRow = map.cellsInRect({
231
+ left,
232
+ top,
233
+ right: isRowSelection ? right : left + 1,
234
+ bottom: isRowSelection ? top + 1 : bottom,
235
+ });
236
+
237
+ const cellsInLastRow =
238
+ bottom - top === 1
239
+ ? cellsInFirstRow
240
+ : map.cellsInRect({
241
+ left: isRowSelection ? left : right - 1,
242
+ top: isRowSelection ? bottom - 1 : top,
243
+ right,
244
+ bottom,
245
+ });
246
+
247
+ const head = table.start + cellsInFirstRow[0];
248
+ const anchor = table.start + cellsInLastRow[cellsInLastRow.length - 1];
249
+ const $head = tr.doc.resolve(head);
250
+ const $anchor = tr.doc.resolve(anchor);
251
+ return tr.setSelection(new CellSelection($anchor, $head));
252
+ }
253
+ }
254
+ return tr;
255
+ };
256
+ }
257
+
258
+ export const selectColumn = select('column');
259
+
260
+ export const selectRow = select('row');
261
+
262
+ export function selectTable (tr: Transaction) {
263
+ const table = findTable(tr.selection);
264
+
265
+ if (table) {
266
+ const { map } = TableMap.get(table.node);
267
+
268
+ if (map && map.length > 0) {
269
+ const head = table.start + map[0];
270
+ const anchor = table.start + map[map.length - 1];
271
+ const $head = tr.doc.resolve(head);
272
+ const $anchor = tr.doc.resolve(anchor);
273
+ return tr.setSelection(new CellSelection($anchor, $head));
274
+ }
275
+ }
276
+
277
+ return tr;
278
+ }
279
+
280
+ export function isColumnGripSelected ({
281
+ editor,
282
+ view,
283
+ state,
284
+ from,
285
+ }: {
286
+ editor: Editor;
287
+ view: EditorView;
288
+ state: EditorState;
289
+ from: number;
290
+ }) {
291
+ const domAtPos = view.domAtPos(from).node as HTMLElement;
292
+ const nodeDOM = view.nodeDOM(from) as HTMLElement;
293
+ const node = nodeDOM || domAtPos;
294
+
295
+ if (
296
+ !editor.isActive(Table.name) ||
297
+ !node ||
298
+ isTableSelected(state.selection)
299
+ ) {
300
+ return false;
301
+ }
302
+
303
+ let container = node;
304
+
305
+ while (container && !['TD', 'TH'].includes(container.tagName)) {
306
+ container = container.parentElement!;
307
+ }
308
+
309
+ const gripColumn =
310
+ container &&
311
+ container.querySelector &&
312
+ container.querySelector('a.grip-column.selected');
313
+
314
+ return !!gripColumn;
315
+ }
316
+
317
+ export function isRowGripSelected ({
318
+ editor,
319
+ view,
320
+ state,
321
+ from,
322
+ }: {
323
+ editor: Editor;
324
+ view: EditorView;
325
+ state: EditorState;
326
+ from: number;
327
+ }) {
328
+ const domAtPos = view.domAtPos(from).node as HTMLElement;
329
+ const nodeDOM = view.nodeDOM(from) as HTMLElement;
330
+ const node = nodeDOM || domAtPos;
331
+
332
+ if (
333
+ !editor.isActive(Table.name) ||
334
+ !node ||
335
+ isTableSelected(state.selection)
336
+ ) {
337
+ return false;
338
+ }
339
+
340
+ let container = node;
341
+
342
+ while (container && !['TD', 'TH'].includes(container.tagName)) {
343
+ container = container.parentElement!;
344
+ }
345
+
346
+ const gripRow =
347
+ container &&
348
+ container.querySelector &&
349
+ container.querySelector('a.grip-row.selected');
350
+
351
+ return !!gripRow;
352
+ }