{"version":3,"names":["createContext","useContext","NOOP","createNoopFormContext","formRef","current","fields","Map","errors","setErrors","clearErrors","validationMode","submitAttemptedRef","present","NOOP_FORM_CONTEXT","FormContext","useFormContext","ctx"],"sources":["form-context.ts"],"sourcesContent":["import { type Accessor, createContext, useContext } from \"solid-js\";\nimport type {\n\tFieldValidationMode,\n\tFieldValidityData,\n\tMutableRef,\n} from \"./field-context\";\n\n/**\n * Mapping of field name → error(s). Populated by `<Form>` after server-side\n * validation or external submission feedback.\n */\nexport type FormErrors = Record<string, string | string[]>;\n\n/**\n * Registration record that field controls push into `<Form>` so that `<Form>`\n * can orchestrate cross-field validation / submission.\n */\nexport interface FormFieldEntry {\n\tname: string | undefined;\n\t/**\n\t * Imperatively validate the field's currently-registered control. Returns\n\t * a Promise when the field has an async validator in flight; otherwise\n\t * returns synchronously. Form-level submit awaits the Promise (when\n\t * present) before reading `validityData`, so async validators\n\t * (`zod.parseAsync`, async refinements, server-side checks) block submit.\n\t */\n\tvalidate: (flushSync?: boolean) => Promise<void> | void;\n\tvalidityData: FieldValidityData;\n\tgetValue: () => unknown;\n\tcontrolRef: MutableRef<HTMLElement | null>;\n}\n\n/**\n * Opaque handle held by `<Form>` so field controls have a stable place to\n * register without going through the reactive graph. The `fields` map is\n * mutated directly by field controls — do NOT put it in a signal or store.\n */\nexport interface FormRefState {\n\tfields: Map<string, FormFieldEntry>;\n}\n\nexport interface FormContextValue {\n\t/** Ref holding the mutable fields map. */\n\treadonly formRef: MutableRef<FormRefState>;\n\t/** External errors (e.g. from server validation). */\n\terrors: Accessor<FormErrors>;\n\t/** Replace the entire errors map. */\n\tsetErrors: (next: FormErrors) => void;\n\t/** Clear errors for a single field name (or the whole map if undefined). */\n\tclearErrors: (name: string | undefined) => void;\n\t/** Validation mode used when children don't override via `<Field.Root>`. */\n\tvalidationMode: Accessor<FieldValidationMode>;\n\t/** Whether the user has attempted a submit at least once. */\n\tsubmitAttemptedRef: MutableRef<boolean>;\n\t/** Marker — `true` when this context was provided by a real `<Form>`. */\n\treadonly present: boolean;\n}\n\nconst NOOP = () => {};\n\n/**\n * Factory for a fresh noop form context. Each call builds a new `fields`\n * map so tests (and real code paths) that imperatively mutate\n * `formRef.current.fields` can't leak state across runs via a shared\n * module-load singleton.\n *\n * `useFormContext` calls this when no `<Form>` provider is above, so every\n * consumer receives its own noop instance.\n */\nexport function createNoopFormContext(): FormContextValue {\n\treturn {\n\t\tformRef: { current: { fields: new Map() } },\n\t\terrors: () => ({}),\n\t\tsetErrors: NOOP,\n\t\tclearErrors: NOOP,\n\t\tvalidationMode: () => \"onSubmit\",\n\t\tsubmitAttemptedRef: { current: false },\n\t\tpresent: false,\n\t};\n}\n\n/**\n * Identity-only sentinel. `useFormContext` compares against this to detect\n * \"no `<Form>` provider above\" and return a fresh noop instead of the\n * shared default — preventing cross-call state leaks via `fields`\n * mutations. The sentinel itself is never returned from the hook.\n *\n * Exported as `NOOP_FORM_CONTEXT` for barrel / compat only; application\n * code should call `useFormContext()` and branch on `.present`.\n */\nexport const NOOP_FORM_CONTEXT: FormContextValue = createNoopFormContext();\n\n/**\n * Context carrying `<Form>` state. Provided via `<FormContext value={...}>`.\n * Default value is the shared sentinel — `useFormContext` detects it by\n * identity and substitutes a fresh noop.\n */\nexport const FormContext = createContext<FormContextValue>(NOOP_FORM_CONTEXT);\n\n/**\n * Read the current `<Form>` context. When unwrapped (no `<Form>` ancestor),\n * returns a fresh noop so callers that mutate `formRef.current.fields` can't\n * inadvertently share state with other roots. Callers can branch on\n * `.present` to detect \"no form\".\n */\nexport function useFormContext(): FormContextValue {\n\tconst ctx = useContext(FormContext);\n\tif (ctx === NOOP_FORM_CONTEXT) {\n\t\treturn createNoopFormContext();\n\t}\n\treturn ctx;\n}\n"],"mappings":"AAAA,SAAwBA,aAAa,EAAEC,UAAU,QAAQ,UAAU;;AAOnE;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;;AAsBA,MAAMC,IAAI,GAAGA,CAAA,KAAM,CAAC,CAAC;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAA,EAAqB;EACzD,OAAO;IACNC,OAAO,EAAE;MAAEC,OAAO,EAAE;QAAEC,MAAM,EAAE,IAAIC,GAAG,CAAC;MAAE;IAAE,CAAC;IAC3CC,MAAM,EAAEA,CAAA,MAAO,CAAC,CAAC,CAAC;IAClBC,SAAS,EAAEP,IAAI;IACfQ,WAAW,EAAER,IAAI;IACjBS,cAAc,EAAEA,CAAA,KAAM,UAAU;IAChCC,kBAAkB,EAAE;MAAEP,OAAO,EAAE;IAAM,CAAC;IACtCQ,OAAO,EAAE;EACV,CAAC;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAmC,GAAGX,qBAAqB,CAAC,CAAC;;AAE1E;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMY,WAAW,GAAGf,aAAa,CAAmBc,iBAAiB,CAAC;;AAE7E;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,cAAcA,CAAA,EAAqB;EAClD,MAAMC,GAAG,GAAGhB,UAAU,CAACc,WAAW,CAAC;EACnC,IAAIE,GAAG,KAAKH,iBAAiB,EAAE;IAC9B,OAAOX,qBAAqB,CAAC,CAAC;EAC/B;EACA,OAAOc,GAAG;AACX","ignoreList":[]}