agent-docs 1.3.0 → 1.4.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.
@@ -11,20 +11,23 @@
11
11
  ## Template Structure
12
12
 
13
13
  - **Root element:** `<template>` (renders as `<namespace-component-name>`)
14
- - **Nested `<template>` tags:** required for directives; only allowed attributes:
15
- - `for:each`, `iterator:iteratorname`, `lwc:if`, `lwc:else`, `lwc:elseif`, `if:true|false`
16
- - No other directives or HTML attributes (e.g., no `class` on nested `<template>`)
14
+ - **Nested `<template>` tags:** required for directives; only allowed
15
+ attributes:
16
+ - `for:each`, `iterator:iteratorname`, `lwc:if`, `lwc:else`, `lwc:elseif`,
17
+ `if:true|false`
18
+ - No other directives or HTML attributes (e.g., no `class` on nested
19
+ `<template>`)
17
20
  - **No inline `<style>` or `<script>` tags** — use separate CSS/JS files
18
21
  - Follow Lightning Design System patterns and accessibility guidelines
19
22
 
20
23
  ## Data Binding & Expressions
21
24
 
22
- | Syntax | Usage |
23
- |--------|-------|
24
- | `{property}` | Bind data (no spaces around property) |
25
- | `{data.name}` | Dot notation supported |
26
- | `{!property}` | Two-way binding (form inputs) |
27
- | `{handlerMethod}` | Event handler binding |
25
+ | Syntax | Usage |
26
+ | ----------------- | ------------------------------------- |
27
+ | `{property}` | Bind data (no spaces around property) |
28
+ | `{data.name}` | Dot notation supported |
29
+ | `{!property}` | Two-way binding (form inputs) |
30
+ | `{handlerMethod}` | Event handler binding |
28
31
 
29
32
  ### Allowed Expression Syntax
30
33
 
@@ -40,8 +43,7 @@ The `{expression}` binding syntax **only** supports:
40
43
 
41
44
  ```html
42
45
  <!-- ❌ Logical operators -->
43
- {isReadOnly || isLoading}
44
- {isActive && isVisible}
46
+ {isReadOnly || isLoading} {isActive && isVisible}
45
47
 
46
48
  <!-- ❌ Negation operator -->
47
49
  {!isDisabled}
@@ -50,28 +52,22 @@ The `{expression}` binding syntax **only** supports:
50
52
  {isActive ? 'active' : 'inactive'}
51
53
 
52
54
  <!-- ❌ Arithmetic -->
53
- {count + 1}
54
- {price * quantity}
55
+ {count + 1} {price * quantity}
55
56
 
56
57
  <!-- ❌ Array indexing -->
57
- {items[0].name}
58
- {person[2].name['John']}
58
+ {items[0].name} {person[2].name['John']}
59
59
 
60
60
  <!-- ❌ Function calls in templates -->
61
- {formatDate(startDate)}
62
- {calculateTotal()}
61
+ {formatDate(startDate)} {calculateTotal()}
63
62
 
64
63
  <!-- ❌ String concatenation -->
65
- {'Hello ' + name}
66
- {`Item: ${itemName}`}
64
+ {'Hello ' + name} {`Item: ${itemName}`}
67
65
 
68
66
  <!-- ❌ Comparisons -->
69
- {count > 0}
70
- {status === 'active'}
67
+ {count > 0} {status === 'active'}
71
68
 
72
69
  <!-- ❌ Nullish coalescing / optional chaining in binding -->
73
- {user?.name}
74
- {value ?? 'default'}
70
+ {user?.name} {value ?? 'default'}
75
71
  ```
76
72
 
77
73
  ### ✅ The Solution: Use JavaScript Getters
@@ -79,75 +75,78 @@ The `{expression}` binding syntax **only** supports:
79
75
  All computed logic **must** be moved to getters in the JavaScript class:
80
76
 
81
77
  **JavaScript (myComponent.js):**
