Skip to content

dsankar1/scraft

Repository files navigation

Scraft

React library for JSON configured apps.

Features

  • Available as both a function and React Hook
  • Supports standard React components
  • Dynamic JSON configuration supports string interpolation & function composition
  • Handles page routing & layouts
  • Logs errors detected in the configuration

Installing

Using npm:

$ npm install --save scraft

Using yarn:

$ yarn add scraft

Usage

App.js

import React from 'react';
import { useBuilder } from 'scraft';
import { AppBar, Tabs, ColorBlock } from './components';

const config = readFile('./config.json');
const components = { AppBar, Tabs, ColorBlock };
const utils = { log: message => console.log(message) };

const App = props => {
	const BuiltApp = useBuilder(config, components, utils);
	return <BuiltApp />;
};

or

import React from 'react';
import { build } from 'scraft';
import { AppBar, Tabs, ColorBlock } from './components';

const config = readFile('./config.json');
const components = { AppBar, Tabs, ColorBlock };
const utils = { log: message => console.log(message) };

const App = build(config, components, utils);

config.json

{
    "app": {
        "containerIds": ["appBar"],
        "routes": [
            {
                "path": "/",
                "exact": true,
                "pageId": "rootPage"
            }
        ]
    },
    "pages": [
        {
            "id": "rootPage",
            "containerIds": ["pageTabs"],
            "widgetIds": ["redBlock"],
            "layouts": {
                "lg": [
                    {
                        "i": "redBlock",
                        "x": 0,
                        "y": 0,
                        "w": 12,
                        "h": 4
                    }
                ]
            }
        }
    ],
    "containers": [
        {
            "id": "appBar",
            "component": {
                "type": "AppBar"
            }
        },
        {
            "id": "pageTabs",
            "component": {
                "type": "Tabs"
            }
        }
    ],
    "widgets": [
        {
            "id": "redBlock",
            "handlers": {
                "notifyClick": {
                    "function": "${utils.log}",
                    "parameters": ["Red block clicked!"]
                }
            },
            "component": {
                "type": "ColorBlock",
                "props": {
                    "background": "red",
                    "onClick": "${handlers.notifyClick}"
                }
            }
        }
    ]
}

Configuration API

App

Configures the initial application level state, and containers. These will persist throughout the entire lifetime of the application. Routing within the application is also configured here.

Schema
object().shape({
  initState: object(),
  containerIds: array().of(string()),
  routes: array().of(
    object().shape({
      path: string().required(),
      pageId: string().required()
    })
  )
})

Pages

Configures initial page level state, containers, and widgets. These will persist for as long as the page is mounted. Configuration for widget layout & grid is also available. The widget grid has 12 columns, and the following breakpoints:

  • lg: >= 1200px
  • md: >= 992px
  • sm: >= 768px
  • xs: < 768px
Schema
object().shape({
  id: string().required(),
  initState: object(),
  initLayoutMode: boolean(),
  containerIds: array().of(string()),
  widgetIds: array().of(string()),
  layouts: object().shape({
      lg: array().of(layoutSchema),
      md: array().of(layoutSchema),
      sm: array().of(layoutSchema),
      xs: array().of(layoutSchema)
  }),
  grid: object().shape({
      margin: array()
          .of(number())
          .max(2),
      padding: array()
          .of(number())
          .max(2),
      cols: object().shape({
          lg: number(),
          md: number(),
          sm: number(),
          xs: number()
      }),
      rowHeight: number()
  })
})

Layout Schema

object().shape({
  i: string().required(),
  x: number().required(),
  y: number().required(),
  w: number().required(),
  h: number().required(),
  minW: number(),
  minH: number(),
  maxW: number(),
  maxH: number()
})

Containers & Widgets

Containers and widgets share the same wrapper component which allows for the interpolation of their props. Each of these also allows for the composition of functions via the handlers property. Container components all receive the widgets as children so it's important to pass them down the tree like the following:

const Container = props => {
  return <div>{props.children}</div>;
};
Schema
object().shape({
  id: string().required(),
  initState: object(),
  handlers: object(),
  onMount: string(),
  onUnmount: string(),
  component: object()
      .shape({
          type: string().required(),
          props: object()
      })
      .required()
})

About

React library for JSON configured apps.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published