@ea-lab/reactive-json-docs 0.5.0 → 0.6.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ea-lab/reactive-json-docs",
3
- "version": "0.5.0",
3
+ "version": "0.6.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,7 +26,7 @@
26
26
  "private": false,
27
27
  "devDependencies": {
28
28
  "@craco/craco": "^7.1.0",
29
- "@ea-lab/reactive-json": "^0.4.0",
29
+ "@ea-lab/reactive-json": "^0.5.0",
30
30
  "@ea-lab/reactive-json-chartjs": "^0.0.23",
31
31
  "@npmcli/fs": "^4.0.0",
32
32
  "@reduxjs/toolkit": "^2.6.1",
@@ -75,5 +75,8 @@
75
75
  "last 1 firefox version",
76
76
  "last 1 safari version"
77
77
  ]
78
+ },
79
+ "dependencies": {
80
+ "remark-gfm": "^4.0.1"
78
81
  }
79
82
  }
@@ -0,0 +1,93 @@
1
+ # SetAttributeValue
2
+
3
+ Dynamically sets or modifies the value of an HTML attribute on an element.
4
+
5
+ ## Basic Syntax
6
+
7
+ ```yaml
8
+ actions:
9
+ # Add CSS class
10
+ - what: setAttributeValue
11
+ name: "class"
12
+ value: "active"
13
+
14
+ # Replace attribute value
15
+ - what: setAttributeValue
16
+ name: "data-status"
17
+ mode: "replace"
18
+ value: ~.currentStatus
19
+ ```
20
+
21
+ ## Properties
22
+
23
+ - **name** *(string, required)*: The name of the attribute to modify.
24
+ - **mode** *(string, optional)*: The modification mode. Default: `"append"`.
25
+ - `"append"`: Adds the value to the existing attribute value (space-separated).
26
+ - `"replace"`: Completely replaces the existing attribute value.
27
+ - **value** *(string, required)*: The value to set or append. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`). Automatically converted to string if not already. Special characters are handled safely.
28
+ - **preventDuplicateValues** *(boolean, optional)*: When `true` (default), prevents duplicate values when using append mode.
29
+ - **separator** *(string, optional)*: The separator used between values. Default: `" "` (space).
30
+
31
+ ## Behavior
32
+
33
+ - **Append mode**: Adds the new value to the existing attribute, separated by the specified separator.
34
+ - **Replace mode**: Completely overwrites the existing attribute value.
35
+ - **Duplicate prevention**: In append mode, prevents adding duplicate values when enabled.
36
+
37
+ ## Common Use Cases
38
+
39
+ - **Dynamic CSS classes**: Adding/removing CSS classes based on state.
40
+ - **Data attributes**: Setting data-* attributes for JavaScript integration.
41
+ - **ARIA attributes**: Dynamically updating accessibility attributes.
42
+ - **Style attributes**: Modifying inline styles conditionally.
43
+
44
+ ## Example
45
+
46
+ ```yaml
47
+ renderView:
48
+ - type: input
49
+ attributes:
50
+ type: "text"
51
+ placeholder: "Start typing to see the highlighting..."
52
+ class: "sav-demo-input"
53
+ value: ~.input_data
54
+ style:
55
+ padding: "10px"
56
+ border: "2px solid #007bff"
57
+ borderRadius: "4px"
58
+ fontSize: "16px"
59
+ margin: "10px 0"
60
+ width: "300px"
61
+ display: "block"
62
+ actions:
63
+ - what: setData
64
+ on: change
65
+ path: ~.input_data
66
+ value: <reactive-json:event-new-value>
67
+ - what: setAttributeValue
68
+ name: "class"
69
+ value: "sav-highlighted"
70
+ when: ~.input_data
71
+ isNotEmpty:
72
+
73
+ - type: div
74
+ content: ~.input_data
75
+
76
+ - type: style
77
+ content: |
78
+ .sav-highlighted {
79
+ border-color: #28a745 !important;
80
+ outline: 2px solid #28a745 !important;
81
+ outline-offset: 2px !important;
82
+ }
83
+
84
+ data:
85
+ input_data: ""
86
+ ```
87
+
88
+ ## Notes
89
+
90
+ - The action respects existing attribute values when using append mode.
91
+ - Use replace mode when you need complete control over the attribute value.
92
+ - Duplicate prevention only applies to append mode.
93
+ - The value property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
@@ -0,0 +1,141 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # SetAttributeValue
5
+
6
+ Dynamically sets or modifies the value of an HTML attribute on an element.
7
+
8
+ ## Basic Syntax
9
+
10
+ - type: TabbedSerializer
11
+ yamlSerializedContent: |
12
+ actions:
13
+ # Add CSS class
14
+ - what: setAttributeValue
15
+ name: "class"
16
+ value: "active"
17
+
18
+ # Replace attribute value
19
+ - what: setAttributeValue
20
+ name: "data-status"
21
+ mode: "replace"
22
+ value: ~.currentStatus
23
+
24
+ - type: Markdown
25
+ content: |
26
+ ## Properties
27
+
28
+ - type: DefinitionList
29
+ content:
30
+ - term:
31
+ code: name
32
+ after: "(string, required)"
33
+ details: The name of the attribute to modify.
34
+ - term:
35
+ code: mode
36
+ after: "(string, optional)"
37
+ details:
38
+ type: Markdown
39
+ content: |
40
+ The modification mode. Default: `"append"`
41
+ - `"append"`: Adds the value to the existing attribute value (space-separated)
42
+ - `"replace"`: Completely replaces the existing attribute value
43
+ - term:
44
+ code: value
45
+ after: "(string, required)"
46
+ details: The value to set or append. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`). Automatically converted to string if not already. Special characters are handled safely.
47
+ - term:
48
+ code: preventDuplicateValues
49
+ after: "(boolean, optional)"
50
+ details:
51
+ type: Markdown
52
+ content: When `true` (default), prevents duplicate values when using append mode.
53
+ - term:
54
+ code: separator
55
+ after: "(string, optional)"
56
+ details:
57
+ type: Markdown
58
+ content: |
59
+ The separator used between values. Default: `" "` (space).
60
+
61
+ - type: Markdown
62
+ content: |
63
+
64
+ ## Behavior
65
+
66
+ - **Append mode**: Adds the new value to the existing attribute, separated by the specified separator.
67
+ - **Replace mode**: Completely overwrites the existing attribute value.
68
+ - **Duplicate prevention**: In append mode, prevents adding duplicate values when enabled.
69
+
70
+ ## Common Use Cases
71
+
72
+ - **Dynamic CSS classes**: Adding/removing CSS classes based on state.
73
+ - **Data attributes**: Setting data-* attributes for JavaScript integration.
74
+ - **ARIA attributes**: Dynamically updating accessibility attributes.
75
+ - **Style attributes**: Modifying inline styles conditionally.
76
+
77
+ - type: RjBuildDescriber
78
+ title: "SetAttributeValue Action Examples"
79
+ description:
80
+ - type: Markdown
81
+ content: |
82
+ This example demonstrates how to use the `SetAttributeValue` action to dynamically add CSS classes based on input content.
83
+
84
+ **Expected behavior:**
85
+ - Initially, the input field has normal appearance (base styling)
86
+ - Start typing in the input field
87
+ - When the field is not empty, the 'sav-highlighted' class is automatically added (visual highlighting)
88
+ - Clear the field to remove the highlighting
89
+ - The action uses append mode and responds to the `isNotEmpty` condition
90
+
91
+ Try typing and clearing the input to see how the class attribute changes automatically.
92
+
93
+ toDescribe:
94
+ renderView:
95
+ - type: input
96
+ attributes:
97
+ type: "text"
98
+ placeholder: "Start typing to see the highlighting..."
99
+ class: "sav-demo-input"
100
+ value: ~.input_data
101
+ style:
102
+ padding: "10px"
103
+ border: "2px solid #007bff"
104
+ borderRadius: "4px"
105
+ fontSize: "16px"
106
+ margin: "10px 0"
107
+ width: "300px"
108
+ display: "block"
109
+ actions:
110
+ - what: setData
111
+ on: change
112
+ path: ~.input_data
113
+ value: <reactive-json:event-new-value>
114
+ - what: setAttributeValue
115
+ name: "class"
116
+ value: "sav-highlighted"
117
+ when: ~.input_data
118
+ isNotEmpty:
119
+
120
+ - type: div
121
+ content: ~.input_data
122
+
123
+ - type: style
124
+ content: |
125
+ .sav-highlighted {
126
+ border-color: #28a745 !important;
127
+ outline: 2px solid #28a745 !important;
128
+ outline-offset: 2px !important;
129
+ }
130
+
131
+ data:
132
+ input_data: ""
133
+
134
+ - type: Markdown
135
+ content: |
136
+ ## Notes
137
+
138
+ - The action respects existing attribute values when using append mode.
139
+ - Use replace mode when you need complete control over the attribute value.
140
+ - Duplicate prevention only applies to append mode.
141
+ - The value property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
@@ -0,0 +1,267 @@
1
+ # ToggleAttributeValue
2
+
3
+ Toggles the presence of a specific value in an HTML attribute. Supports both simple on-off toggles and cyclic toggling through multiple values.
4
+
5
+ ## Important Notes
6
+
7
+ ### Action-Based Behavior
8
+ `ToggleAttributeValue` is an **action component** that operates based on data state changes, not direct event triggers. It requires a state variable in your data to activate the toggle behavior. This means you cannot directly use `on: click` with `ToggleAttributeValue` - instead, you must use `setData` with `on: click` to change a state variable, then use `when/is` conditions on the toggle action to respond to that state change.
9
+
10
+ ### Base Attribute Detection
11
+ `ToggleAttributeValue` determines what to toggle by examining the **original attributes** defined in your component's props, not the current DOM state. This means:
12
+
13
+ - ✅ **Stable behavior**: The toggle always works relative to the initial attribute values
14
+ - ✅ **No infinite loops**: Changes don't trigger recursive re-evaluation
15
+ - ⚠️ **Limitation**: The toggle cannot detect or work with values that were dynamically added by other attribute actions (`SetAttributeValue`, `UnsetAttributeValue`)
16
+
17
+ **Example**: If your component initially has `class="base"` and another action adds `"dynamic"`, the toggle will only work with `"base"` and won't see `"dynamic"`.
18
+
19
+ ## Basic Syntax
20
+
21
+ ```yaml
22
+ actions:
23
+ # Toggle CSS class.
24
+ - what: toggleAttributeValue
25
+ name: "class"
26
+ value: "active"
27
+
28
+ # Cyclic toggle with array.
29
+ - what: toggleAttributeValue
30
+ name: "class"
31
+ value: ["theme-light", "theme-dark", "theme-auto", ""]
32
+
33
+ # Keep attribute when empty.
34
+ - what: toggleAttributeValue
35
+ name: "data-optional"
36
+ value: "enabled"
37
+ keepAttributeWhenEmpty: true
38
+
39
+ # Conditional toggle.
40
+ - what: toggleAttributeValue
41
+ name: "data-features"
42
+ value: ~.featureName
43
+ when: ~.shouldToggle
44
+ is: true
45
+ ```
46
+
47
+ ## Properties
48
+
49
+ - **keepAttributeWhenEmpty** *(boolean, optional)*: Whether to keep the attribute when it becomes empty. If `false`, the attribute is removed when no values remain. Default: `false`.
50
+ - **name** *(string, required)*: The name of the attribute to modify.
51
+ - **separator** *(string, optional)*: The separator used between values. Default: `" "` (space).
52
+ - **value** *(string|array, required)*: The value(s) to toggle in the attribute. Can be a single string or an array of strings for cyclic toggling. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`). Automatically converted to string if not already.
53
+
54
+ ## Behavior
55
+
56
+ ### Simple Toggle (string value)
57
+ - **Smart toggle**: Automatically adds the value if missing, removes it if present.
58
+ - **Preservation**: Other values in the attribute remain intact.
59
+ - **Empty handling**: By default, removes the entire attribute if no values remain. Set `keepAttributeWhenEmpty` to `true` to preserve empty attributes.
60
+
61
+ #### Common Examples
62
+ ```yaml
63
+ # Toggle CSS class.
64
+ - what: toggleAttributeValue
65
+ name: "class"
66
+ value: "active"
67
+
68
+ # Toggle readonly attribute.
69
+ - what: toggleAttributeValue
70
+ name: "readonly"
71
+ value: "readonly"
72
+
73
+ # Toggle checked attribute.
74
+ - what: toggleAttributeValue
75
+ name: "checked"
76
+ value: "checked"
77
+ ```
78
+
79
+ ### Cyclic Toggle (array value)
80
+ - **Cyclic behavior**: When `value` is an array, the action cycles through the values in order.
81
+ - **Sequential rotation**: Each toggle moves to the next value in the array.
82
+ - **Empty values handling**: Empty strings (`""`) in the array represent the absence of the value.
83
+ - **Clean detection**: Values are split by separator and empty values (from double separators) are filtered out during detection.
84
+ - **First match priority**: If multiple array values are already present, only the first detected value is replaced.
85
+ - **Default fallback**: If no array values are present, the first array value is applied.
86
+ - **Empty value filtering**: Attributes with empty values from double separators (e.g., `"val1,,val2,"`) are cleaned during detection, treating them as `"val1 val2"`.
87
+ - **Single value arrays**: Arrays with one value behave identically to string values (toggle between value and empty).
88
+ - **Empty string inclusion**: Including `""` in arrays explicitly defines an "empty state" in the cycle.
89
+
90
+ #### Array Behavior Examples
91
+
92
+ ##### Four-step cycle with empty state
93
+ ```yaml
94
+ # Starting with class="theme-light"
95
+ # Clicks will progress: theme-light → theme-dark → theme-auto → "" → theme-light → ...
96
+ value: ["theme-light", "theme-dark", "theme-auto", ""]
97
+ ```
98
+
99
+ ##### Simple alternation
100
+ ```yaml
101
+ # Starting with class="size-small"
102
+ # Clicks will alternate: size-small → size-large → size-small → ...
103
+ value: ["size-small", "size-large"]
104
+ ```
105
+
106
+ ##### Single value array (equivalent to string)
107
+ ```yaml
108
+ # Equivalent to value: "highlight"
109
+ # Toggles: highlight → "" → highlight → ...
110
+ value: ["highlight"]
111
+ ```
112
+
113
+ ## Common Use Cases
114
+
115
+ - **CSS class toggling**: Adding/removing CSS classes based on state changes.
116
+ - **Data attribute management**: Toggling specific values in space-separated data attributes.
117
+ - **Interactive styling**: Toggle styling classes for user interactions.
118
+ - **Feature flags**: Toggle feature-related classes or data attributes.
119
+ - **State cycling**: Cycle through multiple states (e.g., theme variants, size options).
120
+ - **Multi-step processes**: Progress through sequential steps with visual indicators.
121
+
122
+ ## Examples
123
+
124
+ ### Simple Toggle (string value)
125
+ ```yaml
126
+ renderView:
127
+ - type: button
128
+ content: "Toggle 'active' class"
129
+ actions:
130
+ - what: setData
131
+ on: click
132
+ path: ~.toggleActive
133
+ value: "yes"
134
+ when: ~.toggleActive
135
+ is: "no"
136
+ - what: setData
137
+ on: click
138
+ path: ~.toggleActive
139
+ value: "no"
140
+ when: ~.toggleActive
141
+ is: "yes"
142
+
143
+ - type: div
144
+ content: "Element that toggles classes based on state"
145
+ attributes:
146
+ class: "base-class"
147
+ style:
148
+ padding: "10px"
149
+ border: "1px solid #ccc"
150
+ margin: "10px 0"
151
+ actions:
152
+ - what: toggleAttributeValue
153
+ name: "class"
154
+ value: "active"
155
+ when: ~.toggleActive
156
+ is: "yes"
157
+
158
+ data:
159
+ toggleActive: "no"
160
+ ```
161
+
162
+ ### Keep Attribute When Empty
163
+ ```yaml
164
+ renderView:
165
+ - type: button
166
+ content: "Toggle data attribute (keeps when empty)"
167
+ actions:
168
+ - what: setData
169
+ on: click
170
+ path: ~.toggleFeature
171
+ value: "yes"
172
+ when: ~.toggleFeature
173
+ is: "no"
174
+ - what: setData
175
+ on: click
176
+ path: ~.toggleFeature
177
+ value: "no"
178
+ when: ~.toggleFeature
179
+ is: "yes"
180
+
181
+ - type: div
182
+ content: "Element with preserved attribute"
183
+ attributes:
184
+ data-feature: "enabled"
185
+ style:
186
+ padding: "10px"
187
+ border: "1px solid #999"
188
+ margin: "10px 0"
189
+ actions:
190
+ - what: toggleAttributeValue
191
+ name: "data-feature"
192
+ value: "enabled"
193
+ keepAttributeWhenEmpty: true
194
+ when: ~.toggleFeature
195
+ is: "yes"
196
+
197
+ data:
198
+ toggleFeature: "no"
199
+ ```
200
+
201
+ ### Cyclic Toggle (array value)
202
+ ```yaml
203
+ renderView:
204
+ - type: button
205
+ content: "Cycle through themes"
206
+ actions:
207
+ - what: setData
208
+ on: click
209
+ path: ~.cycleThemes
210
+ value: "yes"
211
+ when: ~.cycleThemes
212
+ is: "no"
213
+ - what: setData
214
+ on: click
215
+ path: ~.cycleThemes
216
+ value: "no"
217
+ when: ~.cycleThemes
218
+ is: "yes"
219
+
220
+ - type: div
221
+ content: "Element that cycles through theme classes"
222
+ attributes:
223
+ class: "theme-light"
224
+ actions:
225
+ - what: toggleAttributeValue
226
+ name: "class"
227
+ value: ["theme-light", "theme-dark", "theme-auto", ""]
228
+ when: ~.cycleThemes
229
+ is: "yes"
230
+
231
+ - type: button
232
+ content: "Alternate between sizes"
233
+ actions:
234
+ - what: setData
235
+ on: click
236
+ path: ~.alternateSizes
237
+ value: "yes"
238
+ when: ~.alternateSizes
239
+ is: "no"
240
+ - what: setData
241
+ on: click
242
+ path: ~.alternateSizes
243
+ value: "no"
244
+ when: ~.alternateSizes
245
+ is: "yes"
246
+
247
+ - type: div
248
+ content: "Element that alternates between size classes"
249
+ attributes:
250
+ class: "size-small"
251
+ actions:
252
+ - what: toggleAttributeValue
253
+ name: "class"
254
+ value: ["size-small", "size-large"]
255
+ when: ~.alternateSizes
256
+ is: "yes"
257
+
258
+ data:
259
+ cycleThemes: "no"
260
+ alternateSizes: "no"
261
+ ```
262
+
263
+ ## Notes
264
+
265
+ - The `value` property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
266
+ - More efficient than separate SetAttributeValue/UnsetAttributeValue actions for toggle scenarios.
267
+ - Works with any space-separated attribute values (class, data attributes, etc.).
@@ -0,0 +1,244 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # ToggleAttributeValue
5
+
6
+ Toggles the presence of a specific value in an HTML attribute. Supports both simple on-off toggles and cyclic toggling through multiple values.
7
+
8
+ ## Important Notes
9
+
10
+ ### Action-Based Behavior
11
+ `ToggleAttributeValue` is an **action component** that operates based on data state changes, not direct event triggers. It requires a state variable in your data to activate the toggle behavior. This means you cannot directly use `on: click` with `ToggleAttributeValue` - instead, you must use `setData` with `on: click` to change a state variable, then use `when/is` conditions on the toggle action to respond to that state change.
12
+
13
+ ### Base Attribute Detection
14
+ `ToggleAttributeValue` determines what to toggle by examining the **original attributes** defined in your component's props, not the current DOM state. This means:
15
+
16
+ - ✅ **Stable behavior**: The toggle always works relative to the initial attribute values
17
+ - ✅ **No infinite loops**: Changes don't trigger recursive re-evaluation
18
+ - ⚠️ **Limitation**: The toggle cannot detect or work with values that were dynamically added by other attribute actions (`SetAttributeValue`, `UnsetAttributeValue`)
19
+
20
+ **Example**: If your component initially has `class="base"` and another action adds `"dynamic"`, the toggle will only work with `"base"` and won't see `"dynamic"`.
21
+
22
+ ## Basic Syntax
23
+
24
+ - type: TabbedSerializer
25
+ yamlSerializedContent: |
26
+ actions:
27
+ # Toggle CSS class.
28
+ - what: toggleAttributeValue
29
+ name: "class"
30
+ value: "active"
31
+
32
+ # Cyclic toggle with array.
33
+ - what: toggleAttributeValue
34
+ name: "class"
35
+ value: ["theme-light", "theme-dark", "theme-auto", ""]
36
+
37
+ # Keep attribute when empty.
38
+ - what: toggleAttributeValue
39
+ name: "data-optional"
40
+ value: "enabled"
41
+ keepAttributeWhenEmpty: true
42
+
43
+ # Conditional toggle.
44
+ - what: toggleAttributeValue
45
+ name: "data-features"
46
+ value: ~.featureName
47
+ when: ~.shouldToggle
48
+ is: true
49
+
50
+ - type: Markdown
51
+ content: |
52
+ ## Properties
53
+
54
+ - type: DefinitionList
55
+ content:
56
+ - term:
57
+ code: keepAttributeWhenEmpty
58
+ after: "(boolean, optional)"
59
+ details:
60
+ type: Markdown
61
+ content: |
62
+ Whether to keep the attribute when it becomes empty. If `false`, the attribute is removed when no values remain. Default: `false`.
63
+ - term:
64
+ code: name
65
+ after: "(string, required)"
66
+ details: The name of the attribute to modify.
67
+ - term:
68
+ code: separator
69
+ after: "(string, optional)"
70
+ details:
71
+ type: Markdown
72
+ content: |
73
+ The separator used between values. Default: `" "` (space).
74
+ - term:
75
+ code: value
76
+ after: "(string|array, required)"
77
+ details:
78
+ type: Markdown
79
+ content: |
80
+ The value(s) to toggle in the attribute. Can be a single string or an array of strings for cyclic toggling. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`). Automatically converted to string if not already.
81
+
82
+ - type: Markdown
83
+ content: |
84
+
85
+ ## Behavior
86
+
87
+ ### Simple Toggle (string value)
88
+ - **Smart toggle**: Automatically adds the value if missing, removes it if present.
89
+ - **Preservation**: Other values in the attribute remain intact.
90
+ - **Empty handling**: By default, removes the entire attribute if no values remain. Set `keepAttributeWhenEmpty` to `true` to preserve empty attributes.
91
+
92
+ #### Common Examples
93
+
94
+ - type: TabbedSerializer
95
+ yamlSerializedContent: |
96
+ # Toggle CSS class.
97
+ - what: toggleAttributeValue
98
+ name: "class"
99
+ value: "active"
100
+
101
+ # Toggle readonly attribute.
102
+ - what: toggleAttributeValue
103
+ name: "readonly"
104
+ value: "readonly"
105
+
106
+ # Toggle checked attribute.
107
+ - what: toggleAttributeValue
108
+ name: "checked"
109
+ value: "checked"
110
+
111
+ - type: Markdown
112
+ content: |
113
+
114
+ ### Cyclic Toggle (array value)
115
+ - **Cyclic behavior**: When `value` is an array, the action cycles through the values in order.
116
+ - **Sequential rotation**: Each toggle moves to the next value in the array.
117
+ - **Empty values handling**: Empty strings (`""`) in the array represent the absence of the value.
118
+ - **Clean detection**: Values are split by separator and empty values (from double separators) are filtered out during detection.
119
+ - **First match priority**: If multiple array values are already present, only the first detected value is replaced.
120
+ - **Default fallback**: If no array values are present, the first array value is applied.
121
+ - **Empty value filtering**: Attributes with empty values from double separators (e.g., `"val1,,val2,"`) are cleaned during detection, treating them as `"val1 val2"`.
122
+ - **Single value arrays**: Arrays with one value behave identically to string values (toggle between value and empty).
123
+ - **Empty string inclusion**: Including `""` in arrays explicitly defines an "empty state" in the cycle.
124
+
125
+ #### Array Behavior Examples
126
+
127
+ ##### Four-step cycle with empty state
128
+ ```yaml
129
+ # Starting with class="theme-light"
130
+ # Clicks will progress: theme-light → theme-dark → theme-auto → "" → theme-light → ...
131
+ value: ["theme-light", "theme-dark", "theme-auto", ""]
132
+ ```
133
+
134
+ ##### Simple alternation
135
+ ```yaml
136
+ # Starting with class="size-small"
137
+ # Clicks will alternate: size-small → size-large → size-small → ...
138
+ value: ["size-small", "size-large"]
139
+ ```
140
+
141
+ ##### Single value array (equivalent to string)
142
+ ```yaml
143
+ # Equivalent to value: "highlight"
144
+ # Toggles: highlight → "" → highlight → ...
145
+ value: ["highlight"]
146
+ ```
147
+
148
+ ## Common Use Cases
149
+
150
+ - **CSS class toggling**: Adding/removing CSS classes based on state changes.
151
+ - **Data attribute management**: Toggling specific values in space-separated data attributes.
152
+ - **Interactive styling**: Toggle styling classes for user interactions.
153
+ - **Feature flags**: Toggle feature-related classes or data attributes.
154
+ - **State cycling**: Cycle through multiple states (e.g., theme variants, size options).
155
+ - **Multi-step processes**: Progress through sequential steps with visual indicators.
156
+
157
+ - type: RjBuildDescriber
158
+ title: "ToggleAttributeValue Action Examples"
159
+ description:
160
+ - type: Markdown
161
+ content: |
162
+ This example demonstrates how to toggle the readonly attribute using the `ToggleAttributeValue` action.
163
+
164
+ **Expected behavior:**
165
+ - Initially, the input field is editable (normal appearance)
166
+ - Click "Toggle readonly" to make the input readonly (you cannot type in it + visual changes)
167
+ - Click "Toggle readonly" again to make it editable again
168
+ - Click "Reset" to return to the initial state (editable)
169
+ - The toggle action automatically adds/removes the 'readonly' value from the class attribute
170
+
171
+ Try interacting with the buttons to see how the readonly state toggles.
172
+
173
+ toDescribe:
174
+ renderView:
175
+ - type: button
176
+ content: "Toggle readonly"
177
+ actions:
178
+ - what: setData
179
+ on: click
180
+ path: ~.shouldToggle
181
+ value: "yes"
182
+ when: ~.shouldToggle
183
+ is: "no"
184
+ stopPropagation: true
185
+ - what: setData
186
+ on: click
187
+ path: ~.shouldToggle
188
+ value: "no"
189
+ when: ~.shouldToggle
190
+ is: "yes"
191
+ stopPropagation: true
192
+
193
+ - type: button
194
+ content: "Reset"
195
+ actions:
196
+ - what: setData
197
+ on: click
198
+ path: ~.shouldToggle
199
+ value: "no"
200
+ stopPropagation: true
201
+
202
+ - type: input
203
+ attributes:
204
+ type: "text"
205
+ placeholder: "Try typing here when readonly is removed..."
206
+ value: ~.input_value
207
+ class: "tav-demo-input"
208
+ style:
209
+ padding: "10px"
210
+ border: "2px solid #007bff"
211
+ borderRadius: "4px"
212
+ fontSize: "16px"
213
+ margin: "10px 0"
214
+ width: "300px"
215
+ display: "block"
216
+ actions:
217
+ - what: toggleAttributeValue
218
+ name: "class"
219
+ value: "tav-readonly"
220
+ when: ~.shouldToggle
221
+ is: "yes"
222
+ - what: setData
223
+ on: change
224
+ path: ~.input_value
225
+ value: <reactive-json:event-new-value>
226
+ - type: style
227
+ content: |
228
+ .tav-readonly {
229
+ cursor: not-allowed !important;
230
+ opacity: 0.7 !important;
231
+ border-color: #6c757d !important;
232
+ pointer-events: none !important;
233
+ }
234
+
235
+ data:
236
+ shouldToggle: "no"
237
+ input_value: ""
238
+ - type: Markdown
239
+ content: |
240
+ ## Notes
241
+
242
+ - The `value` property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
243
+ - More efficient than separate SetAttributeValue/UnsetAttributeValue actions for toggle scenarios.
244
+ - Works with any space-separated attribute values (class, data attributes, etc.).
@@ -0,0 +1,108 @@
1
+ # UnsetAttribute
2
+
3
+ Completely removes an HTML attribute from an element.
4
+
5
+ ## Basic Syntax
6
+
7
+ ```yaml
8
+ actions:
9
+ # Remove entire attribute
10
+ - what: unsetAttribute
11
+ name: "class"
12
+
13
+ # Conditional removal
14
+ - what: unsetAttribute
15
+ name: "style"
16
+ when: ~.useDefaultStyling
17
+ is: true
18
+ ```
19
+
20
+ ## Properties
21
+
22
+ - **name** *(string, required)*: The name of the attribute to remove completely.
23
+
24
+ ## Behavior
25
+
26
+ - **Complete removal**: Removes the entire attribute and all its values from the DOM element.
27
+ - **Attribute deletion**: The attribute is completely deleted, not just emptied.
28
+ - **Irreversible**: Once removed, the attribute must be explicitly set again to restore it.
29
+
30
+ ## Common Use Cases
31
+
32
+ - **Conditional attribute presence**: Removing attributes entirely based on conditions.
33
+ - **Accessibility cleanup**: Removing ARIA attributes when not needed.
34
+ - **Data attribute management**: Completely removing data-* attributes.
35
+ - **Style reset**: Removing inline style attributes to fall back to CSS.
36
+
37
+ ## Example
38
+
39
+ ```yaml
40
+ renderView:
41
+ - type: button
42
+ content: "Remove readonly attribute"
43
+ actions:
44
+ - what: setData
45
+ on: click
46
+ path: ~.makeEditable
47
+ value: true
48
+ stopPropagation: true
49
+
50
+ - type: button
51
+ content: "Reset"
52
+ actions:
53
+ - what: setData
54
+ on: click
55
+ path: ~.makeEditable
56
+ value: false
57
+ stopPropagation: true
58
+
59
+ - type: input
60
+ attributes:
61
+ type: "text"
62
+ value: ~.input_value
63
+ placeholder: "Try typing here when readonly is removed..."
64
+ class: "ua-demo-input"
65
+ readonly: "readonly"
66
+ style:
67
+ padding: "10px"
68
+ border: "2px solid #007bff"
69
+ borderRadius: "4px"
70
+ fontSize: "16px"
71
+ margin: "10px 0"
72
+ width: "300px"
73
+ display: "block"
74
+ actions:
75
+ - what: unsetAttribute
76
+ name: "readonly"
77
+ when: ~.makeEditable
78
+ is: true
79
+ - what: setData
80
+ on: change
81
+ path: ~.input_value
82
+ value: <reactive-json:event-new-value>
83
+
84
+ - type: style
85
+ content: |
86
+ .ua-demo-input[readonly] {
87
+ cursor: not-allowed !important;
88
+ opacity: 0.7 !important;
89
+ border-color: #6c757d !important;
90
+ }
91
+ .ua-demo-input:not([readonly]) {
92
+ border-color: #28a745 !important;
93
+ outline: 2px solid #28a745 !important;
94
+ outline-offset: 2px !important;
95
+ }
96
+
97
+ data:
98
+ makeEditable: false
99
+ input_value: ""
100
+ ```
101
+
102
+ ## Notes
103
+
104
+ - This action **completely removes the entire attribute**, not just specific values.
105
+ - Use `UnsetAttributeValue` if you only want to remove specific values.
106
+ - The attribute can be restored using `SetAttributeValue` if needed.
107
+ - **Important**: To set an empty attribute (not remove it), use `SetAttributeValue` with an empty string value.
108
+ - Useful for conditional attribute presence rather than conditional values.
@@ -0,0 +1,135 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # UnsetAttribute
5
+
6
+ Completely removes an HTML attribute from an element.
7
+
8
+ ## Basic Syntax
9
+
10
+ - type: TabbedSerializer
11
+ yamlSerializedContent: |
12
+ actions:
13
+ # Remove entire attribute
14
+ - what: unsetAttribute
15
+ name: "class"
16
+
17
+ # Conditional removal
18
+ - what: unsetAttribute
19
+ name: "style"
20
+ when: ~.useDefaultStyling
21
+ is: true
22
+
23
+ - type: Markdown
24
+ content: |
25
+ ## Properties
26
+
27
+ - type: DefinitionList
28
+ content:
29
+ - term:
30
+ code: name
31
+ after: "(string, required)"
32
+ details: The name of the attribute to remove completely.
33
+
34
+ - type: Markdown
35
+ content: |
36
+
37
+ ## Behavior
38
+
39
+ - **Complete removal**: Removes the entire attribute and all its values from the DOM element.
40
+ - **Attribute deletion**: The attribute is completely deleted, not just emptied.
41
+ - **Irreversible**: Once removed, the attribute must be explicitly set again to restore it.
42
+
43
+ ## Common Use Cases
44
+
45
+ - **Conditional attribute presence**: Removing attributes entirely based on conditions.
46
+ - **Accessibility cleanup**: Removing ARIA attributes when not needed.
47
+ - **Data attribute management**: Completely removing data-* attributes.
48
+ - **Style reset**: Removing inline style attributes to fall back to CSS.
49
+
50
+ - type: RjBuildDescriber
51
+ title: "UnsetAttribute Action Examples"
52
+ description:
53
+ - type: Markdown
54
+ content: |
55
+ This example demonstrates how to completely remove HTML attributes using the `UnsetAttribute` action.
56
+
57
+ **Expected behavior:**
58
+ - Initially, the input field is read-only (you cannot type in it) and has visual styling
59
+ - Click "Remove readonly attribute" to remove the entire readonly attribute - the input becomes editable
60
+ - Click "Reset" to restore the readonly attribute - the input becomes read-only again
61
+ - The action completely removes the entire attribute, not just its value
62
+
63
+ Try interacting with the buttons to see how the readonly attribute is completely removed/restored.
64
+
65
+ toDescribe:
66
+ renderView:
67
+ - type: button
68
+ content: "Remove readonly attribute"
69
+ actions:
70
+ - what: setData
71
+ on: click
72
+ path: ~.makeEditable
73
+ value: true
74
+ stopPropagation: true
75
+
76
+ - type: button
77
+ content: "Reset"
78
+ actions:
79
+ - what: setData
80
+ on: click
81
+ path: ~.makeEditable
82
+ value: false
83
+ stopPropagation: true
84
+
85
+ - type: input
86
+ attributes:
87
+ type: "text"
88
+ value: ~.input_value
89
+ placeholder: "Try typing here when readonly is removed..."
90
+ class: "ua-demo-input"
91
+ readonly: "readonly"
92
+ style:
93
+ padding: "10px"
94
+ border: "2px solid #007bff"
95
+ borderRadius: "4px"
96
+ fontSize: "16px"
97
+ margin: "10px 0"
98
+ width: "300px"
99
+ display: "block"
100
+ actions:
101
+ - what: unsetAttribute
102
+ name: "readonly"
103
+ when: ~.makeEditable
104
+ is: true
105
+ - what: setData
106
+ on: change
107
+ path: ~.input_value
108
+ value: <reactive-json:event-new-value>
109
+
110
+ - type: style
111
+ content: |
112
+ .ua-demo-input[readonly] {
113
+ cursor: not-allowed !important;
114
+ opacity: 0.7 !important;
115
+ border-color: #6c757d !important;
116
+ }
117
+ .ua-demo-input:not([readonly]) {
118
+ border-color: #28a745 !important;
119
+ outline: 2px solid #28a745 !important;
120
+ outline-offset: 2px !important;
121
+ }
122
+
123
+ data:
124
+ makeEditable: false
125
+ input_value: ""
126
+
127
+ - type: Markdown
128
+ content: |
129
+ ## Notes
130
+
131
+ - This action **completely removes the entire attribute**, not just specific values.
132
+ - Use `UnsetAttributeValue` if you only want to remove specific values.
133
+ - The attribute can be restored using `SetAttributeValue` if needed.
134
+ - **Important**: To set an empty attribute (not remove it), use `SetAttributeValue` with an empty string value.
135
+ - Useful for conditional attribute presence rather than conditional values.
@@ -0,0 +1,135 @@
1
+ # UnsetAttributeValue
2
+
3
+ Removes a specific value from an HTML attribute while preserving other values.
4
+
5
+ ## Basic Syntax
6
+
7
+ ```yaml
8
+ actions:
9
+ # Remove CSS class
10
+ - what: unsetAttributeValue
11
+ name: "class"
12
+ value: "highlighted"
13
+
14
+ # Remove with template
15
+ - what: unsetAttributeValue
16
+ name: "data-tags"
17
+ value: ~.tagToRemove
18
+ ```
19
+
20
+ ## Properties
21
+
22
+ - **name** *(string, required)*: The name of the attribute to modify.
23
+ - **separator** *(string, optional)*: The separator used between values. Default: `" "` (space).
24
+ - **unsetAllOccurrences** *(boolean, optional)*: When `true` (default), removes all occurrences of the value from the attribute. When `false`, removes the number of elements defined by `unsetCount`.
25
+ - **unsetCount** *(number, optional)*: Specifies the number of objects to remove. Supports template evaluation and is cast to integer. When `0`, removes nothing. When `1` or more, removes the specified number of elements starting from the beginning of the string. When `-1` or less, removes the specified number of elements starting from the end of the string. When undefined or invalid, defaults to removing all occurrences (equivalent to `unsetAllOccurrences: true`).
26
+ - **value** *(string, required)*: The value to remove from the attribute. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`). Automatically converted to string if not already.
27
+
28
+ ## Behavior
29
+
30
+ - **Selective removal**: Removes only the specified value from the attribute.
31
+ - **Occurrence control**: Removes all occurrences by default, or only the first when configured.
32
+ - **Count control**: When `unsetCount` is specified, controls the exact number of elements to remove and the direction (from beginning or end).
33
+ - **Preservation**: Other values in the attribute remain intact.
34
+
35
+ ## Logic Reference
36
+
37
+ ### Behavior Matrix
38
+
39
+ | `unsetAllOccurrences` | `unsetCount` | Behavior | Notes |
40
+ |:---------------------:|:------------:|:---------|:------|
41
+ | `true` | *ignored* | **Removes ALL occurrences** | `unsetCount` is completely ignored |
42
+ | `false` | `1` | Removes **1 occurrence** from beginning | Default behavior when `unsetCount` is valid |
43
+ | `false` | `2` | Removes **2 occurrences** from beginning | |
44
+ | `false` | `-1` | Removes **1 occurrence** from end | |
45
+ | `false` | `-2` | Removes **2 occurrences** from end | |
46
+ | `false` | `0` | **Removes nothing** | |
47
+ | `false` | `undefined` | **Removes ALL occurrences** | Fallback to "all" behavior |
48
+ | `false` | `null` | **Removes ALL occurrences** | Fallback to "all" behavior |
49
+ | `false` | `"invalid"` | **Removes ALL occurrences** | Fallback to "all" behavior |
50
+ | `undefined` | `1` | Removes **1 occurrence** from beginning | `unsetAllOccurrences` defaults to `true`, but valid `unsetCount` applies |
51
+ | `undefined` | `-1` | Removes **1 occurrence** from end | |
52
+ | `undefined` | `0` | **Removes nothing** | |
53
+ | `undefined` | `undefined` | **Removes ALL occurrences** | Complete default behavior |
54
+
55
+ ### Logic Summary
56
+
57
+ 1. **If `unsetAllOccurrences: true`** → removes ALL, ignores `unsetCount`
58
+ 2. **If `unsetAllOccurrences: false` AND `unsetCount` valid** → uses `unsetCount`
59
+ 3. **If `unsetCount` invalid/undefined** → fallback to "remove ALL" even if `unsetAllOccurrences: false`
60
+ 4. **If nothing is defined** → default behavior = "remove ALL"
61
+
62
+ This logic ensures there is always a defined behavior, with an intelligent fallback to "remove all" when parameters are invalid.
63
+
64
+ ## Common Use Cases
65
+
66
+ - **CSS class removal**: Removing specific CSS classes while keeping others.
67
+ - **Data attribute cleanup**: Removing specific values from space-separated data attributes.
68
+ - **Conditional styling**: Removing styling classes based on state changes.
69
+
70
+ ## Example
71
+
72
+ ```yaml
73
+ renderView:
74
+ - type: button
75
+ content: "Remove 'highlighted' class"
76
+ actions:
77
+ - what: setData
78
+ on: click
79
+ path: ~.removeHighlight
80
+ value: true
81
+ stopPropagation: true
82
+
83
+ - type: button
84
+ content: "Reset"
85
+ actions:
86
+ - what: setData
87
+ on: click
88
+ path: ~.removeHighlight
89
+ value: false
90
+ stopPropagation: true
91
+
92
+ - type: input
93
+ attributes:
94
+ type: "text"
95
+ value: "This input has multiple classes..."
96
+ class: "uav-readonly uav-highlighted"
97
+ readonly: "readonly"
98
+ style:
99
+ padding: "10px"
100
+ border: "2px solid #007bff"
101
+ borderRadius: "4px"
102
+ fontSize: "16px"
103
+ margin: "10px 0"
104
+ width: "300px"
105
+ display: "block"
106
+ actions:
107
+ - what: unsetAttributeValue
108
+ name: "class"
109
+ value: "uav-highlighted"
110
+ when: ~.removeHighlight
111
+ is: true
112
+
113
+ - type: style
114
+ content: |
115
+ .uav-readonly {
116
+ cursor: not-allowed !important;
117
+ opacity: 0.7 !important;
118
+ }
119
+ .uav-highlighted {
120
+ border-color: #ffc107 !important;
121
+ outline: 2px solid #ffc107 !important;
122
+ outline-offset: 2px !important;
123
+ }
124
+
125
+ data:
126
+ removeHighlight: false
127
+ ```
128
+
129
+ ## Notes
130
+
131
+ - Only removes exact matches of the specified value.
132
+ - Maintains the integrity of other attribute values.
133
+ - Works with any space-separated attribute values.
134
+ - Safe to use even if the value doesn't exist in the attribute.
135
+ - The value property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
@@ -0,0 +1,185 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # UnsetAttributeValue
5
+
6
+ Removes a specific value from an HTML attribute while preserving other values.
7
+
8
+ ## Basic Syntax
9
+
10
+ - type: TabbedSerializer
11
+ yamlSerializedContent: |
12
+ actions:
13
+ # Remove CSS class
14
+ - what: unsetAttributeValue
15
+ name: "class"
16
+ value: "highlighted"
17
+
18
+ # Remove with template
19
+ - what: unsetAttributeValue
20
+ name: "data-tags"
21
+ value: ~.tagToRemove
22
+
23
+ - type: Markdown
24
+ content: |
25
+ ## Properties
26
+
27
+ - type: DefinitionList
28
+ content:
29
+ - term:
30
+ code: name
31
+ after: "(string, required)"
32
+ details: The name of the attribute to modify.
33
+ - term:
34
+ code: separator
35
+ after: "(string, optional)"
36
+ details:
37
+ type: Markdown
38
+ content: |
39
+ The separator used between values. Default: `" "` (space).
40
+ - term:
41
+ code: unsetAllOccurrences
42
+ after: "(boolean, optional)"
43
+ details:
44
+ type: Markdown
45
+ content: |
46
+ When `true` (default), removes all occurrences of the value from the attribute. When `false`, removes the number of elements defined by `unsetCount`.
47
+ - term:
48
+ code: unsetCount
49
+ after: "(number, optional)"
50
+ details:
51
+ type: Markdown
52
+ content: |
53
+ Specifies the number of objects to remove. Supports template evaluation and is cast to integer. When `0`, removes nothing. When `1` or more, removes the specified number of elements starting from the beginning of the string. When `-1` or less, removes the specified number of elements starting from the end of the string. When undefined or invalid, defaults to removing all occurrences (equivalent to `unsetAllOccurrences: true`).
54
+ - term:
55
+ code: value
56
+ after: "(string, required)"
57
+ details:
58
+ type: Markdown
59
+ content: |
60
+ The value to remove from the attribute. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`). Automatically converted to string if not already.
61
+
62
+ - type: Markdown
63
+ content: |
64
+ ## Behavior
65
+
66
+ - **Selective removal**: Removes only the specified value from the attribute.
67
+ - **Occurrence control**: Removes all occurrences by default, or only the first when configured.
68
+ - **Count control**: When `unsetCount` is specified, controls the exact number of elements to remove and the direction (from beginning or end).
69
+ - **Preservation**: Other values in the attribute remain intact.
70
+
71
+ ## Logic Reference
72
+
73
+ ### Behavior Matrix
74
+
75
+ | `unsetAllOccurrences` | `unsetCount` | Behavior | Notes |
76
+ |:---------------------:|:------------:|:---------|:------|
77
+ | `true` | *ignored* | **Removes ALL occurrences** | `unsetCount` is completely ignored |
78
+ | `false` | `1` | Removes **1 occurrence** from beginning | Default behavior when `unsetCount` is valid |
79
+ | `false` | `2` | Removes **2 occurrences** from beginning | |
80
+ | `false` | `-1` | Removes **1 occurrence** from end | |
81
+ | `false` | `-2` | Removes **2 occurrences** from end | |
82
+ | `false` | `0` | **Removes nothing** | |
83
+ | `false` | `undefined` | **Removes ALL occurrences** | Fallback to "all" behavior |
84
+ | `false` | `null` | **Removes ALL occurrences** | Fallback to "all" behavior |
85
+ | `false` | `"invalid"` | **Removes ALL occurrences** | Fallback to "all" behavior |
86
+ | `undefined` | `1` | Removes **1 occurrence** from beginning | `unsetAllOccurrences` defaults to `true`, but valid `unsetCount` applies |
87
+ | `undefined` | `-1` | Removes **1 occurrence** from end | |
88
+ | `undefined` | `0` | **Removes nothing** | |
89
+ | `undefined` | `undefined` | **Removes ALL occurrences** | Complete default behavior |
90
+
91
+ ### Logic Summary
92
+
93
+ 1. **If `unsetAllOccurrences: true`** → removes ALL, ignores `unsetCount`
94
+ 2. **If `unsetAllOccurrences: false` AND `unsetCount` valid** → uses `unsetCount`
95
+ 3. **If `unsetCount` invalid/undefined** → fallback to "remove ALL" even if `unsetAllOccurrences: false`
96
+ 4. **If nothing is defined** → default behavior = "remove ALL"
97
+
98
+ This logic ensures there is always a defined behavior, with an intelligent fallback to "remove all" when parameters are invalid.
99
+
100
+ ## Common Use Cases
101
+
102
+ - **CSS class removal**: Removing specific CSS classes while keeping others.
103
+ - **Data attribute cleanup**: Removing specific values from space-separated data attributes.
104
+ - **Conditional styling**: Removing styling classes based on state changes.
105
+
106
+ - type: RjBuildDescriber
107
+ title: "UnsetAttributeValue Action Examples"
108
+ description:
109
+ - type: Markdown
110
+ content: |
111
+ This example demonstrates how to selectively remove specific CSS classes using the `UnsetAttributeValue` action.
112
+
113
+ **Expected behavior:**
114
+ - Initially, the input field has both 'readonly' and 'highlighted' classes (readonly + visual styling)
115
+ - Click "Remove 'highlighted' class" to remove only the 'highlighted' class (removing visual styling but keeping readonly)
116
+ - Click "Reset" to restore the original classes
117
+ - Notice how only the specified value is removed while other classes remain intact
118
+
119
+ Try interacting with the buttons to see how specific classes are selectively removed.
120
+
121
+ toDescribe:
122
+ renderView:
123
+ - type: button
124
+ content: "Remove 'highlighted' class"
125
+ actions:
126
+ - what: setData
127
+ on: click
128
+ path: ~.removeHighlight
129
+ value: true
130
+ stopPropagation: true
131
+
132
+ - type: button
133
+ content: "Reset"
134
+ actions:
135
+ - what: setData
136
+ on: click
137
+ path: ~.removeHighlight
138
+ value: false
139
+ stopPropagation: true
140
+
141
+ - type: input
142
+ attributes:
143
+ type: "text"
144
+ value: "This input has multiple classes..."
145
+ class: "uav-readonly uav-highlighted"
146
+ readonly: "readonly"
147
+ style:
148
+ padding: "10px"
149
+ border: "2px solid #007bff"
150
+ borderRadius: "4px"
151
+ fontSize: "16px"
152
+ margin: "10px 0"
153
+ width: "300px"
154
+ display: "block"
155
+ actions:
156
+ - what: unsetAttributeValue
157
+ name: "class"
158
+ value: "uav-highlighted"
159
+ when: ~.removeHighlight
160
+ is: true
161
+
162
+ - type: style
163
+ content: |
164
+ .uav-readonly {
165
+ cursor: not-allowed !important;
166
+ opacity: 0.7 !important;
167
+ }
168
+ .uav-highlighted {
169
+ border-color: #ffc107 !important;
170
+ outline: 2px solid #ffc107 !important;
171
+ outline-offset: 2px !important;
172
+ }
173
+
174
+ data:
175
+ removeHighlight: false
176
+
177
+ - type: Markdown
178
+ content: |
179
+ ## Notes
180
+
181
+ - Only removes exact matches of the specified value.
182
+ - Maintains the integrity of other attribute values.
183
+ - Works with any space-separated attribute values.
184
+ - Safe to use even if the value doesn't exist in the attribute.
185
+ - The value property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
@@ -17,6 +17,12 @@ Actions in Reactive-JSON allow you to modify element behavior and appearance bas
17
17
  ### Navigation
