import { useEffect, useMemo, useState, createElement, useContext } from 'react'
import {
useEditor,
EditorContext,
EditorContent as BaseEditorContent
} from '@tiptap/react'
export { useEditorState } from '@tiptap/react'
const EDITOR_STYLE_DEFAULTS = {
bold: false,
italic: false,
strike: false,
code: false,
codeBlock: false,
orderedList: false,
bulletList: false,
blockquote: false
}
const EDITOR_STYLE_KEYS = Object.keys(EDITOR_STYLE_DEFAULTS)
export { useEditor }
export const EditorProvider = ({ children, ...options }) => {
const editor = useEditor(options)
const props = useMemo(() => ({ value: { editor } }), [editor])
return (editor) ? createElement(EditorContext.Provider, props, children) : null
}
export const EditorContent = ({ className }) => {
const { editor } = useCurrentEditor()
const props = useMemo(() => ({ editor, className }), [editor, className])
return (editor) ? createElement(BaseEditorContent, props) : null
}
export const useCurrentEditor = () => {
return useContext(EditorContext)
}
export const useEditorStyles = () => {
const { editor } = useContext(EditorContext)
const [styles, setStyles] = useState(EDITOR_STYLE_DEFAULTS)
useEffect(() => {
if (!editor) {
setStyles(EDITOR_STYLE_DEFAULTS)
return
}
const updateActiveStyles = () => {
setStyles((prev) => EDITOR_STYLE_KEYS.reduce((acc, key) => {
const val = editor.isActive(key)
return val === prev[key] ? acc : { ...acc, [key]: val }
}, prev))
}
editor.on('selectionUpdate', updateActiveStyles)
editor.on('transaction', updateActiveStyles)
return () => {
editor.off('selectionUpdate', updateActiveStyles)
editor.off('transaction', updateActiveStyles)
}
}, [editor])
return { styles }
}