@wix/agent-skills 1.16.2 → 1.17.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 +1 -1
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +134 -120
- package/skills/wix-app/references/EMBEDDED_SCRIPT.md +6 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +2 -2
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +2 -2
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +182 -99
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +92 -47
- package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +15 -6
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +275 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +29 -42
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +153 -449
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +66 -19
- package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +53 -158
- package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +78 -0
- package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +42 -134
- package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +27 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +45 -24
- package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +63 -179
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +79 -163
- package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +36 -21
- package/skills/wix-app/references/editor-react-component/SSR.md +30 -99
- package/skills/wix-base44-connector/SKILL.md +34 -17
- package/skills/wix-base44-connector/scripts/utils.js +33 -25
- package/skills/wix-headless/entry/bootstrap.mjs +9 -2
- package/skills/wix-headless/references/SDK_HANDOFF.md +1 -1
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +42 -23
- package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +10 -8
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +27 -24
- package/skills/wix-headless/references/managed/AUTHENTICATION.md +5 -0
- package/skills/wix-manage/SKILL.md +14 -2
- package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +20 -13
- package/skills/wix-manage/references/bookings/create-class-service.md +1 -1
- package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +24 -11
- package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +5 -5
- package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +182 -5
- package/skills/wix-manage/references/seo/manage-seo-tags.md +315 -0
- package/skills/wix-manage/references/seo/manage-url-redirects.md +250 -0
- package/skills/wix-manage/references/sites/query-sites.md +72 -161
- package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +5 -6
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +13 -9
- package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +10 -7
- package/skills/wix-vibe-headless/platforms/base44.md +13 -10
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +2 -0
- package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js +9 -8
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +4 -1
- package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +23 -11
- package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +1 -1
- package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +29 -31
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +15 -8
- package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +37 -38
- package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +2 -2
- package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js +35 -35
- package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +0 -172
- package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +0 -143
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +0 -484
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +0 -225
- package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +0 -6
- package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +0 -95
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Manifest Build Errors
|
|
2
|
+
|
|
3
|
+
Use this reference only when `npx wix build` or `npx wix generate manifest`
|
|
4
|
+
exits with an error. Read the error name from the first token before the colon
|
|
5
|
+
(`IoError:`, `ParseError:`, or `NotFoundError:`), then apply the matching fix.
|
|
6
|
+
|
|
7
|
+
| Error | Fix |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `IoError: Failed to load compiled bundle` | Re-run `npx wix build`; fix any TypeScript/build errors it reports first |
|
|
10
|
+
| `IoError: Failed to access component "X" from compiled bundle` | Corrupted artifact — delete `dist/`, re-run `npx wix build` from scratch |
|
|
11
|
+
| `IoError: CSS selector matching failed for "X"` | Fix invalid selector syntax in `<componentName>.module.css` |
|
|
12
|
+
| `IoError: Component "X" render produced no root element` | Component returns null or bare text — ensure it always renders a root JSX element |
|
|
13
|
+
| `IoError` (render phase, no other pattern) | SSR crash — remove browser-only APIs (`window`, `document`, `localStorage`) used at render time; ensure props have defaults |
|
|
14
|
+
| `NotFoundError: File not found` | Restore the missing source file or fix its registered/imported path; do not re-scaffold an existing component |
|
|
15
|
+
| `NotFoundError: Component "X" was not found as a named export` | Confirm `component.tsx` has a default export and re-run `npx wix build` |
|
|
16
|
+
| `ParseError: Failed to parse TypeScript config` | Fix `tsconfig.json`; run `npx tsc --noEmit` to surface the error |
|
|
17
|
+
| `ParseError: Failed to extract component types from "X"` | TypeScript error in the component — run `npx tsc --noEmit` and fix |
|
|
18
|
+
| `ParseError: Failed to compile "<file.scss>"` | SCSS syntax error — line/column is in the error message |
|
|
19
|
+
| `ParseError: Failed to parse CSS file for component "X"` | CSS syntax error in `.module.css` — line/column is in the error message |
|
|
20
|
+
|
|
21
|
+
After each fix, re-run `npx wix build && npx wix generate manifest` to confirm.
|
|
22
|
+
|
|
23
|
+
## Checklist
|
|
24
|
+
|
|
25
|
+
- [ ] The fix matches the reported error name and message.
|
|
26
|
+
- [ ] Build errors are resolved before manifest generation is retried.
|
|
27
|
+
- [ ] Both build and manifest generation pass after the fix.
|
|
@@ -1,39 +1,60 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Named Parts and Root Election
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use this reference to choose the component root and decide which inner elements
|
|
4
|
+
receive independent editor controls.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
## Elect the Root First
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- **Stutter test** — a part class repeating the component's own noun (`confetti-button-button`) means the wrapper took the root's name. Collapse it and promote the real element.
|
|
8
|
+
The root is always the component's editor element. It carries the unprefixed
|
|
9
|
+
`'<component-name>'` global class and receives top-level `id`, `className`,
|
|
10
|
+
`direction`, and `a11y`. It never has an `elementProps` entry.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- If the component reduces to one meaningful control, link, media surface, or
|
|
13
|
+
list, make that semantic element the root.
|
|
14
|
+
- Add a wrapper root only when it lays out multiple sibling parts, owns
|
|
15
|
+
sizing/scrolling/clipping, or hosts a root-level prop-triggered state.
|
|
16
|
+
- Do not add a wrapper solely to hold root props or position decoration.
|
|
17
|
+
- If an inner part name stutters (`confetti-button-button`), the real semantic
|
|
18
|
+
element probably should have been the root.
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
## Identify Named Inner Parts
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
A named inner part is an element whose styling or data/content a site owner
|
|
23
|
+
would plausibly control independently in the editor. It receives:
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
- one prefixed global class: `'<component-name>-<part-name>'`
|
|
26
|
+
- one CSS Module class
|
|
27
|
+
- one matching `elementProps` entry, spread onto the element
|
|
20
28
|
|
|
21
|
-
|
|
29
|
+
Apply this filter to every candidate:
|
|
22
30
|
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
31
|
+
- A state or variant (`selected`, `active`, `open`, `disabled`) is not a part.
|
|
32
|
+
Implement it as a prefixed design-state modifier on the affected part.
|
|
33
|
+
- A hidden and shown version of the same element is one part, not two.
|
|
34
|
+
- A grouping or layout-only wrapper is not a part.
|
|
35
|
+
- A static child whose styling and data are fully owned by its parent is not a
|
|
36
|
+
part. For example, an image whose source and appearance both belong to its
|
|
37
|
+
carousel slide can remain module-class-only.
|
|
38
|
+
- An inner interactive element (`button`, `a`, `input`, and equivalent semantic
|
|
39
|
+
controls) is a named part because it has an independent interaction and
|
|
40
|
+
styling surface.
|
|
41
|
+
- Positional duplicates such as previous/next buttons are one part when they
|
|
42
|
+
share the same semantic editor surface. Distinguish position with data or a
|
|
43
|
+
module-only helper class, not separate part names.
|
|
29
44
|
|
|
30
|
-
## Sanity
|
|
45
|
+
## Sanity Check
|
|
31
46
|
|
|
32
|
-
|
|
47
|
+
For each candidate, ask:
|
|
33
48
|
|
|
34
|
-
> Would the
|
|
49
|
+
> Would the controls for this element be a strict subset of its parent's controls?
|
|
35
50
|
|
|
36
|
-
If yes
|
|
51
|
+
If yes, remove the part. Then check the root in reverse: if it has one child part
|
|
52
|
+
and no independent surface, remove the wrapper and promote the child.
|
|
37
53
|
|
|
38
|
-
|
|
54
|
+
## Checklist
|
|
39
55
|
|
|
56
|
+
- [ ] The root is the component's best semantic element.
|
|
57
|
+
- [ ] The root has no `elementProps` entry or duplicate prefixed part class.
|
|
58
|
+
- [ ] Each inner part offers independent data or styling control.
|
|
59
|
+
- [ ] Every named inner part has global/module classes and `elementProps` wiring.
|
|
60
|
+
- [ ] States, wrappers, decorations, and positional variants are not extra parts.
|
|
@@ -1,203 +1,87 @@
|
|
|
1
1
|
# Props vs CSS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use this reference to decide whether a value belongs in the public React
|
|
4
|
+
contract, component logic, or editable CSS.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
## Decision Table
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
| Value controls | Put it in | Examples |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| User-authored content or data | React prop | `label`, `items`, `image`, `link` |
|
|
11
|
+
| Stable runtime behavior | React prop | `disabled`, `required`, `autoPlay`, `loop` |
|
|
12
|
+
| Value derived from props or state | Component logic | subtotal, active count, formatted label |
|
|
13
|
+
| Appearance or layout | CSS | spacing, alignment, orientation, icon position |
|
|
14
|
+
| Breakpoint-specific visibility | CSS/editor controls | show label, compact layout, mobile visibility |
|
|
15
|
+
| Direction | React prop plus logical CSS | `direction?: Direction` |
|
|
8
16
|
|
|
9
|
-
|
|
10
|
-
Is this a content/data property?
|
|
11
|
-
│
|
|
12
|
-
├─ YES → Can it be derived from other props / internal state?
|
|
13
|
-
│ │
|
|
14
|
-
│ ├─ YES (subtotal = price × qty, fullName = first + last, etc.)
|
|
15
|
-
│ │ └─ ❌ NOT a prop → compute internally
|
|
16
|
-
│ │
|
|
17
|
-
│ └─ NO (label, items, imageSrc, link, title, etc.)
|
|
18
|
-
│ └─ ✅ React prop
|
|
19
|
-
│
|
|
20
|
-
└─ NO → Would a user want this to vary per breakpoint?
|
|
21
|
-
│
|
|
22
|
-
├─ YES (showLabel, orientation, displayMode, iconPosition)
|
|
23
|
-
│ └─ ❌ NOT a prop → CSS only
|
|
24
|
-
│
|
|
25
|
-
└─ NO → Is it direction (RTL/LTR)?
|
|
26
|
-
│
|
|
27
|
-
├─ YES
|
|
28
|
-
│ └─ ✅ React prop (internationalization)
|
|
29
|
-
│
|
|
30
|
-
└─ NO → Is it behavior (disabled, required)?
|
|
31
|
-
│
|
|
32
|
-
├─ YES
|
|
33
|
-
│ └─ ✅ React prop
|
|
34
|
-
│
|
|
35
|
-
└─ NO
|
|
36
|
-
└─ ❌ NOT a prop → CSS only
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Rules
|
|
42
|
-
|
|
43
|
-
Components must distinguish between content/data and visual/layout properties:
|
|
44
|
-
|
|
45
|
-
- **Content/Data** (same across all breakpoints) → React props ✅
|
|
46
|
-
- **Visual/Layout** (vary by breakpoint) → CSS only, NOT props ❌
|
|
47
|
-
|
|
48
|
-
### What CAN be props
|
|
49
|
-
|
|
50
|
-
- Content data that stays the same: `label`, `items`, `imageSrc`, `link`, `title`
|
|
51
|
-
- Behavior that's consistent: `disabled`, `required`, `searchable`, `multiple`
|
|
52
|
-
|
|
53
|
-
### What CANNOT be props (must be CSS)
|
|
54
|
-
|
|
55
|
-
- Visual display decisions: `showLabel`, `showIcon`, `displayMode`, `iconOnly`
|
|
56
|
-
- Layout decisions: `orientation`, `alignment`, `compact`
|
|
57
|
-
- Visibility toggles: `hideOnMobile`, `showOnDesktop`, `mobileView`
|
|
17
|
+
Ask in this order:
|
|
58
18
|
|
|
59
|
-
|
|
19
|
+
1. Can the value be derived? Compute it internally.
|
|
20
|
+
2. Does it select content or stable behavior? Use a prop.
|
|
21
|
+
3. Could a site owner reasonably vary it by breakpoint? Use CSS/editor controls.
|
|
22
|
+
4. Otherwise, keep visual and layout choices in CSS.
|
|
60
23
|
|
|
61
|
-
|
|
24
|
+
## Visibility Rules
|
|
62
25
|
|
|
63
|
-
|
|
26
|
+
Do not add `showLabel`, `showIcon`, `hideOnMobile`, `displayMode`, or similar
|
|
27
|
+
props for purely presentational visibility. Render the named part and let the
|
|
28
|
+
editor control that part per breakpoint.
|
|
64
29
|
|
|
65
|
-
|
|
66
|
-
- Show cover art on desktop, hide on tablet
|
|
67
|
-
- Show full controls on large screens, minimal on small screens
|
|
68
|
-
|
|
69
|
-
**Pattern:** These look like "feature toggles" but they're actually "layout modes".
|
|
70
|
-
|
|
71
|
-
**Exception:** `direction` (RTL/LTR) is a mandatory prop for internationalization, not a breakpoint-responsive property.
|
|
72
|
-
|
|
73
|
-
**Critical Rule:** If a property should be customizable per breakpoint, it CANNOT be a React prop.
|
|
74
|
-
|
|
75
|
-
### How to Implement
|
|
76
|
-
|
|
77
|
-
Visibility/display properties can be overridden per breakpoint by the user via the editor — but, just like background colors, the component still authors the resting defaults in CSS:
|
|
78
|
-
|
|
79
|
-
1. **Always render all elements** — No conditional rendering with props
|
|
80
|
-
2. **Do NOT hardcode visibility-toggling display in CSS** (e.g. `display: none` to hide an element by default) — visibility is user-controlled per breakpoint. Layout `display` (`flex`, `grid`, etc.) on layout containers is fine and expected. Resting visual properties (background, color, border-radius, padding, font) DO belong in CSS — see `CSS-GUIDELINES.md`.
|
|
81
|
-
3. **Visibility is user-controlled** — Users control what shows/hides per breakpoint via the editor
|
|
30
|
+
Use this pattern:
|
|
82
31
|
|
|
83
32
|
```tsx
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
33
|
+
<div
|
|
34
|
+
{...elementProps?.progressBar}
|
|
35
|
+
className={classNames(
|
|
36
|
+
'audio-player-progress-bar',
|
|
37
|
+
styles.progressBar,
|
|
38
|
+
elementProps?.progressBar?.className,
|
|
39
|
+
)}
|
|
40
|
+
>
|
|
41
|
+
{/* progress UI */}
|
|
42
|
+
</div>
|
|
93
43
|
```
|
|
94
44
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
1. **"Would a user want this to vary per breakpoint?"** (mobile vs desktop vs tablet)
|
|
100
|
-
- If YES → CSS only, NOT a prop
|
|
101
|
-
|
|
102
|
-
2. **"Does this control WHAT is displayed vs WHICH content to display?"**
|
|
103
|
-
- `showProgressBar` → Controls WHAT (layout decision) → CSS only
|
|
104
|
-
- `audioUrl` → Specifies WHICH audio file (content) → Prop is OK
|
|
105
|
-
|
|
106
|
-
3. **"Does it change the visual appearance or layout?"**
|
|
107
|
-
- `showControls`, `orientation`, `alignment` → Visual/layout → CSS only
|
|
108
|
-
- `disabled`, `required`, `autoPlay` → Behavior (not visual) → Props are OK
|
|
45
|
+
Do not interpret this rule as "never conditionally render." Conditional output
|
|
46
|
+
is valid when data, semantics, or runtime behavior requires it—for example an
|
|
47
|
+
empty-state message, a loading branch, or content that does not exist.
|
|
109
48
|
|
|
110
|
-
|
|
49
|
+
Behavior-critical visibility may also be a prop when visibility itself changes
|
|
50
|
+
the interaction contract. `pauseButtonVisibility` in an autoplaying component
|
|
51
|
+
is the canonical exception: the editor preview must be able to force the
|
|
52
|
+
play/pause control visible.
|
|
111
53
|
|
|
112
|
-
|
|
54
|
+
## Examples
|
|
113
55
|
|
|
114
|
-
|
|
115
|
-
- ✅ **Layout properties:** Orientation, alignment, spacing variations, flex/grid directions → CSS only
|
|
116
|
-
- ❌ **Content properties:** Text, media URLs, links, data → Props are OK
|
|
117
|
-
- ❌ **Internationalization:** RTL/LTR (`direction` prop) → Props are OK (not breakpoint-responsive)
|
|
56
|
+
### Content and Behavior Props
|
|
118
57
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
interface ButtonProps {
|
|
129
|
-
showLabel?: boolean; // ❌ Breakpoint-customizable
|
|
130
|
-
showIcon?: boolean; // ❌ Breakpoint-customizable
|
|
131
|
-
displayMode?: 'icon-only' | 'label-only' | 'both'; // ❌
|
|
132
|
-
iconPosition?: 'left' | 'right'; // ❌ Layout
|
|
133
|
-
orientation?: 'horizontal' | 'vertical'; // ❌ Layout
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**✅ Correct — only data as props:**
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
interface ButtonProps {
|
|
141
|
-
label: string; // ✅ Content data
|
|
142
|
-
icon: VectorArt; // ✅ Content data
|
|
143
|
-
}
|
|
58
|
+
```ts
|
|
59
|
+
export type AudioPlayerProps = {
|
|
60
|
+
title?: string;
|
|
61
|
+
audioUrl?: string;
|
|
62
|
+
disabled?: boolean;
|
|
63
|
+
autoPlay?: boolean;
|
|
64
|
+
};
|
|
144
65
|
```
|
|
145
66
|
|
|
146
|
-
###
|
|
147
|
-
|
|
148
|
-
**❌ Wrong — show/hide as props:**
|
|
67
|
+
### Visual Decisions Kept Out of Props
|
|
149
68
|
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Conditional rendering
|
|
159
|
-
{showProgressBar && <div className={styles.progressBar}>...</div>}
|
|
69
|
+
```ts
|
|
70
|
+
// Do not add these to the public contract:
|
|
71
|
+
// showIcon?: boolean
|
|
72
|
+
// orientation?: 'horizontal' | 'vertical'
|
|
73
|
+
// compact?: boolean
|
|
74
|
+
// hideOnMobile?: boolean
|
|
160
75
|
```
|
|
161
76
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
interface AudioPlayerProps {
|
|
166
|
-
audioUrl: string; // ✅ Content data only
|
|
167
|
-
title?: string; // ✅ Content data
|
|
168
|
-
artist?: string; // ✅ Content data
|
|
169
|
-
}
|
|
77
|
+
Define their resting appearance in the CSS Module and expose independently
|
|
78
|
+
editable elements as named parts with global/module classes and `elementProps`
|
|
79
|
+
wiring.
|
|
170
80
|
|
|
171
|
-
|
|
172
|
-
<div className={styles.progressBar}>...</div>
|
|
173
|
-
<div className={styles.volumeControls}>...</div>
|
|
174
|
-
<div className={styles.trackInfo}>...</div>
|
|
81
|
+
## Checklist
|
|
175
82
|
|
|
176
|
-
|
|
177
|
-
.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## Common Mistake: Adding Visual Toggle Props
|
|
185
|
-
|
|
186
|
-
**❌ Wrong:**
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
export interface ButtonProps {
|
|
190
|
-
showIcon?: boolean; // ❌ Breakpoint-customizable
|
|
191
|
-
iconPosition?: 'left' | 'right'; // ❌ Layout
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
**✅ Correct:**
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
export interface ButtonProps {
|
|
199
|
-
label: string;
|
|
200
|
-
icon: VectorArt;
|
|
201
|
-
// Visual variations via CSS
|
|
202
|
-
}
|
|
203
|
-
```
|
|
83
|
+
- [ ] Props represent authored data or stable behavior.
|
|
84
|
+
- [ ] Derived values are computed internally.
|
|
85
|
+
- [ ] Visual and layout choices live in CSS.
|
|
86
|
+
- [ ] Breakpoint visibility uses a named part, not a show/hide prop.
|
|
87
|
+
- [ ] Conditional rendering is used only for real data, semantic, or behavioral branches.
|