Skip to content

Commit 2c9bab0

Browse files
feat(core): form identifiers (#1659)
1 parent c82fe54 commit 2c9bab0

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

packages/form-core/src/FormApi.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ export interface FormOptions<
376376
in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
377377
in out TSubmitMeta = never,
378378
> extends BaseFormOptions<TFormData, TSubmitMeta> {
379+
/**
380+
* The form name, used for devtools and identification
381+
*/
382+
formId?: string
379383
/**
380384
* The default state for the form.
381385
*/
@@ -1238,6 +1242,10 @@ export class FormApi<
12381242
this.update(opts || {})
12391243
}
12401244

1245+
get formId(): string | undefined {
1246+
return this.options.formId
1247+
}
1248+
12411249
/**
12421250
* @private
12431251
*/

packages/form-core/tests/FormApi.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3944,3 +3944,13 @@ it('should preserve nested fields on resetField if defaultValues is not provided
39443944
form.resetField('nested.field.name')
39453945
expect(form.state.values.nested.field.name).toEqual('Nested')
39463946
})
3947+
3948+
it('should accept formId and return it', () => {
3949+
const form = new FormApi({
3950+
defaultValues: { age: 0 },
3951+
formId: 'age',
3952+
})
3953+
form.mount()
3954+
3955+
expect(form.formId).toEqual('age')
3956+
})

packages/react-form/tests/createFormHook.test.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,50 @@ describe('createFormHook', () => {
450450
const inputField1 = getByLabelText('unrelated')
451451
expect(inputField1).toHaveValue('John')
452452
})
453+
454+
it('should accept formId and return it', async () => {
455+
function Submit() {
456+
const form = useFormContext()
457+
458+
return (
459+
<button type="submit" form={form.formId} data-testid="formId-target">
460+
{form.formId}
461+
</button>
462+
)
463+
}
464+
465+
function Comp() {
466+
const form = useAppForm({
467+
formId: 'test',
468+
})
469+
470+
return (
471+
<form.AppForm>
472+
<form
473+
id={form.formId}
474+
onSubmit={(e) => {
475+
e.preventDefault()
476+
form.handleSubmit()
477+
}}
478+
></form>
479+
480+
<form.Subscribe
481+
selector={(state) => state.submissionAttempts}
482+
children={(submissionAttempts) => (
483+
<span data-testid="formId-result">{submissionAttempts}</span>
484+
)}
485+
/>
486+
487+
<Submit />
488+
</form.AppForm>
489+
)
490+
}
491+
492+
const { getByTestId } = render(<Comp />)
493+
const target = getByTestId('formId-target')
494+
const result = getByTestId('formId-result')
495+
496+
await user.click(target)
497+
expect(result).toHaveTextContent('1')
498+
})
453499
})

packages/react-form/tests/useForm.test.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,4 +854,42 @@ describe('useForm', () => {
854854
await user.click(submit)
855855
await waitFor(() => expect(input).toHaveValue('another-test'))
856856
})
857+
858+
it('should accept formId and return it', async () => {
859+
function Comp() {
860+
const form = useForm({
861+
formId: 'test',
862+
})
863+
864+
return (
865+
<>
866+
<form
867+
id={form.formId}
868+
onSubmit={(e) => {
869+
e.preventDefault()
870+
form.handleSubmit()
871+
}}
872+
></form>
873+
874+
<form.Subscribe
875+
selector={(state) => state.submissionAttempts}
876+
children={(submissionAttempts) => (
877+
<span data-testid="formId-result">{submissionAttempts}</span>
878+
)}
879+
/>
880+
881+
<button type="submit" form={form.formId} data-testid="formId-target">
882+
{form.formId}
883+
</button>
884+
</>
885+
)
886+
}
887+
888+
const { getByTestId } = render(<Comp />)
889+
const target = getByTestId('formId-target')
890+
const result = getByTestId('formId-result')
891+
892+
await user.click(target)
893+
expect(result).toHaveTextContent('1')
894+
})
857895
})

0 commit comments

Comments
 (0)