FormEngine

repository·master·Indexed 42 days ago

https://github.com/optimajet/formengine

A lightweight, JSON-first React library for building forms using JSON Schema. It is UI-agnostic and supports themes including MUI, Shadcn, RSuite, and Mantine. FormEngine features built-in validation powered by Zod, with support for Yup, AJV, Superstruct, and Joi. The ecosystem includes a core builder, a JSON schema generator, a CDN-embeddable Viewer bundle, and a premium drag-and-drop Designer for enterprise teams.

Tokens
114.5K
Snippets
347
Records
462
Agent score
53%

What's inside FormEngine

  1. Overview of FormEngine Community

    master
    FormEngine Community is an open-source React library designed for building complex forms with minimal front-end specialization. It provides a high-level abstraction for form creation, offering features like event handling, computed fields, validation, and localization out of the box. It is designed to be UI-agnostic, meaning it can work with various UI libraries such as MUI, Ant Design, and shadcn/ui, or use its own pre-built component suite.
  2. Key features of @react-form-builder/components-rsuite

    master

    The RSuite components library provides several advanced capabilities:

    • UI-Agnostic Core: While this package provides RSuite components, the underlying engine works with any UI library (MUI, Ant Design, shadcn/ui, etc.).
    • Framework Support: Works with Next.js, Remix, or via CDN for framework-agnostic usage.
    • Validation: Built-in support for Zod, with extensibility for Yup, AJV, Superstruct, and Joi.
    • Localization: Uses Fluent.js for powerful localization.
    • Reactive Properties: Uses MobX to power dynamic, real-time component property changes.
    • Custom Actions: Supports custom JavaScript logic via customAction and built-in validation via commonAction.
  3. Key features of the React Form Builder Viewer bundle

    master

    The Viewer bundle provides a high-level integration for displaying forms with the following capabilities:

    • UI-Agnosticism: Works with MUI, Ant Design, shadcn/ui, and more.
    • Pre-Built Components: Includes @react-form-builder/components-rsuite for immediate use.
    • Framework Support: Compatible with Next.js, Remix, or standalone via CDN.
    • Validation: Built-in support for Zod, with extensibility for Yup, AJV, Superstruct, and Joi.
    • Localization: Uses Fluent.js for powerful localization.
    • Reactive Properties: Uses MobX for real-time component property changes.
    • Custom Logic: Supports custom JavaScript actions and common actions like validate.
  4. Key features of FormEngine Community

    master

    FormEngine Community provides several advanced capabilities for form management:

    • UI Agnosticism: Works with MUI, Ant Design, shadcn/ui, and others.
    • Framework Support: Native integration for Next.js and Remix, or framework-agnostic usage via CDN.
    • Validation: Built-in support for Zod, with extensibility to use Yup, AJV, Superstruct, Joi, and more.
    • Reactive Properties: Uses MobX to power dynamic component properties and real-time changes.
    • Custom Logic: Supports Custom Actions via JavaScript and Adaptive Layouts for responsiveness.
    • Flexible Storage: Forms can be stored as complete JSON definitions or generated programmatically via code.
  5. Quickstart with React Suite components

    master

    To build a form using RSuite components, use buildForm from @react-form-builder/core to define your schema using RSuite component names (e.g., RsContainer, RsInput, RsDatePicker, RsButton). Then, render the form using FormViewer from @react-form-builder/core, passing the viewWithCss imported from @react-form-builder/components-rsuite to the view prop.

    import {viewWithCss} from '@react-form-builder/components-rsuite'
    import {buildForm, FormViewer} from '@react-form-builder/core'
    
    const simpleForm = buildForm({errorType: 'RsErrorMessage'})
      .component('container', 'RsContainer')
      .style({flexDirection: 'row'})
      .children((builder) =>
        builder
          .component('firstName', 'RsInput')
          .prop('placeholder', 'Enter your first name')
          .prop('label', 'First Name')
          .validation('required')
    
          .component('lastName', 'RsInput')
          .prop('placeholder', 'Enter your last name')
          .prop('label', 'Last Name')
          .validation('required')
      )
    
      .component('birthDate', 'RsDatePicker')
      .prop('label', 'Birth Date')
      .prop('oneTap', true)
      .validation('min').args({value: '1900-01-07T12:25:37.000Z'})
    
      .component('submit', 'RsButton')
      .prop('children', 'Submit')
      .prop('color', 'blue')
      .prop('appearance', 'primary')
      .event('onClick')
      .commonAction('validate').args({failOnError: true})
      .customAction('onSubmit')
      .json()
    
    export const App = () => {
      return <FormViewer
        view={viewWithCss}
        getForm={() => simpleForm}
        actions={{
          onSubmit: (e) => {
            // submit the form to the backend
            alert('Form data: ' + JSON.stringify(e.data))
          },
        }}
      />
    }
  6. Quickstart with Mantine components

    master

    To implement a form using Mantine components, import the view from @react-form-builder/components-mantine and pass it to the FormViewer component. You must also import the required Mantine CSS styles for the components to render correctly.

    Use the buildForm() builder API to define your form structure, specifying Mantine-prefixed component names (e.g., MtTextInput, MtDatePickerInput, MtButton) and configuring their properties and validation.

    import {view} from '@react-form-builder/components-mantine'
    import {buildForm, FormViewer} from '@react-form-builder/core'
    import '@mantine/core/styles.css'
    import '@mantine/dates/styles.css'
    
    const simpleForm = buildForm()
      .component('container', 'MtContainer')
      .style({flexDirection: 'row'})
      .children((builder) =>
        builder
          .component('firstName', 'MtTextInput')
          .prop('placeholder', 'Enter your first name')
          .prop('label', 'First Name')
          .validation('required')
    
          .component('lastName', 'MtTextInput')
          .prop('placeholder', 'Enter your last name')
          .prop('label', 'Last Name')
          .validation('required')
      )
    
      .component('birthDate', 'MtDatePickerInput')
      .prop('label', 'Birth Date')
      .validation('min').args({value: '1980-01-07T00:00:00.000Z'})
    
      .component('submit', 'MtButton')
      .prop('children', 'Submit')
      .event('onClick')
      .commonAction('validate').args({failOnError: true})
      .customAction('onSubmit')
      .json()
    
    export const App = () => {
      return <FormViewer
        view={view}
        getForm={() => simpleForm}
        actions={{
          onSubmit: (e) => {
            // submit the form to the backend
            alert('Form data: ' + JSON.stringify(e.data))
          },
        }}
      />
    }
  7. Quickstart: Render a form using the Viewer bundle

    master

    To render a form using the Viewer bundle in a plain HTML environment, follow these steps:

    1. Include the script: Load the bundle via CDN.
    2. Define the form: Use buildForm from window.FormEngineViewerBundle to define components, properties, validations, and actions.
    3. Configure the viewer: Create a props object containing:
      • view: The component view to use (e.g., rSuiteComponents.viewWithCss).
      • getForm: A function that returns your form definition.
      • actions: An object mapping custom action names (defined in the form) to JavaScript functions.
    4. Render: Call renderFormViewer(containerId, props) to mount the form to a DOM element.

    Note: The example below uses rSuiteComponents which are included in the bundle.

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>FormEngine bundle embedding example</title>
      <script src="https://unpkg.com/@react-form-builder/viewer-bundle@latest/dist/index.iife.js" async defer></script>
    </head>
    <body style="margin: 20px">
    <div id="viewer"></div>
    
    <script type="text/javascript">
      window.onload = function () {
        const {buildForm, renderFormViewer, rSuiteComponents} = window.FormEngineViewerBundle;
    
        const simpleForm = buildForm({errorType: 'RsErrorMessage'})
          .component('container', 'RsContainer')
          .style({flexDirection: 'row'})
          .children((builder) =>
            builder
              .component('firstName', 'RsInput')
              .prop('placeholder', 'Enter your first name')
              .prop('label', 'First Name')
              .validation('required')
    
              .component('lastName', 'RsInput')
              .prop('placeholder', 'Enter your last name')
              .prop('label', 'Last Name')
              .validation('required')
          )
    
          .component('birthDate', 'RsDatePicker')
          .prop('label', 'Birth Date')
          .prop('oneTap', true)
          .validation('min').args({value: '1900-01-07T12:25:37.000Z'})
    
          .component('submit', 'RsButton')
          .prop('children', 'Submit')
          .prop('color', 'blue')
          .prop('appearance', 'primary')
          .event('onClick')
          .commonAction('validate').args({failOnError: true})
          .customAction('onSubmit')
          .json();
    
        const props = {
          view: rSuiteComponents.viewWithCss,
          getForm: () => simpleForm,
          actions: {
            onSubmit: (e) => {
              // submit the form to the backend
              alert('Form data: ' + JSON.stringify(e.data))
            }
          }
        };
    
        window.viewerRoot = renderFormViewer('viewer', props);
      }
    </script>
    </body>
    </html>