Skip to content

ui-schema/ui-schema

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
February 3, 2023 03:44
July 19, 2022 09:05
July 23, 2020 23:57
.
January 21, 2020 02:20
September 19, 2021 19:48
May 2, 2022 15:27
February 3, 2023 02:11
vup
September 20, 2020 11:25
May 2, 2022 16:32
February 3, 2023 02:11
January 19, 2020 10:37

UI Schema Logo

UI Schema for React

JSON Schema form + UI generator for any design system, first-class support for Material UI React, easily create own widgets and plugins.

Develop your next React app faster, with less code duplications - and without wasting time to implement validations.

Github actions Build react compatibility MIT license PRs Welcome Coverage Status Typed

  • @ui-schema/ui-schema npm (scoped)

  • @ui-schema/ds-material npm (scoped)

  • @ui-schema/ds-bootstrap npm (scoped)

  • @ui-schema/pro npm (scoped)

  • @ui-schema/dictionary npm (scoped)

  • Additional Material-UI Widgets:

    • Date-Time Picker: @ui-schema/material-pickers npm (scoped) Component Documentation
    • Codemirror as Material Input: @ui-schema/material-code npm (scoped) Component Documentation repo
    • react-color picker: @ui-schema/material-color npm (scoped) Component Documentation repo
    • react-colorful picker: @ui-schema/material-colorful npm (scoped) Component Documentation repo
    • 🚧 Drag 'n Drop with react-dnd: @ui-schema/material-dnd npm (scoped) Component Documentation
    • 🚧 EditorJS as Material TextField: @ui-schema/material-editorjs npm (scoped) Component Documentation
    • 🚧 SlateJS as Material TextField: @ui-schema/material-slate npm (scoped) Component Documentation
  • Additional Packages, not only for UI Schema:

    • 🚧 CodeMirror v6 kit: @ui-schema/kit-codemirror npm (scoped) Component Documentation repo
    • 🚧 Drag 'n Drop kit: @ui-schema/kit-dnd npm (scoped) Component Documentation

Documentation

Quick-Start

Schema Examples + Live Editor

Get Help on Slack

🚀 Demo: UI Schema + Material Design + Create React App: Demo Source

Run on CodeSandbox

Run on StackBlitz

Fullscreen Demo


Schema

Use JSON Schema to validate data and automatically create UIs with it - UI-Schema makes it easy to write widgets based on schema structures, use custom UI keywords to make it look great!

Schema Documentation

Features

  • add any design-system or custom widget
    • easily create isolated and atomic widgets, with autowired data and validations
    • customize design system behaviour with e.g. widget compositions
    • easy binding of own design systems and custom widgets
    • easily add advanced features like read-or-write mode
  • auto-rendering by data & schema or full-custom forms with autowired widgets
  • flexible translation of widgets
  • modular, extensible and slim core
    • add own plugins
    • add own validators
    • add own base renderers
    • add own widget matchers & render strategies
    • use what you need
  • performance optimized, only updates HTML which must re-render, perfect for big schemas
  • code-splitting, with custom widget mappings / lazy-loading widgets
  • includes helper functions for store and immutable handling
  • easy nesting for custom object/array widgets with PluginStack
  • validate hidden/auto-generated values, virtualize schema levels (hidden keyword)
  • handle store update from anywhere and however you want
  • extensive documentations of core, widgets
  • typed components and definitions for JSON Schema and UI Schema
  • complex conditionals schemas
  • loading / referencing schemas by URL, connect any API or e.g. babel dynamic loading instead
  • definitions and JSON-Pointer references in schemas
  • JSON Schema extension: UI Schema, change design and even behaviour of widgets
  • JSON Schema versions supported: Draft 2019-09 / Draft-08, Draft-07, Draft-06, Draft-04

🔥 Professional service & support available, reach out now!

Design-System and Widgets Overview

Versions

This project adheres to semver, until 1.0.0 and beginning with 0.1.0: all 0.x.0 releases are like MAJOR releases and all 0.0.x like MINOR or PATCH, modules below 0.1.0 should be considered experimental.

Get the latest version - or help build it:

Example UI Schema

First time? Take the quick-start or take a look into the MUI demo repos: create-react-app & JS (simple) or create-react-app & Typescript (advanced).

Example setup of a renderer, followed by a simple text widget.

Instead of using UIRootRenderer it's also possible to use full custom rendering with e.g. ObjectGroup.

import React from 'react';

