React Easel
A react component to dynamically build reusable forms. See the demo here
Acknowledgements
React Uniform Builder is built on top of uniforms and simple-schema with styling inspiration from formBuilder
This project is maintained by Amdirent, Inc. If you'd like to build forms that hook up to arbitrary processes, and a dynamically created database table, check out Amdirent Opslab
Usage
Installing
npm install --save react-easel
or
yarn add react-easel
Quick Start
First, ensure you have loaded bootstrap4 css. This library can be used with custom components and custom styling, but defaults exist for bootstrap.
; <Easel onSchemaChange=consolelog ...defaultsbootstrap4 />
Using onSchemaChange
, you can extract a json defintion of a SimpleSchema, which can then be used to render the form like so:
;;; const AutoForm = defaultsbootstrap4AutoForm;const AutoField = defaultsbootstrap4AutoField; const jsonSchemaDef = <your json definition of a SimpleSchema> <AutoForm model={} schema=jsonSchemaDef onSubmit=consolelog> <AutoFields autoField=AutoField /></AutoForm>
Note: onSchemaChange
exists to get data out. It should not be used to drive Easel
like a normal controlled component. Easel
will populate initial values with props.schema
, but it does not update on componentWillReceiveProps
. This is because the process of creating Easel
's interanal state from a schema is slow, but onSchemaChange
is called every time a component is rearanged. Using this like a normal controlled component leads to a laggy drag and drop experience.
Defining Your Own Components/Inputs
Defaults exist for bootstrap4. You can see those in src/bootstrap4/defaults
The easel component expects five props:
Argument | Description |
---|---|
AutoForm |
A uniforms AutoForm. Can import directly from your uniforms package of choice, or use a custom form |
components |
A list of component definitions that will appear in the sidebar to be used on the form builder |
AutoField |
A uniforms AutoField component capable of rendering all the specified components . This will receive a prop componentType , which you can use to decide which component to render. |
onSchemaChange |
A callback function that will receive a json representation of the SimpleSchema when the component changes. This SimpleSchema can be used to render future forms. |
schema |
(optional) A json representation of an existing SimpleSchema to render. |
Component Definiton
Components are defined as follows:
Argument | Type | Description |
---|---|---|
type |
string |
A unique identifier for the component. Ex: 'Text Field' |
schema |
object |
Corresponds to the node-simple-schema definition. Should, at the very least, contain type |
sidebar |
object |
The definition for what will show in the sidebar |
sidebar.text |
string |
The text that shows up on the sidebar. Ex: 'Text Field' |
sidebar.icon |
React Component |
The icon that shows up in the sidebar. Ex: <i className="fa fa-pencil" /> |
admin |
object |
Definition of any additional configuration the field has. Defaults include name , placeholder , label , optional , and value |
admin.schema |
SimpleSchema |
A Simple Schema definition to render configuration fields for this Component. Whatever is filled into these fields will be passed as a prop to the component |
Example: Using react-select instead of a regular select
First, make a uniforms driven react-select component:
;;;; const ReactSelect = ; ;
Now, override the Select field in the bootstrap defaults with your custom select field:
;; const myDefaults = ...defaultsbootstrap4 ;myDefaultscomponents = defaultsbootstrap4; <Easel onSchemaChange=consolelog ...myDefaults />
Example: Adding a WYSIWYG editor
For this example, we're going to use Trumbowyg
.
First, make the Uniforms driven component:
;;;; global$ = globaljQuery = window$ = windowjQuery = $; const Trumbowyg = default; let id = 0; // Made to only load the first value passed, that way trumbo can do its thing.Component { superprops context; thisstate = data: propsvalue } { const props = thisprops; return <Trumbowyg id="react-trumbowyg" + ++id placeholder=propsplaceholder data=thisstatevalue onChange= { props; } /> } ;
Now, create your easel:
;;; // A custom auto field capable of using `componentType` to decide to render the WYSIWYG { return thiscontextuniformsname; } { const props = this; if propscomponentType === 'WYSIWYG' return <MyTrumboWyg ...props /> return <defaultsbootstrap4AutoField ...thisprops />; } const WYSIWYGComponent = type: 'WYSIWYG Editor' schema: type: String sidebar: icon: <i className="fa fa-file-text-o"/> text: 'WYSIWYG Editor' <Easel AutoForm=defaultsbootstrap4AutoForm AutoField=CustomAuto components=defaultsbootstrap4components/>
Example: Text Area with admin configuration.
Uniforms-bootstrap4 gives us a LongTextField, and that LongTextField can take rows
as a prop. We'd like to show that in the admin section of the field in Easel.
This example will just show the component configuration, since this already exists in defaults.bootstrap4
; const LongTextFieldComponent = type: 'Textarea' schema: String uniforms: rows: 10 sidebar: icon: <i className="fa fa-pencil-square-o" /> text: 'Textarea' admin: schema: rows: type: Number