78
+
82
79
  ```javascript
83
80
  import { LightningElement, api, track } from 'lwc';
84
81
 
85
82
  export default class MyComponent extends LightningElement {
86
- @api isReadOnly = false;
87
- @api isLoading = false;
88
- @track items = [];
89
-
90
- // ✅ Logical operators → getter
91
- get isDisabled() {
92
- return this.isReadOnly || this.isLoading;
93
- }
94
-
95
- // ✅ Negation → getter
96
- get isEnabled() {
97
- return !this.isDisabled;
98
- }
99
-
100
- // ✅ Ternary → getter
101
- get buttonLabel() {
102
- return this.isLoading ? 'Loading...' : 'Submit';
103
- }
104
-
105
- // ✅ Arithmetic → getter
106
- get itemCountPlusOne() {
107
- return this.count + 1;
108
- }
109
-
110
- // ✅ Array indexing → getter
111
- get firstItemName() {
112
- return this.items[0]?.name || '';
113
- }
114
-
115
- // ✅ String formatting → getter
116
- get formattedCount() {
117
- return `${this.count} items`;
118
- }
119
-
120
- // ✅ Comparisons for conditional rendering → getter
121
- get hasItems() {
122
- return this.items.length > 0;
123
- }
124
-
125
- // ✅ Complex class computation → getter
126
- get containerClass() {
127
- return {
128
- 'slds-box': true,
129
- 'slds-theme_shade': this.isActive,
130
- 'slds-hide': !this.isVisible
131
- };
132
- }
83
+ @api isReadOnly = false;
84
+ @api isLoading = false;
85
+ @track items = [];
86
+
87
+ // ✅ Logical operators → getter
88
+ get isDisabled() {
89
+ return this.isReadOnly || this.isLoading;
90
+ }
91
+
92
+ // ✅ Negation → getter
93
+ get isEnabled() {
94
+ return !this.isDisabled;
95
+ }
96
+
97
+ // ✅ Ternary → getter
98
+ get buttonLabel() {
99
+ return this.isLoading ? 'Loading...' : 'Submit';
100
+ }
101
+
102
+ // ✅ Arithmetic → getter
103
+ get itemCountPlusOne() {
104
+ return this.count + 1;
105
+ }
106
+
107
+ // ✅ Array indexing → getter
108
+ get firstItemName() {
109
+ return this.items[0]?.name || '';
110
+ }
111
+
112
+ // ✅ String formatting → getter
113
+ get formattedCount() {
114
+ return `${this.count} items`;
115
+ }
116
+
117
+ // ✅ Comparisons for conditional rendering → getter
118
+ get hasItems() {
119
+ return this.items.length > 0;
120
+ }
121
+
122
+ // ✅ Complex class computation → getter
123
+ get containerClass() {
124
+ return {
125
+ 'slds-box': true,
126
+ 'slds-theme_shade': this.isActive,
127
+ 'slds-hide': !this.isVisible,
128
+ };
129
+ }
133
130
  }
134
131
  ```
135
132
 
136
133
  **HTML (myComponent.html):**
134
+
137
135
  ```html
138
136
  <template>
139
- <template lwc:if={hasItems}>
140
- <div class={containerClass}>
141
- <p>{formattedCount}</p>
142
- <p>First item: {firstItemName}</p>
143
- </div>
144
- </template>
145
-
146
- <lightning-button
147
- label={buttonLabel}
148
- disabled={isDisabled}
149
- onclick={handleClick}>
150
- </lightning-button>
137
+ <template lwc:if="{hasItems}">
138
+ <div class="{containerClass}">
139
+ <p>{formattedCount}</p>
140
+ <p>First item: {firstItemName}</p>
141
+ </div>
142
+ </template>
143
+
144
+ <lightning-button
145
+ label="{buttonLabel}"
146
+ disabled="{isDisabled}"
147
+ onclick="{handleClick}"
148
+ >
149
+ </lightning-button>
151
150
  </template>
152
151
  ```
153
152
 
