UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

157 lines (144 loc) 4.42 kB
/* eslint-disable camelcase */ import {type ObjectSchemaType, type Path, type ValidationMarker} from '@sanity/types' import {useMemo, useState} from 'react' import {type FormNodePresence} from '../../presence' import {useCurrentUser} from '../../store' import {createCallbackResolver} from './conditional-property/createCallbackResolver' import {createPrepareFormState} from './formState' import {type ObjectFormNode, type StateTree} from './types' import {immutableReconcile} from './utils/immutableReconcile' /** @internal */ export type FormState< T extends {[key in string]: unknown} = {[key in string]: unknown}, S extends ObjectSchemaType = ObjectSchemaType, > = ObjectFormNode<T, S> /** @internal */ export interface UseFormStateOptions { schemaType: ObjectSchemaType documentValue: unknown comparisonValue: unknown openPath: Path focusPath: Path presence: FormNodePresence[] validation: ValidationMarker[] fieldGroupState?: StateTree<string> | undefined collapsedFieldSets?: StateTree<boolean> | undefined collapsedPaths?: StateTree<boolean> | undefined readOnly?: boolean changesOpen?: boolean } /** @internal */ export function useFormState< T extends {[key in string]: unknown} = {[key in string]: unknown}, S extends ObjectSchemaType = ObjectSchemaType, >({ comparisonValue, documentValue, fieldGroupState, collapsedFieldSets, collapsedPaths, focusPath, openPath, presence, validation, readOnly: inputReadOnly, changesOpen, schemaType, }: UseFormStateOptions): FormState<T, S> | null { // note: feel free to move these state pieces out of this hook const currentUser = useCurrentUser() const [prepareHiddenState] = useState(() => createCallbackResolver({property: 'hidden'})) const [prepareReadOnlyState] = useState(() => createCallbackResolver({property: 'readOnly'})) const [prepareFormState] = useState(() => createPrepareFormState()) const [reconcileFieldGroupState] = useState(() => { let last: StateTree<string> | undefined return (state: StateTree<string> | undefined) => { const result = immutableReconcile(last ?? null, state) last = result return result } }) const reconciledFieldGroupState = useMemo(() => { return reconcileFieldGroupState(fieldGroupState) }, [fieldGroupState, reconcileFieldGroupState]) const [reconcileCollapsedPaths] = useState(() => { let last: StateTree<boolean> | undefined return (state: StateTree<boolean> | undefined) => { const result = immutableReconcile(last ?? null, state) last = result return result } }) const reconciledCollapsedPaths = useMemo( () => reconcileCollapsedPaths(collapsedPaths), [collapsedPaths, reconcileCollapsedPaths], ) const [reconcileCollapsedFieldsets] = useState(() => { let last: StateTree<boolean> | undefined return (state: StateTree<boolean> | undefined) => { const result = immutableReconcile(last ?? null, state) last = result return result } }) const reconciledCollapsedFieldsets = useMemo( () => reconcileCollapsedFieldsets(collapsedFieldSets), [collapsedFieldSets, reconcileCollapsedFieldsets], ) const {hidden, readOnly} = useMemo(() => { return { hidden: prepareHiddenState({ currentUser, documentValue: documentValue, schemaType, }), readOnly: prepareReadOnlyState({ currentUser, documentValue: documentValue, schemaType, readOnly: inputReadOnly, }), } }, [ prepareHiddenState, currentUser, documentValue, schemaType, prepareReadOnlyState, inputReadOnly, ]) return useMemo(() => { return prepareFormState({ schemaType, fieldGroupState: reconciledFieldGroupState, collapsedFieldSets: reconciledCollapsedFieldsets, collapsedPaths: reconciledCollapsedPaths, documentValue, comparisonValue, focusPath, openPath, readOnly, hidden, currentUser, presence, validation, changesOpen, }) as ObjectFormNode<T, S> }, [ prepareFormState, schemaType, reconciledFieldGroupState, reconciledCollapsedFieldsets, reconciledCollapsedPaths, documentValue, comparisonValue, focusPath, openPath, readOnly, hidden, currentUser, presence, validation, changesOpen, ]) }