{"version":3,"file":"createFormHook.cjs","sources":["../../src/createFormHook.tsx"],"sourcesContent":["import {\n  createComponent,\n  createContext,\n  mergeProps,\n  splitProps,\n  useContext,\n} from 'solid-js'\nimport { createFieldGroup } from './createFieldGroup'\nimport { createForm } from './createForm'\nimport type {\n  AnyFieldApi,\n  AnyFormApi,\n  BaseFormOptions,\n  DeepKeysOfType,\n  FieldApi,\n  FieldsMap,\n  FormAsyncValidateOrFn,\n  FormOptions,\n  FormValidateOrFn,\n} from '@tanstack/form-core'\nimport type {\n  Accessor,\n  Component,\n  Context,\n  JSXElement,\n  ParentProps,\n} from 'solid-js'\nimport type { FieldComponent } from './createField'\nimport type { AppFieldExtendedSolidFieldGroupApi } from './createFieldGroup'\nimport type { SolidFormExtendedApi } from './createForm'\n\n/**\n * TypeScript inferencing is weird.\n *\n * If you have:\n *\n * @example\n *\n * interface Args<T> {\n *     arg?: T\n * }\n *\n * function test<T>(arg?: Partial<Args<T>>): T {\n *     return 0 as any;\n * }\n *\n * const a = test({});\n *\n * Then `T` will default to `unknown`.\n *\n * However, if we change `test` to be:\n *\n * @example\n *\n * function test<T extends undefined>(arg?: Partial<Args<T>>): T;\n *\n * Then `T` becomes `undefined`.\n *\n * Here, we are checking if the passed type `T` extends `DefaultT` and **only**\n * `DefaultT`, as if that's the case we assume that inferencing has not occurred.\n */\ntype UnwrapOrAny<T> = [unknown] extends [T] ? any : T\ntype UnwrapDefaultOrAny<DefaultT, T> = [DefaultT] extends [T]\n  ? [T] extends [DefaultT]\n    ? any\n    : T\n  : T\n\nexport function createFormHookContexts() {\n  // We should never hit the `null` case here\n  const fieldContext = createContext<Accessor<AnyFieldApi>>(\n    null as unknown as Accessor<AnyFieldApi>,\n  )\n\n  function useFieldContext<TData>() {\n    const field = useContext(fieldContext)\n\n    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n    if (!field) {\n      throw new Error(\n        '`fieldContext` only works when within a `fieldComponent` passed to `createFormHook`',\n      )\n    }\n\n    return field as Accessor<\n      FieldApi<\n        any,\n        string,\n        TData,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any,\n        any\n      >\n    >\n  }\n\n  // We should never hit the `null` case here\n  const formContext = createContext<AnyFormApi>(null as unknown as AnyFormApi)\n\n  function useFormContext() {\n    const form = useContext(formContext)\n\n    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n    if (!form) {\n      throw new Error(\n        '`formContext` only works when within a `formComponent` passed to `createFormHook`',\n      )\n    }\n\n    return form as SolidFormExtendedApi<\n      // If you need access to the form data, you need to use `withForm` instead\n      Record<string, never>,\n      any,\n      any,\n      any,\n      any,\n      any,\n      any,\n      any,\n      any,\n      any,\n      any,\n      any\n    >\n  }\n\n  return { fieldContext, useFieldContext, useFormContext, formContext }\n}\n\ninterface CreateFormHookProps<\n  TFieldComponents extends Record<string, Component<any>>,\n  TFormComponents extends Record<string, Component<any>>,\n> {\n  fieldComponents: TFieldComponents\n  fieldContext: Context<Accessor<AnyFieldApi>>\n  formComponents: TFormComponents\n  formContext: Context<AnyFormApi>\n}\n/**\n * @private\n */\nexport type AppFieldExtendedSolidFormApi<\n  TFormData,\n  TOnMount extends undefined | FormValidateOrFn<TFormData>,\n  TOnChange extends undefined | FormValidateOrFn<TFormData>,\n  TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n  TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n  TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n  TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TSubmitMeta,\n  TFieldComponents extends Record<string, Component<any>>,\n  TFormComponents extends Record<string, Component<any>>,\n> = SolidFormExtendedApi<\n  TFormData,\n  TOnMount,\n  TOnChange,\n  TOnChangeAsync,\n  TOnBlur,\n  TOnBlurAsync,\n  TOnSubmit,\n  TOnSubmitAsync,\n  TOnDynamic,\n  TOnDynamicAsync,\n  TOnServer,\n  TSubmitMeta\n> &\n  NoInfer<TFormComponents> & {\n    AppField: FieldComponent<\n      TFormData,\n      TOnMount,\n      TOnChange,\n      TOnChangeAsync,\n      TOnBlur,\n      TOnBlurAsync,\n      TOnSubmit,\n      TOnSubmitAsync,\n      TOnDynamic,\n      TOnDynamicAsync,\n      TOnServer,\n      TSubmitMeta,\n      NoInfer<TFieldComponents>\n    >\n    AppForm: Component<ParentProps>\n  }\n\nexport interface WithFormProps<\n  TFormData,\n  TOnMount extends undefined | FormValidateOrFn<TFormData>,\n  TOnChange extends undefined | FormValidateOrFn<TFormData>,\n  TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n  TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n  TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n  TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n  TSubmitMeta,\n  TFieldComponents extends Record<string, Component<any>>,\n  TFormComponents extends Record<string, Component<any>>,\n  TRenderProps extends Record<string, unknown> = Record<string, never>,\n> extends FormOptions<\n  TFormData,\n  TOnMount,\n  TOnChange,\n  TOnChangeAsync,\n  TOnBlur,\n  TOnBlurAsync,\n  TOnSubmit,\n  TOnSubmitAsync,\n  TOnDynamic,\n  TOnDynamicAsync,\n  TOnServer,\n  TSubmitMeta\n> {\n  // Optional, but adds props to the `render` function outside of `form`\n  props?: TRenderProps\n  render: (\n    props: ParentProps<\n      NoInfer<TRenderProps> & {\n        form: AppFieldExtendedSolidFormApi<\n          TFormData,\n          TOnMount,\n          TOnChange,\n          TOnChangeAsync,\n          TOnBlur,\n          TOnBlurAsync,\n          TOnSubmit,\n          TOnSubmitAsync,\n          TOnDynamic,\n          TOnDynamicAsync,\n          TOnServer,\n          TSubmitMeta,\n          TFieldComponents,\n          TFormComponents\n        >\n      }\n    >,\n  ) => JSXElement\n}\n\nexport interface WithFieldGroupProps<\n  TFieldGroupData,\n  TFieldComponents extends Record<string, Component<any>>,\n  TFormComponents extends Record<string, Component<any>>,\n  TSubmitMeta,\n  TRenderProps extends Record<string, unknown> = Record<string, never>,\n> extends BaseFormOptions<TFieldGroupData, TSubmitMeta> {\n  // Optional, but adds props to the `render` function outside of `form`\n  props?: TRenderProps\n  render: (\n    props: ParentProps<\n      NoInfer<TRenderProps> & {\n        group: AppFieldExtendedSolidFieldGroupApi<\n          unknown,\n          TFieldGroupData,\n          string | FieldsMap<unknown, TFieldGroupData>,\n          undefined | FormValidateOrFn<unknown>,\n          undefined | FormValidateOrFn<unknown>,\n          undefined | FormAsyncValidateOrFn<unknown>,\n          undefined | FormValidateOrFn<unknown>,\n          undefined | FormAsyncValidateOrFn<unknown>,\n          undefined | FormValidateOrFn<unknown>,\n          undefined | FormAsyncValidateOrFn<unknown>,\n          undefined | FormValidateOrFn<unknown>,\n          undefined | FormAsyncValidateOrFn<unknown>,\n          undefined | FormAsyncValidateOrFn<unknown>,\n          // this types it as 'never' in the render prop. It should prevent any\n          // untyped meta passed to the handleSubmit by accident.\n          unknown extends TSubmitMeta ? never : TSubmitMeta,\n          TFieldComponents,\n          TFormComponents\n        >\n      }\n    >,\n  ) => JSXElement\n}\n\nexport function createFormHook<\n  const TComponents extends Record<string, Component<any>>,\n  const TFormComponents extends Record<string, Component<any>>,\n>(opts: CreateFormHookProps<TComponents, TFormComponents>) {\n  function useAppForm<\n    TFormData,\n    TOnMount extends undefined | FormValidateOrFn<TFormData>,\n    TOnChange extends undefined | FormValidateOrFn<TFormData>,\n    TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n    TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n    TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n    TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TSubmitMeta,\n  >(\n    props: Accessor<\n      FormOptions<\n        TFormData,\n        TOnMount,\n        TOnChange,\n        TOnChangeAsync,\n        TOnBlur,\n        TOnBlurAsync,\n        TOnSubmit,\n        TOnSubmitAsync,\n        TOnDynamic,\n        TOnDynamicAsync,\n        TOnServer,\n        TSubmitMeta\n      >\n    >,\n  ): AppFieldExtendedSolidFormApi<\n    TFormData,\n    TOnMount,\n    TOnChange,\n    TOnChangeAsync,\n    TOnBlur,\n    TOnBlurAsync,\n    TOnSubmit,\n    TOnSubmitAsync,\n    TOnDynamic,\n    TOnDynamicAsync,\n    TOnServer,\n    TSubmitMeta,\n    TComponents,\n    TFormComponents\n  > {\n    const form = createForm(props)\n\n    const AppForm = ((formProps) => {\n      return (\n        <opts.formContext.Provider value={form}>\n          {formProps.children}\n        </opts.formContext.Provider>\n      )\n    }) as Component<ParentProps>\n\n    const AppField = ((_props) => {\n      const [childProps, fieldProps] = splitProps(_props, ['children'])\n      return (\n        <form.Field {...fieldProps}>\n          {(field) => (\n            <opts.fieldContext.Provider value={field}>\n              {createComponent(\n                () =>\n                  childProps.children(\n                    Object.assign(field, opts.fieldComponents),\n                  ),\n                {},\n              )}\n            </opts.fieldContext.Provider>\n          )}\n        </form.Field>\n      )\n    }) as FieldComponent<\n      TFormData,\n      TOnMount,\n      TOnChange,\n      TOnChangeAsync,\n      TOnBlur,\n      TOnBlurAsync,\n      TOnSubmit,\n      TOnSubmitAsync,\n      TOnDynamic,\n      TOnDynamicAsync,\n      TOnServer,\n      TSubmitMeta,\n      TComponents\n    >\n\n    const extendedForm: AppFieldExtendedSolidFormApi<\n      TFormData,\n      TOnMount,\n      TOnChange,\n      TOnChangeAsync,\n      TOnBlur,\n      TOnBlurAsync,\n      TOnSubmit,\n      TOnSubmitAsync,\n      TOnDynamic,\n      TOnDynamicAsync,\n      TOnServer,\n      TSubmitMeta,\n      TComponents,\n      TFormComponents\n    > = form as never\n    extendedForm.AppField = AppField\n    extendedForm.AppForm = AppForm\n    for (const [key, value] of Object.entries(opts.formComponents)) {\n      // Since it's a generic I need to cast it to an object\n      ;(extendedForm as Record<string, any>)[key] = value\n    }\n\n    return extendedForm\n  }\n\n  function withForm<\n    TFormData,\n    TOnMount extends undefined | FormValidateOrFn<TFormData>,\n    TOnChange extends undefined | FormValidateOrFn<TFormData>,\n    TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n    TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n    TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n    TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TSubmitMeta,\n    TRenderProps extends Record<string, unknown> = {},\n  >({\n    render,\n    props,\n  }: WithFormProps<\n    TFormData,\n    TOnMount,\n    TOnChange,\n    TOnChangeAsync,\n    TOnBlur,\n    TOnBlurAsync,\n    TOnSubmit,\n    TOnSubmitAsync,\n    TOnDynamic,\n    TOnDynamicAsync,\n    TOnServer,\n    TSubmitMeta,\n    TComponents,\n    TFormComponents,\n    TRenderProps\n  >): WithFormProps<\n    UnwrapOrAny<TFormData>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnMount>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnChange>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnChangeAsync>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnBlur>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnBlurAsync>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnSubmit>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync>,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnDynamic>,\n    UnwrapDefaultOrAny<\n      undefined | FormValidateOrFn<TFormData>,\n      TOnDynamicAsync\n    >,\n    UnwrapDefaultOrAny<undefined | FormValidateOrFn<TFormData>, TOnServer>,\n    UnwrapOrAny<TSubmitMeta>,\n    UnwrapOrAny<TComponents>,\n    UnwrapOrAny<TFormComponents>,\n    UnwrapOrAny<TRenderProps>\n  >['render'] {\n    return (innerProps) =>\n      createComponent(\n        render as Component<any>,\n        mergeProps(props ?? {}, innerProps),\n      )\n  }\n\n  function withFieldGroup<\n    TFieldGroupData,\n    TSubmitMeta,\n    TRenderProps extends Record<string, unknown> = {},\n  >({\n    render,\n    props,\n    defaultValues,\n  }: WithFieldGroupProps<\n    TFieldGroupData,\n    TComponents,\n    TFormComponents,\n    TSubmitMeta,\n    TRenderProps\n  >): <\n    TFormData,\n    TFields extends\n      | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n      | FieldsMap<TFormData, TFieldGroupData>,\n    TOnMount extends undefined | FormValidateOrFn<TFormData>,\n    TOnChange extends undefined | FormValidateOrFn<TFormData>,\n    TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n    TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n    TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n    TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n    TFormSubmitMeta,\n  >(\n    params: ParentProps<\n      NoInfer<TRenderProps> & {\n        form:\n          | AppFieldExtendedSolidFormApi<\n              TFormData,\n              TOnMount,\n              TOnChange,\n              TOnChangeAsync,\n              TOnBlur,\n              TOnBlurAsync,\n              TOnSubmit,\n              TOnSubmitAsync,\n              TOnDynamic,\n              TOnDynamicAsync,\n              TOnServer,\n              unknown extends TSubmitMeta ? TFormSubmitMeta : TSubmitMeta,\n              TComponents,\n              TFormComponents\n            >\n          | AppFieldExtendedSolidFieldGroupApi<\n              // Since this only occurs if you nest it within other field groups, it can be more\n              // lenient with the types.\n              unknown,\n              TFormData,\n              string | FieldsMap<unknown, TFormData>,\n              any,\n              any,\n              any,\n              any,\n              any,\n              any,\n              any,\n              any,\n              any,\n              any,\n              unknown extends TSubmitMeta ? TFormSubmitMeta : TSubmitMeta,\n              TComponents,\n              TFormComponents\n            >\n        fields: TFields\n      }\n    >,\n  ) => JSXElement {\n    return function Render(innerProps) {\n      const fieldGroupProps = {\n        form: innerProps.form,\n        fields: innerProps.fields,\n        defaultValues,\n        formComponents: opts.formComponents,\n      }\n      const fieldGroupApi = createFieldGroup(() => fieldGroupProps)\n      return createComponent(\n        render as Component<any>,\n        mergeProps(props ?? {}, innerProps, { group: fieldGroupApi as any }),\n      )\n    }\n  }\n\n  return {\n    useAppForm,\n    withForm,\n    withFieldGroup,\n  }\n}\n"],"names":["createFormHookContexts","fieldContext","createContext","useFieldContext","field","useContext","Error","formContext","useFormContext","form","createFormHook","opts","useAppForm","props","createForm","AppForm","formProps","_$createComponent","Provider","value","children","AppField","_props","childProps","fieldProps","splitProps","Field","_$mergeProps","createComponent","Object","assign","fieldComponents","extendedForm","key","entries","formComponents","withForm","render","innerProps","mergeProps","withFieldGroup","defaultValues","Render","fieldGroupProps","fields","fieldGroupApi","createFieldGroup","group"],"mappings":";;;;;;AAoEO,SAASA,yBAAyB;AAEvC,QAAMC,eAAeC,QAAAA,cACnB,IACF;AAEA,WAASC,kBAAyB;AAChC,UAAMC,QAAQC,QAAAA,WAAWJ,YAAY;AAGrC,QAAI,CAACG,OAAO;AACV,YAAM,IAAIE,MACR,qFACF;AAAA,IACF;AAEA,WAAOF;AAAAA,EA2BT;AAGA,QAAMG,cAAcL,QAAAA,cAA0B,IAA6B;AAE3E,WAASM,iBAAiB;AACxB,UAAMC,OAAOJ,QAAAA,WAAWE,WAAW;AAGnC,QAAI,CAACE,MAAM;AACT,YAAM,IAAIH,MACR,mFACF;AAAA,IACF;AAEA,WAAOG;AAAAA,EAeT;AAEA,SAAO;AAAA,IAAER;AAAAA,IAAcE;AAAAA,IAAiBK;AAAAA,IAAgBD;AAAAA,EAAAA;AAC1D;AA2JO,SAASG,eAGdC,MAAyD;AACzD,WAASC,WAcPC,OA+BA;AACA,UAAMJ,OAAOK,WAAAA,WAAWD,KAAK;AAE7B,UAAME,WAAYC,CAAAA,cAAc;AAC9B,aAAAC,oBACGN,KAAKJ,YAAYW,UAAQ;AAAA,QAACC,OAAOV;AAAAA,QAAI,IAAAW,WAAA;AAAA,iBACnCJ,UAAUI;AAAAA,QAAQ;AAAA,MAAA,CAAA;AAAA,IAGzB;AAEA,UAAMC,YAAaC,CAAAA,WAAW;AAC5B,YAAM,CAACC,YAAYC,UAAU,IAAIC,QAAAA,WAAWH,QAAQ,CAAC,UAAU,CAAC;AAChE,aAAAL,IAAAA,gBACGR,KAAKiB,OAAKC,IAAAA,WAAKH,YAAU;AAAA,QAAAJ,UACtBhB,CAAAA,UAAKa,IAAAA,gBACJN,KAAKV,aAAaiB,UAAQ;AAAA,UAACC,OAAOf;AAAAA,UAAK,IAAAgB,WAAA;AAAA,mBACrCQ,wBACC,MACEL,WAAWH,SACTS,OAAOC,OAAO1B,OAAOO,KAAKoB,eAAe,CAC3C,GACF,CAAA,CACF;AAAA,UAAC;AAAA,QAAA,CAAA;AAAA,MAAA,CAEJ,CAAA;AAAA,IAGP;AAgBA,UAAMC,eAeFvB;AACJuB,iBAAaX,WAAWA;AACxBW,iBAAajB,UAAUA;AACvB,eAAW,CAACkB,KAAKd,KAAK,KAAKU,OAAOK,QAAQvB,KAAKwB,cAAc,GAAG;AAE5DH,mBAAqCC,GAAG,IAAId;AAAAA,IAChD;AAEA,WAAOa;AAAAA,EACT;AAEA,WAASI,SAcP;AAAA,IACAC;AAAAA,IACAxB;AAAAA,EAAAA,GAoCU;AACV,WAAQyB,CAAAA,eACNV,QAAAA,gBACES,QACAE,QAAAA,WAAW1B,SAAS,CAAA,GAAIyB,UAAU,CACpC;AAAA,EACJ;AAEA,WAASE,eAIP;AAAA,IACAH;AAAAA,IACAxB;AAAAA,IACA4B;AAAAA,EAAAA,GAkEc;AACd,WAAO,SAASC,OAAOJ,YAAY;AACjC,YAAMK,kBAAkB;AAAA,QACtBlC,MAAM6B,WAAW7B;AAAAA,QACjBmC,QAAQN,WAAWM;AAAAA,QACnBH;AAAAA,QACAN,gBAAgBxB,KAAKwB;AAAAA,MAAAA;AAEvB,YAAMU,gBAAgBC,kCAAiB,MAAMH,eAAe;AAC5D,aAAOf,QAAAA,gBACLS,QACAE,QAAAA,WAAW1B,SAAS,CAAA,GAAIyB,YAAY;AAAA,QAAES,OAAOF;AAAAA,MAAAA,CAAsB,CACrE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACLjC;AAAAA,IACAwB;AAAAA,IACAI;AAAAA,EAAAA;AAEJ;;;"}