react-hybrid-form
v1.0.0
Published
A super simple, straightforward and powerful hybrid form library which combines the benefits of both controlled or uncontrolled form.
Downloads
68
Maintainers
Readme
Introduction
Welcome to the Hybrid Form Library, a simple, straightforward and high-performance form solution for React applications. This library combines the benefits of both controlled and uncontrolled forms, enabling real-time validation and seamless integration with minimal code.
"My goal with this library is to let you make forms effortless, letting you focus on what matters - while it handles the tedious parts."
Key Features
Hybrid Approach: Leverage the speed and efficiency of uncontrolled forms while enjoying real-time validation of individual fields for an enhanced user experience.
Simplicity and Readability: Integrate and set up forms quickly and easily, ensuring a smooth start without hassle.
Optimized Performance: Achieve high performance for both simple and complex forms without the overhead typically found in other libraries.
Component-Based Architecture: Adhere to React's principles with reusable components, making forms modular and easy to manage.
Custom Styling Support: Easily apply your own styles or leverage popular libraries like Tailwind and Bootstrap to align with your app’s design.
Dedicated Field Components: Utilize specialized components for common input types such as text, password, select, radio, and checkbox.
Advanced Password Handling: Enjoy built-in support for password confirmation logic and toggling visibility with minimal setup.
Type Script Support: Enjoy full TypeScript support for strong typing, enhanced autocompletion, and error detection during development. Benefit from out-of-the-box types for form fields, validation, and submission handling, ensuring type safety and reducing runtime errors.
Why choose this over others ?
Popular form libraries offer robust features, but often add unnecessary complexity and performance overhead for something simple. Here’s how this hybrid form library streamlines the process:
- Performance Without Complexity -
Other Libraries: Often require heavy state management (like Redux Form) or excessive hooks (like React Hook Form), which can lead to performance issues with re-renders, especially in large forms.
This Library: Optimizes performance by minimizing re-renders and decoupling state, combining the speed of uncontrolled forms with the flexibility of real-time validation.
Simple, Minimal API -
Other Libraries: Typically involve multiple hooks and configurations, which can feel overwhelming for simple forms.
This Library: Provides just three core functions keeping the API lean and straightforward for any form setup.
Very Low Learning Curve -
Other Libraries: Require familiarity with advanced React patterns and extensive documentation, which can slow down development, especially for beginners.
This Library: Designed for clarity and ease of use, allowing even beginners to quickly set up and manage forms without extensive prerequisites.
Extremely Light Weight
Other Libraries: Libraries like Formik, React Hook Form, Redux form ...etc can be hefty, often exceeding hundreds and thousands of kilobytes.
This Library: Coming in at an ultra-light 70 KB, it's designed to provide many features without the bloat, ensuring fast loading times and better performance for your app.
Installation
npm install react-hybrid-form
Usage
Start by creating your form component and using the useHybridForm hook to manage form registration and data retrieval:
Tip Here's an important performance optimization tip to remember! -
- Memoize the main form using React.memo()
- Avoid using other states inside the main form.
- Stick to the below pattern as much as you can.
⚠️ Critical Note for TypeScript Devs:
TypeScript may not catch missing
ref
props in field components, which can lead to issues during runtime.Always ensure you pass the
ref
(e.g.,ref = {register("name")}
) to each form field to avoid unexpected behavior.
The form has just 3 simple and straightforward api -
- register() - attaches to the form fields and is crucial for functioning.
- getFormData() - returns entire form data if every validation passes.
- resetForm() - resets the entire form to its default.
import { useHybridForm } from 'react-hybrid-form';
const MyForm = () => {
const [register, getFormData, resetForm] = useHybridForm();
const handleSubmit = (e) => {
e.preventDefault();
const data = getFormData();
if(data){
console.log(data);
resetForm();
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields go here */}
</form>
);
};
Registering Fields :-
⚠️ Critical -
- Requires field provided by the library itself.
- name passed to fields and register api should be same.
- No two fields within the form can have the same name.
- Must attach the register api via reference of each field.
Use the register function to integrate each form field. This function automatically handles validation and state management.
<InputField
name="username"
ref={register("username")}
/>
Dedicated Field Components :-
Each field component is specialized for its input type, offering a consistent API and handling common validation requirements. All fields require a name prop and a ref prop attached to register function. The name specified in the field should match the name passed to the register function.
Standard Input Field :
<InputField name="username" // required type="text" // default is text validate={validationFn()} // optional ref={register("username")} // required defaultValue="" // optional and defaults to "" placeholder="username" // optional if label is provided label="Username: " // optional if placeholder is provided />
Dedicated Password field :
- Built in password visibility toggling
- Automatic and easy confirm password validation
requiresConfirmation & requiresTogglingVisibility are special props to enable or disable the confirm password feature or the password visibility toggling feature.
<PasswordField name="password" // required ref={register("password")} // required validate={validatePassword} // required placeholder="password" // optional if label is provided requiresConfirmation={false} // Optional, default is true label="Password: " // optional if placeholder is provided requiresTogglingVisibility={false} // Optional, default is true />
Text Area Field :
<TextAreaField name="bio" // required ref={register("bio")} // required validate={validationFn()} // optional defaultValue="" // optional and defaults to "" placeholder="bio" // optional if label is provided label="Bio: " // optional if placeholder is provided />
Radio, Select and Checkbox Fields :
<SelectField name="country" // required label="Country" // required options={[ { value: "usa", label: "USA" }, { value: "canada", label: "Canada" }, ]} // required & defaults to 1st option ref={register("country")} // required /> <RadioField name="gender" // required label="Gender" // required options={[ { value: "male", label: "Male" }, { value: "female", label: "Female" }, ]} // required & defaults to 1st option ref={register("gender")} // required /> <CheckBoxField name="interests" // required label="Interests" // required options={[ { value: "sports", label: "Sports" }, { value: "music", label: "Music" }, ]} // required & defaults to 1st option ref={register("interests")} // required />
Validation :-
The library allows for real-time validation by adding custom validation functions which can easily be passed as props to individual fields thereby centralizing and abstracting complexity. You can use external libraries like Yup or Zod or write custom validation functions directly.
Example using a custom validation fn
const validateUsername = (value) => {
if (!value) return "Username is required";
if (value.length < 3) return "Username must be at least 3 characters";
return null;
};
<InputField
name="username"
ref={register("username")}
validate={validateUsername}
/>
Styling :-
This library is designed with flexible styling in mind, allowing custom classes for each element of a field. You can use popular styling libraries or your own custom CSS classes.
Each class is specific to individual elements within the field, and acts same way as className in react.
Common styling class props -
| Prop | Description | Applies To | | :--------: | :------------------------: | :--------: | | fieldClass | Styles the field container | All fields | | labelClass | Styles the label | All fields | | errorClass | Styles error messages | All fields |
Specific styling class Props
| Prop | Description | Applies To | | :-------------------: | :-------------------------------: | :------------------------------------: | | inputClass | Styles the input element | Standard input fields | | textareaClass | Styles the textarea | TextAreaField | | optionsClass | Styles the options wrapper | SelectField, RadioField, CheckboxField | | optionClass | Styles individual options | RadioField, CheckboxField | | toggleVisibilityClass | Styles the visibility toggle icon | PasswordField |
Recommended way to style using classes ( custom, tailwind, bootstrap ...etc) -
Example :-
CSS -
.field {
gap: 0.5rem;
display: flex;
flex-direction: column;
}
.label {
color: #333;
font-weight: 600;
margin-bottom: 0.5rem;
}
.input {
padding: 0.5rem;
border-radius: 0.25rem;
border: 1px solid #ccc;
}
.options {
gap: 1rem;
display: flex;
}
.option {
gap: 0.5rem;
display: flex;
align-items: center;
}
.textarea {
resize: none;
padding: 0.5rem;
}
.togglePwdVisibility {
top: 50%;
right: 0.5rem;
width: 1.25em;
cursor: pointer;
position: absolute;
transform: translateY(-50%);
}
.err-txt {
color: red;
font-size: 0.8rem;
padding-left: 0.5rem;
}
JSX -
<InputField
labelClass="text-lg text-black md:text-semibold"
fieldClass="field"
inputClass="input"
errorClass="err-txt"
/>
<PasswordField
labelClass="label"
fieldClass="flex flex-column gap-2"
inputClass="input"
errorClass="err-txt"
toggleVisibilityClass="togglePwdVisibility"
/>
<TextAreaField
rows={5}
cols={10}
labelClass="label"
fieldClass="field"
errorClass="text-red-500 text-sm"
textareaClass="textarea"
/>
<SelectField
fieldClass="field"
labelClass="label"
optionsClass="flex gap-2
/>
<RadioField
fieldClass="field"
labelClass="label"
optionClass="flex gap-1"
optionsClass="options"
/>
<CheckboxField
labelClass="label"
fieldClass="field"
optionClass="option"
optionsClass="options"
/>
Conclusion :-
The Hybrid Form Library is designed to streamline form handling in React, offering a blend of simplicity, performance, and flexibility. It's an ideal choice for developers who want a powerful tool without the complexity of traditional form libraries. Simplify your workflow, minimize overhead, and focus on building great user experiences.
Explore More :-
Check out the EXAMPLES HERE to see how easy it is to build forms with this library. Whether you're using TypeScript or JavaScript, these demos will help you get up and running quickly.
About the Author
This library is created and maintained by Shahin M Hashim. Contributions are encouraged and greatly appreciated! If you have feedback or ideas, don’t hesitate to reach out or submit an issue.
LICENSE
This library is open-source to support the developer community. Please respect the effort and dedication behind it by avoiding the creation of direct derivative works aimed at competing with this project. Licensed under MIT