UNPKG

@apexcura/ui-builder

Version:

A low-code UI builder library for dynamic form generation and reusable components built with React, Redux, Tailwind, and Ant Design.

312 lines (269 loc) 8.41 kB
# @apexcura/ui-builder A **powerful, JSON Schema-driven UI renderer** built for React applications. It handles everything — from rendering UI elements to managing state via Redux, making API calls, handling validations, and defining event flows — all configurable through a single JSON schema. > ⚡ Declarative. Scalable. Developer-friendly. --- ## ✨ Features * 🧹 **Schema-Driven UI Rendering** Define forms, tables, dashboards, charts, and dynamic layouts using a flexible JSON structure. * 🧠 **State Management with Redux Toolkit** Automatically sets up Redux stores, reducers, actions, and selectors for your UI based on the schema. * 🔁 **Built-in API Integration** Perform GET, POST, PUT, DELETE requests — all defined declaratively in the schema. * ⚙️ **Event Handling Without Code** Manage click handlers, form submissions, conditional rendering, and navigation using event maps. * 💿 **Redux Persist Support** Automatically persists state across sessions. * 🎨 **TailwindCSS + Ant Design UI** Combines the flexibility of Tailwind with the power of Ant Design components. * 📊 **Highcharts Support** Render charts using `highcharts` and `highcharts-react-official` directly from JSON. * 🔐 **Form Validations, Modals, Toasts, Print View, Rich Text, and More** All natively supported via schema keys. --- ## 🚀 Get Started ### Installation ```bash npm install @apexcura/ui-builder ``` > ⚠️ Make sure to install the required peer dependencies: ```bash npm install react react-dom react-redux @reduxjs/toolkit redux-thunk redux-persist react-router-dom ``` > ℹ️ Add required CSS imports to your main application file: ```bash import '@apexcura/ui-builder/dist/styles/index.css'; ``` --- ## 🛠 Usage Inside the project's reducers list add dynamicStateReducer also into it with name dynamic ```tsx import { combineReducers } from "@reduxjs/toolkit"; import { resetState } from "./actions"; import { dynamicStateReducer } from "@apexcura/ui-builder"; // Package Slice import appStateReducer from "./appState/appStateSlice"; // Project slice const appReducer = combineReducers({ appState: appStateReducer, dynamic: dynamicStateReducer, // UIBuilder's state slice }); const rootReducer = (state: RootState | undefined, action: any): RootState => { if (action.type === resetState.type) { state = undefined; } return appReducer(state, action); }; export default rootReducer; export type RootState = ReturnType<typeof appReducer>; ``` Create a wrapper component that provides the necessary context: ```tsx // src/index.tsx function App() { return ( <ACWrapperContext props={{ constants: CONSTANTS, // constants if you have any store: store, // redux store object utils: Utils, // Utils object of that project (which contains makeApiCall function) }} > <Provider store={store}> ... </Provider> </ACWrapperContext> ); } ``` > ℹ️ As each project has its own api calling patterns along with their own base urls, our library directly call the project's api functions using project's base urls only --- ## Creating Your First View Define a schema and use the UIBuilder component to render it: ```tsx import { UIBuilder } from "@apexcura/ui-builder"; import useAppNavigate from "../../hooks/useAppNavigate"; import basicSchema from "../../schemas/basicSchema.json"; const BasicExample = () => { const navigate = useAppNavigate(); // you can use useNavigate hook also return <UIBuilder json={basicSchema} navigate={navigate} />; }; export default BasicExample; ``` --- ## 📄 Example Schema ```json { "name": "basic-example-form", "schema": [ { "name": "physio_evaluation", "initial_states": { "org_name": "@localStorage.organization.name" }, "className": "w-full flex bg-white rounded-md p-2 py-6", "fields": [ { "name": "name", "label": "First Name", "element": "input-text", "required": true, "placeholder": "Eg: Jon Doe", "color": "primary", "valueSource": { "storedLocation": "patient_details.first_name" }, "handlers": [ { "action": "changeState", "type": "onChange", "args": { "storedLocation": "patient_details.first_name" } } ] }, { "name": "phno", "label": "Phone number", "element": "input-number", "required": true, "placeholder": "Eg: 9123456789", "color": "primary", "valueSource": { "storedLocation": "patient_details.phno" }, "handlers": [ { "action": "changeState", "type": "onChange", "args": { "storedLocation": "patient_details.phno" } } ] }, { "name": "btn-cancel", "label": "Previous", "element": "button", "variant": "outlined", "color": "primary", "iconClassName": "aci-left-arrow aci-dynamic-size size-[12px]", "handlers": [ { "action": "changeState", "args": { "storedLocation": "selectedTab", "value": "patient_details" } } ] }, { "name": "btn-submit", "label": "Save and next", "iconClassName": "aci-right-arrow aci-dynamic-size size-[12px]", "iconPosition": "right", "element": "button", "variant": "solid", "handlers": [ { "action": "validateForm", "args": { "onTrue": [ { "action": "makeApiCall", "args": { "api": { "endpoint": "/addPatient", "method": "POST", "payload": { "patient_umr": "@state.patient_details.uhid", "formData": "@state.patient_details" }, "onSuccess": [ { "action": "displayToast", "args": { "type": "success", "message": "Patient added successfully!!!" } } ] } } } ] } } ] }, { "name": "effects", "handlers": [ { "action": "makeApiCall", "args": { "api": { "endpoint": "/patient/${patient_id}", "method": "GET", "params": { "patient_id": "@state.patient_id" }, "onSuccess": [ { "action": "changeState", "args": { "storedLocation": "patient_details_resp" } } ], "onFailure": [ { "action": "displayToast", "args": { "type": "error", "message": "Unable to fetch details" } } ] } }, "dependencies": ["patient_id"] } ] } ], "handlers": [] } ] } ``` --- ## 🧪 Development ### Build the project: ```bash npm install npm run build ``` ### Watch for changes during development: ```bash npm run watch ``` ### Lint and format code: ```bash npm run lint npm run format ``` --- ## 🧹 Built With * ⚛️ React 18 * 🧰 Redux Toolkit * 💿 Redux Persist * 🧠 Redux Thunk * 🎨 TailwindCSS + Ant Design * 📊 Highcharts * 📄 React Quill * 🖰 React To Print * 📦 Webpack --- ## 📘 License ISC © \[Apex Cura HealthCare]