@@ -155,17 +154,20 @@ export default class MyComponent extends LightningElement {
155
154
 
156
155
  Salesforce made this intentional choice for:
157
156
 
158
- | Reason | Explanation |
159
- |--------|-------------|
160
- | **Performance** | Simple property lookups are fast; no runtime expression parsing/evaluation |
161
- | **Security** | No risk of template injection or expression-based exploits |
162
- | **Predictability** | Reactivity is straightforward—change a property, component re-renders |
163
- | **Testability** | All logic lives in unit-testable JavaScript, not scattered in templates |
164
- | **Debugging** | Stack traces point to JS files, not opaque template expressions |
157
+ | Reason | Explanation |
158
+ | ------------------ | -------------------------------------------------------------------------- |
159
+ | **Performance** | Simple property lookups are fast; no runtime expression parsing/evaluation |
160
+ | **Security** | No risk of template injection or expression-based exploits |
161
+ | **Predictability** | Reactivity is straightforward—change a property, component re-renders |
162
+ | **Testability** | All logic lives in unit-testable JavaScript, not scattered in templates |
163
+ | **Debugging** | Stack traces point to JS files, not opaque template expressions |
165
164
 
166
165
  ### AI Agent Rule Summary
167
166
 
168
- > **LWC Template Expression Rule:** The `{...}` binding syntax accepts ONLY property names and dot-notation paths. Any logic requiring operators (`||`, `&&`, `?:`, `+`, `>`, `===`, etc.), function calls, array indexing, or string interpolation MUST be implemented as a getter in the JavaScript class.
167
+ > **LWC Template Expression Rule:** The `{...}` binding syntax accepts ONLY
168
+ > property names and dot-notation paths. Any logic requiring operators (`||`,
169
+ > `&&`, `?:`, `+`, `>`, `===`, etc.), function calls, array indexing, or string
170
+ > interpolation MUST be implemented as a getter in the JavaScript class.
169
171
 
170
172
  ```
171
173
  Template binding: {propertyName} or {object.nested.property}
@@ -174,41 +176,49 @@ Computed logic: get computedProperty() { return /* any JS expression */; }
174
176
 
175
177
  ## Conditional Rendering
176
178
 
177
- Use `lwc:if`, `lwc:elseif`, `lwc:else` directives (prefer over multiple templates for simple conditions):
179
+ Use `lwc:if`, `lwc:elseif`, `lwc:else` directives (prefer over multiple
180
+ templates for simple conditions):
178
181
 
179
182
  ```html
180
- <template lwc:if={condition}>...</template>
181
- <template lwc:elseif={otherCondition}>...</template>
183
+ <template lwc:if="{condition}">...</template>
184
+ <template lwc:elseif="{otherCondition}">...</template>
182
185
  <template lwc:else>...</template>
183
186
  ```
184
187
 
185
- **Note:** The condition must be a simple property reference or getter—not an expression:
188
+ **Note:** The condition must be a simple property reference or getter—not an
189
+ expression:
186
190
 
187
191
  ```html
188
192
  <!-- ❌ Invalid -->
189
- <template lwc:if={items.length > 0}>
193
+ <template lwc:if="{items.length">
194
+ 0}>
190
195
 
191
- <!-- ✅ Valid — use a getter -->
192
- <template lwc:if={hasItems}>
196
+ <!-- ✅ Valid — use a getter -->
197
+ <template lwc:if="{hasItems}"></template
198
+ ></template>
193
199
  ```
194
200
 
195
201
  ## List Rendering
196
202
 
197
203
  ### for:each
204
+
198
205
  ```html
199
- <template for:each={array} for:item="item">
200
- <div key={item.uniqueId}>{item.property}</div>
206
+ <template for:each="{array}" for:item="item">
207
+ <div key="{item.uniqueId}">{item.property}</div>
201
208
  </template>
202
209
  ```
210
+
203
211
  - `key` required: string/number, **not** index or object
204
212
  - Access current item via `for:item="itemName"` → `{itemName.property}`
205
213
 
206
214
  ### iterator
215
+
207
216
  ```html
208
- <template iterator:it={array}>
209
- <div key={it.value.uniqueId}>{it.value.property}</div>
217
+ <template iterator:it="{array}">
218
+ <div key="{it.value.uniqueId}">{it.value.property}</div>
210
219
  </template>
211
220
  ```
221
+
212
222
  - Iterator name must be lowercase
213
223
  - Properties: `{it.value.property}`, `{it.index}`, `{it.first}`, `{it.last}`
214
224
  - Combine with `lwc:if` for first/last styling: `lwc:if={it.first}`
@@ -219,21 +229,24 @@ Use `lwc:if`, `lwc:elseif`, `lwc:else` directives (prefer over multiple template
219
229
  - Override `render()` to return template based on state
220
230
  - CSS must match template filename: `templateTwo.html` → `templateTwo.css`
221
231
  - Default: `componentName.html` when no `render()` override
222
- - **Prefer `lwc:if` for simple variations; use multiple templates for significantly different layouts**
232
+ - **Prefer `lwc:if` for simple variations; use multiple templates for
233
+ significantly different layouts**
223
234
 
224
235
  ## Class Object Binding (LWC API v62.0+)
225
236
 
226
237
  Bind dynamic classes using arrays or objects instead of string concatenation:
227
238
 
228
- | Input | Output |
229
- |-------|--------|
230
- | `["highlight", "yellow"]` | `class="highlight yellow"` |
231
- | `{highlight: true, hidden: false}` | `class="highlight"` |
239
+ | Input | Output |
240
+ | ---------------------------------- | -------------------------- |
241
+ | `["highlight", "yellow"]` | `class="highlight yellow"` |
242
+ | `{highlight: true, hidden: false}` | `class="highlight"` |
232
243
 
233
- - Booleans, numbers, functions render as empty string (use `String(value)` if needed)
244
+ - Booleans, numbers, functions render as empty string (use `String(value)` if
245
+ needed)
234
246
  - Use getters to compute complex class combinations
235
247
 
236
248
  **Example with getter:**
249
+
237
250
  ```javascript
