Skip to content

Releases: brophdawg11/remix-validity-state

v0.11.1

08 Mar 13:35
Compare
Choose a tag to compare
v0.11.1 Pre-release
Pre-release

What's Changed

  • Fix serverFormInfo.valid computation on the server by @brophdawg11 in #59

Full Changelog: v0.11.0...v0.11.1

v0.11.0

04 Mar 12:34
Compare
Choose a tag to compare
v0.11.0 Pre-release
Pre-release

The values in serverFormInfo.submittedValues should now be type-safe based on your formDefinition, however it does seem to require the usage of TS satisfies to get the proper inference. For example:

interface FormSchema {
  inputs: {
    firstName: InputDefinition;
  };
}

let formDefinition = {
  inputs: {
    firstName: {
      validationAttrs: {
        required: true,
      },
    },
  },
} satisfies FormSchema; // 👈 Important!  Requires TS 4.9+

export const action = async ({ request }: ActionArgs) => {
  const formData = await request.formData();
  const serverFormInfo = await validateServerFormData(formData, formDefinition);
  if (!serverFormInfo.valid) { return json({ serverFormInfo }); }
  serverFormInfo.submittedValues.firstName
                              // ^? string 👈
  ...
};

Note: This will hopefully get better in the future but for now you should only trust these types if serverFormInfo.valid === true since if it's invalid we can't guarantee what got submitted.

In simple cases you probably won't notice much of a change here, since normal <input type="text"> inputs will always submit a string value even if not required. Where this gets interesting is in more complex situations where you may submit multiple values or not submit a value at all.

Multiple Controls

Sometimes you want to accept multiple values with the same name. To tell RVS about this you can now add a multiple boolean prop to your formDefinition to indicate that you will render multiple controls with the same name, and this will change the type to string[] since we'll get the values via formData.getAll():

let formDefinition = {
  inputs: {
    hobby: {
      multiple: true, // 👈
    },
  },
} satisfies FormSchema;

