A new major release of Fielder is now live ππ
This latest release has been the result of countless hours exploring form design - here's what's new!
How we got here
With the initial release of Fielder, the goal was to create a form library that was unbound from existing form library constraints.
Removing the rigidity of monolithic validation schemas, Fielder posed as a simpler solution for forms by coupling validation to fields rather than forms.
const [fieldProps, fieldMeta] = useField({
name: "username",
validate: useCallback((value) => {
if (!value) {
throw Error("Username is required!");
}
}, []),
});
Example field-first validation in Fielder V1
This change in approach has proven to be effective in creating simple and flexible forms which can evolve over time (with exception).
This latest release compliments this mantra, continuing the focus on evolutionary and adaptive form design.
New features
Along with bug fixes and optimizations, this release comes with two major features which are designed to:
- Make validation even more flexible
- Remove the need for user-created form state
Validation events
Validation events are a new addition to Fielder which simplify specifying when validation occurs and what validation logic is executed for a given event.
const usernameValidation = ({ value, trigger }) => {
// Event agnostic validation (sync)
if (!value) {
throw Error("Username is required");
}
// Validation on submit (async)
if (trigger == "submit") {
return isUsernameTaken(value).then((taken) => {
if (taken) {
throw Error("Username is already taken");
}
});
}
};
In this above example, you can see we are able to run more expensive async validation exclusively on validation events such as submit
.
Submission
Complimenting the new validation events, there's a new useSubmit
hook which can be used for completion and progression in a form.
See the new submission guide in the docs
const { isValidating, hasSubmitted, handleSubmit } = useSubmit(() => {
console.log("Submit validation succeeded!");
});
handleSubmit(); // Trigger submission
It returns a handleSubmit
function which guards submission logic from being called until validation completes.
There's also additional state for tracking the status of async submit
validation (isValidating
) and for tracking whether the handleSubmit
function has been called (hasSubmitted
).
Combined with validation events, this hook provides all the necessary tools to do complex submit-specific validation without ever having to introduce your own state.
const usernameValidation = ({ value, trigger }) => {
if (!value) {
throw Error("Username is required");
}
if (trigger == "submit") {
return isUsernameTaken(value).then(taken => {
if (taken) {
throw Error("Username is already taken");
}
})
}
}
const Form = () => {
const [usernameProps, usernameMeta] = useField({
name: 'username',
initialValue: '',
validate: usernameValidation
});
const { isValidating, hasSubmitted, handleSubmit } = useSubmit((values) => {
fetch('/submit-form', {
method: 'POST',
body: JSON.stringify(values),
});
});
return (
<div>
<input type="text" {...usernameProps} />
<button onClick={handleSubmit}>
{isValidating ? <Spinner /> : "Submit"}
</button>
</div>
);
}
Get started
Whether you're new or looking to update, head on over to the docs site to get started and be sure to check out the new live examples.
Hopefully, you found this interesting! If you have any thoughts or comments, feel free to drop them below or hit me up on twitterβ-β@andyrichardsonn
Disclaimer: All thoughts and opinions expressed in this article are my own.
Top comments (0)