// Import Schema UI Provider and Render engine
import {isInvalid} from '@ui-schema/ui-schema/ValidityReporter';
import {createOrderedMap} from '@ui-schema/ui-schema/Utils/createMap';
import {UIStoreProvider, createStore} from '@ui-schema/ui-schema/UIStore';
import {storeUpdater} from '@ui-schema/ui-schema/storeUpdater';
import {UIMetaProvider, useUIMeta} from '@ui-schema/ui-schema/UIMeta';
// new in `0.4.0-alpha.1`:
// import {injectPluginStack} from '@ui-schema/ui-schema/applyPluginStack';
// deprecated since `0.4.0-alpha.1`:
import {UIRootRenderer} from '@ui-schema/ui-schema/UIRootRenderer';
// basic in-schema translator / `t` keyword support
import {relTranslator} from '@ui-schema/ui-schema/Translate/relT';
// Get the widgets binding for your design-system
import {widgets} from '@ui-schema/ds-material/widgetsBinding';
// new in `0.4.0-alpha.1`:
// import {GridContainer} from '@ui-schema/ds-material/GridContainer';

// could be fetched from some API or bundled with the app
const schemaBase = {
    type: 'object',
    properties: {
        country: {
            type: 'string',
            widget: 'Select',
            enum: [
                'usa',
                'canada',
                'eu'
            ],
            default: 'eu',
            tt: 'upper'
        },
        name: {
            type: 'string',
            maxLength: 20,
        }
    },
    required: [
        'country',
        'name',
    ],
};

// or fetch from API
const data = {};

// for `>=0.4.0-alpha.1`:
// const GridStack = injectPluginStack(GridContainer)

export const DemoForm = () => {
    // optional state for display errors/validity
    const [showValidity, setShowValidity] = React.useState(false);

    // needed variables and setters for the render engine, create wherever you like
    const [store, setStore] = React.useState(() => createStore(createOrderedMap(data)));
    const [schema/*, setSchema*/] = React.useState(() => createOrderedMap(schemaBase));

    // `useUIMeta` can be used safely, without performance impact (`useUI` has a performance impact)
    const {widgets, t} = useUIMeta()

    const onChange = React.useCallback((actions) => {
        setStore(storeUpdater(actions))
    }, [setStore])

    return <>
        <UIStoreProvider
            store={store}
            onChange={onChange}
            showValidity={showValidity}
        >
            {/*
              * for `>=0.4.0-alpha.1`:
              */}
            {/*<GridStack isRoot schema={schema}/>*}

            {/*
              * deprecated since `0.4.0-alpha.1`:
              */}
            <UIRootRenderer schema={schema}/>
        </UIStoreProvider>

        <button
            /* show the validity only at submit (or pass `true` to `showValidity`) */
            onClick={() =>
                isInvalid(store.getValidity()) ?
                    setShowValidity(true) :
                    console.log('doingSomeAction:', store.valuesToJS())
            }
        >send!
        </button>
    </>
};

export default function App() {
    return <UIMetaProvider
        widgets={widgets}
        t={relTranslator}
        // never pass down functions like this - always use e.g. `React.useCallback`, check performance docs for more
        //t={(text, context, schema) => {/* add translations */}}
    >
        {/*
          * somewhere in `YourRouterAndStuff` are your custom forms,
          * it's possible to nest `UIMetaProvider` if you need to have different widgets,
          * e.g. depending on some lazy loaded component tree
          */}
        <YourRouterAndStuff/>
    </UIMetaProvider>
}

Example Simple Text Widget

Easily create new widgets, this is all for a simple text (type=string) widget:

import React from 'react';
import { TransTitle, WidgetProps, WithScalarValue } from '@ui-schema/ui-schema';

const Widget = (
    {
        value, storeKeys, onChange,
        required, schema,
        errors, valid,
        ...props
    }: WidgetProps & WithScalarValue,
) => {
    return <>
        <label><TransTitle schema={schema} storeKeys={storeKeys}/></label>

        <input
            type={'text'}
            required={required}
            value={value || ''}
            onChange={(e) => {
                onChange({
                    storeKeys,
                    scopes: ['value'],
                    // or use another StoreAction like `update`
                    type: 'set',
                    data: {
                        value: e.target.value,
                        //internalValue: undefined
                        //valid: undefined
                    },
                    schema,
                    required,
                })
            }}
        />
    </>
}

Contributing

See CONTRIBUTING.md.

License

This project is free software distributed under the MIT License.

See: LICENSE.

© 2022 bemit UG (haftungsbeschränkt)

License Icons

The icons in the badges of the readme's are either from simpleicons or are licensed otherwise:


Created by Michael Becker