history-block-replacement-block.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import type { FC } from 'react'
  2. import {
  3. useCallback,
  4. useEffect,
  5. } from 'react'
  6. import { $applyNodeReplacement } from 'lexical'
  7. import { mergeRegister } from '@lexical/utils'
  8. import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
  9. import { decoratorTransform } from '../utils'
  10. import { HISTORY_PLACEHOLDER_TEXT } from '../constants'
  11. import {
  12. $createHistoryBlockNode,
  13. HistoryBlockNode,
  14. } from './history-block/node'
  15. import type { HistoryBlockProps } from './history-block/index'
  16. import { CustomTextNode } from './custom-text/node'
  17. const REGEX = new RegExp(HISTORY_PLACEHOLDER_TEXT)
  18. const HistoryBlockReplacementBlock: FC<HistoryBlockProps> = ({
  19. roleName,
  20. onEditRole,
  21. onInsert,
  22. }) => {
  23. const [editor] = useLexicalComposerContext()
  24. useEffect(() => {
  25. if (!editor.hasNodes([HistoryBlockNode]))
  26. throw new Error('HistoryBlockNodePlugin: HistoryBlockNode not registered on editor')
  27. }, [editor])
  28. const createHistoryBlockNode = useCallback((): HistoryBlockNode => {
  29. if (onInsert)
  30. onInsert()
  31. return $applyNodeReplacement($createHistoryBlockNode(roleName, onEditRole))
  32. }, [roleName, onEditRole, onInsert])
  33. const getMatch = useCallback((text: string) => {
  34. const matchArr = REGEX.exec(text)
  35. if (matchArr === null)
  36. return null
  37. const startOffset = matchArr.index
  38. const endOffset = startOffset + HISTORY_PLACEHOLDER_TEXT.length
  39. return {
  40. end: endOffset,
  41. start: startOffset,
  42. }
  43. }, [])
  44. useEffect(() => {
  45. return mergeRegister(
  46. editor.registerNodeTransform(CustomTextNode, textNode => decoratorTransform(textNode, getMatch, createHistoryBlockNode)),
  47. )
  48. }, [])
  49. return null
  50. }
  51. export default HistoryBlockReplacementBlock