Skip to content

Releases: edmundhung/conform

v1.3.0

22 Mar 16:00
077215b
Compare
Choose a tag to compare

Hello world! We're finally back after a bit of a break. This release is a bit small, but we hope it's the start of a more regular update schedule moving forward. I'm excited to share that @chimame has joined the team and is prepping our first valibot integration release in #876. We'll be sharing more details about the other changes as well. Thanks for your patience and stay tuned!

Custom coercion

v1.3.0 adds the ability to disable the default auto coercion behavior by setting the disableAutoCoercion option to true in parseWithZod in #871.

function Example() {
  const [form, fields] = useForm({
    onValidate({ formData }) {
      return parseWithZod(formData, {
        schema,
        disableAutoCoercion: true,
      });
    },
  });

  // ...
}

You can then manage how the form value is parsed yourself, or use the new unstable_coerceFormValue helper to coerce form value:

import { parseWithZod, unstable_coerceFormValue as coerceFormValue } from '@conform-to/zod';
import { z } from 'zod';

// Coerce the form value with default behaviour
const schema = coerceFormValue(
  z.object({
    // ...
  })
);

// Coerce the form value with default coercion overrided
const schema = coerceFormValue(
  z.object({
    ref: z.number()
    date: z.date(),
    amount: z.number(),
    confirm: z.boolean(),
  }),
  {
    // Trim the value for all string-based fields
    // e.g. `z.string()`, `z.number()` or `z.boolean()`
    string: (value) => {
      if (typeof value !== 'string') {
         return value;
      }

      const result = value.trim();

      // Treat it as `undefined` if the value is empty
      if (result === '') {
         return undefined;
      }

      return result;
    },

    // Override the default coercion with `z.number()`
    number: (value) => {
      // Pass the value as is if it's not a string
      if (typeof value !== 'string') {
        return value;
      }

      // Trim and remove commas before casting it to number
      return Number(value.trim().replace(/,/g, ''));
    },

    // Disable coercion for `z.boolean()`
    boolean: false,
  },
);

You can also customize coercion for a specific schema by setting the customize option.

import {
  parseWithZod,
  unstable_coerceFormValue as coerceFormValue,
} from '@conform-to/zod';
import { useForm } from '@conform-to/react';
import { z } from 'zod';
import { json } from './schema';

const metadata = z.object({
  number: z.number(),
  confirmed: z.boolean(),
});

const schema = coerceFormValue(
  z.object({
    ref: z.string(),
    metadata,
  }),
  {
    customize(type) {
      // Customize how the `metadata` field value is coerced
      if (type === metadata) {
        return (value) => {
          if (typeof value !== 'string') {
            return value;
          }

          // Parse the value as JSON
          return JSON.parse(value);
        };
      }

      // Return `null` to keep the default behavior
      return null;
    },
  },
);

This helper is currently released with the unstable_ prefix to collect more feedbacks. Lock your version to the patch version range (e.g. ~1.3.0) if you want to use this feature without unexpected changes.

Other Improvements

New Contributors

Full Changelog: v1.2.2...v1.3.0

v1.2.2

19 Sep 22:15
2f2111c
Compare
Choose a tag to compare

What's Changed

