robobyte-front-builder 1.0.26 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INTEGRATION.md +6 -0
- package/LICENSE +65 -0
- package/README.md +166 -21
- package/docs/ReportViewer.md +581 -0
- package/docs/fetchReportData.md +379 -0
- package/docs/printLayout.md +405 -0
- package/package.json +29 -1
- package/src/lib/index.js +14 -0
- package/src/lib/muiTheme.js +655 -0
- package/src/lib/providers/RoboByteFrontBuilderProvider.jsx +45 -1
- package/src/pages/_app.js +1 -0
- package/src/pages/printBuilder/index.jsx +26 -19
- package/src/pages/viewBuilder/index.jsx +29 -19
- package/training/00-index.md +168 -0
- package/training/01-input.md +144 -0
- package/training/02-checkbox.md +107 -0
- package/training/03-dropdown.md +135 -0
- package/training/04-datepicker.md +139 -0
- package/training/05-radio.md +123 -0
- package/training/06-number.md +133 -0
- package/training/07-textarea.md +114 -0
- package/training/08-richtext.md +112 -0
- package/training/09-tag.md +110 -0
- package/training/10-time.md +107 -0
- package/training/11-toggle.md +108 -0
- package/training/12-signature.md +107 -0
- package/training/13-autocomplete.md +134 -0
- package/training/14-button.md +168 -0
- package/training/15-label.md +138 -0
- package/training/16-header.md +128 -0
- package/training/17-divider.md +96 -0
- package/training/18-image.md +105 -0
- package/training/19-link.md +108 -0
- package/training/20-banner.md +122 -0
- package/training/21-progress-circle.md +101 -0
- package/training/22-progress-line.md +93 -0
- package/training/23-menu.md +139 -0
- package/training/24-popover.md +114 -0
- package/training/25-layout.md +116 -0
- package/training/26-layout-cell.md +143 -0
- package/training/27-card.md +87 -0
- package/training/28-wizard.md +126 -0
- package/training/29-wizard-step.md +92 -0
- package/training/30-repeater.md +123 -0
- package/training/31-dialog.md +131 -0
- package/training/32-breadcrumb.md +121 -0
- package/training/33-dataGrid.md +129 -0
- package/training/34-dataTableViewer.md +115 -0
- package/training/35-reportViewer.md +673 -0
- package/training/36-viewRenderer.md +110 -0
- package/training/37-treeView.md +170 -0
- package/training/38-kpi-metric.md +148 -0
- package/training/39-kpi-trend.md +105 -0
- package/training/40-kpi-badge.md +112 -0
- package/training/41-kpi-statusDot.md +118 -0
- package/training/42-kpi-iconBox.md +114 -0
- package/training/43-kpi-gauge.md +143 -0
- package/training/44-kpi-bulletChart.md +126 -0
- package/training/45-kpi-colorScale.md +143 -0
- package/training/46-kpi-rating.md +125 -0
- package/training/47-kpi-countdown.md +151 -0
- package/training/48-fetchReportData.md +276 -0
- package/training/49-printLayout.md +215 -0
- package/training/examples/01-login-form.json +176 -0
- package/training/examples/02-contact-form.json +141 -0
- package/training/examples/03-kpi-cards-row.json +123 -0
- package/training/examples/04-settings-toggles.json +153 -0
- package/training/examples/05-user-profile-card.json +136 -0
- package/training/examples/06-date-range-filter.json +108 -0
- package/training/examples/07-search-bar-results.json +130 -0
- package/training/examples/08-notification-settings.json +131 -0
- package/training/examples/09-employee-profile-form.json +259 -0
- package/training/examples/10-invoice-form.json +241 -0
- package/training/examples/11-dashboard-overview.json +251 -0
- package/training/examples/12-registration-wizard.json +154 -0
- package/training/examples/13-product-catalog.json +168 -0
- package/training/examples/14-data-table-with-filters.json +180 -0
- package/training/examples/15-tabbed-profile.json +92 -0
- package/training/examples/16-kpi-full-row.json +203 -0
- package/training/examples/17-tree-detail-view.json +139 -0
- package/training/examples/18-employee-management.json +233 -0
- package/training/examples/19-sales-dashboard.json +272 -0
- package/training/examples/20-checkout-wizard.json +225 -0
- package/training/examples/21-analytics-page.json +222 -0
- package/training/examples/22-hr-onboarding.json +222 -0
- package/training/examples/23-document-browser.json +241 -0
- package/training/examples/24-order-management.json +290 -0
- package/training/examples/25-crm-contact-page.json +272 -0
|
@@ -46,10 +46,12 @@
|
|
|
46
46
|
import { useEffect, useMemo } from 'react'
|
|
47
47
|
import { useRouter } from 'next/router'
|
|
48
48
|
import { Toaster } from 'react-hot-toast'
|
|
49
|
+
import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles'
|
|
49
50
|
import { ModuleRegistry } from 'ag-grid-community'
|
|
50
51
|
import { AllEnterpriseModule, LicenseManager } from 'ag-grid-enterprise'
|
|
51
52
|
import { NavigationExtensionProvider } from '../navigation/NavigationExtensionContext'
|
|
52
53
|
import { AgGridThemeProvider } from '../agGridThemeContext'
|
|
54
|
+
import { buildMuiTheme, isResolvedMuiTheme, DEFAULT_MUI_THEME } from '../muiTheme'
|
|
53
55
|
import { configureRoboByte } from '../../services/config'
|
|
54
56
|
import { AuthContext } from '../../context/AuthContext'
|
|
55
57
|
import { setRouter } from '../../services/routerRef'
|
|
@@ -107,6 +109,26 @@ const RoboByteFrontBuilderProvider = ({
|
|
|
107
109
|
* pass a plain params object.
|
|
108
110
|
*/
|
|
109
111
|
agGridTheme = null,
|
|
112
|
+
/**
|
|
113
|
+
* Optional MUI theme overrides applied to every component the package
|
|
114
|
+
* renders. Three accepted shapes:
|
|
115
|
+
*
|
|
116
|
+
* 1. nothing (default) — uses DEFAULT_MUI_THEME from lib/muiTheme.js
|
|
117
|
+
* 2. theme options object — deep-merged on top of the defaults, e.g.
|
|
118
|
+
* muiTheme={{ palette: { primary: { main: '#6366f1' } }, shape: { borderRadius: 12 } }}
|
|
119
|
+
* 3. a pre-built MUI Theme — used as-is (escape hatch for full control)
|
|
120
|
+
*
|
|
121
|
+
* The package mounts a `<MuiThemeProvider>` wrapping children with the
|
|
122
|
+
* resolved theme. Host apps with their own outer `<ThemeProvider>` should
|
|
123
|
+
* pass their theme options here so the package's internal components share
|
|
124
|
+
* the host's visual identity.
|
|
125
|
+
*
|
|
126
|
+
* Pass `disableMuiTheme={true}` to skip the inner ThemeProvider entirely —
|
|
127
|
+
* use this when the host has already wrapped the app in its own
|
|
128
|
+
* ThemeProvider and wants it to win without merging.
|
|
129
|
+
*/
|
|
130
|
+
muiTheme = null,
|
|
131
|
+
disableMuiTheme = false,
|
|
110
132
|
toasterProps = {},
|
|
111
133
|
}) => {
|
|
112
134
|
// Apply URL + endpoint config synchronously before any child renders.
|
|
@@ -130,7 +152,29 @@ const RoboByteFrontBuilderProvider = ({
|
|
|
130
152
|
[user, accessToken]
|
|
131
153
|
)
|
|
132
154
|
|
|
133
|
-
|
|
155
|
+
// ── Resolve the MUI theme ────────────────────────────────────────────────
|
|
156
|
+
// Three cases:
|
|
157
|
+
// - disableMuiTheme: no wrapping ThemeProvider; host provides its own
|
|
158
|
+
// - muiTheme is a pre-built Theme: use as-is
|
|
159
|
+
// - muiTheme is null OR an options object: deep-merge with defaults
|
|
160
|
+
// JSON.stringify keys the memo so a fresh `{ palette: { ... } }` literal
|
|
161
|
+
// each render doesn't rebuild the theme. Resolved Themes (case 2) are
|
|
162
|
+
// expected to be stable from the caller's side.
|
|
163
|
+
const resolvedMuiTheme = useMemo(() => {
|
|
164
|
+
if (disableMuiTheme) return null
|
|
165
|
+
if (isResolvedMuiTheme(muiTheme)) return muiTheme
|
|
166
|
+
if (!muiTheme) return DEFAULT_MUI_THEME
|
|
167
|
+
return buildMuiTheme(muiTheme)
|
|
168
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
169
|
+
}, [disableMuiTheme, isResolvedMuiTheme(muiTheme) ? muiTheme : JSON.stringify(muiTheme ?? null)])
|
|
170
|
+
|
|
171
|
+
// Wrapper helper — applies MuiThemeProvider conditionally based on flag.
|
|
172
|
+
const withMuiTheme = (node) =>
|
|
173
|
+
disableMuiTheme
|
|
174
|
+
? node
|
|
175
|
+
: <MuiThemeProvider theme={resolvedMuiTheme}>{node}</MuiThemeProvider>
|
|
176
|
+
|
|
177
|
+
return withMuiTheme(
|
|
134
178
|
<AuthContext.Provider value={authValue}>
|
|
135
179
|
<NavigationExtensionProvider items={navExtensions}>
|
|
136
180
|
<AgGridThemeProvider params={agGridTheme}>
|
package/src/pages/_app.js
CHANGED
|
@@ -31,6 +31,7 @@ export default function App({ Component, pageProps }) {
|
|
|
31
31
|
user={DEV_USER}
|
|
32
32
|
accessToken={DEV_ACCESS_TOKEN}
|
|
33
33
|
agGridLicenseKey={process.env.NEXT_PUBLIC_AG_GRID_LICENSE_KEY}
|
|
34
|
+
agGridTheme={{ accentColor: '#3b82f6', headerHeight: 32 }}
|
|
34
35
|
>
|
|
35
36
|
{getLayout(<Component {...pageProps} />)}
|
|
36
37
|
</RoboByteFrontBuilderProvider>
|
|
@@ -11,30 +11,37 @@ import { Endpoints, Services } from 'services/Endpoints'
|
|
|
11
11
|
import { PRINT_COMPONENT_SECTIONS } from 'views/builder/sidebar/tabs/Components/printComponentCatalog'
|
|
12
12
|
import ComponentsTab from 'views/builder/sidebar/tabs/Components/ComponentsTab'
|
|
13
13
|
import TreeTab from 'views/builder/sidebar/tabs/TreeTab'
|
|
14
|
-
import {
|
|
14
|
+
import { buildMuiTheme } from 'src/lib/muiTheme'
|
|
15
15
|
|
|
16
|
-
// ── Builder themes
|
|
16
|
+
// ── Builder themes ────────────────────────────────────────────────────────────
|
|
17
|
+
// Deep-merge with the package's DEFAULT_MUI_THEME_OPTIONS so every component
|
|
18
|
+
// override (button polish, input focus halo, transitions, Inter typography,
|
|
19
|
+
// soft shadows) is inherited. The builder UI only overrides palette.
|
|
17
20
|
const _STORAGE_KEY = 'rbb:builderThemeMode'
|
|
18
21
|
const BUILDER_THEMES = {
|
|
19
|
-
dark:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
dark: buildMuiTheme(
|
|
23
|
+
{
|
|
24
|
+
palette: {
|
|
25
|
+
primary: { main: '#9c27b0' },
|
|
26
|
+
secondary: { main: '#f5a623' },
|
|
27
|
+
background: { default: '#141618', paper: '#1e2227' },
|
|
28
|
+
divider: '#3a3f45',
|
|
29
|
+
text: { primary: '#e8eaed', secondary: '#9aa0aa' },
|
|
30
|
+
},
|
|
27
31
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
{ mode: 'dark' }
|
|
33
|
+
),
|
|
34
|
+
light: buildMuiTheme(
|
|
35
|
+
{
|
|
36
|
+
palette: {
|
|
37
|
+
primary: { main: '#9c27b0' },
|
|
38
|
+
secondary: { main: '#f5a623' },
|
|
39
|
+
background: { default: '#f0f2f5', paper: '#ffffff' },
|
|
40
|
+
divider: '#dde1e7',
|
|
41
|
+
},
|
|
36
42
|
},
|
|
37
|
-
|
|
43
|
+
{ mode: 'light' }
|
|
44
|
+
),
|
|
38
45
|
}
|
|
39
46
|
function getBuilderThemeMode() {
|
|
40
47
|
try { return localStorage.getItem(_STORAGE_KEY) === 'light' ? 'light' : 'dark' } catch { return 'dark' }
|
|
@@ -9,30 +9,40 @@ import { useRouter } from 'next/router'
|
|
|
9
9
|
import { useEffect, useState } from 'react'
|
|
10
10
|
import { Endpoints, Services } from 'services/Endpoints'
|
|
11
11
|
import { ChevronLeft, ChevronRight } from '@mui/icons-material'
|
|
12
|
-
import {
|
|
12
|
+
import { buildMuiTheme } from 'src/lib/muiTheme'
|
|
13
13
|
|
|
14
|
-
// ── Builder themes
|
|
14
|
+
// ── Builder themes ────────────────────────────────────────────────────────────
|
|
15
|
+
// These deep-merge ON TOP of the package's DEFAULT_MUI_THEME_OPTIONS so every
|
|
16
|
+
// component override (button polish, input focus halo, transitions, soft
|
|
17
|
+
// shadows, Inter typography, …) is inherited. The builder UI just contributes
|
|
18
|
+
// its own palette (purple primary, gold secondary, builder-specific surface
|
|
19
|
+
// colors). Without this merge the builder pages used a bare-palette theme
|
|
20
|
+
// and looked completely different from the rest of the package.
|
|
15
21
|
const _STORAGE_KEY = 'rbb:builderThemeMode'
|
|
16
22
|
const BUILDER_THEMES = {
|
|
17
|
-
dark:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
dark: buildMuiTheme(
|
|
24
|
+
{
|
|
25
|
+
palette: {
|
|
26
|
+
primary: { main: '#9c27b0' },
|
|
27
|
+
secondary: { main: '#f5a623' },
|
|
28
|
+
background: { default: '#141618', paper: '#1e2227' },
|
|
29
|
+
divider: '#3a3f45',
|
|
30
|
+
text: { primary: '#e8eaed', secondary: '#9aa0aa' },
|
|
31
|
+
},
|
|
25
32
|
},
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
{ mode: 'dark' }
|
|
34
|
+
),
|
|
35
|
+
light: buildMuiTheme(
|
|
36
|
+
{
|
|
37
|
+
palette: {
|
|
38
|
+
primary: { main: '#9c27b0' },
|
|
39
|
+
secondary: { main: '#f5a623' },
|
|
40
|
+
background: { default: '#f0f2f5', paper: '#ffffff' },
|
|
41
|
+
divider: '#dde1e7',
|
|
42
|
+
},
|
|
34
43
|
},
|
|
35
|
-
|
|
44
|
+
{ mode: 'light' }
|
|
45
|
+
),
|
|
36
46
|
}
|
|
37
47
|
function getBuilderThemeMode() {
|
|
38
48
|
try { return localStorage.getItem(_STORAGE_KEY) === 'light' ? 'light' : 'dark' } catch { return 'dark' }
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# RoboByte Front Builder — Component Training Reference
|
|
2
|
+
|
|
3
|
+
Complete reference for all components. Use these files to train a local AI model to generate valid builder schemas.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Schema Structure
|
|
8
|
+
|
|
9
|
+
Every schema follows this structure:
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"root": { "type": "layout", "props": { "cols": 1 }, "children": [ ... ] },
|
|
13
|
+
"dialogs": [],
|
|
14
|
+
"actions": [],
|
|
15
|
+
"timers": []
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- **Root is always a `layout`** — never use `container` (banned).
|
|
20
|
+
- Direct children of `layout` must be `layout-cell` nodes.
|
|
21
|
+
- Each `layout-cell` contains one component (or a nested `layout` for complex layouts).
|
|
22
|
+
|
|
23
|
+
### Prop Wrapping (internal)
|
|
24
|
+
In the actual builder schema, props are wrapped in `{ valueType: 'value', value: ... }` objects. The AI generates **simplified** schemas (flat props), and the `schemaTransformer` wraps them automatically:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
// AI generates:
|
|
28
|
+
{ "type": "input", "props": { "key": "name", "label": "Name" }, "style": { "width": "100%" } }
|
|
29
|
+
|
|
30
|
+
// Builder stores internally:
|
|
31
|
+
{ "id": "cmp_xxx", "type": "input", "props": { "main": { "key": { "valueType": "value", "value": "name" }, "label": { "valueType": "value", "value": "Name" } }, "style": { "width": { "valueType": "value", "value": "100%" } }, "advanced": {} }, "children": [] }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Component Categories
|
|
37
|
+
|
|
38
|
+
### Field Components (Form Inputs)
|
|
39
|
+
| File | Component | Purpose |
|
|
40
|
+
|------|-----------|---------|
|
|
41
|
+
| 01-input.md | `input` | Single-line text input |
|
|
42
|
+
| 02-checkbox.md | `checkbox` | Boolean checkbox |
|
|
43
|
+
| 03-dropdown.md | `dropdown` | Select from list |
|
|
44
|
+
| 04-datepicker.md | `datepicker` | Date selection |
|
|
45
|
+
| 05-radio.md | `radio` | Mutually exclusive options |
|
|
46
|
+
| 06-number.md | `number` | Numeric input with formatting |
|
|
47
|
+
| 07-textarea.md | `textarea` | Multi-line text |
|
|
48
|
+
| 08-richtext.md | `richtext` | WYSIWYG HTML editor |
|
|
49
|
+
| 09-tag.md | `tag` | Multi-value chip input |
|
|
50
|
+
| 10-time.md | `time` | Time picker |
|
|
51
|
+
| 11-toggle.md | `toggle` | On/off switch |
|
|
52
|
+
| 12-signature.md | `signature` | Canvas signature pad |
|
|
53
|
+
| 13-autocomplete.md | `autocomplete` | Searchable select with async |
|
|
54
|
+
|
|
55
|
+
### Display Components
|
|
56
|
+
| File | Component | Purpose |
|
|
57
|
+
|------|-----------|---------|
|
|
58
|
+
| 14-button.md | `button` | Action button (submit/reset/custom) |
|
|
59
|
+
| 15-label.md | `label` | Body text display (MUI Typography) |
|
|
60
|
+
| 16-header.md | `header` | Heading text h1–h6 |
|
|
61
|
+
| 17-divider.md | `divider` | Horizontal/vertical separator line |
|
|
62
|
+
| 18-image.md | `image` | Image from URL |
|
|
63
|
+
| 19-link.md | `link` | Clickable hyperlink |
|
|
64
|
+
| 20-banner.md | `banner` | Alert/notification banner |
|
|
65
|
+
| 21-progress-circle.md | `progress-circle` | Circular progress indicator |
|
|
66
|
+
| 22-progress-line.md | `progress-line` | Horizontal progress bar |
|
|
67
|
+
| 23-menu.md | `menu` | Tab navigation bar |
|
|
68
|
+
| 24-popover.md | `popover` | Floating panel triggered by button |
|
|
69
|
+
|
|
70
|
+
### Structure Components
|
|
71
|
+
| File | Component | Purpose |
|
|
72
|
+
|------|-----------|---------|
|
|
73
|
+
| 25-layout.md | `layout` | CSS Grid container (PRIMARY STRUCTURE) |
|
|
74
|
+
| 26-layout-cell.md | `layout-cell` | Grid cell (child of layout) |
|
|
75
|
+
| 27-card.md | `card` | MUI card with title/subheader |
|
|
76
|
+
| 28-wizard.md | `wizard` | Multi-step stepper form |
|
|
77
|
+
| 29-wizard-step.md | `wizard-step` | Single step inside wizard |
|
|
78
|
+
| 30-repeater.md | `repeater` | Repeat template per data array item |
|
|
79
|
+
| 31-dialog.md | `dialog` | Modal overlay |
|
|
80
|
+
| 32-breadcrumb.md | `breadcrumb` | Navigation trail or step indicator |
|
|
81
|
+
|
|
82
|
+
### Data Components
|
|
83
|
+
| File | Component | Purpose |
|
|
84
|
+
|------|-----------|---------|
|
|
85
|
+
| 33-dataGrid.md | `dataGrid` | AG Grid editable table |
|
|
86
|
+
| 34-dataTableViewer.md | `dataTableViewer` | Simple read-only HTML table |
|
|
87
|
+
| 35-reportViewer.md | `reportViewer` | Server-fetched AG Grid report |
|
|
88
|
+
| 36-viewRenderer.md | `viewRenderer` | Embed another saved view |
|
|
89
|
+
| 37-treeView.md | `treeView` | Hierarchical tree component |
|
|
90
|
+
|
|
91
|
+
### KPI Components
|
|
92
|
+
| File | Component | Purpose |
|
|
93
|
+
|------|-----------|---------|
|
|
94
|
+
| 38-kpi-metric.md | `kpi-metric` | Single numeric KPI value |
|
|
95
|
+
| 39-kpi-trend.md | `kpi-trend` | Delta/change with direction icon |
|
|
96
|
+
| 40-kpi-badge.md | `kpi-badge` | Colored status chip/badge |
|
|
97
|
+
| 41-kpi-statusDot.md | `kpi-statusDot` | Small status indicator dot |
|
|
98
|
+
| 42-kpi-iconBox.md | `kpi-iconBox` | Boxed icon with threshold coloring |
|
|
99
|
+
| 43-kpi-gauge.md | `kpi-gauge` | Semicircular arc gauge |
|
|
100
|
+
| 44-kpi-bulletChart.md | `kpi-bulletChart` | Bullet chart (actual vs target) |
|
|
101
|
+
| 45-kpi-colorScale.md | `kpi-colorScale` | Color-scale bar with markers |
|
|
102
|
+
| 46-kpi-rating.md | `kpi-rating` | Star/heart/circle rating |
|
|
103
|
+
| 47-kpi-countdown.md | `kpi-countdown` | Countdown timer to a target date |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Universal Style Props (available on every component's style tab)
|
|
108
|
+
|
|
109
|
+
Every component style tab supports two escape-hatch props for arbitrary CSS:
|
|
110
|
+
|
|
111
|
+
| Prop | Type | Notes |
|
|
112
|
+
|------|------|-------|
|
|
113
|
+
| `elementStyle` | expression | CSS **object** merged at highest priority onto the component wrapper. E.g. `{ outline: '2px solid #f00', transition: 'all 0.2s' }`. |
|
|
114
|
+
| `elementCss` | expression | CSS **string** merged at highest priority. Use when you need shorthand syntax that's hard to express as a JS object. E.g. `"outline: 2px solid red; background: linear-gradient(135deg, #667eea, #764ba2)"`. |
|
|
115
|
+
|
|
116
|
+
> `elementCss` takes effect after `elementStyle`. Both are processed and merged last, so they override ALL other style tab settings.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Critical Rules
|
|
121
|
+
|
|
122
|
+
1. **Root must be `layout`** — never `container` (banned).
|
|
123
|
+
2. **`layout` children must be `layout-cell`** — no other components directly.
|
|
124
|
+
3. **One component per cell** for multi-column layouts (`cols ≥ 2`). For single-column (`cols: 1`), cells can contain nested layouts.
|
|
125
|
+
4. **Use `style` key** (not inside `props`) for layout-cell visual styling: `backgroundColor`, `padding`, `borderRadius`, `boxShadow`.
|
|
126
|
+
5. **Use `props` key** for component behavior props: `key`, `label`, `value`, etc.
|
|
127
|
+
6. **Data is accessed via expressions**: `data.fieldName`, `form.fieldName`, `dataItem.field` (inside repeater).
|
|
128
|
+
7. **Dialogs are siblings of root**, not nested inside it.
|
|
129
|
+
8. **KPI components are leaf nodes** — they have no children.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Quick Decision Guide
|
|
134
|
+
|
|
135
|
+
| Need | Component |
|
|
136
|
+
|------|-----------|
|
|
137
|
+
| Text input | `input` |
|
|
138
|
+
| Multi-line text | `textarea` |
|
|
139
|
+
| Rich formatted text | `richtext` |
|
|
140
|
+
| Number with formatting | `number` |
|
|
141
|
+
| Date | `datepicker` |
|
|
142
|
+
| Time | `time` |
|
|
143
|
+
| Yes/No toggle | `toggle` or `checkbox` |
|
|
144
|
+
| Select one from list | `dropdown` (small list) or `autocomplete` (large/async) |
|
|
145
|
+
| Select multiple | `dropdown` + `multiple: true` or `tag` |
|
|
146
|
+
| Select mutually exclusive (visible) | `radio` |
|
|
147
|
+
| Signature capture | `signature` |
|
|
148
|
+
| Display text | `label` |
|
|
149
|
+
| Display heading | `header` |
|
|
150
|
+
| Display number/metric | `kpi-metric` |
|
|
151
|
+
| Display status | `kpi-badge` or `kpi-statusDot` |
|
|
152
|
+
| Display trend | `kpi-trend` |
|
|
153
|
+
| Display gauge | `kpi-gauge` |
|
|
154
|
+
| Display progress | `progress-line` or `progress-circle` |
|
|
155
|
+
| Display table (static) | `dataTableViewer` |
|
|
156
|
+
| Display table (server) | `reportViewer` |
|
|
157
|
+
| Editable table | `dataGrid` |
|
|
158
|
+
| Tree hierarchy | `treeView` |
|
|
159
|
+
| Embed another view | `viewRenderer` |
|
|
160
|
+
| Repeat a template | `repeater` |
|
|
161
|
+
| Multi-step form | `wizard` + `wizard-step` |
|
|
162
|
+
| Tabs | `menu` |
|
|
163
|
+
| Modal | `dialog` |
|
|
164
|
+
| Floating panel | `popover` |
|
|
165
|
+
| Navigation trail | `breadcrumb` |
|
|
166
|
+
| Alert/notification | `banner` |
|
|
167
|
+
| Action button | `button` |
|
|
168
|
+
| Page structure | `layout` + `layout-cell` |
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Component: input
|
|
2
|
+
|
|
3
|
+
A single-line text input field. Supports labels, placeholders, icons, and real-time validation feedback.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Props — Main Tab
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Options / Notes |
|
|
10
|
+
|------|------|-----------------|
|
|
11
|
+
| `key` | expression | Unique identifier. The user's typed value is stored in `data[key]` and `form[key]`. |
|
|
12
|
+
| `label` | expression | Label text shown above/beside the field. |
|
|
13
|
+
| `labelPosition` | select | `top` · `left` · `right` · `none` |
|
|
14
|
+
| `required` | boolean | Marks field as required; shows asterisk on label. |
|
|
15
|
+
| `value` | expression | Initial/controlled value. Bind to `data.someKey` to pre-fill. |
|
|
16
|
+
| `placeholder` | text | Greyed hint text shown when empty. |
|
|
17
|
+
| `size` | select | `small` · `medium` · `large` |
|
|
18
|
+
| `prefix` | icon | MUI icon displayed at the start of the input. |
|
|
19
|
+
| `suffix` | icon | MUI icon displayed at the end of the input. |
|
|
20
|
+
| `labelPrefix` | icon | Icon displayed before the label text. |
|
|
21
|
+
| `labelSuffix` | icon | Icon displayed after the label text. |
|
|
22
|
+
| `labelIconSize` | expression | Size of label icons, e.g. `"18px"`. |
|
|
23
|
+
| `labelIconColor` | expression | Color of label icons, e.g. `"primary.main"`. |
|
|
24
|
+
| `labelFontSize` | expression | Label text size, e.g. `"14px"`. |
|
|
25
|
+
| `labelFontWeight` | expression | Label font weight, e.g. `"600"`. |
|
|
26
|
+
| `labelColor` | expression | Label text color, e.g. `"#333"` or `"text.secondary"`. |
|
|
27
|
+
| `labelFontStyle` | select | `normal` · `italic` · `oblique` |
|
|
28
|
+
| `labelLetterSpacing` | expression | Letter spacing for label, e.g. `"0.05em"`. |
|
|
29
|
+
| `disabled` | boolean | Disables the field entirely. |
|
|
30
|
+
| `enabled` | boolean | Enables/disables the field from an expression, e.g. `data.isEditable`. |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Props — Style Tab
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Options / Notes |
|
|
37
|
+
|------|------|-----------------|
|
|
38
|
+
| `elementStyle` | expression | CSS object applied directly to the component wrapper as a style override. Highest priority. E.g. `{ outline: '2px solid red' }`. |
|
|
39
|
+
| `elementCss` | expression | CSS string applied to the component wrapper. Alternative to `elementStyle` for shorthand CSS. E.g. `"outline: 2px solid red; transition: all 0.2s"`. |
|
|
40
|
+
| `color` | select | `default` · `primary` · `secondary` · `error` · `warning` · `info` · `success` — MUI color variant for the field border/focus ring. |
|
|
41
|
+
| `display` | expression | CSS display, e.g. `"flex"`. |
|
|
42
|
+
| `width` | expression | Field width, e.g. `"100%"` or `"320px"`. |
|
|
43
|
+
| `height` | expression | Field height override. |
|
|
44
|
+
| `margin` | expression | Outer spacing, e.g. `"0 8px"`. |
|
|
45
|
+
| `padding` | expression | Inner padding override. |
|
|
46
|
+
| `flexDirection` | select | `row` · `column` · `row-reverse` · `column-reverse` |
|
|
47
|
+
| `justifyContent` | select | `flex-start` · `center` · `flex-end` · `space-between` · `space-around` · `space-evenly` |
|
|
48
|
+
| `alignItems` | select | `flex-start` · `center` · `flex-end` · `stretch` · `baseline` |
|
|
49
|
+
| `gap` | expression | Gap between label and input when stacked. |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Props — Actions Tab
|
|
54
|
+
|
|
55
|
+
| Event | Type | Notes |
|
|
56
|
+
|-------|------|-------|
|
|
57
|
+
| `onChange` | action (custom) | Fires every time the user changes the input value. Use to trigger calculations, show/hide elements, or call APIs. |
|
|
58
|
+
| `onBlur` | action (custom) | Fires when the field loses focus. Use for validation or save-on-leave patterns. |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Use Cases
|
|
63
|
+
|
|
64
|
+
**When to use:**
|
|
65
|
+
- Collecting short free-text: names, emails, usernames, search queries, addresses.
|
|
66
|
+
- Any single-line form field that needs validation or a label.
|
|
67
|
+
- Fields requiring icons (e.g. a search icon prefix or password-eye suffix).
|
|
68
|
+
|
|
69
|
+
**When NOT to use:**
|
|
70
|
+
- Multi-line text → use `textarea` or `richtext`.
|
|
71
|
+
- Number input with formatting → use `number`.
|
|
72
|
+
- Date input → use `datepicker`.
|
|
73
|
+
- Selection from a list → use `dropdown`, `radio`, or `autocomplete`.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Schema Examples
|
|
78
|
+
|
|
79
|
+
### Minimal text input
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"type": "input",
|
|
83
|
+
"props": {
|
|
84
|
+
"key": "firstName",
|
|
85
|
+
"label": "First Name",
|
|
86
|
+
"placeholder": "Enter your first name",
|
|
87
|
+
"required": true
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Pre-filled, sized, with icons
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"type": "input",
|
|
96
|
+
"props": {
|
|
97
|
+
"key": "email",
|
|
98
|
+
"label": "Email Address",
|
|
99
|
+
"labelPosition": "top",
|
|
100
|
+
"value": "data.userEmail",
|
|
101
|
+
"placeholder": "user@example.com",
|
|
102
|
+
"prefix": "EmailOutlined",
|
|
103
|
+
"size": "medium",
|
|
104
|
+
"required": true
|
|
105
|
+
},
|
|
106
|
+
"style": {
|
|
107
|
+
"width": "100%",
|
|
108
|
+
"color": "primary"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Disabled read-only field
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"type": "input",
|
|
117
|
+
"props": {
|
|
118
|
+
"key": "userId",
|
|
119
|
+
"label": "User ID",
|
|
120
|
+
"value": "data.userId",
|
|
121
|
+
"labelPosition": "left",
|
|
122
|
+
"disabled": true
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### With onChange action
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"type": "input",
|
|
131
|
+
"props": {
|
|
132
|
+
"key": "searchQuery",
|
|
133
|
+
"label": "Search",
|
|
134
|
+
"prefix": "SearchOutlined",
|
|
135
|
+
"placeholder": "Type to filter..."
|
|
136
|
+
},
|
|
137
|
+
"actions": {
|
|
138
|
+
"onChange": {
|
|
139
|
+
"type": "custom",
|
|
140
|
+
"code": "setData({ filteredList: data.fullList.filter(i => i.name.includes(form.searchQuery)) })"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Component: checkbox
|
|
2
|
+
|
|
3
|
+
A boolean toggle rendered as a checkbox. Stores `true`/`false` in `data[key]`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Props — Main Tab
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Options / Notes |
|
|
10
|
+
|------|------|-----------------|
|
|
11
|
+
| `key` | expression | Unique identifier. Value stored as boolean in `data[key]` and `form[key]`. |
|
|
12
|
+
| `label` | expression | Label text shown next to the checkbox. |
|
|
13
|
+
| `labelPosition` | select | `top` · `left` · `right` · `none` |
|
|
14
|
+
| `required` | boolean | Marks field required. |
|
|
15
|
+
| `value` | expression | Controlled checked state, e.g. `data.isActive`. |
|
|
16
|
+
| `size` | select | `small` · `medium` · `large` |
|
|
17
|
+
| `disabled` | boolean | Prevents toggling. |
|
|
18
|
+
| `enabled` | boolean | Enable/disable from an expression. |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Props — Style Tab
|
|
23
|
+
|
|
24
|
+
Same as Input style tab:
|
|
25
|
+
|
|
26
|
+
| Prop | Type | Options / Notes |
|
|
27
|
+
|------|------|-----------------|
|
|
28
|
+
| `color` | select | `default` · `primary` · `secondary` · `error` · `warning` · `info` · `success` |
|
|
29
|
+
| `display` | expression | CSS display override. |
|
|
30
|
+
| `width` | expression | Wrapper width. |
|
|
31
|
+
| `height` | expression | Wrapper height. |
|
|
32
|
+
| `margin` | expression | Outer margin. |
|
|
33
|
+
| `padding` | expression | Inner padding. |
|
|
34
|
+
| `flexDirection` | select | `row` · `column` · `row-reverse` · `column-reverse` |
|
|
35
|
+
| `justifyContent` | select | `flex-start` · `center` · `flex-end` · `space-between` · `space-around` · `space-evenly` |
|
|
36
|
+
| `alignItems` | select | `flex-start` · `center` · `flex-end` · `stretch` · `baseline` |
|
|
37
|
+
| `gap` | expression | Gap between elements. |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Props — Actions Tab
|
|
42
|
+
|
|
43
|
+
| Event | Type | Notes |
|
|
44
|
+
|-------|------|-------|
|
|
45
|
+
| `onChange` | action (custom) | Fires when the checkbox is toggled. The new value is in `form[key]`. |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Use Cases
|
|
50
|
+
|
|
51
|
+
**When to use:**
|
|
52
|
+
- Accept terms & conditions.
|
|
53
|
+
- Boolean flags on forms: `isActive`, `rememberMe`, `newsletter`.
|
|
54
|
+
- Feature toggles in a settings panel.
|
|
55
|
+
- Multi-select when combined with multiple checkboxes (or use `tag`/`dropdown multiple`).
|
|
56
|
+
|
|
57
|
+
**When NOT to use:**
|
|
58
|
+
- Mutually exclusive options → use `radio`.
|
|
59
|
+
- On/Off toggle with a different appearance → use `toggle`.
|
|
60
|
+
- Multiple-choice with a list → use `dropdown` with `multiple: true`.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Schema Examples
|
|
65
|
+
|
|
66
|
+
### Simple boolean checkbox
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"type": "checkbox",
|
|
70
|
+
"props": {
|
|
71
|
+
"key": "acceptTerms",
|
|
72
|
+
"label": "I accept the terms and conditions",
|
|
73
|
+
"required": true
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Controlled with expression
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"type": "checkbox",
|
|
82
|
+
"props": {
|
|
83
|
+
"key": "isActive",
|
|
84
|
+
"label": "Active",
|
|
85
|
+
"value": "data.record.isActive",
|
|
86
|
+
"labelPosition": "right",
|
|
87
|
+
"color": "success"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### With onChange
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"type": "checkbox",
|
|
96
|
+
"props": {
|
|
97
|
+
"key": "showDetails",
|
|
98
|
+
"label": "Show additional details"
|
|
99
|
+
},
|
|
100
|
+
"actions": {
|
|
101
|
+
"onChange": {
|
|
102
|
+
"type": "custom",
|
|
103
|
+
"code": "setData({ detailsVisible: form.showDetails })"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|