DEV Community

Lee Twito
Lee Twito

Posted on

Create headless forms using a schema

Building forms in web-apps is hard.

At first, it might seem like just a matter of adding a few input fields, but in reality, it's just the beginning.
Forms requirements can become more sophisticated with things like conditional branching, version control, save draft, and more.
PMs and designers often have endless requests for inputs updates or improved localization.

It's a lot to manage!

I've created an open-source form infra for web-apps that gives you your own in-house form builder fully integrated with your component library and design system.

Here's an example:

import { TutimWizard, defaultFields } from "@tutim/fields";
import { FormProvider } from "@tutim/headless";
import { InputType, Field } from "@tutim/types";

// a simple form schema
const config = {
  fields: [
    { key: 'company_name', label: 'Company name', type: 'text' },
    { key: 'num_of_employees', label: 'Number of employees', type: 'select', tooltip: 'Choose your best estimation', options: [{value:'1_50', label:'1 - 50'}, {value:'51_250', label:'51 - 250'}, {value:'above_251', label:'251 +'}] },
    { key: 'stakeholders', label: 'Stakeholders', type: 'array', children: { fields: [{key: 'name', label: 'Full Name', type: 'text'},{key: 'age', label: 'Age', type: 'number',},],},},

// a custom component for a text field
const CustomText: Field = ({ inputProps, fieldConfig }) => {
  const { value = '', onChange } = inputProps;
  // isDisabled,isRequired, options, defaultValue, validations
  const { key, label } = fieldConfig;
  return (
    <div key={key}>
      <label style={{ color: 'green', marginRight: '10px' }}>{label}</label>
      <input value={value} onChange={onChange} style={{ color: 'purple' }} />

// map the custom components over the default components
const fieldComponents: FieldComponents = {


// use Tutim library to render the form
const App = () => {
  return (
    <FormProvider fieldComponents={fieldComponents}>
      <TutimWizard onSubmit={console.log} config={config} />

export default App;
Enter fullscreen mode Exit fullscreen mode

I see adoption for (older) libraries like rjsf, but it's very limited in terms of the UI.

Do you think there's a need for such a library?

Top comments (0)