jotaijs / jotai-form

Form atoms for Jotai
MIT License
135 stars 1 forks source link

Feat: ability to validate atoms , `validateAtoms` #5

Closed barelyhuman closed 2 years ago

barelyhuman commented 2 years ago

Adds the validateAtoms implementation for overall form atom validation.

Usage example:

import { atomWithValidate, validateAtoms } from "jotai-form";

const nameAtom = atomWithValidate("foo", {
  validate: (v) => v, // individual atom validation (nothing here just for this example)
});

const ageAtom = atomWithValidate(18, {
  validate: (v) => v, // individual atom validation (nothing here just for this example)
});

const formStateAtom = validateAtoms(
  {
    name: nameAtom,
    age: ageAtom,
  },
  async (values) => {
   // validating the entire atom group for a specific form
    await Yup.object()
      .shape({
        name: Yup.string().min(3).required(),
        age: Yup.number().min(18).required(),
      })
      .validate(values);
  }
);

export const Component = () => {
  const [name, setName] = useAtom(nameAtom);
  const [age, setAge] = useAtom(ageAtom);
  const [formState] = useAtom(formStateAtom);

  return (
    <>
      <input
        placeholder="Name"
        value={name.value}
        onChange={(e) => setName(e.target.value)}
      />
      <input
        type="number"
        placeholder="Age"
        value={age.value}
        onChange={(e) => setAge(parseInt(e.target.value,10))}
      />
      <button type="submit" disabled={!formState.isValid}>Submit</button>
    </>
  );
};
barelyhuman commented 2 years ago

@dai-shi there is a ts-expect statement in the code that I'd like you to check. I think it's from the official jotai libraries expectation of the Getter type but would need confirmation

dai-shi commented 2 years ago

Types are fixed. You can't have a union type for getter. I'm not sure if it's possible to improve.

barelyhuman commented 2 years ago

Do not merge even if it suffices, have to write tests for async validation

BenBeattieHood commented 2 years ago

Oh wow! I go away for a break, I come back and you've solved this 🤩 Love your work, thank you 👍