Napolean Paced Mischeviously

    @microsoft/fast-form-generator-react
    TypeScript icon, indicating that this package has built-in type declarations

    3.8.0 • Public • Published

    FAST Form generator React

    FAST Form generator React has been deprecated. Use FAST Tooling React instead.

    A self generating UI based on JSON Schemas.

    Dynamically generates a form user interface based on incoming JSON Schemas to change data values of a React component.

    Installing

    npm i --save @microsoft/fast-form-generator-react

    Basic usage


    The required properties are the data, schema, and onChange function. The data should be tied to your state as the data will change when editing the form.

    import Form from "@microsoft/fast-form-generator-react";
    
    /**
     * Add to your render function
     */
    <Form
        data={this.state.currentComponentData}
        schema={currentComponentSchema}
        onChange={handleChange}
    />

    onChange

    The onChange is used as a callback, it should take one argument that is the data that should be updated when any data has been changed from within the generated form.

    Data and data mapping

    Component data passed to the form generator as plain data, there is a mapDataToComponent export from the package which converts any children data to executable React components. It is required that any component that would be mapped from data should be supplied in the childOptions prop.

    Example onChange:

    import { mapDataToComponent } from "@microsoft/fast-form-generator-react";
    
    /**
     * The app on change event
     */
    onChange = (data) => {
        this.setState({
            currentComponentData: mapDataToComponent(data)
        });
    }

    Simple data

    Where the component is a button and the data being passed to the onChange is:

    {
        "disabled": true,
        "children": "Button text"
    }

    Data with component children

    Where the component contains a button and the data being passed to the onChange is:

    Example data:

    {
        "children": {
            "id": "button",
            "props": {
                "disabled": true
            }
        }
    }

    The id corresponds to the components' JSON schema id and the props corresponds to the data being passed to the component.

    Advanced usage


    Outside of the basic use case you can provide some additional functionality through optional properties.

    plugins and onSchemaChange

    Plugins may be created to determine if a form should change based on data. You can identify a piece of schema that should be updated by adding a unique key to your JSON schema formPluginId. When you initialize a custom plugin you will need to pass that same id to the plugin as part of its configuration.

    Example schema:

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "type": "object",
        "properties": {
            "text": {
                "title": "Text",
                "type": "string",
                "example": "Hello world",
                "formPluginId": "my-custom-plugin-identifier"
            },
            "weight": {
                "title": "Weight",
                "type": "string",
                "enum": [
                    "heavy",
                    "medium",
                    "light"
                ]
            }
        },
        "required": [
            "text"
        ]
    }

    Example plugin which returns an unmodified schema, unless the weight property has been specified, then the options become specific to the data:

    import { FormPlugin, FormPluginProps } from "@microsoft/fast-form-generator-react";
    
    export class MyCustomSchemaPlugin extends FormPlugin {
        resolver(schema, data) {
            switch (data.weight) {
                case "heavy":
                    return Object.assign({}, schema, { enum: ["heavy text 1", "heavy text 2"] });
                case "medium":
                    return Object.assign({}, schema, { enum: ["medium text 1", "medium text 2"] });
                case "light":
                    return Object.assign({}, schema, { enum: ["light text 1", "light text 2"] });
            }
    
            return schema;
        }
    }

    Example implementation with the Form:

    Note: When the plugins are used the schema tied to the Form should be set to a state so that it can be kept up-to-date, you will need to use the onSchemaChange callback which will return the newly updated schema.

    import Form from "@microsoft/fast-form-generator-react";
    import { Button, ButtonSchema } from "@microsoft/fast-components-react-msft";
    import { MyCustomSchemaPlugin } from "./my-custom-schema-plugin";
    
    <Form
        data={this.state.currentComponentData}
        schema={this.state.currentComponentSchema}
        onChange={handleChange}
        onSchemaChange={handleSchemaChange}
        plugins={[
            new MyCustomSchemaPlugin({
                id: ["my-custom-plugin-identifier"]
            })
        ]}
    />

    childOptions

    Children by default only include text elements. If you want to add some child components you are providing, you can do this through the childOptions.

    import Form from "@microsoft/fast-form-generator-react";
    import { Button, ButtonSchema } from "@microsoft/fast-components-react-msft";
    
    <Form
        data={this.state.currentComponentData}
        schema={currentComponentSchema}
        onChange={handleChange}
        childOptions={[
            {
                name: "Button",
                component: Button,
                schema: ButtonSchema
            }
        ]}
    />

    location

    The location prop allows the user to control which piece of JSON schema the form is pointing to and has two required properties. It takes dataLocation which is the location of the data to be edited, and onChange which will fire an update when the user performs an action on the form that would change the visible data to be edited. An example of this would be clicking on an array item to edit that item.

    import Form from "@microsoft/fast-form-generator-react";
    
    <Form
        data={this.state.currentComponentData}
        schema={currentComponentSchema}
        onChange={handleChange}
        location={{
            dataLocation: this.state.dataLocation,
            onChange: this.handleChange
        }}
    />
    
    // example method to use for the location onChange
    handleChange = (dataLocation) => {
        this.setState({
            dataLocation: dataLocation
        });
    }

    componentMappingToPropertyNames - There are special components that can be mapped to property names so that they are used. An example would be alignHorizontal which when mapped will show alignment controls instead of a select dropdown. You can map them to one or more different property names so if your component has a property alignHorizontalSpacingForTitle and alignHorizontalSpacingForImage:

    import Form from "@microsoft/fast-form-generator-react";
    
    <Form
        data={this.state.currentComponentData}
        schema={currentComponentSchema}
        onChange={handleChange}
        componentMappingToPropertyNames={{
            alignHorizontal: [
                "alignHorizontalSpacingForTitle",
                "alignHorizontalSpacingForImage"
            ]
        }}
    />

    attributeSettingsMappingToPropertyNames - The attributes of a form item can be mapped to by this prop. An example of updating the textarea row to be 1 when the property name is text:

    import Form from "@microsoft/fast-form-generator-react";
    
    <Form
        data={this.state.currentComponentData}
        schema={currentComponentSchema}
        onChange={handleChange}
        attributeSettingsMappingToPropertyNames={{
            textarea: {
                rows: [
                    {
                        propertyNames: ["text"],
                        value: 1
                    }
                ]
            }
        }
    />

    orderByPropertyNames - Properties can be assigned a category with titles to give the form more structure. They can also be weighted, an example of displaying properties related to content on top of properties which relate to formatting:

    This also tells the form generator to only display categories once there are 4 or more and gives a default category weight

    import Form from "@microsoft/fast-form-generator-react";
    
    <Form
        data={this.state.currentComponentData}
        schema={currentComponentSchema}
        onChange={handleChange}
        orderByPropertyNames={{
            showCategoriesAtPropertyCount: 4,
            defaultCategoryWeight: 20,
            categories: [
                {
                    title: "Content",
                    weight: 50,
                    properties: [
                        { weight: 5, propertyName: ["title, text"] },
                        { weight: 0, propertyName: "details" }
                    ]
                },
                {
                    title: "Formatting",
                    weight: 40,
                    properties: [
                        { weight: 9, propertyName: "alignVertical" },
                        { weight: 7, propertyName: "alignHorizontal" }
                    ]
                }
            ]
        }}
    />

    Writing JSON Schemas

    The schema form generator can interpret most JSON schemas, however there are some things to note when writing JSON schemas that make for a better UI.

    title

    Using a title will add a label to the left or top of the corresponding form element. All properties are required to have a title.

    Example:

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "type": "object",
        "properties": {
            "text": {
                "title": "Text",
                "type": "string",
                "example": "Hello world"
            },
            "weight": {
                "title": "Weight",
                "type": "string",
                "enum": [
                    "heavy"
                ]
            }
        },
        "required": [
            "text"
        ]
    }

    disabled

    Disabled flag is optional and item will be disabled if flag is set to true.

    Example:

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "type": "object",
        "properties": {
            "text": {
                "title": "Text",
                "type": "string",
                "example": "Hello world",
                "disabled": true
            }
        },
        "required": [
            "text"
        ]
    }

    examples & default

    Providing an example or default value will replace the placeholder 'example text' or randomly generated number. It is generally better to add this extra information in case the schema form generator needs to create a new set of data.

    Example:

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "type": "object",
        "properties": {
            "text": {
                "title": "Text",
                "type": "string",
                "example": "Hello world"
            },
            "style": {
                "title": "Style",
                "type": "object",
                "properties": {
                    "color": {
                        "title": "HEX Color",
                        "type": "string",
                        "example": "#FF0000"
                    }
                },
                "required": [
                    "color"
                ]
            }
        },
        "required": [
            "text"
        ]
    }

    Because the style is optional, you can toggle to add it. The schema form generator will see that color is a required piece of data and use the example given to fill in.

    oneOf & anyOf

    The oneOf and anyOf keywords can be used inside a property and at the root level of a schema. This will create a select dropdown so that the user can switch between them. If data has been provided, it will select the first oneOf/anyOf instance it can validate against. The contents of a 'title' property will be used for the contents of the dropdown.

    Example:

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "oneOf": [
            {
                "title": "color",
                "type": "object",
                "properties": {
                    "color": {
                        "title": "HEX Color",
                        "type": "string",
                        "example": "#FF0000"
                    }
                }
            },
            {
                "title": "text",
                "type": "object",
                "properties": {
                    "text": {
                        "title": "Text",
                        "type": "string",
                        "example": "Hello world"
                    }
                }
            }
        ]
    }

    Enums

    Any enums will be converted to a select dropdown.

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "type": "object",
        "properties": {
            "color": {
                "title": "Color",
                "type": "string",
                "enum" : [
                    "red",
                    "green",
                    "blue",
                    "yellow"
                ],
                "default": "red"
            }
        }
    }

    React children

    React children are treated as special objects instead of simple properties and can be defined in an object as reactProperties. They can specify ids from the given childOptions and can be given defaults, currently there is one default text. If no ids are specified all childOptions are considered valid.

    Example of an object that includes children with specific ids and the text default:

    {
        "$schema": "http://json-schema.org/schema#",
        "id": "my-component",
        "title": "My component",
        "type": "object",
        "properties": {
            "color": {
                "title": "Color",
                "type": "string"
            }
        },
        "reactProperties": {
            "children": {
                "title": "Components",
                "type": "children",
                "ids": [
                    "my-component",
                    "my-button-component"
                ],
                "defaults": [
                    "text"
                ]
            }
        }
    }

    Type object

    The object type will create its own section which can be navigated to via a link that is created on its parent object. Once it has been navigated to, breadcrumbs will appear above allowing the user to navigate back to the parent object.

    Keywords that cannot be interpreted

    allOf & $ref

    The allOf and $ref keywords cannot be interpreted by the schema form generator. To allow for most of the functionality there is a tool inside the @microsoft/fast-permutator which will simplify the schema and merge allOf arrays when it finds them, see simplifySchemas.

    Keywords

    none

    Install

    npm i @microsoft/fast-form-generator-react

    DownloadsWeekly Downloads

    8

    Version

    3.8.0

    License

    MIT

    Unpacked Size

    234 kB

    Total Files

    134

    Last publish

    Collaborators

    • microsoft1es
    • fastsvc
    • chrisdholt
    • awentzel
    • janechu
    • fluentweb
    • nirice