@ea-lab/reactive-json-docs 0.8.0 → 1.0.0-alpha.0
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/package.json +7 -5
- package/public/rjbuild/docs/advanced-concepts/plugins/plugin-system.md +47 -1
- package/public/rjbuild/docs/advanced-concepts/plugins/plugin-system.yaml +53 -1
- package/public/rjbuild/docs/core/dataMapping/simpleMapping.yaml +14 -4
- package/public/rjbuild/docs/core/element/form/Input.md +307 -0
- package/public/rjbuild/docs/core/element/form/Input.yaml +572 -0
- package/public/rjbuild/docs/core/element/special/Count.yaml +99 -31
- package/public/rjbuild/docs/core/element/special/DataFilter.yaml +118 -38
- package/public/rjbuild/docs/core/element/special/ReactiveJsonSubroot.yaml +154 -34
- package/public/rjbuild/docs/core/element/special/Switch.md +5 -5
- package/public/rjbuild/docs/core/element/special/Switch.yaml +9 -18
- package/public/rjbuild/docs/core/example/html.md +2 -2
- package/public/rjbuild/docs/core/example/html.yaml +2 -3
- package/public/rjbuild/docs/core/example/native-html-forms.md +245 -0
- package/public/rjbuild/docs/core/example/native-html-forms.yaml +393 -0
- package/public/rjbuild/docs/core/reaction/addData.md +17 -3
- package/public/rjbuild/docs/core/reaction/addData.yaml +53 -9
- package/public/rjbuild/docs/core/reaction/fetchData.yaml +44 -8
- package/public/rjbuild/docs/core/reaction/setData.md +18 -4
- package/public/rjbuild/docs/core/reaction/setData.yaml +18 -4
- package/public/rjbuild/docs/docs-components/Mermaid.md +254 -0
- package/public/rjbuild/docs/docs-components/Mermaid.yaml +339 -0
- package/public/rjbuild/docs/docs-components/index.yaml +1 -0
- package/public/rjbuild/docs/getting-started/actions.md +1 -1
- package/public/rjbuild/docs/index.yaml +2 -1
- package/public/rjbuild/docs/install.md +2 -5
- package/public/rjbuild/docs/install.yaml +4 -10
- package/public/rjbuild/docs/{core → integration/bootstrap}/action/Popover.md +1 -1
- package/public/rjbuild/docs/{core → integration/bootstrap}/action/Tooltip.md +1 -1
- package/public/rjbuild/docs/integration/bootstrap/element/html/AccordionItem.md +69 -0
- package/public/rjbuild/docs/integration/bootstrap/element/html/Modal.md +127 -0
- package/public/rjbuild/docs/integration/bootstrap/element/html/Tabs.md +150 -0
- package/public/rjbuild/docs/integration/bootstrap/element/html/index.md +13 -0
- package/public/rjbuild/docs/integration/bootstrap/element/special/index.md +19 -0
- package/public/rjbuild/docs/integration/bootstrap/example/website.md +41 -0
- package/public/rjbuild/docs/integration/bootstrap/overview.md +69 -0
- package/public/rjbuild/docs/integration/bootstrap/overview.yaml +87 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/action/Popover.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/action/Tooltip.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/CheckBoxField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/CheckBoxField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/DateField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/DateField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/NumberField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/NumberField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/SelectField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/SelectField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextAreaField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextAreaField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/formElementsCommon.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/index.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/index.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/AccordionItem.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/Modal.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/Tabs.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/special/BootstrapElement.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/special/BootstrapElement.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/accordion.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/accordion.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/dynamic-content.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/dynamic-content.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/website.yaml +0 -0
- /package/public/rjbuild/docs/{chartjs → integration/chartjs}/components.yaml +0 -0
- /package/public/rjbuild/docs/{chartjs → integration/chartjs}/overview.yaml +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ea-lab/reactive-json-docs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-alpha.0",
|
|
4
4
|
"description": "Complete documentation for Reactive-JSON - Components, examples and LLM-parsable guides",
|
|
5
5
|
"main": "public/rjbuild/docs/index.yaml",
|
|
6
6
|
"files": [
|
|
@@ -26,17 +26,17 @@
|
|
|
26
26
|
"private": false,
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@craco/craco": "^7.1.0",
|
|
29
|
-
"@ea-lab/reactive-json": "^0.
|
|
30
|
-
"@ea-lab/reactive-json-chartjs": "^0.0
|
|
29
|
+
"@ea-lab/reactive-json": "^1.0.0-alpha.6",
|
|
30
|
+
"@ea-lab/reactive-json-chartjs": "^1.0.0",
|
|
31
31
|
"@npmcli/fs": "^4.0.0",
|
|
32
32
|
"@reduxjs/toolkit": "^2.6.1",
|
|
33
33
|
"@testing-library/jest-dom": "^6.6.3",
|
|
34
34
|
"@testing-library/react": "^16.3.0",
|
|
35
35
|
"@testing-library/user-event": "^14.6.1",
|
|
36
|
-
"bootstrap": "^5.3.
|
|
36
|
+
"bootstrap": "^5.3.7",
|
|
37
37
|
"lodash": "^4.17.21",
|
|
38
38
|
"react": "^19.1.0",
|
|
39
|
-
"react-bootstrap": "^2.10.
|
|
39
|
+
"react-bootstrap": "^2.10.10",
|
|
40
40
|
"react-dom": "^19.1.0",
|
|
41
41
|
"react-markdown": "^10.1.0",
|
|
42
42
|
"react-redux": "^9.2.0",
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
]
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
+
"@ea-lab/reactive-json-bootstrap": "^0.0.2",
|
|
81
|
+
"mermaid": "^11.10.1",
|
|
80
82
|
"remark-gfm": "^4.0.1"
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -109,6 +109,51 @@ const App = () => {
|
|
|
109
109
|
};
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
### Component Override Behavior
|
|
113
|
+
|
|
114
|
+
When using `mergeComponentCollections` with multiple plugins, **the last component with a given name takes precedence**. This allows you to override default components with custom implementations.
|
|
115
|
+
|
|
116
|
+
```jsx
|
|
117
|
+
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
|
|
118
|
+
import { defaultComponents } from "@ea-lab/reactive-json";
|
|
119
|
+
import { customComponents } from "./plugins/customComponents.js";
|
|
120
|
+
|
|
121
|
+
const plugins = mergeComponentCollections([
|
|
122
|
+
defaultComponents, // Contains a "Button" component
|
|
123
|
+
customComponents // Also contains a "Button" component - this one will be used
|
|
124
|
+
]);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This override mechanism is particularly useful for:
|
|
128
|
+
|
|
129
|
+
- **Customizing default components**: Replace built-in components with your own implementations
|
|
130
|
+
- **Theme customization**: Override components to match your design system
|
|
131
|
+
- **Feature enhancement**: Add functionality to existing components
|
|
132
|
+
- **Third-party integration**: Replace components with versions from external libraries
|
|
133
|
+
|
|
134
|
+
**Example: Overriding a Default Button**
|
|
135
|
+
|
|
136
|
+
```jsx
|
|
137
|
+
// Default plugin has a basic Button
|
|
138
|
+
const defaultPlugin = {
|
|
139
|
+
element: {
|
|
140
|
+
Button: BasicButton // Simple button implementation
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Your custom plugin overrides it
|
|
145
|
+
const customPlugin = {
|
|
146
|
+
element: {
|
|
147
|
+
Button: EnhancedButton // Button with animations and custom styling
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// EnhancedButton will be used everywhere "Button" is referenced
|
|
152
|
+
const plugins = mergeComponentCollections([defaultPlugin, customPlugin]);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**⚠️ Important**: Component names must match exactly (case-sensitive) for the override to work. The order in the `mergeComponentCollections` array determines precedence.
|
|
156
|
+
|
|
112
157
|
### Custom ReactiveJsonRoot Wrapper
|
|
113
158
|
|
|
114
159
|
Creating a custom wrapper allows you to **centralize plugin inclusion** across your entire application. Instead of manually importing and merging plugins in every component that uses Reactive-JSON, you define them once in a wrapper component.
|
|
@@ -172,4 +217,5 @@ export const ReportPage = () => {
|
|
|
172
217
|
2. **Use descriptive names** for components and plugins
|
|
173
218
|
3. **Document component props** and usage patterns
|
|
174
219
|
4. **Provide examples** for complex components
|
|
175
|
-
5. **
|
|
220
|
+
5. **Be intentional with component names** - use unique names unless you specifically want to override existing components
|
|
221
|
+
6. **Document overrides** when replacing default components to help other developers understand the customization
|
|
@@ -124,6 +124,57 @@ renderView:
|
|
|
124
124
|
|
|
125
125
|
- type: Markdown
|
|
126
126
|
content: |
|
|
127
|
+
### Component Override Behavior
|
|
128
|
+
|
|
129
|
+
When using `mergeComponentCollections` with multiple plugins, **the last component with a given name takes precedence**. This allows you to override default components with custom implementations.
|
|
130
|
+
|
|
131
|
+
- type: SyntaxHighlighter
|
|
132
|
+
language: jsx
|
|
133
|
+
content: |
|
|
134
|
+
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
|
|
135
|
+
import { defaultComponents } from "@ea-lab/reactive-json";
|
|
136
|
+
import { customComponents } from "./plugins/customComponents.js";
|
|
137
|
+
|
|
138
|
+
const plugins = mergeComponentCollections([
|
|
139
|
+
defaultComponents, // Contains a "Button" component
|
|
140
|
+
customComponents // Also contains a "Button" component - this one will be used
|
|
141
|
+
]);
|
|
142
|
+
|
|
143
|
+
- type: Markdown
|
|
144
|
+
content: |
|
|
145
|
+
This override mechanism is particularly useful for:
|
|
146
|
+
|
|
147
|
+
- **Customizing default components**: Replace built-in components with your own implementations
|
|
148
|
+
- **Theme customization**: Override components to match your design system
|
|
149
|
+
- **Feature enhancement**: Add functionality to existing components
|
|
150
|
+
- **Third-party integration**: Replace components with versions from external libraries
|
|
151
|
+
|
|
152
|
+
**Example: Overriding a Default Button**
|
|
153
|
+
|
|
154
|
+
- type: SyntaxHighlighter
|
|
155
|
+
language: jsx
|
|
156
|
+
content: |
|
|
157
|
+
// Default plugin has a basic Button
|
|
158
|
+
const defaultPlugin = {
|
|
159
|
+
element: {
|
|
160
|
+
Button: BasicButton // Simple button implementation
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Your custom plugin overrides it
|
|
165
|
+
const customPlugin = {
|
|
166
|
+
element: {
|
|
167
|
+
Button: EnhancedButton // Button with animations and custom styling
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// EnhancedButton will be used everywhere "Button" is referenced
|
|
172
|
+
const plugins = mergeComponentCollections([defaultPlugin, customPlugin]);
|
|
173
|
+
|
|
174
|
+
- type: Markdown
|
|
175
|
+
content: |
|
|
176
|
+
**⚠️ Important**: Component names must match exactly (case-sensitive) for the override to work. The order in the `mergeComponentCollections` array determines precedence.
|
|
177
|
+
|
|
127
178
|
### Custom ReactiveJsonRoot Wrapper
|
|
128
179
|
|
|
129
180
|
Creating a custom wrapper allows you to **centralize plugin inclusion** across your entire application. Instead of manually importing and merging plugins in every component that uses Reactive-JSON, you define them once in a wrapper component.
|
|
@@ -193,6 +244,7 @@ renderView:
|
|
|
193
244
|
2. **Use descriptive names** for components and plugins
|
|
194
245
|
3. **Document component props** and usage patterns
|
|
195
246
|
4. **Provide examples** for complex components
|
|
196
|
-
5. **
|
|
247
|
+
5. **Be intentional with component names** - use unique names unless you specifically want to override existing components
|
|
248
|
+
6. **Document overrides** when replacing default components to help other developers understand the customization
|
|
197
249
|
|
|
198
250
|
templates:
|
|
@@ -134,10 +134,15 @@ renderView:
|
|
|
134
134
|
version: "v1.2.3"
|
|
135
135
|
status: "success"
|
|
136
136
|
|
|
137
|
-
- type:
|
|
137
|
+
- type: button
|
|
138
138
|
content: "Simulate API Call with Data Mapping"
|
|
139
139
|
attributes:
|
|
140
|
-
|
|
140
|
+
style:
|
|
141
|
+
padding: "8px 16px"
|
|
142
|
+
margin: "8px 0"
|
|
143
|
+
border: "1px solid #007bff"
|
|
144
|
+
borderRadius: "4px"
|
|
145
|
+
cursor: "pointer"
|
|
141
146
|
actions:
|
|
142
147
|
- what: fetchData
|
|
143
148
|
on: click
|
|
@@ -250,10 +255,15 @@ renderView:
|
|
|
250
255
|
|
|
251
256
|
The mapping below tries to extract `user.name` and `user.email` which don't exist in this response, triggering the `onErrorMap` fallback values.
|
|
252
257
|
|
|
253
|
-
- type:
|
|
258
|
+
- type: button
|
|
254
259
|
content: "Test Missing Data Handling"
|
|
255
260
|
attributes:
|
|
256
|
-
|
|
261
|
+
style:
|
|
262
|
+
padding: "8px 16px"
|
|
263
|
+
margin: "8px 0"
|
|
264
|
+
border: "1px solid #ffc107"
|
|
265
|
+
borderRadius: "4px"
|
|
266
|
+
cursor: "pointer"
|
|
257
267
|
actions:
|
|
258
268
|
- what: fetchData
|
|
259
269
|
on: click
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
The `Input` component provides a native HTML input field with automatic data synchronization, combining the simplicity of native HTML with the convenience of automatic data binding.
|
|
4
|
+
|
|
5
|
+
> **About specialized input components**
|
|
6
|
+
>
|
|
7
|
+
> For common input types, you can use specialized wrapper components that pre-set the `inputType`:
|
|
8
|
+
>
|
|
9
|
+
> - `TextField` (text), `EmailField` (email), `PasswordField` (password)
|
|
10
|
+
> - `UrlField` (url), `SearchField` (search), `TelField` (tel)
|
|
11
|
+
> - `NumberField` (number), `RangeField` (range)
|
|
12
|
+
> - `DateField` (date), `TimeField` (time), `DateTimeField` (datetime-local)
|
|
13
|
+
> - `MonthField` (month), `WeekField` (week)
|
|
14
|
+
> - `ColorField` (color), `FileField` (file), `HiddenField` (hidden)
|
|
15
|
+
>
|
|
16
|
+
> All these components use the same properties as `Input` but with a predefined input type.
|
|
17
|
+
>
|
|
18
|
+
> Using convenience components makes it easier to override specific component types through reactive-json's [plugin system](/docs/advanced-concepts/plugins/plugin-system). For example, you can replace all `EmailField` components with a custom implementation while leaving other input types unchanged.
|
|
19
|
+
|
|
20
|
+
## Basic Syntax
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
- type: Input
|
|
24
|
+
dataLocation: ~.fieldName
|
|
25
|
+
label: "Field Label:"
|
|
26
|
+
placeholder: "Enter value..."
|
|
27
|
+
inputType: "text"
|
|
28
|
+
inputAttributes:
|
|
29
|
+
required: true
|
|
30
|
+
attributes:
|
|
31
|
+
style:
|
|
32
|
+
marginBottom: "10px"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Properties
|
|
36
|
+
|
|
37
|
+
- `dataLocation` (string, optional): Path to bind the field value in the data context.
|
|
38
|
+
- `defaultFieldValue` (string, optional): Default value when no data is present.
|
|
39
|
+
- `label` (string, optional): Field label text (supports template evaluation).
|
|
40
|
+
- `placeholder` (string, optional): Placeholder text (supports template evaluation).
|
|
41
|
+
- `inputType` (string, optional): HTML input type (default: "text", supports template evaluation).
|
|
42
|
+
- `attributes` (object, optional): Attributes applied to the container div (or merged with inputAttributes if no wrapper).
|
|
43
|
+
- `inputAttributes` (object, optional): Attributes applied directly to the input element.
|
|
44
|
+
- `labelAttributes` (object, optional): Attributes applied to the label (htmlFor is automatically managed).
|
|
45
|
+
- `forceWrapper` (boolean, optional): Forces the presence (true) or absence (false) of the wrapper div. If omitted, wrapper is automatic only if label is present.
|
|
46
|
+
- `actions` (array, optional): Actions to execute based on field state.
|
|
47
|
+
|
|
48
|
+
## Data Management
|
|
49
|
+
|
|
50
|
+
The component automatically synchronizes its value with the global data context. When `dataLocation` is used, the value is stored at the specified path. Without `dataLocation`, the value is stored in the template context using the component's `datafield`.
|
|
51
|
+
|
|
52
|
+
## Input Types
|
|
53
|
+
|
|
54
|
+
The `inputType` property supports all HTML5 input types:
|
|
55
|
+
- `text` (default): Standard text input
|
|
56
|
+
- `email`: Email validation
|
|
57
|
+
- `password`: Masked password input
|
|
58
|
+
- `url`: URL validation
|
|
59
|
+
- `tel`: Telephone number input
|
|
60
|
+
- `search`: Search input with clear button
|
|
61
|
+
- `number`: Numeric input
|
|
62
|
+
- `date`: Date picker
|
|
63
|
+
- And all other HTML5 types
|
|
64
|
+
|
|
65
|
+
## Wrapper Control
|
|
66
|
+
|
|
67
|
+
The component uses a flexible wrapper system that adapts based on the presence of a label and the `forceWrapper` property.
|
|
68
|
+
|
|
69
|
+
### Default Behavior
|
|
70
|
+
When no `forceWrapper` is specified, the component automatically determines whether to use a wrapper div. If a label is present, the component wraps both the label and input in a div container. If no label is present, the input is rendered directly without a wrapper.
|
|
71
|
+
|
|
72
|
+
### Explicit Control with `forceWrapper`
|
|
73
|
+
You can override the default behavior using the `forceWrapper` property. Setting `forceWrapper: true` will always create a wrapper div, even without a label. Setting `forceWrapper: false` will never create a wrapper, even when a label is present.
|
|
74
|
+
|
|
75
|
+
### HTML Output Examples
|
|
76
|
+
|
|
77
|
+
**With label (automatic wrapper):**
|
|
78
|
+
```html
|
|
79
|
+
<div>
|
|
80
|
+
<label htmlFor="input-abc123">Field Label:</label>
|
|
81
|
+
<input id="input-abc123" type="text" value="" />
|
|
82
|
+
</div>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Without label (no wrapper):**
|
|
86
|
+
```html
|
|
87
|
+
<input id="input-xyz789" type="text" value="" />
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Force wrapper without label:**
|
|
91
|
+
```html
|
|
92
|
+
<div>
|
|
93
|
+
<input id="input-def456" type="text" value="" />
|
|
94
|
+
</div>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Attribute Merging
|
|
98
|
+
When a wrapper is present, the `attributes` are applied to the div container and `inputAttributes` are applied to the input element. When no wrapper is present, both `attributes` and `inputAttributes` are merged and applied to the input element.
|
|
99
|
+
|
|
100
|
+
## Integrated vs Separated Labels
|
|
101
|
+
|
|
102
|
+
### Integrated Label (convenience)
|
|
103
|
+
```yaml
|
|
104
|
+
- type: Input
|
|
105
|
+
label: "My field:"
|
|
106
|
+
dataLocation: ~.value
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Advantages**: Simple, automatic accessibility (htmlFor)
|
|
110
|
+
**Limitations**: No conditional actions, limited styling
|
|
111
|
+
|
|
112
|
+
### Separated Label (full control)
|
|
113
|
+
```yaml
|
|
114
|
+
- type: label
|
|
115
|
+
content: "My field:"
|
|
116
|
+
attributes:
|
|
117
|
+
htmlFor: "my-input-id"
|
|
118
|
+
actions:
|
|
119
|
+
- what: setAttributeValue
|
|
120
|
+
when: ~.hasError
|
|
121
|
+
is: true
|
|
122
|
+
attribute: style.color
|
|
123
|
+
value: "red"
|
|
124
|
+
- type: Input
|
|
125
|
+
dataLocation: ~.value
|
|
126
|
+
forceWrapper: false
|
|
127
|
+
inputAttributes:
|
|
128
|
+
id: "my-input-id"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Advantages**: Conditional actions, advanced styling, full control
|
|
132
|
+
**Disadvantages**: More verbose, manual accessibility management
|
|
133
|
+
|
|
134
|
+
**Recommendation**: Use the integrated label for most cases. Opt for separated label only if you need conditional actions or advanced styling.
|
|
135
|
+
|
|
136
|
+
## Examples
|
|
137
|
+
|
|
138
|
+
### Basic Example
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
renderView:
|
|
142
|
+
- type: Input
|
|
143
|
+
dataLocation: ~.username
|
|
144
|
+
label: "Username:"
|
|
145
|
+
placeholder: "Enter your username"
|
|
146
|
+
|
|
147
|
+
data:
|
|
148
|
+
username: ""
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Different Input Types
|
|
152
|
+
|
|
153
|
+
```yaml
|
|
154
|
+
renderView:
|
|
155
|
+
- type: Input
|
|
156
|
+
dataLocation: ~.email
|
|
157
|
+
label: "Email:"
|
|
158
|
+
placeholder: "user@example.com"
|
|
159
|
+
inputType: "email"
|
|
160
|
+
- type: Input
|
|
161
|
+
dataLocation: ~.password
|
|
162
|
+
label: "Password:"
|
|
163
|
+
placeholder: "Enter password"
|
|
164
|
+
inputType: "password"
|
|
165
|
+
- type: Input
|
|
166
|
+
dataLocation: ~.website
|
|
167
|
+
label: "Website:"
|
|
168
|
+
placeholder: "https://example.com"
|
|
169
|
+
inputType: "url"
|
|
170
|
+
- type: Input
|
|
171
|
+
dataLocation: ~.age
|
|
172
|
+
label: "Age:"
|
|
173
|
+
inputType: "number"
|
|
174
|
+
inputAttributes:
|
|
175
|
+
min: 0
|
|
176
|
+
max: 120
|
|
177
|
+
|
|
178
|
+
data:
|
|
179
|
+
email: ""
|
|
180
|
+
password: ""
|
|
181
|
+
website: ""
|
|
182
|
+
age: ""
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Custom Attributes
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
renderView:
|
|
189
|
+
- type: Input
|
|
190
|
+
dataLocation: ~.productCode
|
|
191
|
+
label: "Product Code:"
|
|
192
|
+
placeholder: "ABC-123"
|
|
193
|
+
inputAttributes:
|
|
194
|
+
pattern: "[A-Z]{3}-[0-9]{3}"
|
|
195
|
+
title: "Format: ABC-123 (3 letters, dash, 3 numbers)"
|
|
196
|
+
maxLength: 7
|
|
197
|
+
style:
|
|
198
|
+
textTransform: "uppercase"
|
|
199
|
+
attributes:
|
|
200
|
+
style:
|
|
201
|
+
marginBottom: "10px"
|
|
202
|
+
|
|
203
|
+
data:
|
|
204
|
+
productCode: ""
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Wrapper Control
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
renderView:
|
|
211
|
+
# No label → no wrapper automatically
|
|
212
|
+
- type: Input
|
|
213
|
+
dataLocation: ~.noWrapper
|
|
214
|
+
placeholder: "Input without wrapper"
|
|
215
|
+
|
|
216
|
+
# With label → automatic wrapper
|
|
217
|
+
- type: Input
|
|
218
|
+
dataLocation: ~.autoWrapper
|
|
219
|
+
label: "With automatic wrapper:"
|
|
220
|
+
placeholder: "Input with wrapper"
|
|
221
|
+
|
|
222
|
+
# Force wrapper even without label
|
|
223
|
+
- type: Input
|
|
224
|
+
dataLocation: ~.forceWrapper
|
|
225
|
+
placeholder: "Forced wrapper"
|
|
226
|
+
forceWrapper: true
|
|
227
|
+
attributes:
|
|
228
|
+
style:
|
|
229
|
+
border: "2px solid blue"
|
|
230
|
+
padding: "10px"
|
|
231
|
+
|
|
232
|
+
# No wrapper even with label
|
|
233
|
+
- type: Input
|
|
234
|
+
dataLocation: ~.noWrapperForced
|
|
235
|
+
label: "Label without wrapper:"
|
|
236
|
+
placeholder: "Input without forced wrapper"
|
|
237
|
+
forceWrapper: false
|
|
238
|
+
# attributes merged with inputAttributes
|
|
239
|
+
attributes:
|
|
240
|
+
style:
|
|
241
|
+
border: "2px solid red"
|
|
242
|
+
|
|
243
|
+
data:
|
|
244
|
+
noWrapper: ""
|
|
245
|
+
autoWrapper: ""
|
|
246
|
+
forceWrapper: ""
|
|
247
|
+
noWrapperForced: ""
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Custom Label Attributes
|
|
251
|
+
|
|
252
|
+
```yaml
|
|
253
|
+
renderView:
|
|
254
|
+
- type: Input
|
|
255
|
+
dataLocation: ~.customLabel
|
|
256
|
+
label: "Custom label:"
|
|
257
|
+
placeholder: "Input with styled label"
|
|
258
|
+
labelAttributes:
|
|
259
|
+
style:
|
|
260
|
+
color: "blue"
|
|
261
|
+
fontWeight: "bold"
|
|
262
|
+
fontSize: "14px"
|
|
263
|
+
className: "custom-label"
|
|
264
|
+
|
|
265
|
+
data:
|
|
266
|
+
customLabel: ""
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### With Actions
|
|
270
|
+
|
|
271
|
+
```yaml
|
|
272
|
+
renderView:
|
|
273
|
+
- type: Input
|
|
274
|
+
dataLocation: ~.searchTerm
|
|
275
|
+
label: "Search:"
|
|
276
|
+
placeholder: "Type to search..."
|
|
277
|
+
inputType: "search"
|
|
278
|
+
actions:
|
|
279
|
+
- what: setData
|
|
280
|
+
when: ~.searchTerm
|
|
281
|
+
hasLength: ">0"
|
|
282
|
+
path: ~.isSearching
|
|
283
|
+
value: true
|
|
284
|
+
|
|
285
|
+
data:
|
|
286
|
+
searchTerm: ""
|
|
287
|
+
isSearching: false
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Advantages
|
|
291
|
+
|
|
292
|
+
- **No external dependencies**: Works without any CSS framework
|
|
293
|
+
- **Full control**: Custom styling and behavior
|
|
294
|
+
- **Performance**: Lighter than component libraries
|
|
295
|
+
- **Accessibility**: Direct control over ARIA attributes, automatic htmlFor
|
|
296
|
+
- **Automatic synchronization**: Unlike raw HTML elements that require manual setData actions
|
|
297
|
+
- **Flexible wrapper**: Avoids unnecessary HTML when not needed
|
|
298
|
+
- **Flexibility**: Integrated label for convenience, separated for advanced control
|
|
299
|
+
|
|
300
|
+
## Limitations
|
|
301
|
+
|
|
302
|
+
- No built-in validation beyond HTML5 input type validation
|
|
303
|
+
- No support for input masking or formatting
|
|
304
|
+
- No built-in error message display
|
|
305
|
+
- Styling must be provided via external CSS or style attributes
|
|
306
|
+
- Template evaluation for `inputType` should return valid HTML input types
|
|
307
|
+
- Integrated label is limited: for conditional actions, prefer separated label
|