| import { | |
| createContext, | |
| useContext, | |
| useRef, | |
| } from 'react' | |
| import { | |
| create, | |
| useStore as useZustandStore, | |
| } from 'zustand' | |
| import type { | |
| FileEntity, | |
| } from './types' | |
| type Shape = { | |
| files: FileEntity[] | |
| setFiles: (files: FileEntity[]) => void | |
| } | |
| export const createFileStore = ( | |
| value: FileEntity[] = [], | |
| onChange?: (files: FileEntity[]) => void, | |
| ) => { | |
| return create<Shape>(set => ({ | |
| files: [...value], | |
| setFiles: (files) => { | |
| set({ files }) | |
| onChange?.(files) | |
| }, | |
| })) | |
| } | |
| type FileStore = ReturnType<typeof createFileStore> | |
| export const FileContext = createContext<FileStore | null>(null) | |
| export function useStore<T>(selector: (state: Shape) => T): T { | |
| const store = useContext(FileContext) | |
| if (!store) | |
| throw new Error('Missing FileContext.Provider in the tree') | |
| return useZustandStore(store, selector) | |
| } | |
| export const useFileStore = () => { | |
| return useContext(FileContext)! | |
| } | |
| type FileProviderProps = { | |
| children: React.ReactNode | |
| value?: FileEntity[] | |
| onChange?: (files: FileEntity[]) => void | |
| } | |
| export const FileContextProvider = ({ | |
| children, | |
| value, | |
| onChange, | |
| }: FileProviderProps) => { | |
| const storeRef = useRef<FileStore>() | |
| if (!storeRef.current) | |
| storeRef.current = createFileStore(value, onChange) | |
| return ( | |
| <FileContext.Provider value={storeRef.current}> | |
| {children} | |
| </FileContext.Provider> | |
| ) | |
| } | |