Coder Social home page Coder Social logo

virtuslab-open-source / formts Goto Github PK

View Code? Open in Web Editor NEW
25.0 25.0 2.0 1.3 MB

Type-safe, declarative and performant React form & validation library

Home Page: https://virtuslab-open-source.github.io/formts/

License: MIT License

JavaScript 0.21% TypeScript 99.64% Shell 0.14%

formts's People

Contributors

cyp3rius avatar dependabot[bot] avatar mixvar avatar pidkopajo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

formts's Issues

debounced validation

consider adding built-in support for debouncing validation (useful for async validators) if this is not easy to to in userland currently.

add example with debounced async validation

[core] pushItem and removeItem methods on array field handle

from POC:

      /**
       * Will set the array field value to its copy with the item added at the end.
       * Will run field validation with `change` trigger.
       * Will set `isTouched` to `true`.
       */
      pushItem: (item: E) => void;

      /**
       * Will set the array field value to its copy with the item at index `i` removed.
       * Will run field validation with `change` trigger.
       * Will set `isTouched` to `true`.
       */
      removeItem: (i: number) => void;

[core] useFormts v2 - form handle

  • basic form handle impl (values, isTouched, reset, getSubmitHandler)

example:

  const [, form] = useFormts({ Schema });

  const values = form.values
  const onSubmit = form.getSubmitHandler((values) => console.log(values));
  form.reset()

Date instance specified in initialValues causes TypeError

TypeError
Cannot convert undefined or null to object
    at keys (node_modules/virtuslab/formts/dist/module/utils/object.js:26:17)
    at deepMerge (node_modules/virtuslab/formts/dist/module/utils/object.js:100:10)
    at eval (node_modules/virtuslab/formts/dist/module/utils/object.js:103:127)
    at deepMerge (node_modules/virtuslab/formts/dist/module/utils/object.js:100:23)
    at createInitialValues (node_modules/virtuslab/formts/dist/module/core/helpers/create-initial-values.js:14:46)
    at getInitialState (node_modules/virtuslab/formts/dist/module/core/hooks/use-form-controller/formts-reducer.js:127:54)

Check before touchField

touchField is always triggered when setting a new value, but for the same field in 99% sets touched: true when already touched: true.

Add a check before setting touched to skip setting the same value

fix automatic versioning

Currently, automatic versioning only jumps by minor version regardless of the git history.
Maybe smth needs to be done to standard-version configuration

builder based API

  • try implementing createFormSchema and createFormValidator functions using builder pattern for better developer experience
  • consider extracting fields decoder container to top-level export

[core] hook API v2

research and implement new version of API that allows for context-based hook usage and minimizing rerenders after atom-based implementation is ready

pass all form values to validate.rules function

current behaviour:

rules function receives values of fields listed in dependencies array, if present

target behaviour

rules function always receives all form values, regardless of dependencies array. dependencies purpose remains to specify other fields which trigger rerun of validation for given fields. This means that user will be able to use fields which do not trigger validation. Documentation and examples will need to be updated accordingly to make this behaviour obvious.

[core] useFormts v3 - field handles

  • useFormts returning field of type FieldHandleSchema - object containing field handles for all form fields
  • first version of fieldHandle providing: id, value, isTouched, setValue, handleBlur

example:

  const [fields] = useFormts({ Schema });

  const emailField = (
        <input
          value={fields.email.value}
          onChange={e => fields.email.setValue(e.target.value)}
          onBlur={fields.email.handleBlur}
        />
  )

attaching validation rules to individual fields inside arrays

for example given the Schema:

const Schema = createFormSchema(
  fields => ({
    array: fields.array(
      fields.object({
        foo: fields.string(),
        bar: fields.string(),
      })
    ),
  }),
);

it should be possible to attach validators to every array.foo and array.bar fields

validation dependencies

  • allow for using values of other fields inside validation function for any given field using dependencies option
  • trigger validation of all dependent field when given field value changes (consider how validation triggers should work in such case)

remove built-in validation errors

built-in errors are awkward to use. Consider alternative approach where each built-in validation rule accepts exact error to be used.

benefits:

  • easier usage of built-in validators in combination with string errors
  • should work great in combination with unionize for error <=> error message decoupling
  • withError helper can be removed
  • all built-in error types are gone, together with associated problems with their naming

non-react API

make the lib truly view-layer agnostic by allowing usage outside of react or even without react altogether.
set stage for possible integration with other UI frameworks than react.

Atom cache

Create cashe for atoms per path to share between rerenders and usages of useField.

[chore]: project setup - CI

  • setup CI (TravisCI or CircleCI)
  • setup publishing to public NPM registry under @virtuslab/formts
  • require passing check on CI before merging in a PR
  • automatic NPM release and CHANGELOG.MD update after merging a PR to master

FieldHandle.handleChange function

Simplify binding to onChange function of various inputs by taking the responsibility of extracting value from event automatically using available runtime information - field type and input type

optionally also add parseEvent function for extracting value from event without passing it to setValue

add FieldHandle.reset method

reset method for rolling back value to initial value, clearing touched flag and errors. Should propagate down on composite fields

[core] object fields

  • object field decoder that composes other decoders into an object
  • support object fields in createFormSchema function

[validation] form validation API v1

basic implementation of:

  • createFormValidator function
  • built-in validators
  • holding errors state
  • reflecting isValid and errors in formHandle and fieldHandle

example:

const validator = createForm.validator(Schema, (validate) => [
  validate({
    field: Schema.userName,
    rules: () => [required()]
  }),
  validate({
    field: Schema.email,
    rules: () => [
      required(),
      (email) => (/someregex/.test(email) ? null : "Invalid email address!")
    ]
  })
]);

out of scope:

  • async validation
  • validation dependencies

validation rule compose util

util function for composing multiple validation rules into one that runs all in paralel (rather than one after another until error is found)

separate import path for validators

currently in order to use provided validation rules one has to import all as namespace.
this is not convenient and prevents tree-shaking of individual validation rule functions.

import { validators } from "@virtuslab/formts";

change the build config so that this is possible instead:

import { required, minLength } from "@virtuslab/formts/validators";

handling of optional fields / lack of field value

current solution:

  • fields.number() corresponds to type number | "" to represent empty input value as ""
  • fields.date() corresponds to type Date | null to represent lack of date
  • fields.choice() can accept "" to represent empty select input
  • other fields do not have dedicated type representing lack of value

this can be confusing and require additional casting of form state to domain models on submit.
research better solution

[build] proper dist output

research & implement the most appropriate way to generate /dist folder to make the lib consumable for widest possible audience.

Atom based state

Replace usage of React useReducer hook with atom based state.

This should allow for subscribing to just the required piece of form state for each hook.

requires #59

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.