@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.
Files changed (66) hide show
  1. package/package.json +7 -5
  2. package/public/rjbuild/docs/advanced-concepts/plugins/plugin-system.md +47 -1
  3. package/public/rjbuild/docs/advanced-concepts/plugins/plugin-system.yaml +53 -1
  4. package/public/rjbuild/docs/core/dataMapping/simpleMapping.yaml +14 -4
  5. package/public/rjbuild/docs/core/element/form/Input.md +307 -0
  6. package/public/rjbuild/docs/core/element/form/Input.yaml +572 -0
  7. package/public/rjbuild/docs/core/element/special/Count.yaml +99 -31
  8. package/public/rjbuild/docs/core/element/special/DataFilter.yaml +118 -38
  9. package/public/rjbuild/docs/core/element/special/ReactiveJsonSubroot.yaml +154 -34
  10. package/public/rjbuild/docs/core/element/special/Switch.md +5 -5
  11. package/public/rjbuild/docs/core/element/special/Switch.yaml +9 -18
  12. package/public/rjbuild/docs/core/example/html.md +2 -2
  13. package/public/rjbuild/docs/core/example/html.yaml +2 -3
  14. package/public/rjbuild/docs/core/example/native-html-forms.md +245 -0
  15. package/public/rjbuild/docs/core/example/native-html-forms.yaml +393 -0
  16. package/public/rjbuild/docs/core/reaction/addData.md +17 -3
  17. package/public/rjbuild/docs/core/reaction/addData.yaml +53 -9
  18. package/public/rjbuild/docs/core/reaction/fetchData.yaml +44 -8
  19. package/public/rjbuild/docs/core/reaction/setData.md +18 -4
  20. package/public/rjbuild/docs/core/reaction/setData.yaml +18 -4
  21. package/public/rjbuild/docs/docs-components/Mermaid.md +254 -0
  22. package/public/rjbuild/docs/docs-components/Mermaid.yaml +339 -0
  23. package/public/rjbuild/docs/docs-components/index.yaml +1 -0
  24. package/public/rjbuild/docs/getting-started/actions.md +1 -1
  25. package/public/rjbuild/docs/index.yaml +2 -1
  26. package/public/rjbuild/docs/install.md +2 -5
  27. package/public/rjbuild/docs/install.yaml +4 -10
  28. package/public/rjbuild/docs/{core → integration/bootstrap}/action/Popover.md +1 -1
  29. package/public/rjbuild/docs/{core → integration/bootstrap}/action/Tooltip.md +1 -1
  30. package/public/rjbuild/docs/integration/bootstrap/element/html/AccordionItem.md +69 -0
  31. package/public/rjbuild/docs/integration/bootstrap/element/html/Modal.md +127 -0
  32. package/public/rjbuild/docs/integration/bootstrap/element/html/Tabs.md +150 -0
  33. package/public/rjbuild/docs/integration/bootstrap/element/html/index.md +13 -0
  34. package/public/rjbuild/docs/integration/bootstrap/element/special/index.md +19 -0
  35. package/public/rjbuild/docs/integration/bootstrap/example/website.md +41 -0
  36. package/public/rjbuild/docs/integration/bootstrap/overview.md +69 -0
  37. package/public/rjbuild/docs/integration/bootstrap/overview.yaml +87 -0
  38. /package/public/rjbuild/docs/{core → integration/bootstrap}/action/Popover.yaml +0 -0
  39. /package/public/rjbuild/docs/{core → integration/bootstrap}/action/Tooltip.yaml +0 -0
  40. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/CheckBoxField.md +0 -0
  41. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/CheckBoxField.yaml +0 -0
  42. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/DateField.md +0 -0
  43. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/DateField.yaml +0 -0
  44. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/NumberField.md +0 -0
  45. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/NumberField.yaml +0 -0
  46. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/SelectField.md +0 -0
  47. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/SelectField.yaml +0 -0
  48. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextAreaField.md +0 -0
  49. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextAreaField.yaml +0 -0
  50. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextField.md +0 -0
  51. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextField.yaml +0 -0
  52. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/formElementsCommon.md +0 -0
  53. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/index.md +0 -0
  54. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/index.yaml +0 -0
  55. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/AccordionItem.yaml +0 -0
  56. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/Modal.yaml +0 -0
  57. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/Tabs.yaml +0 -0
  58. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/special/BootstrapElement.md +0 -0
  59. /package/public/rjbuild/docs/{core → integration/bootstrap}/element/special/BootstrapElement.yaml +0 -0
  60. /package/public/rjbuild/docs/{core → integration/bootstrap}/example/accordion.md +0 -0
  61. /package/public/rjbuild/docs/{core → integration/bootstrap}/example/accordion.yaml +0 -0
  62. /package/public/rjbuild/docs/{core → integration/bootstrap}/example/dynamic-content.md +0 -0
  63. /package/public/rjbuild/docs/{core → integration/bootstrap}/example/dynamic-content.yaml +0 -0
  64. /package/public/rjbuild/docs/{core → integration/bootstrap}/example/website.yaml +0 -0
  65. /package/public/rjbuild/docs/{chartjs → integration/chartjs}/components.yaml +0 -0
  66. /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.8.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.7.1",
30
- "@ea-lab/reactive-json-chartjs": "^0.0.23",
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.5",
36
+ "bootstrap": "^5.3.7",
37
37
  "lodash": "^4.17.21",
38
38
  "react": "^19.1.0",
39
- "react-bootstrap": "^2.10.2",
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. **Choose non-conflicting names** with existing components
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. **Choose non-conflicting names** with existing components
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: BsButton
137
+ - type: button
138
138
  content: "Simulate API Call with Data Mapping"
139
139
  attributes:
140
- class: "btn btn-primary mb-3"
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: BsButton
258
+ - type: button
254
259
  content: "Test Missing Data Handling"
255
260
  attributes:
256
- class: "btn btn-warning mb-3"
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