Skip to content

Commit

Permalink
feat(conform-react): accept custom ref object (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung authored Mar 23, 2023
1 parent b2cc882 commit 18b71e9
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
18 changes: 12 additions & 6 deletions packages/conform-react/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export interface FormConfig<
*/
id?: string;

/**
* A form ref object. Conform will fallback to its own ref object if it is not provided.
*/
ref?: RefObject<HTMLFormElement>;

/**
* Define when the error should be reported initially.
* Support "onSubmit", "onChange", "onBlur".
Expand Down Expand Up @@ -141,7 +146,7 @@ export function useForm<
ClientSubmission extends Submission | Submission<Schema> = Submission,
>(config: FormConfig<Schema, ClientSubmission> = {}): [Form, Fieldset<Schema>] {
const configRef = useRef(config);
const ref = useRef<HTMLFormElement>(null);
const formRef = useRef<HTMLFormElement>(null);
const [lastSubmission, setLastSubmission] = useState(
config.lastSubmission ?? null,
);
Expand Down Expand Up @@ -183,6 +188,7 @@ export function useForm<
constraint: config.constraint,
form: config.id,
};
const ref = config.ref ?? formRef;
const fieldset = useFieldset(ref, fieldsetConfig);
const [noValidate, setNoValidate] = useState(
config.noValidate || !config.fallbackNative,
Expand Down Expand Up @@ -215,7 +221,7 @@ export function useForm<
}

setLastSubmission(submission);
}, [config.lastSubmission]);
}, [ref, config.lastSubmission]);

useEffect(() => {
const form = ref.current;
Expand All @@ -224,8 +230,8 @@ export function useForm<
return;
}

reportSubmission(ref.current, lastSubmission);
}, [lastSubmission]);
reportSubmission(form, lastSubmission);
}, [ref, lastSubmission]);

useEffect(() => {
// Revalidate the form when input value is changed
Expand Down Expand Up @@ -262,7 +268,7 @@ export function useForm<
}
};
const handleInvalid = (event: Event) => {
const form = getFormElement(ref.current);
const form = ref.current;
const field = event.target;

if (
Expand Down Expand Up @@ -320,7 +326,7 @@ export function useForm<
document.removeEventListener('invalid', handleInvalid, true);
document.removeEventListener('reset', handleReset);
};
}, []);
}, [ref]);

const form: Form = {
ref,
Expand Down
7 changes: 7 additions & 0 deletions playground/app/routes/input-attributes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { conform, useForm, parse } from '@conform-to/react';
import { json, type ActionArgs } from '@remix-run/node';
import { Form, useActionData } from '@remix-run/react';
import { useRef } from 'react';
import { Playground, Field, Alert } from '~/components';

interface Schema {
Expand All @@ -25,8 +26,10 @@ export async function action({ request }: ActionArgs) {

export default function Example() {
const lastSubmission = useActionData<typeof action>();
const ref = useRef<HTMLFormElement>(null);
const [form, { title, description, images, rating, tags }] = useForm<Schema>({
id: 'test',
ref,
lastSubmission,
constraint: {
title: {
Expand Down Expand Up @@ -57,6 +60,10 @@ export default function Example() {
},
});

if (form.ref !== ref || form.props.ref !== ref) {
throw new Error('Invalid ref object');
}

return (
<Form method="post" encType="multipart/form-data" {...form.props}>
<Playground title="Input attributes" lastSubmission={lastSubmission}>
Expand Down

0 comments on commit 18b71e9

Please sign in to comment.