wwf
2025-05-20 938c3e5a587ce950a94964ea509b9e7f8834dfae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import {
  useCallback,
  useEffect,
} from 'react'
import {
  $getSelection,
  $isRangeSelection,
} from 'lexical'
import { mergeRegister } from '@lexical/utils'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import type { LinkNode } from '@lexical/link'
import { $isLinkNode } from '@lexical/link'
import { $isListItemNode } from '@lexical/list'
import { getSelectedNode } from '../../utils'
import { useNoteEditorStore } from '../../store'
 
export const useFormatDetector = () => {
  const [editor] = useLexicalComposerContext()
  const noteEditorStore = useNoteEditorStore()
 
  const handleFormat = useCallback(() => {
    editor.getEditorState().read(() => {
      if (editor.isComposing())
        return
 
      const selection = $getSelection()
 
      if ($isRangeSelection(selection)) {
        const node = getSelectedNode(selection)
        const {
          setSelectedIsBold,
          setSelectedIsItalic,
          setSelectedIsStrikeThrough,
          setSelectedLinkUrl,
          setSelectedIsLink,
          setSelectedIsBullet,
        } = noteEditorStore.getState()
        setSelectedIsBold(selection.hasFormat('bold'))
        setSelectedIsItalic(selection.hasFormat('italic'))
        setSelectedIsStrikeThrough(selection.hasFormat('strikethrough'))
        const parent = node.getParent()
        if ($isLinkNode(parent) || $isLinkNode(node)) {
          const linkUrl = ($isLinkNode(parent) ? parent : node as LinkNode).getURL()
          setSelectedLinkUrl(linkUrl)
          setSelectedIsLink(true)
        }
        else {
          setSelectedLinkUrl('')
          setSelectedIsLink(false)
        }
 
        if ($isListItemNode(parent) || $isListItemNode(node))
          setSelectedIsBullet(true)
        else
          setSelectedIsBullet(false)
      }
    })
  }, [editor, noteEditorStore])
 
  useEffect(() => {
    document.addEventListener('selectionchange', handleFormat)
    return () => {
      document.removeEventListener('selectionchange', handleFormat)
    }
  }, [handleFormat])
 
  useEffect(() => {
    return mergeRegister(
      editor.registerUpdateListener(() => {
        handleFormat()
      }),
    )
  }, [editor, handleFormat])
 
  return {
    handleFormat,
  }
}