export const action = async ({ request }: ActionArgs) => {
  const formData = await request.formData();
  const serverFormInfo = await validateServerFormData(formData, formDefinition);
  if (!serverFormInfo.valid) { return json({ serverFormInfo }); }
  serverFormInfo.submittedValues.hobby
                              // ^? string[] 👈

Multiple Values

Checkboxes accept multiple by default so they don't require a multiple field in the formDefinition and will have a type of string[] | null by default or string[] if you also include required: true

let formDefinition = {
  inputs: {
    hobby: {
      validationAttrs: {
        type: "checkbox",
      }
    },
    favoriteHobby: {
      validationAttrs: {
        type: "checkbox",
        required: true,
      }
    },
  },
} satisfies FormSchema;

export const action = async ({ request }: ActionArgs) => {
  const formData = await request.formData();
  const serverFormInfo = await validateServerFormData(formData, formDefinition);
  if (!serverFormInfo.valid) { return json({ serverFormInfo }); }
  serverFormInfo.submittedValues.hobby
                              // ^? string[] | null 👈
  serverFormInfo.submittedValues.favoriteHobby
                              // ^? string[] 👈

Other controls, such as <select> and <input type="email"> can accept a multiple HTML attribute which lets a single control submit multiple values, so in those cases you include that in your validationAttrs:

let formDefinition = {
  inputs: {
    hobby: {
      element: "select",
      validationAttrs: {
        required: true,
        multiple: true, // 👈
      }
    },
    emails: {
      validationAttrs: {
        type: "email",
        required: true,
        multiple: true, // 👈
      }
    },
  },
} satisfies FormSchema;

export const action = async ({ request }: ActionArgs) => {
  const formData = await request.formData();
  const serverFormInfo = await validateServerFormData(formData, formDefinition);
  if (!serverFormInfo.valid) { return json({ serverFormInfo }); }
  serverFormInfo.submittedValues.hobby
                              // ^? string[] 👈
  serverFormInfo.submittedValues.email
                              // ^? string[] 👈

Minor Changes

Patch Changes

New Contributors

Full Changelog: v0.10.0...v0.11.0

v0.10.1

04 Mar 12:12
Compare
Choose a tag to compare
v0.10.1 Pre-release
Pre-release

⚠️ Please ignore this release, it should have been a minor so it was re-released as 0.11.0

v0.10.0

24 Jan 14:33
Compare
Choose a tag to compare
v0.10.0 Pre-release
Pre-release

⚠️ Note: not a breaking change yet but I'm considering removing serverFormInfo.submittedValues now that we've added value to InputInfo since you'd be able to get those values from serverFormInfo.inputs. So consider submittedValues deprecated and start using inputs[name].value.

What's Changed

  • make serverFormInfo optional in <FormProvider> by @CSFlorin in #42
  • Expose info.value and ref from useValidatedInput() by @brophdawg11 in #43
  • Add support for server-side type=email/type=url intrinsic validation by @brophdawg11 in #44

New Contributors

  • @CSFlorin made their first contribution in #42

Full Changelog: v0.9.1...v0.10.0

v0.9.1

16 Jan 22:59
Compare
Choose a tag to compare
v0.9.1 Pre-release
Pre-release

👀 What's Changed

  • Stabilize error message during subsequent async validations by @brophdawg11 in #36

Full Changelog: v0.9.0...v0.9.1

v0.9.0

16 Jan 17:13
Compare
Choose a tag to compare
v0.9.0 Pre-release
Pre-release

👀 What's Changed

Full Changelog: v0.8.0...v0.9.0

v0.8.0

16 Jan 15:58
Compare
Choose a tag to compare
v0.8.0 Pre-release
Pre-release

👀 What's Changed

  • Add support for other controls (textarea, select, radio, checkbox) by @brophdawg11 in #31. Please see the README for example usage.

⚠️ Breaking Changes

  • <Field> renamed to <Input> for consistency with <TextArea>/<Select>

Full Changelog: v0.7.0...v0.8.0

v0.7.0

15 Jan 00:09
Compare
Choose a tag to compare
v0.7.0 Pre-release
Pre-release

⚠️ Breaking Changes

v0.7.0 has a few breaking changes from v0.6.0. Please red through the below PRs for additional context, but the general changes include:

Changed formValidations to formDefinition

Your now define your form validations in a more comprehensive and explicit object. Previously you maintained formValidations and errorMessages separately, and placed custom validations alongside built-oin validation attributes. Now we have made a single structure that has locations for all of this:

// New Structure
let formDefinition: FormSchema = {
  inputs: {
    firstName: {
      // ✅ Built-in HTML validations
      validationAttrs: {
        required: true,
        pattern: "^[a-zA-Z]+$",
      },
    },
    emailAddress: {
      validationAttrs: {
        type: "email",
        required: true,
      },
      // ✅ Custom validations
      customValidations: {
        async uniqueEmail(value) {
          await new Promise((r) => setTimeout(r, 1000));
          return value !== "john@doe.com" && value !== "jane@doe.com";
        },
      },  
      // ✅ Field-specific error messages
      errorMessages: {
        uniqueEmail(attrValue, name, value) {
          return `The email address "${value}" is already in use!`;
        },
      },
    },
  },
  // ✅ Form-level error messages
  errorMessages: { ... },
};

Changed FormContextProvider to FormProvider

We no longer pass the context object, and instead pass formDefinition and serverFormInfo independently:

// New
<FormProvider formDefinition={formDefinition} serverFormInfo={actionData?.serverFormInfo}>

👀 What's Changed

🎉 New Contributors

Full Changelog: v0.6.0...v0.7.0

v0.6.0

29 Oct 17:28
Compare
Choose a tag to compare
v0.6.0 Pre-release
Pre-release

👀 What's Changed

  • Support formData in server validation by @kentcdodds (#16)
  • Allow user to pass input refs to useValidatedInput by @chaance (#19)
  • useFormContext renamed to useOptionalFormContext by @brophdawg11 (#22)

🎉 New Contributors

Full Changelog: v0.5.0...v0.6.0

v0.5.0

13 Sep 02:25
Compare
Choose a tag to compare
v0.5.0 Pre-release
Pre-release

What's Changed

  • Add better type inference (#13)

Full Changelog: v0.4.0...v0.5.0