{"id":21942853,"url":"https://github.com/react-declarative/react-declarative","last_synced_at":"2025-04-04T20:03:13.483Z","repository":{"id":37812685,"uuid":"330583823","full_name":"react-declarative/react-declarative","owner":"react-declarative","description":"A React form 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 material-ui components, so your application will look beautiful on any device...","archived":false,"fork":false,"pushed_at":"2025-01-04T09:44:18.000Z","size":58221,"stargazers_count":68,"open_issues_count":2,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T09:17:47.157Z","etag":null,"topics":["code-autocomplete","declarative","declarative-programming","form-builder","form-validation","frontend","grid-system","intellisense","json-endpoint","layout-engine","layout-grid","material-ui","mui","nested-grids","react","standalone","state-management","typescript"],"latest_commit_sha":null,"homepage":"https://react-declarative-playground.github.io/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-declarative.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["http://paypal.me/tripolskypetr"]}},"created_at":"2021-01-18T07:12:13.000Z","updated_at":"2025-01-30T14:57:22.000Z","dependencies_parsed_at":"2023-09-22T21:14:30.932Z","dependency_job_id":"2ad30fa0-6f80-426f-a2c6-32cc67c0248a","html_url":"https://github.com/react-declarative/react-declarative","commit_stats":{"total_commits":949,"total_committers":2,"mean_commits":474.5,"dds":"0.0031612223393044925","last_synced_commit":"30d3f21ef08585789c00e3568e60eb4d9300aa03"},"previous_names":["tripolskypetr/react-view-builder"],"tags_count":130,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Freact-declarative","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Freact-declarative/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Freact-declarative/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Freact-declarative/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-declarative","download_url":"https://codeload.github.com/react-declarative/react-declarative/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242658,"owners_count":20907131,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-autocomplete","declarative","declarative-programming","form-builder","form-validation","frontend","grid-system","intellisense","json-endpoint","layout-engine","layout-grid","material-ui","mui","nested-grids","react","standalone","state-management","typescript"],"created_at":"2024-11-29T03:26:59.202Z","updated_at":"2025-04-04T20:03:13.443Z","avatar_url":"https://github.com/react-declarative.png","language":"TypeScript","readme":"\u003cimg src=\"./assets/icons/logo.svg\" height=\"85px\" align=\"right\"\u003e\n\n# ⚛️ react-declarative\n\n\u003e [MUI](https://mui.com/) json endpoint form builder. Check this [Storybook](https://github.com/react-declarative/react-declarative-storybook), the [Playground](https://react-declarative-playground.github.io/) and the [Docs Folder](./docs/Readme.md) for more samples. Also [Playwright End-to-End Testbed](https://github.com/react-declarative/react-declarative-e2e) available\n\n[![npm](https://img.shields.io/npm/v/react-declarative.svg?style=flat-square)](https://npmjs.org/package/react-declarative)\n\n![meme](./meme.png)\n\nA 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 normal on any device...\n\n**More than Forms:** can be used for build any UI like dashboards, CRM and ERP, mobile apps. Solving your problems.  *⭐Star* and *💻Fork* It will be appreciated\n\n\u003c!--\n\n## Contents\n\n1. [Short review](./README.md#short-review)\n2. [Quick start](./README.md#quick-start)\n3. [Installation](./README.md#installation)\n4. [Demos](./README.md#demos)\n5. [Declarative Scaffold component](./README.md#declarative-scaffold-component)\n6. [Declarative KanbanView component](./README.md#declarative-kanbanview-component)\n7. [Declarative WizardView component](./README.md#declarative-wizardview-component)\n8. [VisibilityView and FeatureView components](./README.md#visibilityview-and-featureview-components)\n9. [JSON-templated view engine](./README.md#json-templated-view-engine)\n10. [JSON-templated grid engine](./README.md#json-templated-grid-engine)\n11. [DOM Frames with infinite scroll and transparent-api virtualization](./README.md#dom-frames-with-infinite-scroll-and-transparent-api-virtualization)\n12. [Async hooks and Action components](./README.md#async-hooks-and-action-components)\n13. [Async pipe port](./README.md#async-pipe-port)\n14. [Structural directive port](./README.md#structural-directive-port)\n15. [Animated view transition](./README.md#animated-view-transition)\n16. [Build-in router](./README.md#build-in-router)\n17. [MapReduce Data Pipelines](./README.md#mapreduce-data-pipelines)\n18. [Ref-managed MVVM collection](./README.md#ref-managed-mvvm-collection)\n19. [See also](./README.md#see-also)\n20. [Patterns inside](./README.md#patterns-inside)\n21. [Philosophy notes](./README.md#philosophy-notes)\n22. [License](./README.md#license)\n23. [Thanks](./README.md#thanks)\n\n--\u003e\n\n## Playground\n\n\u003e [!TIP]\n\u003e Try without installing directly [in your web browser](https://react-declarative-playground.github.io/)\n\n![playground](./assets/playground.gif)\n\nLink to [the playground](https://react-declarative-playground.github.io/)\n\n![mantine](./assets/images/mantine.png)\n\nCheck out how your app will look with the [Mantine theme](https://mantine.dev/) installed. You don't have to change any JSON schemas.\n\nThe [Mantine theme playground](https://react-declarative-mantine.github.io/)\n\n## Using with AI\n\n![screencast](./assets/images/claude.gif)\n\nThere is a guide to make GPT-4 generate form schemas automatically. Check [the docs folder for guide](./docs/Readme.md#using-with-ai)\n\n\u003cimg src=\"./assets/icons/decart.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Short review\n\n\u003e [!TIP]\n\u003e A few adjectives which can be applied to `react-declarative`\n\n1. **Accesible**\n\nEvery callback you need: field or group of fields focus/blur event, form invalidity state, [data-testid](https://medium.com/@automationTest/why-your-development-team-should-use-data-testid-attributes-a83f1ca27ebb) and more\n\n2. **Configurable**\n\nEach field can be statically [hidden by settings dictionary](https://github.com/react-declarative/react-pocketbase-crm?tab=readme-ov-file#feature-model-and-dynamic-field-visibility) and dynamically by form state condition. Same if you want to disable or make field readonly\n\n3. **Extendable**\n\nIt allow you to override any field type by slot context or [inject custom JSX](./demo/src/pages/GalleryPage.tsx#L206) directly into form without additional boilerplate. Also that lib can be used with all React ecosystem, for example, try with [Million.js](https://dev.to/tobysolutions/million-30-all-you-need-to-know-3d2), It makes `react-declarative` extreamly performant even on 2016 devices\n\n4. **Maintainable**\n\nWrite code without going into [technical debt](https://en.wikipedia.org/wiki/Technical_debt). The big diffrence with [jsonforms](https://jsonforms.io/docs/#how-does-it-work) is you actually write less code cause you don't need `data schema`. In `react-declarative` all validations are build into `ui schema`, so backend endpoint can be changed partially if some properties are unused (see [PATCH method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH))\n\n5. **Reflectable**\n\nEach form schema can be [reflected](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.typeinfo?view=net-8.0) by using `getAvailableFields` for additional inline validations, data cleanup if some fields are not required anymore, data export (generate [excel export](https://www.npmjs.com/package/xlsx) from current form). That extreamly hard to implement with `jsonforms`\n\n6. **Reliable**\n\nReact 18 [Concurrent render](https://react.dev/blog/2022/03/29/react-v18#what-is-concurrent-react) used under the hood (state updates in async *useEffect*) so the `jsonforms` will slow down on 200+ fields form, `react-declarative` will not. Also [RPS](https://en.wikipedia.org/wiki/Web_server#requests_per_second) optimised by [debounce of form state change event](https://rxjs.dev/api/operators/debounce). That means you will need less hardware measures on a server side to implement autosubmit\n\n7. **Code-Splittable**\n\nJSON templates can be downloaded statically, builded dynamically, [lazy-loaded dynamically](https://webpack.js.org/concepts/module-federation/)\n\n8. **Scalable**\n\nEasy internationalization with translation dictionaries for Combobox field. [JSX Factory for labels translation](https://github.com/react-declarative/react-i18n-jsx-factory). An organisation for tutoring newbies [with 25 projects with AI](https://github.com/react-declarative/brainjs-cryptocurrency-trend), reactive programming and more \n\n9. **Integrable**\n\n\u003c!--Consolidates multiple aspects of the development process into one cohesive tool, providing a streamlined and efficient workflow for developers. It unifies state management and ui building into a single approach, managing project code modules dependency resolution, asset sharing, and software design, as a result eliminates the heterogeneous made by usage of separate tools.--\u003e\nIt combines various development tasks into one tool, making the process simpler and faster. It manages app state, user interface building, code dependencies, asset sharing, and software design all in one place.\n\n10. **Customisable**\n\nA game-changer for your app look is the `react-declarative-mantine`. That library provides `\u003cOneSlotFactory /\u003e` with all fields redesigned. Check out [how your app can look like](https://react-declarative-mantine.github.io/) without changing any JSON schemas.\n\n\u003cimg src=\"./assets/icons/masonry.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Quick start\n\n\u003e [!IMPORTANT]\n\u003e There is a `create-react-app` template available [in this repository](https://github.com/react-declarative/cra-template-react-declarative)\n\n```bash\nyarn create react-app --template cra-template-react-declarative .\n```\n\nor\n\n```bash\nnpx create-react-app . --template=react-declarative\n```\n\n\u003cimg src=\"./assets/icons/babylon.svg\" height=\"40px\" align=\"right\"\u003e\n\n## Installation\n\n\u003e [!NOTE]\n\u003e There is a sample app avalible in the [demo](./demo/src/index.tsx) folder...\n\n```bash\nnpm install --save react-declarative tss-react @mui/material @emotion/react @emotion/styled\n```\n\n\u003cimg src=\"./assets/icons/watch.svg\" height=\"40px\" align=\"right\"\u003e\n\n## Migrate\n\n\u003e [!NOTE]\n\u003e A lightweight version with `\u003cOne /\u003e` component and dependencies only published in [react-declarative-lite](https://github.com/react-declarative/react-declarative-lite) npm package. Useful when you want to use `\u003cOne /\u003e` forms in existing app\n\n```bash\nnpm install --save react-declarative-lite\n```\n\n\u003cimg src=\"./assets/icons/world.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Demos\n\n\u003e [!NOTE]\n\u003e 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.\u003cbr\u003e Check [the docs folder](./docs/Readme.md)\n\nThis 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](https://github.com/react-declarative/react-declarative-storybook), browse [an organization with sample projects](https://github.com/react-declarative), and [read the source code](https://github.com/react-declarative/react-declarative)\n\nSeveral starter kits available (Check [Playwright End-to-End testbed](https://github.com/react-declarative/react-declarative-e2e))\n\n**1. Pure React Starter**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/cra-template-react-declarative](https://github.com/react-declarative/cra-template-react-declarative)\n\n```bash\nyarn create react-app --template cra-template-react-declarative .\n```\n\n**2. Ethers.js/React Starter**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/cra-template-solidity](https://github.com/react-declarative/cra-template-solidity)\n\n```bash\nyarn create react-app --template cra-template-solidity .\n```\n\n**3. AppWrite/React Starter**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/cra-template-appwrite](https://github.com/react-declarative/cra-template-appwrite)\n\n```bash\nyarn create react-app --template cra-template-appwrite .\n```\n\nand few more quite interesting demo projects\n\n**1. Playwright End-to-End Testbed**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/react-declarative-e2e](https://github.com/react-declarative/react-declarative-e2e)\n\n```bash\ngit clone https://github.com/react-declarative/react-declarative-e2e.git\n```\n\n**2. ERC-20 Payment gateway**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/erc20-payment-gateway](https://github.com/react-declarative/erc20-payment-gateway)\n\n```bash\ngit clone https://github.com/react-declarative/erc20-payment-gateway.git\n```\n\n**3. React Face KYC**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/react-face-kyc](https://github.com/react-declarative/react-face-kyc)\n\n```bash\ngit clone https://github.com/react-declarative/react-face-kyc.git\n```\n\n**4. BrainJS Cryptocurrency Trend**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/brainjs-cryptocurrency-trend](https://github.com/react-declarative/brainjs-cryptocurrency-trend)\n\n```bash\ngit clone https://github.com/react-declarative/brainjs-cryptocurrency-trend.git\n```\n\n**5. NFT Mint Tool**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/nft-mint-tool](https://github.com/react-declarative/nft-mint-tool)\n\n```bash\ngit clone https://github.com/react-declarative/nft-mint-tool.git\n```\n\n**6. React PocketBase CRM**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/react-pocketbase-crm](https://github.com/react-declarative/react-pocketbase-crm)\n\n```bash\ngit clone https://github.com/react-declarative/react-pocketbase-crm.git\n```\n\n**7. ChatGPT Ecommerce Grid**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/chatgpt-ecommerce-prompt](https://github.com/react-declarative/chatgpt-ecommerce-prompt)\n\n```bash\ngit clone https://github.com/react-declarative/chatgpt-ecommerce-prompt.git\n```\n\n**8. React Native lightweight version of this library**\n\n\u003e [!NOTE]\n\u003e GitHub repo: [https://github.com/react-declarative/rn-declarative](https://github.com/react-declarative/rn-declarative)\n\n```bash\ngit clone https://github.com/react-declarative/rn-declarative.git\n```\n\n\u003cimg src=\"./assets/icons/fallen.svg\" height=\"40px\" align=\"right\"\u003e\n\n## Declarative Scaffold component\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/App.Scaffold2.tsx)\n\nThe `\u003cScaffold2 /\u003e` implements the basic Material Design visual layout structure by using config instead of manual ui elements composition. \n\n![scaffold2](./assets/scaffold2.gif)\n\n```tsx\nconst options: IScaffold2Group[] = [\n  {\n    id: 'build',\n    label: 'Build',\n    children: [\n      {\n        id: 'authentication',\n        label: 'Authentication',\n        isVisible: async () =\u003e await ioc.authService.hasRole('unauthorized'),\n        icon: PeopleIcon,\n        tabs: [\n          { id: 'tab1', label: 'Tab1 in header', },\n          { id: 'tab2', label: 'Tab2 in header', },\n        ],\n        options: [\n          { id: 'tab1', label: 'Tab1 in side menu' },\n          { id: 'tab2', label: 'Tab2 in side menu' },\n        ],\n      },\n      { id: 'Database', label: 'Label is optional (can be generated automatically from ID in snake case)', icon: DnsRoundedIcon, },\n      { id: 'Storage', isDisabled: async () =\u003e await myAmazingGuard(), icon: PermMediaOutlinedIcon, },\n      { id: 'Hosting', icon: PublicIcon, },\n\n      ...\n\n```\n\n\u003cimg src=\"./assets/icons/box.svg\" height=\"40px\" align=\"right\"\u003e\n\n## Declarative KanbanView component\n\nThe `\u003cKanbanView /\u003e` allow you to build [kanban](https://en.wikipedia.org/wiki/Kanban_(development)) boards with realtime support\n\n![kanbanview](./assets/kanbanview.gif)\n\n```tsx\n\nconst rows: IBoardRow\u003cILeadRow\u003e[] = [\n  {\n    label: \"Display name\",\n    value: (id, employee) =\u003e\n      [employee.first_name, employee.last_name].join(\" \"),\n  },\n  {\n    label: \"Email\",\n    value: (id, employee) =\u003e employee.email,\n    click: (id, data, payload) =\u003e payload.pickEmployeePreviewModal(id),\n  },\n  {\n    label: \"Phone\",\n    value: (id, employee) =\u003e employee.phone,\n  },\n  {\n    label: \"Hire date\",\n    value: (id, employee) =\u003e employee.hire_date,\n  },\n];\n\nconst columns: IBoardColumn\u003cILeadRow\u003e[] = [\n  {\n    color: \"#00ACC1\",\n    column: \"cold\",\n    label: \"Cold\",\n    rows,\n  },\n  {\n    color: \"#9C27B0\",\n    column: \"contact\",\n    label: \"Contact\",\n    rows,\n  },\n  {\n    color: \"#FFA000\",\n    column: \"draft\",\n    label: \"Draft\",\n    rows,\n  },\n  {\n    color: \"#2E7D32\",\n    column: \"deal\",\n    label: \"In a deal\",\n    rows,\n  },\n];\n\n...\n\n\u003cKanbanView\u003cILeadRow\u003e\n  sx={{\n    height: \"calc(100vh - 145px)\",\n  }}\n  onChangeColumn={handleChangeColumn}\n  columns={columns}\n  items={data}\n/\u003e\n```\n\n\u003cimg src=\"./assets/icons/x.svg\" height=\"55px\" align=\"right\"\u003e\n\n## Declarative WizardView component\n\nThe `\u003cWizardView /\u003e` component allows you to build [action wizard](https://en.wikipedia.org/wiki/Wizard_(software)) with [stepper](https://mui.com/material-ui/react-stepper/) and nested routing\n\n![wizardview](./assets/wizardview.gif)\n\n```tsx\n\nconst steps: IWizardStep[] = [\n  {\n    id: \"select\",\n    label: \"Choose file\",\n  },\n  {\n    id: \"validate\",\n    label: \"Validation\",\n  },\n  {\n    id: \"import\",\n    label: \"Import\",\n  },\n];\n\nconst routes: IWizardOutlet[] = [\n  {\n    id: \"select\",\n    element: SelectFileView,\n    isActive: (pathname) =\u003e !!parseRouteUrl(\"/select-file\", pathname),\n  },\n  {\n    id: \"validate\",\n    element: ValidateFileView,\n    isActive: (pathname) =\u003e !!parseRouteUrl(\"/validate-file\", pathname),\n  },\n  {\n    id: \"import\",\n    element: ImportFileView,\n    isActive: (pathname) =\u003e !!parseRouteUrl(\"/import-file\", pathname),\n  },\n];\n\n...\n\n\u003cWizardView pathname=\"/select-file\" steps={steps} routes={routes} /\u003e\n\n...\n\nconst SelectFileView = ({\n    history\n}: IWizardOutletProps) =\u003e {\n  return (\n    \u003cWizardContainer\n      Navigation={\n        \u003cWizardNavigation\n          hasNext\n          onNext={() =\u003e history.replace(\"/validate-file\")}\n        /\u003e\n      }\n    \u003e\n        \u003cp\u003e123\u003c/p\u003e\n    \u003c/WizardContainer\u003e\n  );\n};\n\n```\n\n\u003cimg src=\"./assets/icons/magnum-opus.svg\" height=\"30px\" align=\"right\"\u003e\n\n## VisibilityView and FeatureView components\n\nThe `\u003cVisibilityView /\u003e` and `\u003cFeatureView /\u003e` components allows you to build configurable UI by using [reflection](https://en.wikipedia.org/wiki/Reflective_programming)\n\n![visibility](./assets/visibility.gif)\n\n```tsx\nconst groups: IVisibilityGroup[] = [\n  {\n    name: \"employee_visibility\",\n    /**\n     * @type {IField[] | TypedField[]}\n     * @description Same field type from `\u003cOne /\u003e` template engine\n     */\n    fields: employee_fields,\n  },\n];\n\n...\n\n\u003cVisibilityView\n  expandAll\n  data={{ employee_visibility: data }}\n  groups={groups}\n  onChange={({ employee_visibility }) =\u003e onChange(employee_visibility)}\n/\u003e\n```\n\nBy using [feature-oriented programming](https://en.wikipedia.org/wiki/Feature-oriented_domain_analysis) you can adjust view to different roles of users by partially hiding text, images and buttons\n\n```tsx\nconst features: IFeatureGroup[] = [\n  {\n    title: \"Employee\",\n    expanded: true,\n    children: [\n      {\n        name: \"employee_preview_modal\",\n        label: \"Employee preview modal\",\n        description: \"Click on row open preview modal\",\n      },\n      {\n        name: \"employee_toggle_inactive\",\n        label: \"Employee toggle inactive\",\n        description: \"Can toggle employee activity\",\n      },\n    ],\n  },\n];\n\n...\n\n\u003cFeatureView\n  expandAll\n  data={data}\n  features={features}\n  onChange={onChange}\n/\u003e\n\n...\n\n\u003cIf\n  payload={userId}\n  condition={async (userId) =\u003e {\n    return await ioc.permissionRequestService.getOwnerContactVisibilityByUserId(userId)\n  }}\n  Loading=\"Loading\"\n  Else=\"Hidden\"\n\u003e\n  {owner_contact}\n\u003c/If\u003e\n\n```\n\n\n\u003cimg src=\"./assets/icons/solomon.svg\" height=\"55px\" align=\"right\"\u003e\n\n## JSON-templated view engine\n\n**1. Layout grid**\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/pages/LayoutPage.tsx)\n\n![layout-grid](./assets/layout.gif)\n\n```tsx\nconst fields: TypedField[] = [\n  {\n    type: FieldType.Line,\n    title: 'User info',\n  },\n  {\n    type: FieldType.Group,\n    phoneColumns: '12',\n    tabletColumns: '6',\n    desktopColumns: '4',\n    fields: [\n      {\n        type: FieldType.Text,\n        title: 'First name',\n        defaultValue: 'Petr',\n        description: 'Your first name',\n        leadingIcon: Face,\n        focus() { console.log(\"focus :-)\"); },\n        blur() { console.log(\"blur :-(\"); },\n        name: 'firstName',\n      },\n      {\n        type: FieldType.Text,\n        title: 'Last name',\n        defaultValue: 'Tripolsky',\n        description: 'Your last name',\n        name: 'lastName',\n      },\n\n      ...\n\n];\n```\n\n**2. Form validation**\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/pages/ValidationPage.tsx)\n\n![form-validation](./assets/validation.gif)\n\n```tsx\nconst fields: TypedField[] = [\n  {\n    type: FieldType.Text,\n    name: 'email',\n    trailingIcon: Email,\n    defaultValue: 'tripolskypetr@gmail.com',\n    isInvalid({email}) {\n      const expr = /^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$/g;\n      if (!expr.test(email)) {\n        return 'Invalid email address';\n      } else {\n        return null;\n      }\n    },\n    isDisabled({disabled}) {\n      return disabled;\n    },\n    isVisible({visible}) {\n      return visible;\n    }\n},\n{\n    type: FieldType.Expansion,\n    title: 'Settings',\n    description: 'Hide or disable',\n    fields: [\n      {\n        type: FieldType.Switch,\n        title: 'Mark as visible',\n        name: 'visible',\n        defaultValue: true,\n      },\n\n      ...\n\n```\n\n**3. Gallery of controls**\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/pages/GalleryPage.tsx)\n\n![gallery](./assets/gallery.gif)\n\n```tsx\nconst fields: TypedField[] = [\n  {\n    type: FieldType.Paper,\n    fields: [\n      {\n        type: FieldType.Line,\n        title: 'Checkboxes',\n      },\n      {\n        type: FieldType.Checkbox,\n        name: 'checkbox1',\n        columns: '3',\n        title: 'Checkbox 1',\n      },\n      {\n        type: FieldType.Checkbox,\n        name: 'checkbox2',\n        columns: '3',\n        title: 'Checkbox 2',\n      },\n\n      ...\n\n```\n\n**4. JSX Injection**\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/pages/GalleryPage.tsx)\n\n```tsx\nconst fields: TypedField[] = [\n  {\n    type: FieldType.Paper,\n    fields: [\n      {\n        type: FieldType.Component,\n        element: (props) =\u003e \u003cLogger {...props}/\u003e, \n      },\n    ],\n  },\n\n  ...\n\n];\n```\n\n**5. UI-Kit override**\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./src/components/One/components/SlotFactory)\n\n```tsx\n\u003cOneSlotFactory\n  CheckBox={MyCheckBox}\n  Text={MyInput}\n  ...\n\u003e\n  \u003cOne\n    ...\n  /\u003e\n  ...\n\u003c/OneSlotFactory\u003e\n```\n\n**6. Hiding fields by business functions**\n\n\u003e [!NOTE]\n\u003e See [RBAC](https://en.wikipedia.org/wiki/Role-based_access_control)\n\n```tsx\nconst fields: TypedField[] = [\n  {\n    type: FieldType.Text,\n    name: 'phone',\n    hidden: ({ payload }) =\u003e {\n      return !payload.features.has('show-phone-number');\n    },\n  },\n\n  ...\n\n];\n```\n\n\u003cimg src=\"./assets/icons/saturn.svg\" height=\"35px\" align=\"right\"\u003e\n\n## JSON-templated grid engine\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/pages/ListPage.tsx)\n\nAdaptive json-configurable data grid with build-in mobile device support\n\n![list](./assets/images/list.png)\n\n```tsx\n\nconst filters: TypedField[] = [\n  {\n    type: FieldType.Text,\n    name: 'firstName',\n    title: 'First name',\n  },\n  {\n    type: FieldType.Text,\n    name: 'lastName',\n    title: 'Last name',\n  }\n];\n\nconst columns: IColumn[] = [\n  {\n    type: ColumnType.Text,\n    field: 'id',\n    headerName: 'ID',\n    width: (fullWidth) =\u003e Math.max(fullWidth - 650, 200),\n    columnMenu: [\n      {\n        action: 'test-action',\n        label: 'Column action',\n      },\n    ],\n  },\n  ...\n];\n\nconst actions: IListAction[] = [\n  {\n    type: ActionType.Add,\n    label: 'Create item'\n  },\n  ...\n];\n\nconst operations: IListOperation[] = [\n  {\n    action: 'operation-one',\n    label: 'Operation one',\n  },\n];\n\nconst chips: IListChip[] = [\n  {\n    label: 'The chip1_enabled is true',\n    name: 'chip1_enabled',\n    color: '#4caf50',\n  },\n  ...\n];\n\nconst rowActions: IListRowAction[] = [\n  {\n    label: 'chip1',\n    action: 'chip1-action',\n    isVisible: ({ chip1_enabled }) =\u003e chip1_enabled,\n  },\n  ...\n];\n\n...\n\nreturn (\n  \u003cListTyped\n    withMobile\n    withSearch\n    withArrowPagination\n    rowActions={rowActions}\n    actions={actions}\n    filters={filters}\n    columns={columns}\n    operations={operations}\n    chips={chips}\n  /\u003e\n)\n\n```\n\n\u003cimg src=\"./assets/icons/square_compasses.svg\" height=\"35px\" align=\"right\"\u003e\n\n## DOM Frames with infinite scroll and `transparent-api virtualization`\n\n\u003e [!NOTE]\n\u003e You can use [InfiniteView](./src/components/InfiniteView/InfiniteView.tsx) for always-mounted or [VirtualView](./src/components/VirtualView/VirtualView.tsx) for virtualized infinite lists \n\n![virtualization](./assets/virtualization.gif)\n\n```tsx\n\u003cVirtualView\n  component={Paper}\n  sx={{\n    width: \"100%\",\n    height: 250,\n    mb: 1,\n  }}\n  onDataRequest={() =\u003e {\n    console.log('data-request');\n    setItems((items) =\u003e [\n      ...items,\n      ...[uuid(), uuid(), uuid(), uuid(), uuid()],\n    ]);\n  }}\n\u003e\n  {items.map((item) =\u003e (\n    \u003cspan key={item}\u003e{item}\u003c/span\u003e\n  ))}\n\u003c/VirtualView\u003e\n```\n\n\u003cimg src=\"./assets/icons/whenthesummerdies.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Async hooks and Action components\n\n\u003e [!NOTE]\n\u003e Hooks for fetching, caching and updating asynchronous data. Promise-based [command pattern](https://docs.devexpress.com/WPF/17353/mvvm-framework/commands/delegate-commands) ui components. The hooks will help you to avoid [multiple POST method execution](https://en.wikipedia.org/wiki/REST) when user missclick button. The components will show load indicator while `onClick` promise is pending\n\nThe `useAsyncProgress` will manage percent range of execution (`0% - 100%` for `\u003cLinearProgress /\u003e` value)\n\n```tsx\nconst { execute } = useAsyncProgress(\n  async ({ data }) =\u003e {\n    await createContact(data);\n  },\n  {\n    onProgress: (percent) =\u003e {\n      setProgress(percent);\n    },\n    onError: (errors) =\u003e {\n      setErrors(errors);\n    },\n    onEnd: (isOk) =\u003e {\n      history.replace(\"/report\");\n    },\n  }\n);\n\n...\n\n\u003cActionButton\n  onClick={async () =\u003e {\n    const file = await chooseFile(\n      \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n    );\n    if (file) {\n      const rows = await parseExcelContacts(file);\n      execute(\n        rows.map((row, idx) =\u003e ({\n          data: row,\n          label: `Row №${idx + 2}`,\n        }))\n      );\n    }\n  }}\n\u003e\n  Choose XLSX\n\u003c/ActionButton\u003e\n```\n\nThe `useSinglerunAction` will not execute any additional calls while original promise is pending\n\n```tsx\nconst { execute } = useSinglerunAction(\n  async () =\u003e {\n   const file = await chooseFile(\"image/jpeg, image/png\");\n    if (file) {\n      const filePath = await ioc.appwriteService.uploadFile(file);\n      onChange(filePath);\n    }\n  }\n);\n\n...\n\n\u003cActionIcon onClick={execute}\u003e\n  \u003cCloudUploadIcon /\u003e\n\u003c/ActionIcon\u003e\n```\n\nThe `useQueuedAction` will queue all promise fulfillment in functions execution order. Quite useful while [state reducer pattern](https://en.wikipedia.org/wiki/Redux_(JavaScript_library)) when coding [realtime](https://en.wikipedia.org/wiki/WebSocket).\n\n```tsx\nconst { execute } = useQueuedAction(\n  async ({ type, payload }) =\u003e {\n    if (type === \"create-action\") {\n      ...\n    }\n    if (type === \"update-action\") {\n\n    }\n    if (type === \"remove-action\") {\n      ...\n    }\n  },\n  {\n    onLoadStart: () =\u003e ioc.layoutService.setAppbarLoader(true),\n    onLoadEnd: () =\u003e ioc.layoutService.setAppbarLoader(false),\n  }\n);\n\n...\n\nuseEffect(() =\u003e ioc.kanbanService.createSubject.subscribe(execute), []);\n\nuseEffect(() =\u003e ioc.kanbanService.updateSubject.subscribe(execute), []);\n\nuseEffect(() =\u003e ioc.kanbanService.removeSubject.subscribe(execute), []);\n\n```\n\nThe `usePreventAction` will prevent any other action execution [while single one is pending](https://en.wikipedia.org/wiki/Semaphore_(programming))\n\n```tsx\nconst {\n  handleLoadStart,\n  handleLoadEnd,\n  loading,\n} = usePreventAction();\n\n...\n\n\u003cActionButton\n  disabled={loading}\n  onLoadStart={handleLoadStart}\n  onLoadEnd={handleLoadEnd}\n\u003e\n  Action 1\n\u003c/ActionButton\u003e\n\n...\n\n\u003cActionButton\n  disabled={loading}\n  onLoadStart={handleLoadStart}\n  onLoadEnd={handleLoadEnd}\n\u003e\n  Action 2\n\u003c/ActionButton\u003e\n```\n\nThe `usePreventNavigate` will [prevent navigate](https://medium.com/@goldhand/routing-design-patterns-fed766ad35fa) while action is running\n\n```tsx\nconst { handleLoadStart, handleLoadEnd } = usePreventNavigate({\n  history: ioc.routerService,\n});\n\n...\n\n\u003cActionButton\n  onLoadStart={handleLoadStart}\n  onLoadEnd={handleLoadEnd}\n\u003e\n  Action\n\u003c/ActionButton\u003e\n```\n\nThe `useAsyncValue` will help you to manage [react-hooks/rules-of-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks) while working with remote data\n\n```tsx\nconst [data, { loading, error }, setData] = useAsyncValue(async () =\u003e {\n  return await getData();\n});\n\nif (loading || error) {\n  return null;\n}\n\nreturn (\n  \u003cpre\u003e\n    {JSON.stringify(data, null, 2)}\n  \u003c/pre\u003e\n)\n\n...\n\nconst handleChangeData = async () =\u003e {\n  const newData = await fetchApi('/api/v1/data', {\n    method: \"POST\",\n    ...\n  })\n  setData(newData)\n}\n\n```\n\n\u003cimg src=\"./assets/icons/stone.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Async pipe port\n\n\u003e [!NOTE]\n\u003e See [angular2 docs](https://angular.io/api/common/AsyncPipe)\n\n```tsx\nimport { Async } from 'react-declarative'\n\nimport { CircularProgress } from '@mui/material'\n\nconst PostItem = ({\n  id,\n}) =\u003e {\n\n  const { getPostById } = useBlogApi();\n\n  return (\n    \u003cAsync payload={id} Loader={CircularProgress}\u003e\n      {async (id) =\u003e {\n        const { title, body } = await getPostById(id);\n        return (\n          \u003cdiv\u003e\n            \u003cp\u003e{title}\u003c/p\u003e\n            \u003cp\u003e{body}\u003c/p\u003e\n          \u003c/div\u003e\n        );\n      }}\n    \u003c/Async\u003e\n  );\n};\n```\n\n\u003cimg src=\"./assets/icons/triangle.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Structural directive port\n\n\u003e [!NOTE]\n\u003e See [angular2 docs](https://angular.io/guide/structural-directives)\n\n```tsx\nimport { If } from 'react-declarative'\n\nconst ProfilePage = () =\u003e {\n  const { hasRole } = useRoleApi();\n  return (\n    \u003cIf condition={() =\u003e hasRole(\"admin\")}\u003e\n      \u003cbutton\u003eThe admin's button\u003c/button\u003e\n    \u003c/If\u003e\n  );\n};\n```\n\n\u003cimg src=\"./assets/icons/monade.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Animated view transition\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/pages/RevealPage.tsx)\n\n```tsx\nimport { FetchView } from 'react-declarative'\n\nconst PostList = () =\u003e {\n\n  const { getPosts } = useBlogApi();\n\n  const state = [\n    getPosts,\n  ];\n\n  return (\n    \u003cFetchView state={state} animation=\"fadeIn\"\u003e\n      {(posts) =\u003e (\n        \u003cdiv\u003e\n          {posts.map((post, idx) =\u003e (\n            \u003cp key={idx}\u003e\n              \u003cb\u003e{post.title}\u003c/b\u003e\n              {post.body}\n            \u003c/p\u003e\n          ))}\n        \u003c/div\u003e\n      )}\n    \u003c/FetchView\u003e\n  );\n};\n```\n\n\u003cimg src=\"./assets/icons/positron.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Build-in router\n\n\u003e [!NOTE]\n\u003e Link to the [source code](./demo/src/App.tsx)\n\n```tsx\nimport { Switch } from 'react-declarative';\n\n...\n\nconst routes = [\n  {\n    path: '/mint-page',\n    guard: async () =\u003e await ioc.roleService.has('whitelist'),\n    prefetch: async () =\u003e await ioc.ethersService.init(),\n    unload: async () =\u003e await ioc.ethersService.dispose(),\n    redirect: () =\u003e {\n      let isOk = true;\n      isOk = isOk \u0026\u0026 ioc.ethersService.isMetamaskAvailable;\n      isOk = isOk \u0026\u0026 ioc.ethersService.isProviderConnected;\n      isOk = isOk \u0026\u0026 ioc.ethersService.isAccountEnabled;\n      if (isOk) {\n        return \"/connect-page\";\n      }\n      return null;\n    },\n  },\n];\n\n...\n\nconst App = () =\u003e (\n  \u003cSwitch history={history} items={routes} /\u003e\n);\n```\n\n\u003cimg src=\"./assets/icons/assignation.svg\" height=\"35px\" align=\"right\"\u003e\n\n## MapReduce Data Pipelines\n\n\u003e [!NOTE]\n\u003e Link to the [source code](https://github.com/react-declarative/react-face-kyc/blob/master/src/hooks/useFaceWasm/emitters.ts)\n\n```tsx\nimport { Source } from 'react-declarative';\n\n...\n\nconst verifyCompleteEmitter = Source.multicast(() =\u003e\n  Source\n    .join([\n      captureStateEmitter,\n      Source.fromInterval(1_000),\n    ])\n    .reduce((acm, [{ state: isValid }]) =\u003e {\n      if (isValid) {\n        return acm + 1;\n      }\n      return 0;\n    }, 0)\n    .tap((ticker) =\u003e {\n      if (ticker === 1) {\n        mediaRecorderInstance.beginCapture();\n      }\n    })\n    .filter((ticker) =\u003e ticker === CC_SECONDS_TO_VERIFY)\n    .tap(() =\u003e {\n      mediaRecorderInstance.endCapture();\n    })\n);\n```\n\n\u003cimg src=\"./assets/icons/chronos.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Ref-managed MVVM collection\n\n\u003e Link to the [source code](./demo/src/pages/MvvmPage.tsx)\n\n```tsx\nimport { useCollection } from \"react-declarative\";\n\n...\n\nconst collection = useCollection({\n  onChange: (collection, target) =\u003e console.log({\n    collection,\n    target,\n  }),\n  initialValue: [],\n});\n\nconst handleAdd = async () =\u003e {\n  const { id, ...data } = await fetchApi(\"/api/v1/counters/create\", {\n    method: \"POST\",\n  });\n  collection.push({\n    id,\n    ...data,\n  });\n};\n\nconst handleUpsert = async () =\u003e {\n  const updatedItems = await fetchApi(\"/api/v1/counters/list\");\n  collection.upsert(updatedItems);\n};\n\nreturn (\n  \u003c\u003e\n    \u003cbutton onClick={handleAdd}\u003eAdd item\u003c/button\u003e\n    \u003cbutton onClick={handleUpsert}\u003eUpsert items\u003c/button\u003e\n    \u003cul\u003e\n      {collection.map((entity) =\u003e (\n        \u003cListItem key={entity.id} entity={entity} /\u003e\n      ))}\n    \u003c/ul\u003e\n  \u003c/\u003e\n);\n```\n\n\u003cimg src=\"./assets/icons/heraldry.svg\" height=\"35px\" align=\"right\"\u003e\n\n## See also\n\n```tsx\nimport { ConstraintView } from 'react-declarative';\nimport { DragDropView } from 'react-declarative';\nimport { ScrollView } from 'react-declarative';\nimport { ScaleView } from 'react-declarative';\nimport { FadeView } from 'react-declarative';\nimport { TabsView } from 'react-declarative';\nimport { WaitView } from 'react-declarative';\nimport { PingView } from 'react-declarative';\nimport { OfflineView } from 'react-declarative';\nimport { RevealView } from 'react-declarative';\nimport { SecretView } from 'react-declarative';\nimport { PortalView } from 'react-declarative';\nimport { RecordView } from 'react-declarative';\nimport { CardView } from 'react-declarative';\nimport { ErrorView } from 'react-declarative';\nimport { AuthView } from 'react-declarative';\nimport { InfiniteView } from 'react-declarative';\nimport { VirtualView } from 'react-declarative';\n```\n\n\u003cimg src=\"./assets/icons/consciousness.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Patterns inside\n\n1. [MVVM](https://backbonejs.org/#Collection) - `useCollection`, `useModel`\n2. [DI](https://angular.io/guide/dependency-injection) - `provide`, `inject`, `createServiceManager`\n3. [Builder](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder?view=net-7.0) - `useListEditor`, `useMediaStreamBuilder`\n4. [Adapter](https://en.wikipedia.org/wiki/Adapter_pattern) - `normalizeText`\n5. [Observer](https://en.wikipedia.org/wiki/Observer_pattern) - `useChangeSubject`, `useSubject`, `useRenderWaiter`, `Subject`, `BehaviorSubject`, `EventEmitter`, `fromPromise`\n6. [Command](https://en.wikipedia.org/wiki/Command_pattern) - `ActionTrigger`, `ActionFilter`, `ActionButton`, `ActionToggle`, `ActionMenu`, `ActionIcon`, `ActionModal`, `InfiniteView`, `VirtualView`, `useActionModal`\n7. [Coroutine](https://en.wikipedia.org/wiki/Coroutine) - `FetchView`, `WaitView`, `PingView`, `Async`, `If`, `useAsyncAction`\n8. [Routing](https://medium.com/@goldhand/routing-design-patterns-fed766ad35fa) - `Switch`, `OutletView`, `getRouteParams`, `getRouteItem`, `useRouteParams`, `useRouteItem`, `createRouteItemManager`, `createRouteParamsManager`\n9. [Monad](https://en.wikipedia.org/wiki/Monad_(functional_programming)) - `singleshot`, `cancelable`, `queued`, `cached`, `debounce`, `compose`, `trycatch`, `memoize`, `ttl`, `lock`\n10. [Composition](https://reactjs.org/docs/composition-vs-inheritance.html) - `VirtualView`, `InfiniteView`, `PortalView`, `RevealView`, `PingView`, `WaitView`, `FadeView`, `ScaleView`, `ScrollView`, `ModalManager`\n11. [HoC](https://reactjs.org/docs/higher-order-components.html) - `ConstraintView`, `AutoSizer`, `FetchView`, `Async`, `If`\n12. [Facade](https://en.wikipedia.org/wiki/Facade_pattern) - `Subject`, `Observer`\n13. [Scheduled-task](https://en.wikipedia.org/wiki/Scheduled-task_pattern) - `Task`, `singlerun`\n14. [RAD](https://en.wikipedia.org/wiki/Rapid_application_development) - `RecordView`, `CardView`\n15. [Functional](https://en.wikipedia.org/wiki/Functional_programming) - `useActualValue`, `useActualCallback`, `useActualState`, `useSearchParams`, `useSearchState`, `useChange`\n16. [Declarative](https://en.wikipedia.org/wiki/Declarative_programming) - `One`, `List`, `Scaffold`, `Scaffold2`, `RecordView`, `CardView`\n17. [Reactive](https://en.wikipedia.org/wiki/ReactiveX) - `EventEmitter`, `Subject`, `BehaviorSubject`, `Observer`\n18. [Lambda Architecture](https://en.wikipedia.org/wiki/Lambda_architecture) - `Source`, `Operator`, `useSource`, `useSubscription`\n19. [Aspect Oriented](https://en.wikipedia.org/wiki/Aspect-oriented_programming) - `serviceManager`, `Source`\n20. [Reflection](https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection) - `getAvailableFields`, `VisibilityView`\n21. [Pagination](https://medium.com/@oshiryaeva/offset-vs-cursor-based-pagination-which-is-the-right-choice-for-your-project-e46f65db062f) - `useOffsetPaginator`, `useCursorPaginator`\n22. [Feature model](https://en.wikipedia.org/wiki/Feature_model) - `useFeatureView`, `useVisibilityView`, `FeatureView`, `VisibilityView`\n23. [Software Fault Prevention](https://en.wikipedia.org/wiki/Software_fault_tolerance) - `ErrorBoundary`, `ErrorView`\n\n\u003cimg src=\"./assets/icons/cosmos.svg\" height=\"35px\" align=\"right\"\u003e\n\n## Philosophy notes\n\n1. [React: declarative vs imperative](./NOTES.md#react-declarative-vs-imperative)\n\n    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\n\n2. [Fractal pattern](./NOTES.md#fractal-pattern-fractal-project-structure)\n\n    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.\n\n3. [SOLID in react-declarative](./NOTES.md#solid-in-react-declarative)\n\n    SOLID principles described by simple words with examples in a source code\n\n4. [Product-oriented principles](./NOTES.md#product-oriented-principles)\n\n    These principles will help you to keep the code as clean as possible when you need to make a MVP immediately\n\n5. [Oriented graphs: reduce algoritm difficulty](./NOTES.md#reduce-algoritm-difficulty-when-working-with-oriented-graphs)\n\n    The real useful note for working with oriented graphs\n\n6. [Using underected data flow for building software product line](./NOTES.md#using-underected-data-flow-for-building-software-product-line)\n\n    Useful snippets to split procedure code with the inversion of control pattern\n\n7. [Frontend as a service bus for Service-Oriented Architecture (SOA)](./NOTES.md#frontend-as-a-service-bus-for-service-oriented-architecture-soa)\n\n    Serverless compution pros and no cons with react-declarative\n\n8. [Make SPA Java again](./NOTES.md#make-spa-java-again)\n\n    The problem of clean architecture in modern React apps\n\n\u003cimg src=\"./assets/icons/tree.svg\" height=\"65px\" align=\"right\"\u003e\n\n## License\n\n\u003e P.S. Got a question? Feel free to [write It in issues](https://github.com/react-declarative/react-declarative/issues), I need traffic\n\nMIT [@tripolskypetr](https://github.com/tripolskypetr)\n\n## External References\n\n1. [Playground](https://react-declarative-playground.github.io/)\n2. [Storybook](https://react-declarative.github.io/)\n3. [Typedoc](https://react-declarative-typedoc.github.io/)\n\n## Thanks\n\nDude, you reached that point, omg. Could you \n[Star it on GitHub](https://github.com/react-declarative/react-declarative) plz)\n\n","funding_links":["http://paypal.me/tripolskypetr"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-declarative%2Freact-declarative","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-declarative%2Freact-declarative","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-declarative%2Freact-declarative/lists"}