react-declarative
TypeScript icon, indicating that this package has built-in type declarations

2.2.125 • Public • Published

⚛️ react-declarative

MUI json endpoint form builder. Check this storybook for more samples...

npm

meme

A React view builder which interacts with a JSON endpoint to generate nested 12-column grids with input fields and automatic state management in a declarative style. Endpoint is typed by TypeScript guards (IntelliSense available). This tool is based on MUI components, so your application will look beautiful on any device...

Quick start

There is a create-react-app template available in this repository

yarn create react-app --template cra-template-react-declarative .

or

npx create-react-app . --template=react-declarative

Installation

There is a sample app avalible in demo folder...

npm install --save react-declarative tss-react @mui/material @emotion/react @emotion/styled

Demos

The react-declarative is not just a form builder. This one is the huge framework with dashboard adaptive cards builder, crud-based Grid component and more.

This tool also provide it's own way of rapid application development by simplifying app state managament. New features appear frequently, so you should be able to read the project's storybook, browse an organization with sample projects, and read the source code.

Also, several starter kits available

1. Pure React Starter

GitHub repo: https://github.com/react-declarative/cra-template-react-declarative

yarn create react-app --template cra-template-react-declarative .

2. Ethers.js/React Starter

GitHub repo: https://github.com/react-declarative/cra-template-solidity

yarn create react-app --template cra-template-solidity .

3. AppWrite/React Starter

GitHub repo: https://github.com/react-declarative/cra-template-appwrite

yarn create react-app --template cra-template-appwrite .

Declarative Scaffold component

Link to source code

The <Scaffold2 /> implements the basic Material Design visual layout structure by using config instead of manual ui elements composition.

scaffold2

