import { useMemo, useState, useEffect } from 'react' import useLocalStorageState from 'use-local-storage-state' import useSessionStorageState from 'use-session-storage-state' import { useQueryState, createParser } from 'nuqs' /** * react * This holds the editor state, using React state. * It also provides helper methods to manipulate state. * * @params {object} init - Initial pattern settings * @return {array} return - And array with get, set, and update methods */ export const useReactEditorState = (Swizzled, init = {}, setEphemeralState) => { const [state, setState] = useState(init) const update = useMemo( () => Swizzled.methods.stateUpdateFactory(setState, setEphemeralState), [setState] ) return [state, setState, update] } /** * storage * This holds the editor state, using local storage. * It also provides helper methods to manipulate state. * * @params {object} init - Initial pattern settings * @return {array} return - And array with get, set, and update methods */ export const useStorageEditorState = (Swizzled, init = {}, setEphemeralState) => { const [state, setState] = useLocalStorageState('fs-editor', { defaultValue: init }) const update = useMemo( () => Swizzled.methods.stateUpdateFactory(setState, setEphemeralState), [setState] ) return [state, setState, update] } /** * session * This holds the editor state, using session storage. * It also provides helper methods to manipulate state. * * @params {object} init - Initial pattern settings * @return {array} return - And array with get, set, and update methods */ export const useSessionEditorState = (Swizzled, init = {}, setEphemeralState) => { const [state, setState] = useSessionStorageState('fs-editor', { defaultValue: init }) const update = useMemo( () => Swizzled.methods.stateUpdateFactory(setState, setEphemeralState), [setState] ) return [state, setState, update] } /** * url * This holds the editor state, using session storage. * It also provides helper methods to manipulate state. * * @params {object} init - Initial pattern settings * @return {array} return - And array with get, set, and update methods */ export const useUrlEditorState = (Swizzled, init = {}, setEphemeralState) => { const [state, setState] = useQueryState('s', pojoParser) const update = useMemo( () => Swizzled.methods.stateUpdateFactory(setState, setEphemeralState), [setState] ) /* * Set the initial state */ useEffect(() => { // Handle state on a hard reload or cold start if (typeof URLSearchParams !== 'undefined') { let urlState = false try { const params = new URLSearchParams(document.location.search) const s = params.get('s') if (typeof s === 'string' && s.length > 0) urlState = JSON.parse(s) if (urlState) setState(urlState) else setState(init) } catch (err) { setState(init) } } }, []) return [state, setState, update] } /* * Our URL state library does not support storing Javascript objects out of the box. * But it allows us to pass a customer parser to handle them, so this is that parser */ const pojoParser = createParser({ parse: (v) => { let val try { val = JSON.parse(v) } catch (err) { val = null } return val }, serialize: (v) => { let val try { val = JSON.stringify(v) } catch (err) { val = null } return val }, })