Skip to content

Releases: airjp73/remix-validated-form

Zod Form Data 1.1.0

27 Jan 04:32
Compare
Choose a tag to compare

New Features

zfd.file

A new helper to assist in asserting required/optional on file inputs. Docs here.

Accept a zod schema in zfd.formData

zfd.formData can now accept a zod schema in addition to accepting objects. Docs here

PRs

Includes #40

Remix Validated Form v3.4.0

24 Jan 13:59
Compare
Choose a tag to compare

New Feature

Added handling to getInputProps for checkboxes and radio inputs. To use this, make sure you pass the type prop through getInputProps.

<input {...getInputProps({ type: 'checkbox' })} />

Zod Form Data v1.0.0

21 Jan 04:24
3da1b11
Compare
Choose a tag to compare

This is a release of a new package, zod-form-data. It's designed to help ease some pain-points for writing zod schema for form data.

Docs: https://www.remix-validated-form.io/zod-form-data

Remix Validated Form v3.3.0

19 Jan 00:18
Compare
Choose a tag to compare

New Features

This adds support for automatically handling multiple inputs that have the same name.

PRs

Includes #24

Remix Validated Form v3.2.0

16 Jan 00:50
Compare
Choose a tag to compare

New Features

getInputProps

useField is now a lot simpler to use for most cases thanks to the new getInputProps. You can read about it in more detail here.

import { useField } from "remix-validated-form";

type MyInputProps = {
  name: string;
  label: string;
};

export const MyInput = ({ name, label }: InputProps) => {
  const { error, getInputProps } = useField(name);
  return (
    <div>
      <label htmlFor={name}>{label}</label>
      <input {...getInputProps({ id: name })} />
      {error && (
        <span className="my-error-class">{error}</span>
      )}
    </div>
  );
};

Touched states

It is now possible to track the touched state of a field with the touched and setTouched return values of useField (docs).

hasBeenSubmitted in form context

You can now determine if the user has attempted to submit the form using hasBeenSubmitted from useFormContext (docs).

Docs changes

The props headers in the reference section are now linkable. 😄

PRs

Includes #25

v3.1.0

04 Jan 04:14
Compare
Choose a tag to compare

Adds two new features:

  • An isValid value is now returned from useFormContext.
  • When form validation fails via an attempted submit, the first invalid input will be focused. It is also now possible to use useField to specify a handleReceiveFocus callback that will be called when an input is going to receive focus this way. This is primarily to support custom components that use hidden inputs for their value and some other ui for the "input".

v3.0.0

31 Dec 04:02
Compare
Choose a tag to compare

Breaking Change

The withZod and withYup validators are now published as separate packages.
This was done to prevent you from needing to install both zod and yup in order to appease Typescript.

Migration

Update and install packages

Install the updated remix-validated-form and the adapter package of your choice

npm install remix-validated-form@latest @remix-validated-form/with-zod

or

npm install remix-validated-form@latest @remix-validated-form/with-zod

Change imports

Change these imports

import { withYup, withZod } from 'remix-validated-form';

to this

import { withYup } from '@remix-validated-form/with-yup';
import { withZod } from '@remix-validated-form/with-zod';

PRs included

Full Changelog: v2.1.1...v3.0.0

2.1.1

26 Dec 04:09
Compare
Choose a tag to compare

Fixed a minor issue where the hidden subaction input was being included even when no subaction was specified.

v2.1.0

17 Dec 02:28
Compare
Choose a tag to compare

Included PRs

PR #12
PR #11

2.0.0

13 Dec 14:54
Compare
Choose a tag to compare

New Features

Support for nested data by using paths for field names.

Thanks @lucascurti! #4

Example form:

export default function MyForm() {
  const { defaultValues } = useLoaderData();
  return (
    <ValidatedForm
      validator={validator}
      method="post"
      defaultValues={defaultValues}
    >
      <MyInput name="firstName" label="First Name" />
      <MyInput name="lastName" label="Last Name" />
      <MyInput name="address.street" label="Street" />
      <MyInput name="address.city" label="City" />
      <MyInput name="phones[0].type" label="Phone 1 Type" />
      <MyInput name="phones[0].number" label="Phone 1 Number" />
      <MyInput name="phones[1].type" label="Phone 2 Type" />
      <MyInput name="phones[1].number" label="Phone 2 Number" />
      <MySubmitButton />
    </ValidatedForm>
  );
}

When you validate in your action, the data for this form will come out like this:

{
  firstName: 'John',
  lastName: 'Doe',
  address: {
    street: 'Some street',
    city: 'Anytown',
  },
  phones: [
    { number: '5551234', type: 'cell' },
    { number: '5552345', type: 'home' },
  ],
}

And when you pass defaultValues to the ValidatedForm, this is the shape it will expect for those.

Validators can accept FormData directly

A small DX improvement, you no longer need to use Object.fromEntries to convert your FormData before validating it.
You can still pass plain objects to the validator as well.

-  const data = validator.validate(Object.fromEntries(await request.formData()));
+ const data = validator.validate(await request.formData());

Breaking changes

This change is only breaking if you have fields in your forms that contain dots . or square brackets [].
There isn't currently a way to escape these characters and create fields with names that contain these characters.
If this feature is important to you, please feel free to file an issue. 😄

Migrating

If you already have a form fields that have paths for names (my.field[0]), you will need to update the following:

  • You validation schemas should expect a nested data structure rather than an object with paths for keys.
  • Any code consuming the return value of a validator should also expect a nested data structure.
  • When passing defaultValues to a form, it expects a nested data structure.
-  const validator = withYup(yup.object({
-    "nested.field": yup.string().required(),
-    "arrayField[0]": yup.string().required(),
-  })
+  const validator = withYup(yup.object({
+    nested: yup.object({ field: yup.string().required() })
+    arrayField: yup.array(yup.string())
+  })

// Expected return value from `validator.validate`
-  {
-    "nested.field": "some value",
-    "arrayField[0]": "another value",
-  }
+  {
+    nested: { field: "some value" }
+    arrayField: ["another value"]
+  }