@tapgiants/form is build on the top of Formik and exports all the Formik functionality. The main goal of the package is to provide simple form field components with no need for form state managment.
Install peer dependencies:
yarn add recompose
Install @tapgiants/form
yarn add @tapgiants/form
Form
component should be used in a combination with withForm
in order to receive formikBag
which will be passed to the FormContext
.
It receives formikBag
props and
custom props passed to the form component.
import React from 'react';
import Form, { Field, Submit, withForm } from '@tapgiants/form';
const FormMarkup = ({ formName, ...formikBag }) => (
// Pass formikBag props to the Form component. In this way formik props are set in the `FormContext`
<Form {...formikBag}>
<h1>{formName}</h1>
<Field
input="email"
name="email"
label="E-mail"
/>
<Field
input="password"
name="password"
label="Password"
/>
<Submit>Login</Submit>
</Form>
);
// Here we use withForm in order to provide the FormikBag props to the Form component
const TapGiantsForm = withForm({
mapPropsToValues: () => ({ email: '', password: '' }),
handleSubmit: (values, formikBag) => {
const { setSubmitting } = formikBag;
setSubmitting(false);
console.log('handleSubmit values: ', values);
// handleSubmit values: { email: "", password: "" }
console.log('handleSubmit formikBag', formikBag);
// handleSubmit formikBag: check https://jaredpalmer.com/formik/docs/api/withFormik
}
})(FormMarkup);
// Pass custom prop to the form
export default () => <TapGiantsForm formName="Test Form" />;
withForm
is a withFormik
wrapper.
Formik reference.
All passed props will be provided to the button
tag in the component.
<Submit>Login</Submit>
// OR
<Submit className="class-name">Login</Submit>
Defines field type. The default type is text
.
Possible types:
text
textarea
select
checkbox
checkboxGroup
radioGroup
email
password
number
Field name.
Field label.
Field label.
Field hint.
Options property will be used to populate the select field. The following options shape is required:
[
{ value: 'BG', label: 'Bulgaria' },
{ value: 'BF', label: 'Burkina Faso' },
{ value: 'BI', label: 'Burundi' }
]
If the value of the includeBlank
prop is set to false
removes the empty option from the select.
Custom onChange
handler. It receives two arguments.
The first one is the standard event passed when onChange
is called, so you can get selected value with e.target.value.
The second one is the formCtx
.
Custom onBlur
handler. It receives two arguments.
The first one is the standard event passed when onBlur
is called, so you can get selected value with e.target.value.
The second one is the formCtx
.
Options property will be used to create the radio options. The following options shape is required:
[
{ value: 'male', label: 'Male' },
{ value: 'female', label: 'Female' }
]
Options property will be used to create the checkbox options. The following options shape is required:
[
{ value: 1, label: 'IT' },
{ value: 2, label: 'Cinema' },
{ value: 3, label: 'Pharmacy' }
]
Use in order to create custom checkbox group.
If WrapperComponent
is passed it will receive Formik's FieldArray array helpers.
Use in order to customize how the checkbox will be rendered.
It will receive the following props:
- name: String - Checkbox group name.
- label: String - Option label.
- value: Any - Option value.
- index: Integer - The position of the option in passed
options
prop. - groupValues: Array - Selected options.
- push: Function -
arrayHelpers.push
is a FieldArray helper. - remove: Function -
arrayHelpers.remove
is a FieldArray helper.
import React from 'react';
import Form, { Field, Submit, withForm } from '@tapgiants/form';
const FormMarkup = ({ formName, ...formikBag }) => (
<Form {...formikBag}>
<h1>{formName}</h1>
{/* Text field */}
<Field
name="name"
label="Name"
/>
{/* Email field */}
<Field
input="email"
name="email"
label="Email"
/>
{/* Password field */}
<Field
input="password"
name="password"
label="Password"
/>
{/* Select field */}
<Field
input="select"
name="country"
label="Country"
options={[
{ value: 'BG', label: 'Bulgaria' },
{ value: 'BF', label: 'Burkina Faso' },
{ value: 'BI', label: 'Burundi' }
]}
/>
{/* Select field with no blank option and custom onChange and onBlur */}
<Field
input="select"
name="color"
label="Color"
options={[
{ value: 'red', label: 'Red' },
{ value: 'green', label: 'Green' },
{ value: 'blue', label: 'Blue' }
]}
includeBlank={false}
onChange={(e, formCtx) => {
console.log('e', e);
console.log('formCtx', formCtx);
}}
onBlur={(e, formCtx) => {
console.log('e', e);
console.log('formCtx', formCtx);
}}
/>
{/* Radio buttons field */}
<Field
input="radioGroup"
name="gender"
label="Gender"
options={[
{ value: 'male', label: 'Male' },
{ value: 'female', label: 'Female' }
]}
/>
{/* Checkbox field */}
<Field
input="checkbox"
name="active"
label="active"
/>
{/* Checkboxes group field */}
<Field
input="checkboxGroup"
name="industries"
label="Industries"
options={[
{ value: 1, label: 'IT' },
{ value: 2, label: 'Cinema' },
{ value: 3, label: 'Pharmacy' }
]}
/>
{/* Textarea field */}
<Field
input="textarea"
name="notes"
label="Notes"
/>
<Submit>Register</Submit>
</Form>
);
const TapGiantsForm = withForm({
mapPropsToValues: () => ({
name: '',
email: '',
password: '',
country: '',
color: 'red',
gender: '',
active: false,
industries: [],
notes: ''
}),
handleSubmit: (values, formikBag) => {
const { setSubmitting } = formikBag;
setSubmitting(false);
console.log('handleSubmit values: ', values);
// handleSubmit values:
// handleSubmit values:
// {
// active: true,
// color: "blue",
// country: "BG",
// email: "john.doe@exmaple.com",
// gender: "male",
// industries: [2],
// name: "John Doe",
// notes: "Very important note!",
// password: "123456"
// }
console.log('handleSubmit formikBag', formikBag);
// handleSubmit formikBag: check https://jaredpalmer.com/formik/docs/api/withFormik
}
})(FormMarkup);
export default () => <TapGiantsForm formName="Test Form Fields" />;
If React.Component
is passed as an input prop to the Field
it will receive the following props:
Field name.
Field label.
formCtx
prop contains all the props passed to the <Form>
and
a list of Formik methods and props. Formik reference.
All passed props to the Field
will be provided to the custom component.
import React from 'react';
import Form, { Field, Submit, withForm } from '@tapgiants/form';
import '../style.css';
const ActiveInput = ({ name, placeholder, formCtx }) => {
const { values, setFieldValue } = formCtx;
return (
<a href="#" className={values[name] ? 'active' : 'inactive'} onClick={(e) => {
e.preventDefault();
setFieldValue(name, !values[name]);
}}>{values[name] ? 'Deactivate me!' : 'Activate me!'}{values[name]}</a>
);
};
const FormMarkup = ({ formName, ...formikBag }) => (
<Form {...formikBag}>
<h1>{formName}</h1>
{/* Text field */}
<Field
name="name"
label="Name"
/>
{/* Email field */}
<Field
input="email"
name="email"
label="Email"
/>
<Field
input={ActiveInput}
name="active"
label="Active"
/>
<Submit>Register</Submit>
</Form>
);
const TapGiantsForm = withForm({
mapPropsToValues: () => ({
name: '',
email: '',
active: false
}),
handleSubmit: (values, formikBag) => {
const { setSubmitting } = formikBag;
setSubmitting(false);
console.log('handleSubmit values: ', values);
// handleSubmit values:
// { name: "", email: "", active: false }
console.log('handleSubmit formikBag', formikBag);
// handleSubmit formikBag: check https://jaredpalmer.com/formik/docs/api/withFormik
}
})(FormMarkup);
export default () => <TapGiantsForm formName="Test Form Custom Field" />;
FormContext
stores all the passed props and Formik
props and methods.
In order to use FormContext
just wrap your component with it and all the context will be provided via render prop
function.
Formik reference.
import React from 'react';
import Form, {
Field,
Submit,
withForm,
FormContext
} from '@tapgiants/form';
const FancyFormComponent = () => (
<FormContext.Consumer>
{(formCtx) => {
console.log('formCtx', formCtx);
// https://jaredpalmer.com/formik/docs/api/formik#formik-render-methods-and-props
return <div>Something very facny that depends on the form context.</div>;
}}
</FormContext.Consumer>
);
const FormMarkup = ({ formName, ...formikBag }) => (
<Form {...formikBag}>
<h1>{formName}</h1>
<Field
name="name"
label="Name"
/>
<Field
input="email"
name="email"
label="Email"
/>
<Field
input="checkbox"
name="active"
label="active"
/>
<FancyFormComponent />
<Submit>Save</Submit>
</Form>
);
const TapGiantsForm = withForm({
mapPropsToValues: () => ({
name: '',
email: '',
active: false
}),
handleSubmit: (values, formikBag) => {
const { setSubmitting } = formikBag;
setSubmitting(false);
console.log('handleSubmit values: ', values);
// handleSubmit values:
// {
// active: true,
// email: "john.doe@exmaple.com",
// name: "John Doe",
// }
console.log('handleSubmit formikBag', formikBag);
// handleSubmit formikBag: check https://jaredpalmer.com/formik/docs/api/withFormik
}
})(FormMarkup);
export default () => <TapGiantsForm formName="Test Form Context" />;
Formik docs.
Link the package from your target project and run yarn start
. This will start the webpacker watcher.
Once you are satisfied with your changes, use yarn publish
to push the new version to npmjs.org.