index.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import {
  2. memo,
  3. useEffect,
  4. } from 'react'
  5. import {
  6. $insertNodes,
  7. COMMAND_PRIORITY_EDITOR,
  8. createCommand,
  9. } from 'lexical'
  10. import { mergeRegister } from '@lexical/utils'
  11. import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
  12. import type { HistoryBlockType } from '../../types'
  13. import {
  14. $createHistoryBlockNode,
  15. HistoryBlockNode,
  16. } from './node'
  17. export const INSERT_HISTORY_BLOCK_COMMAND = createCommand('INSERT_HISTORY_BLOCK_COMMAND')
  18. export const DELETE_HISTORY_BLOCK_COMMAND = createCommand('DELETE_HISTORY_BLOCK_COMMAND')
  19. export type RoleName = {
  20. user: string
  21. assistant: string
  22. }
  23. export type HistoryBlockProps = {
  24. roleName: RoleName
  25. onEditRole: () => void
  26. onInsert?: () => void
  27. onDelete?: () => void
  28. }
  29. const HistoryBlock = memo(({
  30. history = { user: '', assistant: '' },
  31. onEditRole = () => {},
  32. onInsert,
  33. onDelete,
  34. }: HistoryBlockType) => {
  35. const [editor] = useLexicalComposerContext()
  36. useEffect(() => {
  37. if (!editor.hasNodes([HistoryBlockNode]))
  38. throw new Error('HistoryBlockPlugin: HistoryBlock not registered on editor')
  39. return mergeRegister(
  40. editor.registerCommand(
  41. INSERT_HISTORY_BLOCK_COMMAND,
  42. () => {
  43. const historyBlockNode = $createHistoryBlockNode(history, onEditRole)
  44. $insertNodes([historyBlockNode])
  45. if (onInsert)
  46. onInsert()
  47. return true
  48. },
  49. COMMAND_PRIORITY_EDITOR,
  50. ),
  51. editor.registerCommand(
  52. DELETE_HISTORY_BLOCK_COMMAND,
  53. () => {
  54. if (onDelete)
  55. onDelete()
  56. return true
  57. },
  58. COMMAND_PRIORITY_EDITOR,
  59. ),
  60. )
  61. }, [editor, history, onEditRole, onInsert, onDelete])
  62. return null
  63. })
  64. HistoryBlock.displayName = 'HistoryBlock'
  65. export { HistoryBlock }
  66. export { HistoryBlockNode } from './node'
  67. export { default as HistoryBlockReplacementBlock } from './history-block-replacement-block'