OverviewFilesCommitsIssuesDocsReleasesPeers

holepunchto-deps / @holepunchto / keet-editor / src / use-editor.js

69 lines · javascript ref:
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 }
}