store.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { useContext } from 'react'
  2. import {
  3. useStore as useZustandStore,
  4. } from 'zustand'
  5. import { createStore } from 'zustand/vanilla'
  6. import NoteEditorContext from './context'
  7. type Shape = {
  8. linkAnchorElement: HTMLElement | null
  9. setLinkAnchorElement: (open?: boolean) => void
  10. linkOperatorShow: boolean
  11. setLinkOperatorShow: (linkOperatorShow: boolean) => void
  12. selectedIsBold: boolean
  13. setSelectedIsBold: (selectedIsBold: boolean) => void
  14. selectedIsItalic: boolean
  15. setSelectedIsItalic: (selectedIsItalic: boolean) => void
  16. selectedIsStrikeThrough: boolean
  17. setSelectedIsStrikeThrough: (selectedIsStrikeThrough: boolean) => void
  18. selectedLinkUrl: string
  19. setSelectedLinkUrl: (selectedLinkUrl: string) => void
  20. selectedIsLink: boolean
  21. setSelectedIsLink: (selectedIsLink: boolean) => void
  22. selectedIsBullet: boolean
  23. setSelectedIsBullet: (selectedIsBullet: boolean) => void
  24. }
  25. export const createNoteEditorStore = () => {
  26. return createStore<Shape>(set => ({
  27. linkAnchorElement: null,
  28. setLinkAnchorElement: (open) => {
  29. if (open) {
  30. setTimeout(() => {
  31. const nativeSelection = window.getSelection()
  32. if (nativeSelection?.focusNode) {
  33. const parent = nativeSelection.focusNode.parentElement
  34. set(() => ({ linkAnchorElement: parent }))
  35. }
  36. })
  37. }
  38. else {
  39. set(() => ({ linkAnchorElement: null }))
  40. }
  41. },
  42. linkOperatorShow: false,
  43. setLinkOperatorShow: linkOperatorShow => set(() => ({ linkOperatorShow })),
  44. selectedIsBold: false,
  45. setSelectedIsBold: selectedIsBold => set(() => ({ selectedIsBold })),
  46. selectedIsItalic: false,
  47. setSelectedIsItalic: selectedIsItalic => set(() => ({ selectedIsItalic })),
  48. selectedIsStrikeThrough: false,
  49. setSelectedIsStrikeThrough: selectedIsStrikeThrough => set(() => ({ selectedIsStrikeThrough })),
  50. selectedLinkUrl: '',
  51. setSelectedLinkUrl: selectedLinkUrl => set(() => ({ selectedLinkUrl })),
  52. selectedIsLink: false,
  53. setSelectedIsLink: selectedIsLink => set(() => ({ selectedIsLink })),
  54. selectedIsBullet: false,
  55. setSelectedIsBullet: selectedIsBullet => set(() => ({ selectedIsBullet })),
  56. }))
  57. }
  58. export function useStore<T>(selector: (state: Shape) => T): T {
  59. const store = useContext(NoteEditorContext)
  60. if (!store)
  61. throw new Error('Missing NoteEditorContext.Provider in the tree')
  62. return useZustandStore(store, selector)
  63. }
  64. export const useNoteEditorStore = () => {
  65. return useContext(NoteEditorContext)!
  66. }