| 
									
										
										
										
											2023-02-06 09:34:50 +00:00
										 |  |  | import type { Editor } from '@tiptap/vue-3' | 
					
						
							| 
									
										
										
										
											2022-12-13 13:02:43 +00:00
										 |  |  | import { Extension, useEditor } from '@tiptap/vue-3' | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  | import Placeholder from '@tiptap/extension-placeholder' | 
					
						
							|  |  |  | import Document from '@tiptap/extension-document' | 
					
						
							|  |  |  | import Paragraph from '@tiptap/extension-paragraph' | 
					
						
							|  |  |  | import Text from '@tiptap/extension-text' | 
					
						
							|  |  |  | import Mention from '@tiptap/extension-mention' | 
					
						
							| 
									
										
										
										
											2022-11-26 02:01:50 +00:00
										 |  |  | import HardBreak from '@tiptap/extension-hard-break' | 
					
						
							|  |  |  | import Bold from '@tiptap/extension-bold' | 
					
						
							|  |  |  | import Italic from '@tiptap/extension-italic' | 
					
						
							|  |  |  | import Code from '@tiptap/extension-code' | 
					
						
							| 
									
										
										
										
											2023-01-10 21:16:56 +00:00
										 |  |  | import History from '@tiptap/extension-history' | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  | import { Plugin } from 'prosemirror-state' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import type { Ref } from 'vue' | 
					
						
							| 
									
										
										
										
											2023-01-16 11:40:47 +00:00
										 |  |  | import { TiptapEmojiSuggestion, TiptapHashtagSuggestion, TiptapMentionSuggestion } from './tiptap/suggestion' | 
					
						
							|  |  |  | import { TiptapPluginCodeBlockShiki } from './tiptap/shiki' | 
					
						
							|  |  |  | import { TiptapPluginCustomEmoji } from './tiptap/custom-emoji' | 
					
						
							|  |  |  | import { TiptapPluginEmoji } from './tiptap/emoji' | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | export interface UseTiptapOptions { | 
					
						
							| 
									
										
										
										
											2023-01-04 10:21:18 +00:00
										 |  |  |   content: Ref<string> | 
					
						
							| 
									
										
										
										
											2022-11-29 22:47:24 +00:00
										 |  |  |   placeholder: Ref<string | undefined> | 
					
						
							| 
									
										
										
										
											2022-11-25 14:07:31 +00:00
										 |  |  |   onSubmit: () => void | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |   onFocus: () => void | 
					
						
							|  |  |  |   onPaste: (event: ClipboardEvent) => void | 
					
						
							|  |  |  |   autofocus: boolean | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function useTiptap(options: UseTiptapOptions) { | 
					
						
							| 
									
										
										
										
											2023-02-06 09:34:50 +00:00
										 |  |  |   if (process.server) | 
					
						
							|  |  |  |     return { editor: ref<Editor | undefined>() } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |   const { | 
					
						
							|  |  |  |     autofocus, | 
					
						
							|  |  |  |     content, | 
					
						
							|  |  |  |     placeholder, | 
					
						
							|  |  |  |   } = options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const editor = useEditor({ | 
					
						
							|  |  |  |     content: content.value, | 
					
						
							|  |  |  |     extensions: [ | 
					
						
							|  |  |  |       Document, | 
					
						
							|  |  |  |       Paragraph, | 
					
						
							| 
									
										
										
										
											2022-11-26 02:01:50 +00:00
										 |  |  |       HardBreak, | 
					
						
							|  |  |  |       Bold, | 
					
						
							|  |  |  |       Italic, | 
					
						
							|  |  |  |       Code, | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |       Text, | 
					
						
							| 
									
										
										
										
											2023-01-16 11:40:47 +00:00
										 |  |  |       TiptapPluginEmoji, | 
					
						
							|  |  |  |       TiptapPluginCustomEmoji.configure({ | 
					
						
							| 
									
										
										
										
											2022-12-27 18:38:57 +00:00
										 |  |  |         inline: true, | 
					
						
							|  |  |  |         HTMLAttributes: { | 
					
						
							|  |  |  |           class: 'custom-emoji', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }), | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |       Mention.configure({ | 
					
						
							| 
									
										
										
										
											2023-01-16 11:40:47 +00:00
										 |  |  |         suggestion: TiptapMentionSuggestion, | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |       }), | 
					
						
							| 
									
										
										
										
											2022-11-26 06:55:54 +00:00
										 |  |  |       Mention | 
					
						
							| 
									
										
										
										
											2023-01-04 20:47:29 +00:00
										 |  |  |         .extend({ name: 'hashtag' }) | 
					
						
							| 
									
										
										
										
											2022-11-26 06:55:54 +00:00
										 |  |  |         .configure({ | 
					
						
							| 
									
										
										
										
											2023-01-16 11:40:47 +00:00
										 |  |  |           suggestion: TiptapHashtagSuggestion, | 
					
						
							| 
									
										
										
										
											2022-11-26 06:55:54 +00:00
										 |  |  |         }), | 
					
						
							| 
									
										
										
										
											2023-01-16 10:22:26 +00:00
										 |  |  |       Mention | 
					
						
							|  |  |  |         .extend({ name: 'emoji' }) | 
					
						
							|  |  |  |         .configure({ | 
					
						
							| 
									
										
										
										
											2023-01-16 11:40:47 +00:00
										 |  |  |           suggestion: TiptapEmojiSuggestion, | 
					
						
							| 
									
										
										
										
											2023-01-16 10:22:26 +00:00
										 |  |  |         }), | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |       Placeholder.configure({ | 
					
						
							| 
									
										
										
										
											2023-01-09 09:34:26 +00:00
										 |  |  |         placeholder: () => placeholder.value!, | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |       }), | 
					
						
							| 
									
										
										
										
											2023-01-16 11:40:47 +00:00
										 |  |  |       TiptapPluginCodeBlockShiki, | 
					
						
							| 
									
										
										
										
											2023-01-10 21:16:56 +00:00
										 |  |  |       History.configure({ | 
					
						
							|  |  |  |         depth: 10, | 
					
						
							|  |  |  |       }), | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |       Extension.create({ | 
					
						
							|  |  |  |         name: 'api', | 
					
						
							|  |  |  |         addKeyboardShortcuts() { | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             'Mod-Enter': () => { | 
					
						
							| 
									
										
										
										
											2022-11-25 14:07:31 +00:00
										 |  |  |               options.onSubmit() | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |               return true | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         onFocus() { | 
					
						
							|  |  |  |           options.onFocus() | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         addProseMirrorPlugins() { | 
					
						
							|  |  |  |           return [ | 
					
						
							|  |  |  |             new Plugin({ | 
					
						
							|  |  |  |               props: { | 
					
						
							|  |  |  |                 handleDOMEvents: { | 
					
						
							|  |  |  |                   paste(view, event) { | 
					
						
							|  |  |  |                     options.onPaste(event) | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             }), | 
					
						
							|  |  |  |           ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  |     onUpdate({ editor }) { | 
					
						
							|  |  |  |       content.value = editor.getHTML() | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     editorProps: { | 
					
						
							|  |  |  |       attributes: { | 
					
						
							|  |  |  |         class: 'content-editor content-rich', | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     autofocus, | 
					
						
							|  |  |  |     editable: true, | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-25 18:10:17 +00:00
										 |  |  |   watch(content, (value) => { | 
					
						
							|  |  |  |     if (editor.value?.getHTML() === value) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     editor.value?.commands.setContent(value || '', false) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2023-01-09 09:34:26 +00:00
										 |  |  |   watch(placeholder, () => { | 
					
						
							|  |  |  |     editor.value?.view.dispatch(editor.value?.state.tr) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2022-11-25 18:10:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-25 13:21:02 +00:00
										 |  |  |   return { | 
					
						
							|  |  |  |     editor, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |