refastform
v0.9.0
Published
React Fast Form
Downloads
102
Readme
React Fast Form
Stupidly simple and fast form engine for React.
- Subscription-based rendering: only required fields will re-render when changing anything in form;
- Form errors validation through Yup;
- Very simple API;
- Typescript-ready.
Installation
npm i --save refastformUsage
Create form with two HTML input fields
import { Form, HTMLInput } from "refastform";
const FORM_INITIAL_STATE = {
firstName: string,
lastName: string,
};
export const MyForm = () => (
<Form
initialValue={FORM_INITIAL_STATE}
onSubmit={data => alert(`Hi, ${data.firstName} ${data.lastName}!`)}
>
<div>
<HTMLInput model='.firstName' placeholder='First name' />
<HTMLInput model='.lastName' placeholder='Last name' />
</div>
<button type='submit'>Submit form!</button>
</Form>
);Add validation schema
import { Form, HTMLInput } from "refastform";
import * as Yup from 'yup';
const FORM_INITIAL_STATE = {
firstName: string,
lastName: string,
};
const validationSchema = Yup.object().shape({
firstName: Yup.string.nullable().required(),
lastName: Yup.string.nullable(),
})
export const MyForm = () => (
<Form
initialValue={FORM_INITIAL_STATE}
validationSchema={validationSchema}
onSubmit={data => alert(`Hi, ${data.firstName} ${data.lastName}!`)}
>
<div>
<HTMLInput model='.firstName' placeholder='First name' />
<HTMLInput model='.lastName' placeholder='Last name' />
</div>
<button type='submit'>Submit form!</button>
</Form>
);Create custom field
import { Form, ControlledField, type ControlledHookProps, chainNativeEvents } from "refastform";
import { TextBox } from 'my-cool-ui-kit';
export const CustomInput = ({ model, readonly, disabled, ...props }: ControlledHookProps & ComponentProps<"input">) => (
<ControlledField<string>
model={model}
disabled={disabled}
readonly={readonly}
render={({ error, value, disabled, ...libEvents }) => (
<>
<TextBox
value={value}
disabled={disabled}
error={error}
{...props}
{...chainNativeEvents(libEvents, props)} />
</>
)}
/>
);
const MyApp = () => (
<Form initialValues={{}}>
<CustomInput model='.text' />
</Form>
);
chainNativeEventscould be used to simplify connection between lib'sonChange/onBlur/onFocusand user provided props.
For more information, look at
<ControlledField />types
Use <Fieldset /> to create reusable form segments
(some unchanged code parts omitted)
import { Form, HTMLInput } from "refastform";
// ...
const FullNameSegment = ({ model }: { model: string }) => (
<Fieldset model={model}>
<HTMLInput model=".first" placeholder="First" />
<HTMLInput model=".middle" placeholder="Middle" />
<HTMLInput model=".last" placeholder="Last" />
</Fieldset>
)
export const MyForm = () => (
<Form
initialValue={FORM_INITIAL_STATE}
validationSchema={validationSchema}
onSubmit={data => alert(`Hi, ${data.firstName} ${data.lastName}!`)}
>
<div>
Your name:
{/* Will add first/middle/last into form root object */}
<FullNameSegment model='.' />
</div>
...
<div>
Parents information:
{/* Will add motherFullname.first/middle/last and fatherFullname.first/middle/last in two lines */}
<FullNameSegment model='.motherFullname' />
<FullNameSegment model='.fatherFullname' />
</div>
<button type='submit'>Submit form!</button>
</Form>
);
<Fieldset />and<Form />also acceptsdisabledandreadonlyprops that will be pushed to all fields bellow.
Use useFormValue to create dependent fields
import { Fieldset, Form, HTMLCheckbox, HTMLInput } from "refastform";
const NoExperienceReasonField = () => {
// Obtain `.hasNoExperience` value and subscribe for it's changes
const hasNoExperience = useFormValue(".hasNoExperience");
// Disable field if checkbox is'nt set
return <HTMLInput model=".noExperienceReason" placeholder="why" disabled={!hasNoExperience} />;
};
export const MyForm = () => (
<Form initialValues={{}}>
<HTMLCheckbox model='.noExperience' id='no-experience-check' />
<label htmlFor='no-experience-check'>I have no experience</label>
<NoExperienceReasonField />
</Form>
);Use <ValueProvider /> to create dependent fields
Same as above, but in a more compact way:
import { Fieldset, Form, HTMLCheckbox, HTMLInput, HTMLRadio, ValueProvider } from "refastform";
export const MyForm = () => (
<Form initialValues={{}}>
<CustomInput model='.noExperience' id='no-experience-check' />
<label htmlFor='no-experience-check'>I have no experience</label>
<ValueProvider model='.hasNoExperience'>
{(hasNoExperience: boolean) => (
<HTMLInput model=".noExperienceReason" placeholder="why" disabled={!hasNoExperience} />
)}
</ValueProvider>
</Form>
);