LetsForm

repository·main·Indexed 41 days ago

https://github.com/guidone/lets-form

An open-source JSON to React form generator (v0.13.1) that abstracts UI boilerplate by supporting multiple frameworks including Material UI, Ant Design, RSuite, ReactBootstrap, and Mantine. It leverages React Hook Form for performance and provides a visual designer for schema generation.

Tokens
77.8K
Snippets
188
Records
237
Agent score
49%

What's inside LetsForm

  1. Create React forms with JSON schemas

    main

    LetsForm allows you to generate React forms using simple JSON schemas. It supports multiple UI frameworks including Material UI, Ant Design (AntD), RSuite, ReactBootstrap, and Mantine, as well as plain React.

    To use a specific framework, import the corresponding entry point from lets-form. For example, to use RSuite 5, import from lets-form/react-rsuite5.

    import LetsForm from 'lets-form/react-rsuite5';
    // Other entry points:
    // import LetsForm from 'lets-form/react-antd';
    // import LetsForm from 'lets-form/react-bootstrap';
    // import LetsForm from 'lets-form/react-material-ui';
    // import LetsForm from 'lets-form/react-mantine';
    // import LetsForm from 'lets-form/react';
  2. Quickstart: Render a simple RSuite form

    main

    To render a form, define a JSON schema object and pass it to the <LetsForm /> component. You can use the LetsForm Designer to generate these schemas visually.

    Note: When using RSuite, you must also import the RSuite CSS.

    import React from 'react';
    import LetsForm from 'lets-form/react-rsuite5';
    import 'rsuite/dist/rsuite.min.css';
    
    // The JSON schema defining the form structure
    const MY_FORM = {
      "$schema": "https://cdn.jsdelivr.net/npm/lets-form/schemas/react-rsuite5/form.json",
      "version": 1,
      "layout": "vertical",
      "validationMode": "onSubmit",
      "fluid": true,
      "fields": [
        {
          "component": "input-text",
          "label": "My Field",
          "name": "my_field"
        }
      ],
      "name": "Simplest example"
    };
    
    const MyView = () => {
      return (
        <LetsForm
          form={MY_FORM}
          onSubmit={(values) => {
            console.log('Submitting...', values);
          }}
        />
      );
    }
  3. Import LetsForm with framework-specific packages

    main

    Due to breaking changes in v0.7.12, imports must now use consistent naming conventions that match the UI framework names used in the JSON schema. Ensure you are using the correct package path for your framework:

    • React: import LetsForm from 'lets-form/react'; (unchanged)
    • Ant Design: import LetsForm from 'lets-form/react-antd'; (previously lets-form/antd)
    • RSuite5: import LetsForm from 'lets-form/react-rsuite5'; (previously lets-form/rsuite5)
    • React Bootstrap: import LetsForm from 'lets-form/react-bootstrap'; (previously lets-form/bootstrap)
    • Material UI: import LetsForm from 'lets-form/react-material-ui'; (previously lets-form/material-ui)
    // For AntD
    import LetsForm from 'lets-form/react-antd';
    
    // For RSuite5
    import LetsForm from 'lets-form/react-rsuite5';
    
    // For Material UI
    import LetsForm from 'lets-form/react-material-ui';
  4. Understand the AntDUpload payload format

    main

    When the onChange callback is triggered, AntDUpload translates the raw Ant Design file list into a consistent format. This ensures that whether you are uploading a single file or multiple files, the data structure is predictable.

    Single File Mode (multiple={false}): onChange receives a single object:

    {
      "blobFile": "[File Object]",
      "name": "filename.ext",
      "fileKey": "unique_uid"
    }

    Note: If no file is selected, it receives null.

    Multiple Files Mode (multiple={true}): onChange receives an array of objects:

    [
      { "blobFile": "[File Object]", "name": "file1.ext", "fileKey": "uid1" },
      { "blobFile": "[File Object]", "name": "file2.ext", "fileKey": "uid2" }
    ]
  5. Transform marks for SliderAnt

    main

    When providing marks to SliderAnt, you should pass an array of objects containing value and label. The component internally converts this array into the object format expected by the underlying Ant Design Slider component (e.g., { [value]: label }).

    const marks = [
      { value: 0, label: 'Low' },
      { value: 100, label: 'High' }
    ];
    
    // SliderAnt converts this to: { 0: 'Low', 100: 'High' }
    <SliderAnt marks={marks} />
  6. Understand CheckboxRSuite value toggling logic

    main

    The CheckboxRSuite component implements specific state transition logic when the user interacts with the checkbox. The behavior depends on the current isChecked state and the indeterminate prop:

    1. If isChecked is true: The new value becomes false.
    2. If isChecked is false:
      • If indeterminate is true: The new value becomes null.
      • If indeterminate is false: The new value becomes true.
    3. If isChecked is null: The new value becomes true.

    This allows for a three-state checkbox (checked, unchecked, and indeterminate/null) when the indeterminate prop is enabled.

  7. Set time increments with timeSteps

    main

    You can control the granularity of the time selection by providing timeStepsHours, timeStepsMinutes, or timeStepsSeconds. If you provide any of these, the component will construct a timeSteps object for the underlying MUI picker.

    Defaults for missing steps when any step is provided:

    • hours: 1
    • minutes: 5
    • seconds: 5
    // Select time in 15-minute increments
    <Time 
      timeStepsMinutes={15} 
    />
  8. Configure RadioGroup layout and options

    main

    The RadioGroup component provides specific ways to control how options are displayed:

    Vertical Layout (Default)

    When inline is not provided or is false, the component maps over the options array and renders them inside a <Space direction="vertical"> component. Each option is rendered as a <Radio> component.

    Inline Layout

    When inline={true} is passed, the component passes the options and optionType props directly to the underlying Ant Design Radio.Group. This is useful when you want to use Ant Design's built-in horizontal or button-style radio groups.

    Option Shape

    Regardless of layout, the options prop expects an array of objects with the following structure:

    [ 
      { "label": "Display Text", "value": "actual_value" }
    ]