const options: IScaffold2Group[] = [
  {
    id: 'build',
    label: 'Build',
    children: [
      {
        id: 'authentication',
        label: 'Authentication',
        isVisible: async () => await ioc.authService.hasRole('unauthorized'),
        icon: PeopleIcon,
        tabs: [
          { id: 'tab1', label: 'Tab1 in header', },
          { id: 'tab2', label: 'Tab2 in header', },
        ],
        options: [
          { id: 'tab1', label: 'Tab1 in side menu' },
          { id: 'tab2', label: 'Tab2 in side menu' },
        ],
      },
      { id: 'Database', label: 'Label is optional (can be generated automatically from ID in snake case)', icon: DnsRoundedIcon, },
      { id: 'Storage', isDisabled: async () => await myAmazingGuard(), icon: PermMediaOutlinedIcon, },
      { id: 'Hosting', icon: PublicIcon, },

      ...

JSON-templated view engine

1. Layout grid

Link to source code

layout-grid

const fields: TypedField[] = [
  {
    type: FieldType.Line,
    title: 'User info',
  },
  {
    type: FieldType.Group,
    phoneColumns: '12',
    tabletColumns: '6',
    desktopColumns: '4',
    fields: [
      {
        type: FieldType.Text,
        title: 'First name',
        defaultValue: 'Petr',
        description: 'Your first name',
        leadingIcon: Face,
        focus() { console.log("focus :-)"); },
        blur() { console.log("blur :-("); },
        name: 'firstName',
      },
      {
        type: FieldType.Text,
        title: 'Last name',
        defaultValue: 'Tripolsky',
        description: 'Your last name',
        name: 'lastName',
      },

      ...

];

2. Form validation

Link to source code

form-validation

const fields: TypedField[] = [
  {
    type: FieldType.Text,
    name: 'email',
    trailingIcon: Email,
    defaultValue: 'tripolskypetr@gmail.com',
    isInvalid({email}) {
      const expr = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/g;
      if (!expr.test(email)) {
        return 'Invalid email address';
      } else {
        return null;
      }
    },
    isDisabled({disabled}) {
      return disabled;
    },
    isVisible({visible}) {
      return visible;
    }
},
{
    type: FieldType.Expansion,
    title: 'Settings',
    description: 'Hide or disable',
    fields: [
      {
        type: FieldType.Switch,
        title: 'Mark as visible',
        name: 'visible',
        defaultValue: true,
      },

      ...

3. Gallery of controls

Link to source code

gallery

const fields: TypedField[] = [
  {
    type: FieldType.Paper,
    fields: [
      {
        type: FieldType.Line,
        title: 'Checkboxes',
      },
      {
        type: FieldType.Checkbox,
        name: 'checkbox1',
        columns: '3',
        title: 'Checkbox 1',
      },
      {
        type: FieldType.Checkbox,
        name: 'checkbox2',
        columns: '3',
        title: 'Checkbox 2',
      },

      ...

4. JSX Injection

Link to source code

const fields: TypedField[] = [
  {
    type: FieldType.Paper,
    fields: [
      {
        type: FieldType.Component,
        element: (props) => <Logger {...(props || {})}/>, 
      },
    ],
  },

  ...

];

JSON-templated grid engine

Link to source code

Adaptive json-configurable data grid with build-in mobile device support

list

const filters: TypedField[] = [
  {
    type: FieldType.Text,
    name: 'firstName',
    title: 'First name',
  },
  {
    type: FieldType.Text,
    name: 'lastName',
    title: 'Last name',
  }
];

const columns: IColumn[] = [
  {
    type: ColumnType.Text,
    field: 'id',
    headerName: 'ID',
    width: (fullWidth) => Math.max(fullWidth - 650, 200),
    columnMenu: [
      {
        action: 'test-action',
        label: 'Column action',
      },
    ],
  },
  ...
];

const actions: IListAction[] = [
  {
    type: ActionType.Add,
    label: 'Create item'
  },
  ...
];

const operations: IListOperation[] = [
  {
    action: 'operation-one',
    label: 'Operation one',
  },
];

const chips: IListChip[] = [
  {
    label: 'The chip1_enabled is true',
    name: 'chip1_enabled',
    color: '#4caf50',
  },
  ...
];

const rowActions: IListRowAction[] = [
  {
    label: 'chip1',
    action: 'chip1-action',
    isVisible: ({ chip1_enabled }) => chip1_enabled,
  },
  ...
];

...

return (
  <ListTyped
    withMobile
    withSearch
    withArrowPagination
    rowActions={rowActions}
    actions={actions}
    filters={filters}
    columns={columns}
    operations={operations}
    chips={chips}
  />
)

DOM Frames with infinite scroll and transparent-api virtualization

You can use InfiniteView for always-mounted or VirtualView for virtualized infinite lists

virtualization

<VirtualView
  component={Paper}
  sx={{
    width: "100%",
    height: 250,
    mb: 1,
  }}
  onDataRequest={() => {
    console.log('data-request');
    setItems((items) => [
      ...items,
      ...[uuid(), uuid(), uuid(), uuid(), uuid()],
    ]);
  }}
>
  {items.map((item) => (
    <span key={item}>{item}</span>
  ))}
</VirtualView>

Async pipe port

See angular2 docs

import { Async } from 'react-declarative'

import { CircularProgress } from '@mui/material'

const PostItem = ({
  id,
}) => {

  const { getPostById } = useBlogApi();

  return (
    <Async payload={id} Loader={CircularProgress}>
      {async (id) => {
        const { title, body } = await getPostById(id);
        return (
          <div>
            <p>{title}</p>
            <p>{body}</p>
          </div>
        );
      }}
    </Async>
  );
};

Structural directive port

See angular2 docs

import { If } from 'react-declarative'

const ProfilePage = () => {
  const { hasRole } = useRoleApi();
  return (
    <If condition={() => hasRole("admin")}>
      <button>The admin's button</button>
    </If>
  );
};

Animated view transition

Link to source code

import { FetchView } from 'react-declarative'

const PostList = () => {

  const { getPosts } = useBlogApi();

  const state = [
    getPosts,
  ];

  return (
    <FetchView state={state} animation="fadeIn">
      {(posts) => (
        <div>
          {posts.map((post, idx) => (
            <p key={idx}>
              <b>{post.title}</b>
              {post.body}
            </p>
          ))}
        </div>
      )}
    </FetchView>
  );
};

Build-in router

Link to source code

import { Switch } from 'react-declarative';

...

const routes = [
  {
    path: '/mint-page',
    guard: async () => await ioc.roleService.has('whitelist'),
    prefetch: async () => await ioc.ethersService.init(),
    unload: async () => await ioc.ethersService.dispose(),
    redirect: () => {
      let isOk = true;
      isOk = isOk && ioc.ethersService.isMetamaskAvailable;
      isOk = isOk && ioc.ethersService.isProviderConnected;
      isOk = isOk && ioc.ethersService.isAccountEnabled;
      if (isOk) {
        return "/connect-page";
      }
      return null;
    },
  },
];

...

const App = () => (
  <Switch history={history} items={routes} />
);

See also

import { ConstraintView } from 'react-declarative';
import { DragDropView } from 'react-declarative';
import { ScrollView } from 'react-declarative';
import { ScaleView } from 'react-declarative';
import { FadeView } from 'react-declarative';
import { TabsView } from 'react-declarative';
import { WaitView } from 'react-declarative';
import { PingView } from 'react-declarative';
import { OfflineView } from 'react-declarative';
import { RevealView } from 'react-declarative';
import { SecretView } from 'react-declarative';
import { PortalView } from 'react-declarative';
import { RecordView } from 'react-declarative';
import { CardView } from 'react-declarative';
import { ErrorView } from 'react-declarative';
import { AuthView } from 'react-declarative';
import { InfiniteView } from 'react-declarative';
import { VirtualView } from 'react-declarative';

Patterns inside

  1. MVVM - useCollection, useModel
  2. DI - provide, inject, createServiceManager
  3. Builder - useListEditor, useMediaStreamBuilder
  4. Observer - useChangeSubject, useSubject, useRenderWaiter, Subject, BehaviorSubject, EventEmitter, fromPromise
  5. Command - ActionTrigger, ActionFilter, ActionButton, ActionToggle, ActionMenu, ActionIcon, ActionModal, InfiniteView, VirtualView, useActionModal
  6. Coroutine - FetchView, WaitView, PingView, Async, If, useAsyncAction
  7. Routing - Switch, getRouteParams, getRouteItem, useRouteParams, useRouteItem, createRouteItemManager, createRouteParamsManager
  8. Monad - singleshot, cancelable, queued, cached, debounce, compose
  9. Composition - VirtualView, InfiniteView, PortalView, RevealView, PingView, WaitView, FadeView, ScaleView, ScrollView
  10. HoC - ConstraintView, AutoSizer, FetchView, Async, If
  11. Facade - Subject, Observer
  12. RAD - RecordView, CardView
  13. Functional - useActualValue, useActualCallback, useActualState, useSearchParams, useSearchState, useChange
  14. Declarative - One, List, Scaffold, Scaffold2, RecordView, CardView
  15. Reactive - EventEmitter, Subject, BehaviorSubject, Observer

Philosophy notes

  1. React: declarative vs imperative

    Declarative programming is when a more qualified specialist writing code in a way when its behavior can be changed by using external config which represent oriented graph of objects

  2. Fractal pattern

    Fractal pattern conveys that similar patterns recur progressively and the same thought process is applied to the structuring of codebase i.e All units repeat themselves.

  3. SOLID in react-declarative

    SOLID principles described by simple words with examples in a source code

License

MIT © tripolskypetr

Install

npm i react-declarative

DownloadsWeekly Downloads

6,536

Version

2.2.125

License

MIT

Unpacked Size

910 kB

Total Files

9

Last publish

Collaborators

  • tripolskypetr