complex-form-generator
TypeScript icon, indicating that this package has built-in type declarations

1.0.5 • Public • Published

Complex Form Generator

This package allows you to generate a form with a special seed object in React based on a simple or complex JS object that you need user input for. Object keys of the seed are used as input labels, and each key's value is used to infer the type of input. This means strings, numbers, booleans, nested objects, and certain configurations of nested arrays are fair game as object value types. Apart from these, there is a seed API to support a handful of custom input types. It also ships with Bootstrap 5 styling.

Prerequisites

This is a React component, so you will need "react": ">=18". If you want to use the shipped styles, you will need "bootstrap": ">=5". If you would like to use code editor inputs, you will need "@monaco-editor/react": "^4.5.0".

Demo

Please visit my NPM platform to view a demo of this package.

Installation

With Yarn:

yarn add complex-form-generator

With NPM:

npm install complex-form-generator

Usage

Creating a seed object

To create a seed object, simply start with the default state of the payload you need. Consider the rather simple payload named SEED provided in the example below. This payload as-is will generate a form with input tag types inferred from each key's value type, and labels generated from the keynames. For more complex input types, you can use special keywords outlined below. It is strongly recommended to use the Seed type when writing your seed object to be able to easily enter correct keyword parameters.

Instantiating the component

Once your seed is written, simply supply it to the FormGenerator component, and use the onChange/onSubmit methods to read the parsed payload from the form. Information on additional props can be found below.

Ex:

import FormGenerator from 'complex-form-generator'

// optional type definition
type MyPayloadType = {
  name: string
  age: number
  address: {
    city: string
    state: string
  }
  hobbies: {
    name: string
    years: number
  }[]
}

const SEED: Seed = {
  name: 'John',
  age: 30,
  address: { city: 'Anytown', state: 'NY' },
  hobbies: [{ name: 'Music', years: 14 }],
}

const App = () => {
  return (
    <FormGenerator<MyPayloadType>
      seed={SEED}
      onChange={(payload) => console.log('onChange', payload)}
      onSubmit={(payload) => console.log('onSubmit', payload)}
    />
  )
}

Seed API

Primitive values

The primitive values supported are strings, numbers, and booleans. They each respectively render text inputs, number inputs, and checkboxes.

Ex:

{
  stringInput: 'a string',
  numberInput: 50,
  booleanInput: true,
}

Object values

The object values supported are standard JS objects, and arrays. Object values can be any Seed object. Object values render the keyname as a heading and its contents as its own seed. For arrays, additional buttons are rendered to add and remove items to the list - only the first document of the array is used as the template for added items. It is recommended to just supply a single element for arrays, unless you need additional, one-off elements with different inputs. Currently, primitive values in arrays are not supported.

Ex:

{
  objectValue: {
    first: '',
    second: 96,
    third: {
      nested: true,
      thanks: "you're welcome",
    },
  },
  arrayValue: [
    {
      key1: 'a default value',
      key2: 24,
      key3: false,
      key4: { an: 'object' }
    },
  ],
}

Keywords

For form input types that are more complex than the simple string, number, and boolean inputs, you can use a supported keyword, prefixed with '$', to render a specific input type. To use a keyword, simply specify the keyword in place of the keyname(s) you want to customize.

Ex:

{ keyName: value } -> { $keyWord: { keyName: _keywordValue, ...otherKeyNames } }

Currently, the following keywords are available to provide support for more specific or complex input types. They each have a unique value type to specify all the data required to configure the input.


$useTextArea

Render a textarea input.

Spec type:
string
Ex:
{ 
  $useTextArea: { keyName: '' },
}

$useDateArea

Render a date input. Default values must be in ISO 8601 - any other string will not be rendered in the input and will be overwritten in ISO 8601 on change.

Spec type:
string
Ex:
{ 
  $useDateArea: { keyName: '' },
}

$useCodeArea

Render a code editor. It uses Monaco Editor React, you can read their docs here. You will need to import it yourself if supply it to the _instance field.

Spec type:
{
  _value: string,
  _language: MonacoLanguages
  _instance: MemoExoticComponent<(props: EditorProps) => JSX.Element>
}
Ex:
import Editor from '@monaco-editor/react'

{ 
  $useCodeArea: {
    codeArea: {
      _value: `list = [1, 2, 3]
for e in list:
    print(e)`,
      _language: 'python',
      _instance: Editor
    },
  },
}

$useSelectOptions

Render a select tag with options. Each option has optional parameters to specify a different label and provide any additional payload items when that option is selected. Default values can be a string, which renders a standard single-option select and associated payloads one-at-a-time, or an array of strings, which renders a multi-option select and associated payloads stacked in order. If an empty default value is supplied or does not match any of the option values supplied, it will be replaced by the first option value.

Spec type:
{
  _defaultValue: string | string[]
  _options: {
    _value: string
    _label?: string
    _assocPayload?: Seed
  }[]
}
Ex:
{
  selectOptions: {
    _defaultValue: 'option2',
    _options: [
      { _value: 'option1', _label: 'A custom option label' },
      { _value: 'option2' },
      {
        _value: 'option3',
        _assocPayload: {
          keep: 'nesting',
          excitement: 100,
          $useDateArea: { today: '' },
        },
      },
    ],
  },
}

Component API

To use the FormGenerator component, simply provide the required seed obejct prop. To use the payload that is parsed from the form input, use the

Props

Name Type Default Value Description
<T> T extends Record<string, any> any An optional type definition provided by you to compile a specific type for your payload.
seed Seed The Seed object of the form to be generated.
formId string An optional id attribute for the generated form.
onChange (payload: T) => void A callback that is supplied with the latest state of the payload and is fired every time any value in the form changes.
onSubmit (payload: T) => void A callback that is supplied with the latest state of the payload and is fired when the form is submitted. Using this prop also renders an additional submit button at the bottom of the form.
suppressStyles boolean false Suppresses all styles applied to the form. Disables the following props as they will have no effect.
floatingLabels boolean false Enables Bootstrap's floating labels for each input instead of a standard label/input setup.
groupNestedObjects boolean false Visually groups all nested objects with a card outline. This applies to JS object values, array values, and select options values if any of the options has an associated payload.

Contribution

Feedback and contribution of any kind is greatly appreciated! If you would like to contribute, please follow these steps:

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Add your changes: git add .
  4. Commit your changes: git commit -m 'Add some feature'
  5. Push the branch: git push origin my-new-feature
  6. Submit a pull request

Authors

  • Ron Gorai - rgorai: Initial version

Future releases

  • Input validation
  • Primitive value array support
  • CSS classname API for custom styles
  • dark theme support

Package Sidebar

Install

npm i complex-form-generator

Weekly Downloads

3

Version

1.0.5

License

MIT

Unpacked Size

108 kB

Total Files

18

Last publish

Collaborators

  • rgorai