@salesforce/afv-skills 1.5.2 → 1.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/README.md +5 -6
- package/package.json +3 -3
- package/skills/generating-apex/SKILL.md +16 -9
- package/skills/generating-apex/assets/abstract.cls +0 -1
- package/skills/generating-apex/assets/batch.cls +0 -1
- package/skills/generating-apex/assets/domain.cls +0 -1
- package/skills/generating-apex/assets/dto.cls +0 -1
- package/skills/generating-apex/assets/exception.cls +0 -1
- package/skills/generating-apex/assets/interface.cls +0 -1
- package/skills/generating-apex/assets/invocable.cls +0 -1
- package/skills/generating-apex/assets/queueable.cls +0 -1
- package/skills/generating-apex/assets/schedulable.cls +0 -1
- package/skills/generating-apex/assets/selector.cls +0 -1
- package/skills/generating-apex/assets/service.cls +0 -1
- package/skills/generating-apex/assets/trigger.cls +1 -1
- package/skills/generating-apex/assets/utility.cls +0 -1
- package/skills/generating-apex/references/AccountDeduplicationBatch.cls +0 -1
- package/skills/generating-apex/references/AccountSelector.cls +0 -1
- package/skills/generating-apex/references/AccountService.cls +0 -1
- package/skills/generating-apex-test/assets/test-class-template.cls +3 -3
- package/skills/generating-apex-test/references/assertion-patterns.md +1 -1
- package/skills/generating-apex-test/references/async-testing.md +1 -1
- package/skills/generating-experience-lwr-site/SKILL.md +1 -2
- package/skills/generating-experience-lwr-site/docs/configure-content-themeLayout.md +8 -5
- package/skills/uplifting-components-to-slds2/SKILL.md +236 -0
- package/skills/uplifting-components-to-slds2/references/color-hooks-decision-guide.md +438 -0
- package/skills/uplifting-components-to-slds2/references/common-patterns.md +87 -0
- package/skills/uplifting-components-to-slds2/references/examples.md +443 -0
- package/skills/uplifting-components-to-slds2/references/migration-checklist.md +67 -0
- package/skills/uplifting-components-to-slds2/references/non-color-hooks-decision-guide.md +333 -0
- package/skills/uplifting-components-to-slds2/references/rule-lwc-token-to-slds-hook.md +135 -0
- package/skills/uplifting-components-to-slds2/references/rule-no-deprecated-tokens-slds1.md +211 -0
- package/skills/uplifting-components-to-slds2/references/rule-no-hardcoded-values.md +160 -0
- package/skills/uplifting-components-to-slds2/references/rule-no-slds-class-overrides.md +126 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Non-Color Styling Hooks Guide
|
|
2
|
+
|
|
3
|
+
Reference for replacing hardcoded spacing, sizing, typography, border, radius, and shadow values with SLDS 2 styling hooks. These hooks use numbered scales with straightforward mappings — unlike color hooks, they rarely require context-based decisions.
|
|
4
|
+
|
|
5
|
+
**Pattern for all replacements:**
|
|
6
|
+
```css
|
|
7
|
+
property: var(--slds-g-[hook], originalValue);
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
**Important: Only replace values that match a hook's actual rendered value.** If a hardcoded value falls between two hooks (e.g., `3px` when hooks offer `4px` and `8px`), leave it unchanged. The linter auto-fix handles exact matches; manual fixes should only apply when there's a clear correspondence. Forcing a non-matching value into the nearest hook changes the component's visual appearance.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Critical Rule: Never Invent Hooks
|
|
15
|
+
|
|
16
|
+
**Only use hooks that actually exist in SLDS 2.** The linter is the source of truth for which hooks exist and what values they map to. Do not:
|
|
17
|
+
|
|
18
|
+
- **Guess hook names** — Hooks like `--slds-g-spacing-medium`, `--slds-g-font-weight-bold`, `--slds-g-radius-large` do NOT exist. SLDS 2 uses numbered scales only (e.g., `--slds-g-spacing-4`, `--slds-g-font-weight-7`).
|
|
19
|
+
- **Extrapolate patterns** — If you see `--slds-g-spacing-1` through `--slds-g-spacing-12`, do not assume `--slds-g-spacing-13` exists. Each category has a fixed scale defined by the design system.
|
|
20
|
+
- **Invent semantic names** — There are no `--slds-g-spacing-page`, `--slds-g-font-heading`, or `--slds-g-shadow-modal` hooks. Hooks are numeric, not semantic.
|
|
21
|
+
|
|
22
|
+
**When unsure whether a hook exists:** Run the linter (`npx @salesforce-ux/slds-linter@latest lint --fix .`). It will suggest valid hooks for flagged values. If the linter doesn't flag a value or doesn't suggest a hook, leave it hardcoded.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Table of Contents
|
|
27
|
+
|
|
28
|
+
- [Spacing Hooks](#spacing-hooks)
|
|
29
|
+
- [Sizing Hooks](#sizing-hooks)
|
|
30
|
+
- [Typography Hooks](#typography-hooks)
|
|
31
|
+
- [Border Width Hooks](#border-width-hooks)
|
|
32
|
+
- [Border Radius Hooks](#border-radius-hooks)
|
|
33
|
+
- [Shadow Hooks](#shadow-hooks)
|
|
34
|
+
- [Uplift Decision Tree](#uplift-decision-tree--non-color)
|
|
35
|
+
- [Common Mistakes](#common-mistakes)
|
|
36
|
+
- [Accessibility Notes](#accessibility-notes)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Spacing Hooks
|
|
41
|
+
|
|
42
|
+
**Prefix:** `--slds-g-spacing-*`
|
|
43
|
+
**Use for:** `margin`, `padding`, `gap`, `row-gap`, `column-gap`
|
|
44
|
+
**Do NOT use for:** `width`, `height`, or other dimension properties (use sizing hooks)
|
|
45
|
+
|
|
46
|
+
**Scale range: 1–12.** There is no `--slds-g-spacing-13` or higher. If a value exceeds 5rem/80px, leave it hardcoded.
|
|
47
|
+
|
|
48
|
+
### Density-Aware Spacing
|
|
49
|
+
|
|
50
|
+
For components that adapt between comfy and compact display density, use density-aware variants:
|
|
51
|
+
|
|
52
|
+
| Hook Pattern | Applies To |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `--slds-g-spacing-var-*` | All sides (margin, padding) |
|
|
55
|
+
| `--slds-g-spacing-var-block-*` | Vertical only (top/bottom) |
|
|
56
|
+
| `--slds-g-spacing-var-inline-*` | Horizontal only (left/right) |
|
|
57
|
+
|
|
58
|
+
Use density-aware hooks for data tables, forms, cards, tabs, and navigation components that need to respond to the user's density preference.
|
|
59
|
+
|
|
60
|
+
### Examples
|
|
61
|
+
|
|
62
|
+
```css
|
|
63
|
+
/* Before */
|
|
64
|
+
.card-body { padding: 1rem; }
|
|
65
|
+
.list-item { margin-bottom: 0.5rem; }
|
|
66
|
+
.grid { gap: 1.5rem; }
|
|
67
|
+
|
|
68
|
+
/* After — hook names come from the linter, not guesswork */
|
|
69
|
+
.card-body { padding: var(--slds-g-spacing-4, 1rem); }
|
|
70
|
+
.list-item { margin-bottom: var(--slds-g-spacing-2, 0.5rem); }
|
|
71
|
+
.grid { gap: var(--slds-g-spacing-5, 1.5rem); }
|
|
72
|
+
|
|
73
|
+
/* Multi-value shorthand */
|
|
74
|
+
.button { padding: var(--slds-g-spacing-2, 0.5rem) var(--slds-g-spacing-4, 1rem); }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Sizing Hooks
|
|
80
|
+
|
|
81
|
+
**Prefix:** `--slds-g-sizing-*`
|
|
82
|
+
**Use for:** `width`, `height`, `min-width`, `max-width`, `min-height`, `max-height`
|
|
83
|
+
**Do NOT use for:** `margin`, `padding`, `gap` (use spacing hooks)
|
|
84
|
+
**Scale range: 1–16.** There is no `--slds-g-sizing-17` or higher.
|
|
85
|
+
|
|
86
|
+
### Examples
|
|
87
|
+
|
|
88
|
+
```css
|
|
89
|
+
/* Before */
|
|
90
|
+
.icon { width: 32px; height: 32px; }
|
|
91
|
+
|
|
92
|
+
/* After */
|
|
93
|
+
.icon { width: var(--slds-g-sizing-9, 32px); height: var(--slds-g-sizing-9, 32px); }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Typography Hooks
|
|
99
|
+
|
|
100
|
+
### Font Scale
|
|
101
|
+
|
|
102
|
+
**Prefix:** `--slds-g-font-scale-*` (and `--slds-g-font-size-base` for 13px)
|
|
103
|
+
**Use for:** `font-size`
|
|
104
|
+
**Scale range: neg-4 through 10**, plus `base` (0.8125rem/13px). Negative values (`neg-1` to `neg-4`) are for small/caption text. There is no `--slds-g-font-scale-11` or higher.
|
|
105
|
+
|
|
106
|
+
Density-aware variant: `--slds-g-font-scale-var-*` (also 1–10) — adapts between comfy and compact.
|
|
107
|
+
|
|
108
|
+
### Font Weight
|
|
109
|
+
|
|
110
|
+
**Prefix:** `--slds-g-font-weight-*`
|
|
111
|
+
**Use for:** `font-weight`
|
|
112
|
+
**Scale range: 1–7.** Maps to CSS weight values 100–700. There is no `--slds-g-font-weight-8` or higher.
|
|
113
|
+
|
|
114
|
+
**Weight pairing guidance in SLDS 2:**
|
|
115
|
+
- Display text (large scale) → lighter weight
|
|
116
|
+
- Titles/headings → regular weight
|
|
117
|
+
- Buttons/small body titles → semi-bold weight
|
|
118
|
+
- Inline emphasis within body → bold weight (sparingly)
|
|
119
|
+
|
|
120
|
+
### Line Height
|
|
121
|
+
|
|
122
|
+
**Prefix:** `--slds-g-font-lineheight-*`
|
|
123
|
+
**Use for:** `line-height`
|
|
124
|
+
**Scale range: 1–6.** Values range from 1 to 2. There is no `--slds-g-font-lineheight-7` or higher.
|
|
125
|
+
|
|
126
|
+
### Font Family
|
|
127
|
+
|
|
128
|
+
| Hook | Use Case |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `--slds-g-font-family` | Default font family |
|
|
131
|
+
| `--slds-g-font-family-base` | Base font family |
|
|
132
|
+
| `--slds-g-font-family-monospace` | Code snippets |
|
|
133
|
+
|
|
134
|
+
### Content Width
|
|
135
|
+
|
|
136
|
+
**Prefix:** `--slds-g-sizing-content-*` and `--slds-g-sizing-heading-*`
|
|
137
|
+
**Use for:** `max-width` on text containers (uses `ch` units for readable line lengths)
|
|
138
|
+
**Scale range:** `content` 1–3, `heading` 1–3.
|
|
139
|
+
|
|
140
|
+
### Typography Examples
|
|
141
|
+
|
|
142
|
+
```css
|
|
143
|
+
/* Before */
|
|
144
|
+
.title { font-size: 18px; font-weight: bold; line-height: 1.25; }
|
|
145
|
+
.body { font-size: 14px; font-weight: normal; line-height: 1.5; }
|
|
146
|
+
|
|
147
|
+
/* After — let the linter confirm the correct scale numbers */
|
|
148
|
+
.title {
|
|
149
|
+
font-size: var(--slds-g-font-scale-4, 18px);
|
|
150
|
+
font-weight: var(--slds-g-font-weight-4, bold);
|
|
151
|
+
line-height: var(--slds-g-font-lineheight-2, 1.25);
|
|
152
|
+
}
|
|
153
|
+
.body {
|
|
154
|
+
font-size: var(--slds-g-font-scale-1, 14px);
|
|
155
|
+
font-weight: var(--slds-g-font-weight-4, normal);
|
|
156
|
+
line-height: var(--slds-g-font-lineheight-4, 1.5);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Border Width Hooks
|
|
163
|
+
|
|
164
|
+
**Prefix:** `--slds-g-sizing-border-*`
|
|
165
|
+
**Use for:** `border-width`, `border`, `border-top`, etc. (the width component)
|
|
166
|
+
**Scale range: 1–4.** Maps to 1px–4px. There is no `--slds-g-sizing-border-5` or higher.
|
|
167
|
+
|
|
168
|
+
Border widths are NOT density-aware — they stay constant regardless of comfy/compact settings.
|
|
169
|
+
|
|
170
|
+
**SLDS 2 philosophy:** Use borders sparingly. Prefer spacing or shadows for visual separation. Use borders purposefully for structure, interactivity indication, and state communication.
|
|
171
|
+
|
|
172
|
+
### Examples
|
|
173
|
+
|
|
174
|
+
```css
|
|
175
|
+
/* Before */
|
|
176
|
+
.input { border: 1px solid #ccc; }
|
|
177
|
+
|
|
178
|
+
/* After */
|
|
179
|
+
.input { border: var(--slds-g-sizing-border-1, 1px) solid var(--slds-g-color-border-2, #ccc); }
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Border Radius Hooks
|
|
185
|
+
|
|
186
|
+
**Prefix:** `--slds-g-radius-border-*`
|
|
187
|
+
**Use for:** `border-radius`
|
|
188
|
+
**Scale range: 1–4** plus special values `circle` and `pill`. There is no `--slds-g-radius-border-5` or higher.
|
|
189
|
+
|
|
190
|
+
Choose radius by **component type**, not by matching px values. The hook resolves to the design-system value; the original value is preserved as fallback only.
|
|
191
|
+
|
|
192
|
+
| Hook | Components |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `--slds-g-radius-border-1` | Badges, checkboxes |
|
|
195
|
+
| `--slds-g-radius-border-2` | Text inputs, comboboxes, text areas, tooltips |
|
|
196
|
+
| `--slds-g-radius-border-3` | Menus, popovers |
|
|
197
|
+
| `--slds-g-radius-border-4` | Cards, modals, docked composers |
|
|
198
|
+
| `--slds-g-radius-border-circle` | Buttons, button icons, avatars, radios, pills |
|
|
199
|
+
| `--slds-g-radius-border-pill` | Pill-shaped elements |
|
|
200
|
+
|
|
201
|
+
Border radius hooks are NOT density-aware.
|
|
202
|
+
|
|
203
|
+
### Examples
|
|
204
|
+
|
|
205
|
+
```css
|
|
206
|
+
/* Before */
|
|
207
|
+
.card { border-radius: 8px; }
|
|
208
|
+
.button { border-radius: 50%; }
|
|
209
|
+
|
|
210
|
+
/* After — chosen by component type, not px value */
|
|
211
|
+
.card { border-radius: var(--slds-g-radius-border-4, 8px); }
|
|
212
|
+
.button { border-radius: var(--slds-g-radius-border-circle, 50%); }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Shadow Hooks
|
|
218
|
+
|
|
219
|
+
**Prefix:** `--slds-g-shadow-*`
|
|
220
|
+
**Use for:** `box-shadow`
|
|
221
|
+
**Scale range: 1–6.** Directional variants (`-block-start-*`, `-block-end-*`, `-inline-start-*`, `-inline-end-*`) use range **1–4**. Focus variants (`-outline-focus-*`, `-outset-focus-*`, `-inset-focus-*`, `-inset-inverse-focus-*`) only have **1**.
|
|
222
|
+
|
|
223
|
+
Match shadow depth to the element's stacking order — higher shadows for elements visually above others:
|
|
224
|
+
|
|
225
|
+
| Hook | Components |
|
|
226
|
+
|---|---|
|
|
227
|
+
| `--slds-g-shadow-1` | Page headers, joined tables, filter panels, dropdowns, inline edit, slider handles |
|
|
228
|
+
| `--slds-g-shadow-2` | Menus, docked form footer, docked utility bar, color picker, notifications |
|
|
229
|
+
| `--slds-g-shadow-3` | Panels, docked composer, tooltips, toasts |
|
|
230
|
+
| `--slds-g-shadow-4` | Modals, popovers, App Launcher |
|
|
231
|
+
|
|
232
|
+
### Directional Shadows
|
|
233
|
+
|
|
234
|
+
For components positioned against screen edges:
|
|
235
|
+
|
|
236
|
+
| Hook Pattern | Direction |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `--slds-g-shadow-block-start-*` | Upward |
|
|
239
|
+
| `--slds-g-shadow-block-end-*` | Downward (inherits from base) |
|
|
240
|
+
| `--slds-g-shadow-inline-start-*` | Left |
|
|
241
|
+
| `--slds-g-shadow-inline-end-*` | Right |
|
|
242
|
+
|
|
243
|
+
### Focus Shadows
|
|
244
|
+
|
|
245
|
+
| Hook Pattern | Use Case |
|
|
246
|
+
|---|---|
|
|
247
|
+
| `--slds-g-shadow-outline-focus-*` | Simple outline focus |
|
|
248
|
+
| `--slds-g-shadow-outset-focus-*` | Double ring outset focus (white inner, brand outer) |
|
|
249
|
+
| `--slds-g-shadow-inset-focus-*` | Single ring inset focus |
|
|
250
|
+
| `--slds-g-shadow-inset-inverse-focus-*` | Double ring inset focus (brand inner, white outer) |
|
|
251
|
+
|
|
252
|
+
**SLDS 2 philosophy:** Don't apply shadows to base-level components that sit on a surface without covering other components.
|
|
253
|
+
|
|
254
|
+
### Examples
|
|
255
|
+
|
|
256
|
+
```css
|
|
257
|
+
/* Before */
|
|
258
|
+
.modal { box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
|
|
259
|
+
.dropdown { box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
|
260
|
+
|
|
261
|
+
/* After */
|
|
262
|
+
.modal { box-shadow: var(--slds-g-shadow-4, 0 4px 8px rgba(0,0,0,0.1)); }
|
|
263
|
+
.dropdown { box-shadow: var(--slds-g-shadow-1, 0 2px 4px rgba(0,0,0,0.1)); }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Uplift Decision Tree — Non-Color
|
|
269
|
+
|
|
270
|
+
When the linter flags a non-color hardcoded value, follow this process:
|
|
271
|
+
|
|
272
|
+
### Step 1: Run the Linter First
|
|
273
|
+
|
|
274
|
+
Always run `npx @salesforce-ux/slds-linter@latest lint --fix .` before manual fixes. The linter handles exact value-to-hook matches automatically. Only proceed to manual fixes for values the linter flags but cannot auto-fix.
|
|
275
|
+
|
|
276
|
+
### Step 2: Density-Aware or Standard?
|
|
277
|
+
|
|
278
|
+
Only use density-aware hooks if the original value was a variable density token:
|
|
279
|
+
- `--lwc-varSpacingMedium` → `--slds-g-spacing-var-4`
|
|
280
|
+
- `--lwc-spacingMedium` → `--slds-g-spacing-4` (non-variable, use standard hook)
|
|
281
|
+
|
|
282
|
+
### Step 3: No Exact Match — Should You Replace?
|
|
283
|
+
|
|
284
|
+
**Shadow:** If a shadow hook is nearly identical (e.g., offset differs by 1px), replace with the closest equivalent. Otherwise, leave as-is.
|
|
285
|
+
|
|
286
|
+
**Border Radius:** Replace by component type (see table above), not by px value. If the element doesn't match a known component type, leave hardcoded.
|
|
287
|
+
|
|
288
|
+
**Typography:** If between two scale values, use the closest. If far outside the available range, leave as-is.
|
|
289
|
+
|
|
290
|
+
**Spacing/Sizing:** If within 10% of a hook value, update to the closest hook. Otherwise leave as-is.
|
|
291
|
+
|
|
292
|
+
**Hardcoded numerical/structural values:** Never change or remove values like `width: 100%`, `height: 50%`, `max-width: 200px`, `flex: 1`, `height: auto`, `display: none`, `line-height: 1.5`, or `0`. These are layout and structural values, not candidates for hooks. Leave them exactly as they are in the source CSS.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Common Mistakes
|
|
297
|
+
|
|
298
|
+
1. **Inventing hooks that don't exist** — This is the most common and damaging mistake. Named hooks (`--slds-g-spacing-medium`) and out-of-range numbered hooks do not exist. Always verify with the linter.
|
|
299
|
+
|
|
300
|
+
2. **Confusing spacing and sizing** — Spacing is for margins/padding/gaps. Sizing is for width/height/dimensions. Using the wrong one makes the value density-unaware or disrupts the grid system.
|
|
301
|
+
|
|
302
|
+
3. **Replacing or removing hardcoded numerical values** — Never change `width: 100%`, `height: 50%`, `max-width: 200px`, `flex: 1`, `height: auto`, `display: none`, `line-height: 1.5`, or `0`. These are structural/layout values — do not replace them with hooks and do not remove them.
|
|
303
|
+
|
|
304
|
+
4. **Missing fallback values** — Always include the original value as fallback: `var(--slds-g-spacing-4, 1rem)`. Without fallbacks, the component breaks if the hook is unavailable.
|
|
305
|
+
|
|
306
|
+
5. **Ignoring density-aware variants** — For data-dense components (tables, forms, lists), use `--slds-g-spacing-var-*` and `--slds-g-font-scale-var-*` so spacing and text adapt to comfy/compact settings.
|
|
307
|
+
|
|
308
|
+
6. **Using `--slds-c-*` or `--slds-s-*` hooks** — Only `--slds-g-*` (global) hooks are valid for migration. Component and scoped hooks are not for direct use in CSS.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Accessibility Notes
|
|
313
|
+
|
|
314
|
+
### Touch Targets
|
|
315
|
+
- Minimum 24x24 CSS pixels for pointer inputs (WCAG 2.2 Level AA)
|
|
316
|
+
- Minimum 44x44 for touch inputs (industry standard)
|
|
317
|
+
- Use spacing hooks for padding to achieve target sizes on interactive elements
|
|
318
|
+
|
|
319
|
+
### Typography Readability
|
|
320
|
+
- Use body-level font scale or larger for primary body text
|
|
321
|
+
- Default base font size (13px) is at the lower limit for comfortable reading
|
|
322
|
+
- Use a line height of 1.5 as default for body text (WCAG 1.4.12)
|
|
323
|
+
- Optimal line length: 45-75 characters (use content width hooks for max-width)
|
|
324
|
+
|
|
325
|
+
### Focus Visibility
|
|
326
|
+
- Use appropriate border-width hooks for focus state borders
|
|
327
|
+
- Use `--slds-g-shadow-outset-focus-*` for focus rings (double-ring pattern visible on any background)
|
|
328
|
+
- Focus borders must maintain 3:1 minimum contrast with adjacent surfaces
|
|
329
|
+
|
|
330
|
+
### Border Contrast
|
|
331
|
+
- Borders must maintain 3:1 contrast ratio with adjacent surfaces
|
|
332
|
+
- Use higher-contrast border color hooks for interactive elements
|
|
333
|
+
- Use lower-contrast border color hooks for decorative/non-interactive borders
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Rule: LWC Token to SLDS Hook
|
|
2
|
+
|
|
3
|
+
**Rule ID:** `slds/lwc-token-to-slds-hook`
|
|
4
|
+
**Severity:** Error
|
|
5
|
+
**Scope:** Replaces deprecated `--lwc-*` design tokens with SLDS 2 styling hooks.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What the Linter Does
|
|
10
|
+
|
|
11
|
+
The linter detects deprecated `--lwc-*` tokens and reports them as **errors**. When there is only one suggestion, `--fix` auto-applies it. When there are multiple suggestions, manual selection is required. Here's real linter output for a multiple-suggestion case:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
2:14 error The '--lwc-colorBackground' design token is deprecated. Replace it with
|
|
15
|
+
the SLDS 2 styling hook and set the fallback to '--lwc-colorBackground'.
|
|
16
|
+
1. --slds-g-color-surface-2
|
|
17
|
+
2. --slds-g-color-surface-container-2 slds/lwc-token-to-slds-hook
|
|
18
|
+
|
|
19
|
+
✖ 1 SLDS Violation (1 error, 0 warnings)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## CRITICAL: Two-Step Workflow
|
|
25
|
+
|
|
26
|
+
### Step 1: Read Linter Suggestions First (Mandatory)
|
|
27
|
+
|
|
28
|
+
Before doing anything else, extract the numbered suggestions from the linter output.
|
|
29
|
+
|
|
30
|
+
**ABSOLUTE RULE: You can ONLY use hooks from the linter's numbered list. You CANNOT use any other hooks.**
|
|
31
|
+
|
|
32
|
+
- If linter suggests `1. --slds-g-color-surface-2` and `2. --slds-g-color-surface-container-2`
|
|
33
|
+
- You can ONLY choose between those two
|
|
34
|
+
- Using `--slds-g-color-surface-1` is FORBIDDEN (not in the list)
|
|
35
|
+
|
|
36
|
+
### Step 2: Apply Context-Based Decision (Only After Step 1)
|
|
37
|
+
|
|
38
|
+
Now that you have the linter's suggestions, use context to choose the best option FROM THE LIST.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Decision Process
|
|
43
|
+
|
|
44
|
+
### Single Suggestion
|
|
45
|
+
|
|
46
|
+
If the linter gives ONE option, `--fix` auto-applies it. The result looks like:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
color: var(--slds-g-color-on-surface-2, var(--lwc-colorTextDefault));
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Multiple Suggestions
|
|
53
|
+
|
|
54
|
+
If the linter gives MULTIPLE options, apply pattern matching to choose.
|
|
55
|
+
|
|
56
|
+
**Surface vs Container — Core Concept:**
|
|
57
|
+
|
|
58
|
+
**SURFACE** = The overlay itself — the element that creates a new stacking context (pages, modals, popovers, dialogs)
|
|
59
|
+
- The modal/popover/dialog body background (e.g., `.slds-modal`, `.slds-popover`)
|
|
60
|
+
- Main component backgrounds like `.main-body`, `.page-wrapper`, `.THIS`
|
|
61
|
+
|
|
62
|
+
**CONTAINER** = Elements that sit on top of a surface (cards, tiles, headers, footers, list items)
|
|
63
|
+
- Parts within an overlay like `.slds-modal__header`, `.slds-modal__footer`
|
|
64
|
+
- Card components like `.card-header`, `.card-footer`, `.tile-body`
|
|
65
|
+
- Repeating items like `.list-item`, `.table-row`
|
|
66
|
+
|
|
67
|
+
### Pattern Matching
|
|
68
|
+
|
|
69
|
+
When the linter gives surface vs container options:
|
|
70
|
+
|
|
71
|
+
**Choose SURFACE when:**
|
|
72
|
+
- `.slds-modal`, `.slds-popover`, `.slds-dialog` — the overlay itself (creates new stacking context)
|
|
73
|
+
- `main-*`, `*-body`, `*-page`, `*-root`, `*-wrapper`, `*-background` — primary/root elements
|
|
74
|
+
- `.THIS` — component root
|
|
75
|
+
|
|
76
|
+
**Choose CONTAINER when:**
|
|
77
|
+
- `.slds-modal__*`, `.slds-popover__*`, `.slds-dialog__*` — parts within an overlay (header, footer, content)
|
|
78
|
+
- `*-card-*`, `*-tile-*`, `*-item*`, `*-row*` — nested elements within surfaces
|
|
79
|
+
- Sections/panels nested within a card, tile, or item
|
|
80
|
+
|
|
81
|
+
### Step-by-Step Decision Process
|
|
82
|
+
|
|
83
|
+
1. **READ LINTER SUGGESTIONS** — Extract the numbered list of hooks
|
|
84
|
+
2. **IDENTIFY CLASS NAME** — Look at the CSS selector being styled
|
|
85
|
+
3. **PATTERN MATCH** — Check surface patterns first, then container patterns
|
|
86
|
+
4. **SELECT FROM LINTER OPTIONS** — Choose the corresponding option
|
|
87
|
+
5. **NEVER INVENT HOOKS** — Only use hooks explicitly listed by the linter
|
|
88
|
+
|
|
89
|
+
For deeper context investigation (class usage in HTML/JS, component structure), see [color-hooks-decision-guide.md](color-hooks-decision-guide.md).
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Replacement Pattern
|
|
94
|
+
|
|
95
|
+
Always include the original LWC token as fallback:
|
|
96
|
+
|
|
97
|
+
```css
|
|
98
|
+
property: var(--slds-g-[hook], var(--lwc-[originalToken]));
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The nested `var()` fallback ensures compatibility during migration.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Mandatory Rules
|
|
106
|
+
|
|
107
|
+
**Rule 1: ONLY USE LINTER-SUGGESTED HOOKS**
|
|
108
|
+
- Read the linter output first
|
|
109
|
+
- Only use hooks that appear in the linter's numbered list
|
|
110
|
+
- Cannot invent or use hooks not suggested by the linter
|
|
111
|
+
|
|
112
|
+
**Rule 2: USE PATTERN RECOGNITION TO CHOOSE FROM LINTER OPTIONS**
|
|
113
|
+
- One option → use that exact option
|
|
114
|
+
- Multiple options → apply pattern matching:
|
|
115
|
+
- Surface: `.slds-modal`, `.slds-popover`, `.slds-dialog`, `main-*`, `*-body`, `*-page`, `*-root`, `.THIS`
|
|
116
|
+
- Container: `.slds-modal__*`, `.slds-popover__*`, `.slds-dialog__*`, `*-card-*`, `*-tile-*`, `*-item*`, `*-row*`
|
|
117
|
+
- Apply patterns generically — don't memorize specific examples
|
|
118
|
+
|
|
119
|
+
**Rule 3: ALWAYS INCLUDE FALLBACK**
|
|
120
|
+
- Format: `var(--slds-g-[hook], var(--lwc-[originalToken]))`
|
|
121
|
+
|
|
122
|
+
**Rule 4: MINIMAL CHANGES**
|
|
123
|
+
- Only fix actual `slds/lwc-token-to-slds-hook` violations
|
|
124
|
+
- Do not remove any other code or styles
|
|
125
|
+
- Reference line numbers for all modifications
|
|
126
|
+
- If no violations found, return empty list
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Validation Checklist
|
|
131
|
+
|
|
132
|
+
- [ ] All `var(--lwc-*)` tokens have SLDS 2 replacements
|
|
133
|
+
- [ ] Replacements are from the linter's suggested list (not invented)
|
|
134
|
+
- [ ] Original token included as fallback: `var(--slds-g-*, var(--lwc-*))`
|
|
135
|
+
- [ ] Context-appropriate choice when multiple options given
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Rule: No Deprecated Tokens SLDS1
|
|
2
|
+
|
|
3
|
+
**Rule ID:** `slds/no-deprecated-tokens-slds1`
|
|
4
|
+
**Severity:** Error
|
|
5
|
+
**Scope:** Replaces legacy Aura `t(tokenName)` and `token(tokenName)` syntax with SLDS 2 styling hooks.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What the Linter Does
|
|
10
|
+
|
|
11
|
+
The linter detects `t()` and `token()` function calls in CSS, `.cmp`, and `.html` files. These are Aura-era token accessors that are deprecated in SLDS 2.
|
|
12
|
+
|
|
13
|
+
Two message types:
|
|
14
|
+
|
|
15
|
+
**When a replacement exists:**
|
|
16
|
+
```
|
|
17
|
+
Consider removing t(colorTextDefault) or replacing it with --slds-g-color-on-surface-3.
|
|
18
|
+
Set the fallback to t(colorTextDefault).
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**When no replacement exists:**
|
|
22
|
+
```
|
|
23
|
+
Update outdated design tokens to SLDS 2 styling hooks with similar values.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Replacement Pattern
|
|
29
|
+
|
|
30
|
+
Always wrap in `var()` with the original LWC token as fallback:
|
|
31
|
+
|
|
32
|
+
```css
|
|
33
|
+
/* Before — Aura t() syntax */
|
|
34
|
+
color: t(colorTextDefault);
|
|
35
|
+
background-color: t(colorBackgroundAlt);
|
|
36
|
+
|
|
37
|
+
/* After — SLDS 2 hook with LWC fallback */
|
|
38
|
+
color: var(--slds-g-color-on-surface-3, var(--lwc-colorTextDefault));
|
|
39
|
+
background-color: var(--slds-g-color-surface-container-1, var(--lwc-colorBackgroundAlt));
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The nested `var()` fallback ensures compatibility during migration — if the SLDS 2 hook isn't available, the LWC token still resolves.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Common Token Mappings
|
|
47
|
+
|
|
48
|
+
### Text Colors
|
|
49
|
+
|
|
50
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `t(colorTextPlaceholder)` | `--slds-g-color-on-surface-2` | `--lwc-colorTextPlaceholder` |
|
|
53
|
+
| `t(colorTextWeak)` | `--slds-g-color-on-surface-1` | `--lwc-colorTextWeak` |
|
|
54
|
+
| `t(colorTextDefault)` | `--slds-g-color-on-surface-3` | `--lwc-colorTextDefault` |
|
|
55
|
+
| `t(colorTextIconInverse)` | `--slds-g-color-on-surface-inverse-1` | `--lwc-colorTextIconInverse` |
|
|
56
|
+
|
|
57
|
+
### Background Colors
|
|
58
|
+
|
|
59
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `t(colorBackground)` | `--slds-g-color-surface-container-2` | `--lwc-colorBackground` |
|
|
62
|
+
| `t(colorBackgroundAlt)` | `--slds-g-color-surface-container-1` | `--lwc-colorBackgroundAlt` |
|
|
63
|
+
| `t(colorBackgroundAlt2)` | `--slds-g-color-surface-container-2` | `--lwc-colorBackgroundAlt2` |
|
|
64
|
+
|
|
65
|
+
### Spacing
|
|
66
|
+
|
|
67
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `t(spacingXxSmall)` | `--slds-g-spacing-1` | `--lwc-spacingXxSmall` |
|
|
70
|
+
| `t(spacingXSmall)` | `--slds-g-spacing-2` | `--lwc-spacingXSmall` |
|
|
71
|
+
| `t(spacingSmall)` | `--slds-g-spacing-3` | `--lwc-spacingSmall` |
|
|
72
|
+
| `t(spacingMedium)` | `--slds-g-spacing-4` | `--lwc-spacingMedium` |
|
|
73
|
+
| `t(spacingLarge)` | `--slds-g-spacing-5` | `--lwc-spacingLarge` |
|
|
74
|
+
| `t(templateGutters)` | `--slds-g-spacing-3` | `--lwc-templateGutters` |
|
|
75
|
+
|
|
76
|
+
### Border Radius
|
|
77
|
+
|
|
78
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `t(borderRadiusSmall)` | `--slds-g-radius-border-1` | `--lwc-borderRadiusSmall` |
|
|
81
|
+
| `t(borderRadiusMedium)` | `--slds-g-radius-border-2` | `--lwc-borderRadiusMedium` |
|
|
82
|
+
| `t(borderRadiusLarge)` | `--slds-g-radius-border-3` | `--lwc-borderRadiusLarge` |
|
|
83
|
+
|
|
84
|
+
### Font Sizes
|
|
85
|
+
|
|
86
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `t(fontSizeSmall)` | `--slds-g-font-scale-1` | `--lwc-fontSizeSmall` |
|
|
89
|
+
| `t(fontSizeMedium)` | `--slds-g-font-scale-2` | `--lwc-fontSizeMedium` |
|
|
90
|
+
| `t(fontSizeLarge)` | `--slds-g-font-scale-3` | `--lwc-fontSizeLarge` |
|
|
91
|
+
| `t(fontSizeXLarge)` | `--slds-g-font-scale-4` | `--lwc-fontSizeXLarge` |
|
|
92
|
+
|
|
93
|
+
### Font Weights
|
|
94
|
+
|
|
95
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
96
|
+
|---|---|---|
|
|
97
|
+
| `t(fontWeightLight)` | `--slds-g-font-weight-3` | `--lwc-fontWeightLight` |
|
|
98
|
+
| `t(fontWeightRegular)` | `--slds-g-font-weight-4` | `--lwc-fontWeightRegular` |
|
|
99
|
+
| `t(fontWeightBold)` | `--slds-g-font-weight-7` | `--lwc-fontWeightBold` |
|
|
100
|
+
|
|
101
|
+
### Line Heights
|
|
102
|
+
|
|
103
|
+
| Legacy Token | SLDS2 Hook | LWC Fallback |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `t(lineHeightHeading)` | `--slds-g-font-lineheight-2` | `--lwc-lineHeightHeading` |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Tokens with No SLDS 2 Equivalent
|
|
110
|
+
|
|
111
|
+
### Z-Index
|
|
112
|
+
|
|
113
|
+
Z-index tokens have no SLDS 2 hook. Use the hardcoded value directly:
|
|
114
|
+
|
|
115
|
+
```css
|
|
116
|
+
/* Before */
|
|
117
|
+
z-index: t(zIndexSticky);
|
|
118
|
+
|
|
119
|
+
/* After — hardcoded, no hook available */
|
|
120
|
+
z-index: 9000;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Duration
|
|
124
|
+
|
|
125
|
+
Duration tokens are for internal component transitions. Use `--lwc-*` directly — do NOT invent `--slds-g-duration-*` hooks:
|
|
126
|
+
|
|
127
|
+
```css
|
|
128
|
+
/* Bad — inventing a non-existent hook */
|
|
129
|
+
transition: var(--slds-g-duration-slowly, var(--lwc-durationSlowly));
|
|
130
|
+
|
|
131
|
+
/* Good — use --lwc-* directly */
|
|
132
|
+
transition: var(--lwc-durationSlowly);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Available duration tokens: `--lwc-durationInstantly`, `--lwc-durationPromptly`, `--lwc-durationSlowly`.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Wizard Token Mappings
|
|
140
|
+
|
|
141
|
+
### oneDesktopSetupWizardTokens
|
|
142
|
+
|
|
143
|
+
From `oneDesktopSetupWizardTokens.tokens` — map wizard token → base token → SLDS 2:
|
|
144
|
+
|
|
145
|
+
| Wizard Token | SLDS2 Replacement |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `wizardColorTextHeader` | `var(--slds-g-color-on-surface-3, var(--lwc-colorTextDefault))` |
|
|
148
|
+
| `wizardColorActiveMilestoneTracker` | `var(--lwc-colorBackgroundButtonBrand)` |
|
|
149
|
+
| `wizardColorInactiveMilestoneTracker` | `var(--slds-g-color-surface-container-1, var(--lwc-colorBackgroundInputDisabled))` |
|
|
150
|
+
| `wizardColorTextMilestoneTracker` | `var(--slds-g-color-on-surface-3, var(--lwc-colorTextActionLabelActive))` |
|
|
151
|
+
| `wizardFontWeightMilestoneTracker` | `var(--slds-g-font-weight-4, var(--lwc-fontWeightRegular))` |
|
|
152
|
+
| `wizardFontSizeMilestoneTracker` | `var(--slds-g-font-scale-2, var(--lwc-fontSizeMedium))` |
|
|
153
|
+
| `wizardColorBackgroundError` | `var(--slds-g-color-surface-container-2, var(--lwc-colorBackgroundInput))` |
|
|
154
|
+
| `wizardBorderRadiusError` | `var(--slds-g-radius-border-2, var(--lwc-borderRadiusMedium))` |
|
|
155
|
+
|
|
156
|
+
### s1wizardNamespace
|
|
157
|
+
|
|
158
|
+
From `s1wizardNamespace.tokens`:
|
|
159
|
+
|
|
160
|
+
| S1wizard Token | SLDS2 Replacement |
|
|
161
|
+
|---|---|
|
|
162
|
+
| `s1wizardContactFieldBackground` | `var(--slds-g-color-on-surface-1, var(--lwc-colorBackgroundActionbarIconUtility))` |
|
|
163
|
+
| `s1wizardComicHeadingFontFamily` | `var(--slds-g-font-family, var(--lwc-fontFamily))` |
|
|
164
|
+
| `s1wizardComicHeadingTextSize` | `var(--slds-g-font-scale-4, var(--lwc-fontSizeXLarge))` |
|
|
165
|
+
| `s1wizardComicHeadingTextColor` | `var(--slds-g-color-on-surface-3, var(--lwc-colorTextDefault))` |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Font-Family Cleanup
|
|
170
|
+
|
|
171
|
+
After the linter runs, it may add verbose font-stack fallbacks to `font-family`. For **font-family only**, trim to just the hook tokens — remove the hardcoded font stack:
|
|
172
|
+
|
|
173
|
+
```css
|
|
174
|
+
/* Linter output — verbose */
|
|
175
|
+
font-family: var(--slds-g-font-family, var(--lwc-fontFamily, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif));
|
|
176
|
+
|
|
177
|
+
/* Cleaned up — tokens only */
|
|
178
|
+
font-family: var(--slds-g-font-family, var(--lwc-fontFamily));
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
For all other properties, **keep** the linter's fallbacks (rgb, rem, px values).
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Mandatory Rules
|
|
186
|
+
|
|
187
|
+
**Rule 1: ONLY USE LINTER-SUGGESTED HOOKS**
|
|
188
|
+
- Read the linter output first
|
|
189
|
+
- Only use hooks that the linter suggests as replacements
|
|
190
|
+
- If the linter says "no replacement", see "Tokens with No SLDS 2 Equivalent" above
|
|
191
|
+
|
|
192
|
+
**Rule 2: ALWAYS INCLUDE FALLBACK**
|
|
193
|
+
- Format: `var(--slds-g-[hook], var(--lwc-[token]))`
|
|
194
|
+
- The `--lwc-*` fallback ensures the component still works if the SLDS 2 hook isn't available
|
|
195
|
+
|
|
196
|
+
**Rule 3: MINIMAL CHANGES**
|
|
197
|
+
- Only fix actual `slds/no-deprecated-tokens-slds1` violations
|
|
198
|
+
- Do not refactor surrounding code or styles
|
|
199
|
+
- Reference line numbers for all modifications
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Validation Checklist
|
|
204
|
+
|
|
205
|
+
- [ ] All `t()` and `token()` calls have SLDS 2 replacements (or documented as no-equivalent)
|
|
206
|
+
- [ ] Replacements use linter-suggested hooks
|
|
207
|
+
- [ ] Original token included as LWC fallback: `var(--slds-g-*, var(--lwc-*))`
|
|
208
|
+
- [ ] Duration tokens use `--lwc-*` directly (not invented `--slds-g-duration-*`)
|
|
209
|
+
- [ ] Z-index tokens use hardcoded values
|
|
210
|
+
- [ ] Font-family has no font-stack fallback (tokens only)
|
|
211
|
+
- [ ] Re-run linter shows zero errors for this rule
|