fix: revert auto field value update (#778)

Revert #729 and #766

The auto field value update feature introduced in v1.2.0 has caused several critical issues with significant user impact. While I appreciate what they accomplished, I’ve realized the current solution isn't robust enough to handle all potential use cases. To minimize the impact on everyone, I believe it's best to revert these changes for now.

Full Changelog: v1.2.1...v1.2.2

v1.2.1

14 Sep 16:12
24105f4
Compare
Choose a tag to compare

What's Changed

  • Fixed an issue with Conform overwriting the value of input buttons in #766. In v1.2.0, if you have any input buttons rendered, their value will be likely rewritten to empty string as Conform treats it as normal inputs and tries to update its value based on the default value.

Full Changelog: v1.2.0...v1.2.1

v1.2.0

14 Sep 13:31
db63782
Compare
Choose a tag to compare

Embrace the platform

This change is reverted in v1.2.2

One of the most critical changes in this release is the auto field value update implemented in #729. Conform now updates input value using the DOM api instead of relying on the key to re-mount the inputs with the new defaultValue. It means:

  • It is no longer required to pass the key (e.g. fields.title.key) to the input elements unless you are rendering a list.
// Before: The minimum setup
<input key={field.title.key} name={fields.title.name} defaultValue={fields.title.defaultValue} />
// Now: the key props is no longer required 
<input name={fields.title.name}  defaultValue={fields.title.defaultValue} />
// Bonus: if the form is not rendered server side, or you don't mind the user experience before JS is loaded...
<input name={fields.title.name} />
  • Helpers like getInputProps, getSelectProps or getTextareaProps are no longer spreading a key to the input element. If you were seeing the message Warning: A props object containing a "key" prop is being spread into JSX, it should be resolved now.
  • Outstanding issues caused by inputs being unmounted (e.g. #701 and #730) are now fixed

Pre-release

Thanks to pkg.pr.new, we are now releasing a preview version on every pull request (#742)

You will find a comment on the PR like this one from pkg.pr.new with each package name listed. If you expand the item, you will see a command to install the pre-release version. If you are not using pnpm, you can swap it with npm install, or just copy the package URL and replace the version in the package.json with it.

We are also shipping a pre-release version on every commit merged to main in the format https://pkg.pr.new/@conform-to/package@commit . For example, if you would like to install the pre-release version of @conform-to/dom and @conform-to/zod up to db63782, you can run:

npm install https://pkg.pr.new/@conform-to/dom@db63782
npm install https://pkg.pr.new/@conform-to/zod@db63782

Other Improvements

  • Improved the types of submission.payload in #706. If you were using Remix with single fetch, the action results should no longer be in type never. Thanks @timvandam!
  • Fixed empty string default value support in #741. Previously, we suggested using .default() to set a fallback value. However, .default() does not work as expected with z.string().default(''). This issue has now been resolved, but keep in mind that the default value is still subject to validation errors. For more predictable results, we recommend using .transform(value => value ?? defaultValue) instead.
  • Implement zod object coercion in #733. Conform should support nested fields with only checkboxes now.
  • Added bigint coercion support with zod in #726. Thanks @lifeiscontent!
  • Improved the types of the default value in #719. As FormValue should never be null. Thanks @aaronadamsCA!
  • Added a multiple select example with shadcn-ui in #753. Thanks @pwli0755!
  • Improved the shadcn-ui Switch Component example to use control.value in #721. Thanks @reborn2135!
  • Fixed typo in parseWithYup.md and FormProvider.md in #708, #751. Thanks @uttk, @felixyeboah!
  • Improved the ja docs messages in #709, #710, #711, #712. Thanks @k70suK3-k06a7ash1!
  • Explained the usage of allErrors with checkbox group in #735.

New Contributors

Full Changelog: v1.1.5...v1.2.0

v1.1.5

17 Jun 21:03
650c3d7
Compare
Choose a tag to compare

Improvements

  • Fixed an issue with unstable_useControl not resetting the value of the registered input on form reset (#674)

Full Changelog: v1.1.4...v1.1.5

v1.1.4

27 May 20:30
Compare
Choose a tag to compare

Improvements

  • The default value are now serialized properly when inserting an item to a list (#648)
  • Fixed Bigint support on default value (#613, #619, #636)
  • Addressed a few typos and code snippet issues on the docs (#621, #622, #646)
  • Improved build and test setup thanks to @lifeiscontent πŸ™ŒπŸΌ (#616, #615)

New Contributors

Full Changelog: v1.1.3...v1.1.4

v1.1.3

28 Apr 21:08
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.1.2...v1.1.3

v1.1.2

23 Apr 20:37
Compare
Choose a tag to compare

What's Changed

Full Changelog: v1.1.1...v1.1.2

v1.1.1

23 Apr 20:35
Compare
Choose a tag to compare

What's Changed

  • Fixed a vulnerability with Prototype Pollution. You can find the details here.
  • Fixed broken link to intent button page on docs by @marilari88 in #581

Full Changelog: v1.1.0...v1.1.1

v1.1.0

09 Apr 20:09
Compare
Choose a tag to compare

Improvements

  • The form value should now keep in synced on DOM updates (e.g. when you render an addition input) (#491)
  • You can now access the latest form or field metadata in the callback without the need to subscribe it during render (#467)
  • Form errors will be cleared immediately on form submit now instead of waiting until the server result is back (#553)
  • Both the update and reset intents now accept an optional index similar to the insert intent (#555)
  • Conform will revalidate on blur only if there was any changes made before (i.e. an input event was triggered) to minimize the chance server error get cleared simply because of moving focus out of the inputs. (#559)
  • The useFormMetadata hook now accept no formId (#560)
  • Fixed an issue with form reset failed if the form element is unmounted and form id getting out of sync (#571)
  • The type prop returned from the getCollectionProps helper is narrowed down to the specific type by @AMEH64 (#562)
  • Added object and array support to getYupConstraint by @gglee89 (#465)

Docs

New japanese docs are now available on ja.conform.guide! Huge thanks to @coji for the translations. (#558)

New Contributors

Full Changelog: v1.0.6...v1.1.0