238
251
  get cardClasses() {
239
252
  return {
@@ -245,7 +258,7 @@ get cardClasses() {
245
258
  ```
246
259
 
247
260
  ```html
248
- <div class={cardClasses}>...</div>
261
+ <div class="{cardClasses}">...</div>
249
262
  ```
250
263
 
251
264
  ## Inline Style Binding
@@ -253,9 +266,11 @@ get cardClasses() {
253
266
  - Syntax: `style={computedStyles}`
254
267
  - Getter returns semi-colon separated properties: `width: 50%; font-size: 20px`
255
268
  - Use kebab-case CSS properties (`font-size`, not `fontSize`)
256
- - **Prefer CSS classes over inline styles**; use inline for dynamic/computed values only
269
+ - **Prefer CSS classes over inline styles**; use inline for dynamic/computed
270
+ values only
257
271
 
258
272
  **Example:**
273
+
259
274
  ```javascript
260
275
  get progressBarStyle() {
261
276
  return `width: ${this.progressPercent}%; background-color: ${this.barColor}`;
@@ -263,7 +278,7 @@ get progressBarStyle() {
263
278
  ```
264
279
 
265
280
  ```html
266
- <div class="progress-bar" style={progressBarStyle}></div>
281
+ <div class="progress-bar" style="{progressBarStyle}"></div>
267
282
  ```
268
283
 
269
284
  ## Event Handling
@@ -275,10 +290,12 @@ get progressBarStyle() {
275
290
 
276
291
  ```html
277
292
  <!-- ❌ Invalid — no inline functions -->
278
- <button onclick={() => this.handleClick()}>
293
+ <button onclick="{()" ="">
294
+ this.handleClick()}>
279
295
 
280
- <!-- ✅ Valid — method reference -->
281
- <button onclick={handleClick}>
296
+ <!-- ✅ Valid — method reference -->
297
+ <button onclick="{handleClick}"></button>
298
+ </button>
282
299
  ```
283
300
 
284
301
  ## Accessibility
@@ -292,7 +309,8 @@ get progressBarStyle() {
292
309
  - Minimize DOM manipulation
293
310
  - Use lazy loading / pagination for large lists
294
311
  - Avoid unnecessary rerenders by optimizing data binding
295
- - Getters are re-evaluated on every render—keep them lightweight or cache expensive computations
312
+ - Getters are re-evaluated on every render—keep them lightweight or cache
313
+ expensive computations
296
314
 
297
315
  ## Validation Checklist
298
316
 
@@ -303,11 +321,13 @@ get progressBarStyle() {
303
321
  - [ ] No inline `<style>` or `<script>` tags
304
322
  - [ ] No manual DOM manipulation in JS
305
323
  - [ ] Data binding: `{property}` syntax, no spaces
306
- - [ ] **No computed expressions in templates** (no operators, function calls, array indexing)
324
+ - [ ] **No computed expressions in templates** (no operators, function calls,
325
+ array indexing)
307
326
  - [ ] **All computed logic implemented as getters in JS class**
308
327
  - [ ] `for:each`: has `for:item` and unique `key` (string/number)
309
328
  - [ ] `iterator`: lowercase name, unique `key={it.value.uniqueId}`
310
- - [ ] Multiple templates: proper imports, `render()` override, matching CSS filenames
329
+ - [ ] Multiple templates: proper imports, `render()` override, matching CSS
330
+ filenames
311
331
  - [ ] Class binding follows v62.0+ semantics (arrays/objects via getters)
312
332
  - [ ] Inline styles: `style={getter}`, kebab-case properties
313
333
  - [ ] Valid HTML syntax (use Salesforce Extensions Pack for validation)