The Formulaik
project
An open source initiative for defining cross-platform forms, enabling reusable components in a JSON based declarative approach. Formulaik aims to simplify form building across various front-end frameworks. Formulaik defines a protocol for defining form inputs as a sole source of truth (data type, behaviour, validation) in json, which is interpreted by a platform-specific formulaik engine.
🍨
Declarative
The JSON based form declaration is what separates Formulaik from other frameworks. Simply give an array of inputs and component libraries to find their implementation.
Predictable, scalable clean forms
Every input component follows a unique API that make it readable, testable, maintainable and shippable.
Extensible
The component libraries system makes it easy to use a feature team, a project, a company or a community library to jump start a project.
Quick start 🚀
Let's build a login form with email and password inputs.
- React JS
- React Native
- Swift
- Kotlin
- Flutter
- Vue JS
1. Install formulaik and a component library
- npm
- yarn
npm install @formulaik/react @formulaik-community/react-mui
yarn add @formulaik/react @formulaik-community/react-mui
2. Define inputs
const inputs = [
{
component: 'input',
id: 'email',
label: 'Email',
type: "string",
params: {
type: 'email',
placeholder: "email@domain.com"
},
validations: [
{
kind: "format",
value: "email",
message: 'Invalid email format',
},
{
kind: "required",
value: true,
message: "This field can't be blank",
},
],
},
{
component: 'inputPassword',
label: 'Password',
id: 'password',
type: "string",
params: {
type: 'password',
autoComplete: "current-password",
placeholder: "xxxx-xxxx-xxxx"
},
validations: [
{
kind: "matches",
value: /^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/,
message: 'Invalid password, must contain at least 8 characters and at most 18 characters',
},
{
kind: "required",
value: true,
message: "This field can't be blank",
},
]
},
{
component: 'submit',
params: {
text: 'Continue'
}
},
]
3. Provide initial values (optional)
const values = {
email: cookies.get('email'),
}
4. Render forms and handle submit
import Formulaik from '@formulaik/react'
import FormulaikMui from '@formulaik-community/react-mui'
export default (props) => {
const onSubmit = async (values, { setSubmitting }) => {
try {
const { email, password } = values
//... do login
} catch (e) {
console.log(e)
}
}
return <>
<h3>Login</h3>
<Formulaik
components={[FormulaikMui]}
values={values}
inputs={inputs}
onSubmit={onSubmit}
/>
</>
}
1. Install formulaik and a component library
- npm
- yarn
npm install @formulaik/react-native @formulaik-community/react-native-paper
yarn add @formulaik/react-native @formulaik-community/react-native-paper
2. Define inputs
const inputs = [
{
component: 'input',
id: 'email',
label: 'Email',
type: "string",
params: {
type: 'email',
placeholder: "email@domain.com"
},
validation: {
format: {
value: "email",
message: 'Invalid email format',
},
required: {
value: true,
message: "This field can't be blank",
},
}
},
{
component: 'inputPassword',
label: 'Password',
id: 'password',
type: "string",
params: {
type: 'password',
autoComplete: "current-password",
placeholder: "xxxx-xxxx-xxxx"
},
validation: {
matches: {
value: /^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/,
message: 'Invalid password, must contain at least 8 characters and at most 18 characters',
},
required: {
value: true,
message: "This field can't be blank",
},
}
},
{
component: 'submit',
params: {
text: 'Continue'
}
},
]
3. Provide initial values (optional)
const values = {
email: cookies.get('email'),
}
4. Render forms and handle submit
import Formulaik from '@formulaik/react-native'
import FormulaikPaper from '@formulaik-community/react-native-paper'
import { Text } from 'react-native'
export default (props) => {
const onSubmit = async (values, { setSubmitting }) => {
try {
const { email, password } = values
//... do login
} catch (e) {
console.log(e)
}
}
return <>
<Text>Login</Text>
<Formulaik
components={[FormulaikPaper]}
values={values}
inputs={inputs}
onSubmit={onSubmit}
/>
</>
}
Not available yet.
Want to contribute? Join the movement.Not available yet.
Want to contribute? Join the movement.Not available yet.
Want to contribute? Join the movement.Not available yet.
Want to contribute? Join the movement.Decouple your form declaration from its implementation 🖖
Go from having your form inputs behavior cluttered in a React file to a clear separation of concerns between declaration via a JSON and component libraries.
Break the Form into Small Reusable Components
One of the fundamental principles of React is the concept of componentization. Apply this principle to your forms by breaking them down into small, reusable components.
Yup validation
Yup is a schema builder for runtime value parsing and validation. Define a schema, transform a value to match, assert the shape of an existing value, or both. Yup schema are extremely expressive and allow modeling complex, interdependent validations, or value transformation.
Formik underneath
On React we use the powerful Formik library for rendering the inputs. Formik is the world's most popular open source form library for React and React Native.
What do we want?
Ok, what would the perfect CLI generator look like ?
- Easy to read
- Easy to debug
- Separate declaration from implementation
- Reuse components in a project
- Reuse component libraries across projects
- Have a unique multi-platform specification and behavior of our forms