Skip to content

Latest commit

 

History

History
212 lines (176 loc) · 9.58 KB

README.md

File metadata and controls

212 lines (176 loc) · 9.58 KB

ReForm.re

All Contributors

Reasonably making forms sound good

Docs

Check our Docusaurus https://astrocoders.dev/reform

Installation

yarn add bs-reform reschema

Then add it to bsconfig.json

"bs-dependencies": [
 "bs-reform",
 "reschema"
]

Then add lenses-ppx

yarn add lenses-ppx@4.0.0 -D

And update your bsconfig.json with ppx-flags

"ppx-flags": [
 "lenses-ppx/ppx"
]

Features

  • Hook API
  • Schema API
  • Type safe, handleChange properly infers the value of the field it is handling
  • Context Provider
  • Field component
  • Validation strategy, OnDemand and OnChange

What this is and why

Code that deals with strongly typed forms can quickly become walls of repeated text. We created ReForm to be both deadly simple and to make forms sound good leveraging ReasonML's powerful typesytem. Even the schemas we use are nothing more than constructors built-in in the language itself with a small size footprint.

Basic usage

Checkout https://github.com/Astrocoders/reform/blob/master/packages/demo/src/PostAddNext.re for a more complete demo

open BsReform;

module StateLenses = [%lenses
  type state = {
    description: string,
    title: string,
    acceptTerms: bool,
  }
];
module PostAddForm = ReForm.Make(StateLenses);

module FieldString = {
  [@react.component]
  let make = (~field, ~label) => {
    <PostAddForm.Field
      field
      render={({handleChange, error, value, validate}) =>
        <label>
          <span> {React.string(label)} </span>
          <input
            value
            onChange={Helpers.handleChange(handleChange)}
            onBlur={_ => validate()}
          />
          <p> {error->Belt.Option.getWithDefault("")->React.string} </p>
        </label>
      }
    />;
  };
};

[@react.component]
let make = () => {
  let reform =
    PostAddForm.use(
      ~validationStrategy=OnDemand,
      ~schema={
        PostAddForm.Validation.Schema([|
          StringMin(Title, 20),
          StringNonEmpty(Description),
          Custom(
            AcceptTerms,
            values =>
              values.acceptTerms == false
                ? Error("You must accept all the terms") : Valid,
          )
        |]);
      },
      ~onSubmit=
        ({state}) => {
          Js.log2("title", state.values.description);
          Js.log2("description", state.values.description);
          Js.log2("acceptTerms", state.values.description);
          None;
        },
      ~initialState={title: "", description: "", acceptTerms: false},
      (),
    );

  <PostAddForm.Provider value=reform>
    <form
      onSubmit={event => {
        ReactEvent.Synthetic.preventDefault(event);
        reform.submit();
      }}>
      <FieldString field=StateLenses.Title label="Title" />
      <FieldString field=StateLenses.Description label="Description" />
      <PostAddForm.Field
        field=StateLenses.AcceptTerms
        render={({handleChange, error, value}) =>
          <label>
            <p>
              <span> {"Accept terms? " |> React.string} </span>
              <input
                type_="checkbox"
                value={string_of_bool(value)}
                onChange={event =>
                  ReactEvent.Form.target(event)##checked |> handleChange
                }
              />
            </p>
            <p> {error->Belt.Option.getWithDefault("")->React.string} </p>
          </label>
        }
      />
      {reform.state.formState == Submitting
         ? <p> {React.string("Saving...")} </p>
         : <button type_="submit"> {"Submit" |> React.string} </button>}
    </form>
  </PostAddForm.Provider>;
};

Alternatives

Publishing

lerna version major|patch|minor

and then

lerna publish from-git

Support

We usually hang out at https://discord.gg/reasonml or https://reasonml.chat so feel free to ask anything there.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Thomas Deconinck

📖 💻

Gabriel Rubens

💻 🐛 🤔 🖋 📖

Lucas Besen

🚧

Jefferson Carvalho

💻

Luiz Augusto Moratelli

💻

amythos

💻

Lalli Nuorteva

🐛

Matt

🚧

Kyle Davis

👀

Ulugbek Abdullaev

🐛

Khoa Nguyen

💻

Medson Oliveira

💻 🤔

Ana Luiza Portello Bastos

📖

Freddy Harris

🐛

arthur

📖 💻

This project follows the all-contributors specification. Contributions of any kind welcome!