Skip to content

Commit

Permalink
hook up shouldSyncElement option
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Dec 9, 2024
1 parent 50083b1 commit 0566d32
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
8 changes: 0 additions & 8 deletions packages/conform-dom/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,6 @@ export type FormOptions<Schema, FormError = string[], FormValue = Schema> = {
*/
shouldRevalidate?: 'onSubmit' | 'onBlur' | 'onInput';

/**
* Define if the input could be updated by conform.
* Default to inputs that are configured using the `getInputProps`, `getSelectProps` or `getTextareaProps` helpers.
*/
shouldSyncElement?: (
element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,
) => boolean;

/**
* Define if conform should considered the field for dirty state.
* e.g. Excluding form fields that are not managed by Conform, such as CSRF token
Expand Down
24 changes: 21 additions & 3 deletions packages/conform-react/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
unstable_createFormObserver as createFormObserver,
unstable_syncFormState as syncFormState,
} from '@conform-to/dom';
import { useEffect, useId, useState, useLayoutEffect } from 'react';
import { useEffect, useId, useState, useLayoutEffect, useRef } from 'react';
import {
type FormMetadata,
type FieldMetadata,
Expand Down Expand Up @@ -68,13 +68,22 @@ export function useForm<
* Default to `true`.
*/
defaultNoValidate?: boolean;

/**
* Define if the input could be updated by conform.
* Default to inputs that are configured using the `getInputProps`, `getSelectProps` or `getTextareaProps` helpers.
*/
shouldSyncElement?: (
element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,
) => boolean;
}
>,
): [
FormMetadata<Schema, FormError>,
ReturnType<FormMetadata<Schema, FormError>['getFieldset']>,
] {
const { id, ...formConfig } = options;
const optionsRef = useRef(options);
const formId = useFormId<Schema, FormError>(id);
const [context] = useState(() =>
createFormContext({ ...formConfig, formId }),
Expand All @@ -84,7 +93,11 @@ export function useForm<
const formId = context.getFormId();
const disconnect = formObserver.onFieldMounted((formElement) => {
if (formElement === document.forms.namedItem(formId)) {
syncFormState(formElement, context.getState());
syncFormState(
formElement,
context.getState(),
optionsRef.current.shouldSyncElement,
);
// syncFormState must happen before syncFormValue to ensure the newly mounted field have the correct default value set
context.syncFormValue();
}
Expand All @@ -102,6 +115,7 @@ export function useForm<
}, [context]);

useSafeLayoutEffect(() => {
optionsRef.current = options;
context.onUpdate({ ...formConfig, formId });
});

Expand All @@ -121,7 +135,11 @@ export function useForm<
const formElement = document.forms.namedItem(formId);

if (formElement) {
syncFormState(formElement, stateSnapshot);
syncFormState(
formElement,
stateSnapshot,
optionsRef.current.shouldSyncElement,
);
}
}, [context, stateSnapshot]);

Expand Down

0 comments on commit 0566d32

Please sign in to comment.