18
18
  - **[Redirect](./Redirect.md)**: Redirects to a specified URL
19
19
 
20
+ ### Attribute Management
21
+ - **[SetAttributeValue](./Attribute/SetAttributeValue.md)**: Sets or modifies HTML attribute values dynamically
22
+ - **[UnsetAttribute](./Attribute/UnsetAttribute.md)**: Completely removes HTML attributes
23
+ - **[UnsetAttributeValue](./Attribute/UnsetAttributeValue.md)**: Removes specific values from HTML attributes
24
+ - **[ToggleAttributeValue](./Attribute/ToggleAttributeValue.md)**: Toggles the presence of specific values in HTML attributes
25
+
20
26
  ### Event Management
21
27
 
22
28
  Those actions have a special handling in Reactive-JSON. The engine transparently load them
@@ -20,6 +20,12 @@ renderView:
20
20
  ### Navigation
21
21
  - **[Redirect](./Redirect)**: Redirects to a specified URL
22
22
 
23
+ ### Attribute Management
24
+ - **[SetAttributeValue](./Attribute/SetAttributeValue)**: Sets or modifies HTML attribute values dynamically
25
+ - **[UnsetAttribute](./Attribute/UnsetAttribute)**: Completely removes HTML attributes
26
+ - **[UnsetAttributeValue](./Attribute/UnsetAttributeValue)**: Removes specific values from HTML attributes
27
+ - **[ToggleAttributeValue](./Attribute/ToggleAttributeValue)**: Toggles the presence of specific values in HTML attributes
28
+
23
29
  ### Event Management
24
30
 
25
31
  Those actions have a special handling in Reactive-JSON. The engine transparently load them