@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 +5 -2
- package/public/rjbuild/docs/core/action/Attribute/SetAttributeValue.md +93 -0
- package/public/rjbuild/docs/core/action/Attribute/SetAttributeValue.yaml +141 -0
- package/public/rjbuild/docs/core/action/Attribute/ToggleAttributeValue.md +267 -0
- package/public/rjbuild/docs/core/action/Attribute/ToggleAttributeValue.yaml +244 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttribute.md +108 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttribute.yaml +135 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttributeValue.md +135 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttributeValue.yaml +185 -0
- package/public/rjbuild/docs/core/action/index.md +6 -0
- package/public/rjbuild/docs/core/action/index.yaml +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ea-lab/reactive-json-docs",
|
|
3
|
-
"version": "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.
|
|
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
|