@wix/agent-skills 1.31.2 → 1.32.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.
Files changed (40) hide show
  1. package/README.md +4 -12
  2. package/package.json +1 -1
  3. package/skills/wix-app/SKILL.md +39 -15
  4. package/skills/wix-app/references/BACKEND_API.md +1 -1
  5. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +11 -8
  6. package/skills/wix-app/references/SDK_MODULE_MAP.md +1 -1
  7. package/skills/wix-app/references/STORES_VERSIONING.md +24 -2
  8. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +9 -13
  9. package/skills/wix-app/references/dashboard-page/IMAGE_RENDERING.md +61 -0
  10. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +54 -64
  11. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +14 -21
  12. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +37 -30
  13. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +43 -29
  14. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +40 -39
  15. package/skills/wix-app/references/editor-react-component/PARTS.md +8 -6
  16. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +22 -2
  17. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +39 -16
  18. package/skills/wix-app/scripts/sdk-curated.json +45 -0
  19. package/skills/wix-app/scripts/sdk-lookup.cjs +1180 -0
  20. package/skills/wix-base44-connector/SKILL.md +4 -2
  21. package/skills/wix-base44-connector/scripts/utils.cjs +5 -2
  22. package/skills/wix-headless-kit/SKILL.md +4 -1
  23. package/skills/wix-headless-kit/guides/api-run.md +14 -20
  24. package/skills/wix-headless-kit/install/pins.json +1 -1
  25. package/skills/wix-manage/SKILL.md +30 -8
  26. package/skills/wix-manage/references/automations/actions.md +134 -0
  27. package/skills/wix-manage/references/automations/activation-status.md +64 -48
  28. package/skills/wix-manage/references/automations/api-catalog.md +213 -77
  29. package/skills/wix-manage/references/automations/automation-model.md +199 -0
  30. package/skills/wix-manage/references/automations/bracket-expressions.md +132 -0
  31. package/skills/wix-manage/references/automations/build-and-manage-automations.md +305 -26
  32. package/skills/wix-manage/references/automations/triggers.md +190 -0
  33. package/skills/wix-manage/references/collaborators/manage-site-collaborators.md +128 -0
  34. package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +3 -1
  35. package/skills/wix-manage/references/forms/read-forms-and-submissions.md +277 -0
  36. package/skills/wix-manage/references/forms/update-form.md +5 -0
  37. package/skills/wix-manage/references/seo/manage-url-redirects.md +33 -4
  38. package/skills/wix-manage/references/sites/create-headless-site.md +14 -5
  39. package/skills/wix-manage/references/sites/upload-static-site.md +373 -302
  40. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +3 -3
@@ -1,7 +1,5 @@
1
1
  # Accessibility Implementation and Review
2
2
 
3
- Use while authoring; run the review after JSX is complete.
4
-
5
3
  ## Contents
6
4
 
7
5
  - [Implementation Contract](#implementation-contract)
@@ -28,18 +26,31 @@ Every `a11y` field that reaches the DOM becomes an editor control. Read only the
28
26
  field the part needs and write it as its HTML attribute,
29
27
  `aria-label={a11y?.ariaLabel}`. Never spread the whole object.
30
28
 
31
- ```tsx
29
+ The shared-default rule in `COMPONENT-CONTRACT.md` applies to a11y fields too:
30
+ root defaults go in `defaultProps.a11y`; named-part defaults go in
31
+ `defaultProps.elementProps.<partKey>.a11y`, where the key is the part's global class in camelCase.
32
+
33
+ ```ts
34
+ // toggle.props.ts
32
35
  import type { A11y } from '@wix/editor-react-types';
33
36
 
34
- type ToggleProps = {
35
- elementProps?: { toggle?: { className?: string; a11y?: A11y } };
37
+ export type ToggleProps = {
38
+ elementProps?: { toggleButton?: { className?: string; a11y?: A11y } };
36
39
  };
37
40
 
38
- function Toggle({ elementProps }: ToggleProps) {
39
- const { a11y: toggleA11y, ...toggleProps } = elementProps?.toggle ?? {};
41
+ export const defaultProps = {
42
+ elementProps: { toggleButton: { a11y: { ariaLabel: 'Toggle details' } } },
43
+ } satisfies ToggleProps;
44
+ ```
40
45
 
46
+ ```tsx
47
+ // toggle.tsx
48
+ import type { ToggleProps } from './toggle.props';
49
+
50
+ export function Toggle({ elementProps }: ToggleProps) {
51
+ const { a11y: toggleA11y, ...toggleProps } = elementProps?.toggleButton ?? {};
41
52
  return (
42
- <button {...toggleProps} aria-label={toggleA11y?.ariaLabel ?? ARIA_LABELS.toggle}>
53
+ <button {...toggleProps} aria-label={toggleA11y?.ariaLabel}>
43
54
  <svg aria-hidden="true" viewBox="0 0 16 16">
44
55
  <path d="m3 6 5 5 5-5" fill="none" stroke="currentColor" />
45
56
  </svg>
@@ -48,7 +59,7 @@ function Toggle({ elementProps }: ToggleProps) {
48
59
  }
49
60
  ```
50
61
 
51
- Keep the root's typed `a11y?: A11y` prop even when it reads no field. Destructure
62
+ Keep the root's `a11y?: A11y` prop even when it reads no field. Destructure
52
63
  `a11y` out of an `elementProps` entry before spreading the entry; a spread entry
53
64
  records the nested object as a whole. Image alt text comes from the `Image`
54
65
  type's `alt` field, not from `a11y`.
@@ -64,24 +75,12 @@ Use this priority order:
64
75
 
65
76
  Never hardcode an `aria-label` string directly in JSX.
66
77
 
67
- ```tsx
68
- // constants.ts
69
- export const ARIA_LABELS = {
70
- toggle: 'Toggle details',
71
- playButton: 'Play animation',
72
- pauseButton: 'Pause animation',
73
- } as const;
74
-
75
- // component JSX
76
- <button
77
- aria-label={isPlaying ? ARIA_LABELS.pauseButton : ARIA_LABELS.playButton}
78
- >
79
- {isPlaying ? <PauseIcon /> : <PlayIcon />}
80
- </button>;
81
- ```
78
+ For example, a system-owned playback label can use
79
+ `aria-label={isPlaying ? ARIA_LABELS.pauseButton : ARIA_LABELS.playButton}`,
80
+ with those strings defined in `constants.ts`.
82
81
 
83
- Icon-only controls require an accessible name. Controls with visible text,
84
- including an icon plus visible text, usually do not need another ARIA label.
82
+ Icon-only controls need an accessible name; controls with visible text usually
83
+ do not need another ARIA label.
85
84
 
86
85
  ### Preserve Semantic Ownership
87
86
 
@@ -95,8 +94,8 @@ including an icon plus visible text, usually do not need another ARIA label.
95
94
 
96
95
  ## Review Scope
97
96
 
98
- Run this review once the JSX is complete and again after each fix pass, at
99
- most two passes. Do not rerun after a clean result unless JSX changed.
97
+ Review completed JSX and rerun after fixes, at most two passes. After a clean
98
+ result, rerun only if JSX changes.
100
99
 
101
100
  | Request | Pass to the command |
102
101
  | --- | --- |
@@ -105,10 +104,8 @@ most two passes. Do not rerun after a clean result unless JSX changed.
105
104
  | Full audit | `src/extensions/site/components/` |
106
105
 
107
106
  `*.generated.ts` is regenerated from JSX and CSS and is never scanned.
108
- Imported shared components are inspection context, not automatic edit scope.
109
- Report a confirmed shared-component issue instead of changing a broadly reused
110
- primitive unless the requested fix requires that shared change and its impact is
111
- understood.
107
+ Inspect imported shared components, but edit them only when the requested fix
108
+ requires it and the impact is understood; otherwise report the issue.
112
109
 
113
110
  ## Automated Review
114
111
 
@@ -119,16 +116,12 @@ from the consumer Wix package so dependencies resolve from that project.
119
116
  node <SKILL_ROOT>/scripts/scan-a11y-review.cjs <component-dir | files...>
120
117
  ```
121
118
 
122
- One command, one report. It runs the jsx-a11y ESLint rules, a semantic scanner
123
- that follows imports and checks the per-part `a11y` contract, and a render
124
- audit: the component is rendered with `defaultProps` in Node (an SSR check),
125
- loaded into jsdom with its CSS Modules, and audited with axe-core.
126
- `component.preview.tsx` must render without falling back to the placeholder.
119
+ The command runs jsx-a11y ESLint rules, a semantic scanner that follows imports,
120
+ and an SSR/jsdom/axe-core audit with `defaultProps` and CSS Modules.
121
+ `component.preview.tsx` must render without the placeholder.
127
122
 
128
- The JSON report has `summary.line`, then `findings` grouped by rule with a
129
- count, locations or DOM target, the scanner message, and the axe help link,
130
- then `notChecked`. Exit `0` means every scanner ran and found nothing, `1`
131
- means findings, `2` means the review is inconclusive; never treat `2` as clean.
123
+ Read `summary.line`, `findings`, and `notChecked` in the JSON report.
124
+ Exit `0` means clean, `1` means findings, and `2` means inconclusive, never clean.
132
125
  Exit `2` with `render FAILED (missing-deps)` means `jsdom` or `axe-core` is not
133
126
  installed: install them (SKILL.md step 2) and rerun. Exit `2` with
134
127
  `render FAILED (loader)` means the audit could not load a module the component
@@ -147,25 +140,21 @@ For every finding:
147
140
  3. Assign `confirmed`, `false-positive`, or `not-relevant`.
148
141
  4. Fix only confirmed findings.
149
142
 
150
- Scanner output is a lead, not permission to edit blindly.
151
-
152
143
  ### Confidence and Action
153
144
 
154
145
  | Confidence | Evidence | Action |
155
146
  | --- | --- | --- |
156
- | High | The rendered element and static props directly establish the issue. | Confirm and fix when the change is safe and local. |
157
- | Medium | Props or partial component resolution strongly imply the semantics. | Inspect surrounding code, then confirm or discard. |
158
- | Low | Heuristics or unresolved runtime spreads are the main evidence. | Trace further and fix only after confirmation. |
159
- | Unknown | The semantic target cannot be resolved. | Leave unchanged and report the ambiguity when material. |
147
+ | High | Rendered element and static props prove it. | Fix when safe and local. |
148
+ | Medium | Props or partial resolution suggest it. | Inspect, then confirm or discard. |
149
+ | Low | Only heuristics or unresolved spreads. | Trace before fixing. |
150
+ | Unknown | Semantic target unresolved. | Leave unchanged; report material ambiguity. |
160
151
 
161
- Confidence establishes whether a finding is real, not whether its fix is safe.
162
- Apply confirmed local, behavior-preserving fixes. Leave a confirmed issue
163
- unchanged only when product intent is unknowable or the fix requires risky,
164
- non-local behavior changes.
152
+ Apply confirmed local, behavior-preserving fixes. Report issues needing unknown
153
+ product intent or risky, non-local behavior changes.
165
154
 
166
155
  ### Semantic Resolution Order
167
156
 
168
- Resolve rendered behavior in this order:
157
+ Resolve semantics in this order:
169
158
 
170
159
  1. Flagged JSX element and static props
171
160
  2. Explicit polymorphic props such as `as="a"` or `component="button"`
@@ -174,19 +163,20 @@ Resolve rendered behavior in this order:
174
163
  5. Prop evidence such as `href`, `to`, `src`, `alt`, and `role`
175
164
  6. Component-name heuristics
176
165
 
177
- Follow local imports to their rendered root. For package imports, inspect the
178
- resolved package entry when available. Do not assign more confidence than the
179
- evidence supports.
166
+ Follow local imports to their rendered root and package imports to their
167
+ resolved entry. Match confidence to evidence.
180
168
 
181
169
  ## Manual Review
182
170
 
183
- In the default rendered state the command checks names, alt text, ARIA
184
- validity, nesting, list and heading structure, hidden-but-focusable content,
185
- the `a11y` contract, and SSR safety. Verify what it cannot see:
171
+ The command audits default-state semantics, names, ARIA, focus visibility,
172
+ the a11y contract, and SSR. Also verify:
186
173
 
187
174
  - Every meaningful non-default state (expanded, selected, playing, error,
188
175
  empty, hover/focus) keeps correct names, focusability, hidden state, and
189
176
  structure; the command audits only the default render.
177
+ - Trace each a11y field read, including aliases and inner parts, to its matching
178
+ `defaultProps` path and meaningful default. An unused `a11y?: A11y` declaration
179
+ needs no default. Check source; no extra manifest generation is required.
190
180
  - Wrappers and polymorphic components preserve their documented semantics;
191
181
  extension overrides preserve generated accessibility fields.
192
182
  - Accessible names describe the action, and visually hidden text that carries
@@ -202,8 +192,9 @@ the `a11y` contract, and SSR safety. Verify what it cannot see:
202
192
  - The root implements the direction contract, and every `ReactNode` slot
203
193
  isolates nested content with `dir="ltr"`.
204
194
 
205
- - An auto-rotating set of readable parallel items uses `aria-live="off"` while
206
- it is rotating and `aria-live="polite"` while it is stopped.
195
+ - An auto-rotating set of readable parallel items pauses while hovered or
196
+ focused, uses `aria-live="off"` while rotating and `"polite"` while stopped.
197
+ Its root hover/focus handlers are required; never remove them for a finding.
207
198
 
208
199
  ## Pre-Fix Checks for Non-Interactive Controls
209
200
 
@@ -232,7 +223,6 @@ The accessibility review is complete only when:
232
223
  - the command was rerun after the last fix pass; and
233
224
  - the manual review is complete.
234
225
 
235
- After two fix passes, stop and report the remaining findings with their triage.
236
- Preserve visual and runtime behavior. Fix the semantic owner: root, named inner
237
- part, shared primitive, or call site. Then return to the main workflow for the
238
- Wix build, manifest generation, TypeScript check, and relevant project tests.
226
+ After two fix passes, report remaining findings with their triage. Preserve
227
+ visual and runtime behavior. Fix the semantic owner, then resume only the
228
+ build, manifest, TypeScript, and test steps required by the task.
@@ -43,12 +43,11 @@ For carousel-like components that swap readable parallel items, make the item
43
43
  wrapper a live region:
44
44
 
45
45
  - Use `aria-live={isPlaying ? 'off' : 'polite'}` and `aria-atomic="false"`.
46
- - `isPlaying = isPlayOn && !isHovered && !isStoppedByFocus`. Reduced motion
46
+ - `isPlaying = isPlayOn && !isHovered && !isFocusWithin`. Reduced motion
47
47
  starts paused; editor mode, `autoPlay={false}`, and pause set it false.
48
- Keyboard focus remains stopped until the rotation control restarts; hover
49
- pauses temporarily.
50
- - Previous/next changes items. Use root `onMouseEnter`/`onMouseLeave`;
51
- leaving resumes unless focus has stopped rotation.
48
+ - Root `onMouseEnter`/`onMouseLeave` and `onFocus`/`onBlur` (clear only when
49
+ `relatedTarget` leaves the root) pause temporarily; prev/next/dot set
50
+ `isPlayOn` to `false`.
52
51
 
53
52
  ## 1. Define Props
54
53
 
@@ -75,7 +74,7 @@ export interface MyAnimationProps {
75
74
  pauseButtonVisibility?: 'showAlways' | 'showOnHover';
76
75
 
77
76
  elementProps?: {
78
- playButton?: { className?: string };
77
+ myAnimationPlayButton?: { className?: string };
79
78
  };
80
79
  }
81
80
  ```
@@ -126,24 +125,18 @@ do not restart when it turns off. Resume can still override the preference.
126
125
 
127
126
  Derive runtime playback from `isPlayOn` plus only needed conditions. Without
128
127
  another condition, use `const isPlaying = isPlayOn`. A carousel, slideshow,
129
- slider, or gallery also uses hover and focus-stop state:
128
+ slider, or gallery also uses hover and focus state:
130
129
 
131
130
  ```tsx
132
- const isPlaying = isPlayOn && !isHovered && !isStoppedByFocus;
131
+ const isPlaying = isPlayOn && !isHovered && !isFocusWithin;
133
132
  ```
134
133
 
135
134
  Pass `isPlaying` to the renderer. The button uses `isPlayOn` and toggles
136
- between `handlePause` / `handleResume` on click. In a carousel-like component,
137
- focus entering anything except that button sets `isPlayOn` to `false` and
138
- `isStoppedByFocus` to `true`; `handleResume` sets `isPlayOn` to `true` and
139
- clears `isStoppedByFocus`.
135
+ between `handlePause` / `handleResume` on click.
140
136
 
141
137
  ## 3. Add the Play/Pause Button
142
138
 
143
- Use inline SVG icons: a triangle for play and two bars for pause. Declare
144
- `--icon-size` and `--icon-color` on the button. Apply `var(--icon-size)` to the
145
- SVG's CSS `width` and `height` (or React `style`), not raw SVG attributes;
146
- set button `color: var(--icon-color)` and SVG `fill: currentColor`.
139
+ Use inline SVG icons: a triangle for play and two bars for pause. Follow SVG Icons in `CSS-GUIDELINES.md` for `--icon-size` and `--icon-color`.
147
140
 
148
141
  Position the button absolutely so it overlays the content without pushing other elements out of place:
149
142
 
@@ -198,11 +191,11 @@ Wire the named part completely:
198
191
  ```tsx
199
192
  <button
200
193
  type="button"
201
- {...elementProps?.playButton}
194
+ {...elementProps?.myAnimationPlayButton}
202
195
  className={classNames(
203
196
  'my-animation-play-button',
204
197
  styles.playButton,
205
- elementProps?.playButton?.className,
198
+ elementProps?.myAnimationPlayButton?.className,
206
199
  )}
207
200
  onClick={isPlayOn ? handlePause : handleResume}
208
201
  aria-label={
@@ -223,7 +216,8 @@ Wire the named part completely:
223
216
  pointer-events: none;
224
217
  }
225
218
 
226
- .root[data-pause-button-visibility="showOnHover"]:hover .playButton {
219
+ .root[data-pause-button-visibility="showOnHover"]:hover .playButton,
220
+ .root[data-pause-button-visibility="showOnHover"]:focus-within .playButton {
227
221
  opacity: 1;
228
222
  pointer-events: auto;
229
223
  }
@@ -268,9 +262,8 @@ Design mode stops autoplay and exposes the control; preview uses the user's valu
268
262
  - [ ] Autoplay and pause-control props use the documented contract; `loop` is
269
263
  present only when repeat behavior is supported.
270
264
  - [ ] Reduced motion starts paused and never restarts playback automatically.
265
+ - [ ] Hover and focus pause rotation; manual navigation stops it.
271
266
  - [ ] The play/pause button is a fully wired named part with a stable accessible name.
272
- - [ ] Both icons inherit button-owned `--icon-size` for width and height and
273
- `--icon-color` via `color` and `currentColor` for fill or stroke.
274
267
  - [ ] Hover has a paired editor design state; `:focus-visible` remains a
275
268
  standalone keyboard indicator.
276
269
  - [ ] Hover-only visibility changes behavior, not the button's editable styling surface.
@@ -1,14 +1,13 @@
1
1
  # Component Contract
2
2
 
3
- Use this reference when defining props, defaults, named-part wiring, complex data,
4
- or internal file boundaries.
3
+ Use for props, defaults, named parts, data, and file boundaries.
5
4
 
6
5
  ## Public Props Contract
7
6
 
8
- Keep identity and platform contracts together with component-specific data and
9
- behavior. Do not add `children` unless the component is explicitly a container.
7
+ Keep identity, platform props, data, and behavior together. Add `children` only
8
+ for an explicit container.
10
9
 
11
- Use this shape:
10
+ Shape:
12
11
 
13
12
  ```ts
14
13
  import type { A11y, Direction } from '@wix/editor-react-types';
@@ -28,7 +27,7 @@ export type PlanCardProps = {
28
27
  onBlur?: (event: React.FocusEvent) => void;
29
28
 
30
29
  elementProps?: {
31
- cta?: { className?: string; href?: string };
30
+ planCardCta?: { className?: string; href?: string };
32
31
  };
33
32
  };
34
33
  ```
@@ -43,9 +42,8 @@ Rules:
43
42
  - Default to common optional SDK callbacks by capability; add specialized ones
44
43
  when requested. Keep implementation handlers internal.
45
44
  - Use `Array<T>`, not `T[]`, for exported arrays.
46
- - A CTA with a real destination is a native link with that `href`. If it only
47
- performs an action, use a native button. Never use `href="#"` as a fallback;
48
- it creates a focusable link without a meaningful destination.
45
+ - Use a native link for a CTA with a real `href`, or a native button for an
46
+ action. Never fall back to `href="#"`: it has no meaningful destination.
49
47
 
50
48
  ## Numeric Range Constraints
51
49
 
@@ -68,47 +66,49 @@ Treat an independently editable inner element as a named part. Wiring rules:
68
66
 
69
67
  - Root receives top-level `id`, `className`, `direction`, `a11y` — no
70
68
  `elementProps` entry.
71
- - Every named inner part has an `elementProps` entry (even if only `className`
72
- is needed); structural/decorative non-parts use only a CSS Module class.
69
+ - Every named inner part has an `elementProps` entry (`className` at minimum); structural/decorative non-parts use only a CSS Module class.
73
70
 
74
71
  On a raw HTML element, spread the entry and explicitly merge its injected
75
- `className`. Keep the entry key short while prefixing the global class with the
76
- component name.
72
+ `className`. The key is the part's global class in camelCase, never shortened
73
+ (`plan-card-cta` → `planCardCta`); any other key reads `undefined`.
77
74
 
78
75
  ```tsx
79
76
  <a
80
- {...elementProps?.cta}
77
+ {...elementProps?.planCardCta}
81
78
  className={classNames(
82
79
  'plan-card-cta',
83
80
  styles.cta,
84
- elementProps?.cta?.className,
81
+ elementProps?.planCardCta?.className,
85
82
  )}
86
83
  >
87
84
  {label}
88
85
  </a>
89
86
  ```
90
87
 
91
- When a named part renders another component built with this skill, spread the
92
- entry and let that component merge its incoming `className` on its root.
88
+ For a skill-built sub-component, spread the entry; its root merges the incoming
89
+ `className`.
93
90
 
94
91
  ```tsx
95
- <PlanRow {...elementProps?.planRow} item={plan} />
92
+ <PlanRow {...elementProps?.planCardPlanRow} item={plan} />
96
93
  ```
97
94
 
98
- Do not merge the same class at both the call site and the sub-component root.
95
+ Never merge the class at both the call site and the sub-component root.
99
96
 
100
97
  ## Content and Data
101
98
 
102
99
  Compute derived values internally when a small pure expression can derive them
103
- from props or state (e.g. expose `price` and `quantity`; compute `subtotal`; use
104
- numeric types when arithmetic is required).
100
+ from props or state (e.g. expose `price`, `quantity`; compute `subtotal`).
101
+ Use numeric types for arithmetic.
105
102
 
106
103
  ### Data-Driven Components
107
104
 
108
- Export named content props rather than `children` for leaf components — text
109
- (`label`, `title`, `placeholder`), media (`image`, `video`, `icon`), links
110
- (`link`, `href`), collections (`items`, `options`, `menuItems`). Internal
111
- sub-components may still use `children` for composition.
105
+ Export named content props, not `children`, for leaf components — text
106
+ (`label`, `title`), media (`image`, `icon`), links (`link`), collections
107
+ (`items`, `options`). Internal sub-components may use `children`.
108
+
109
+ Every visible text (eyebrow, subtitle, label) is a text prop with a default in
110
+ its own named part. No JSX text literals (`aria-label`: ACCESSIBILITY.md).
111
+ Computed text (a clock) gets one too.
112
112
 
113
113
  ### Container Components
114
114
 
@@ -184,14 +184,20 @@ optional `uri`, `alt`, `width`, `height`; `Link` has optional `href`, `target`
184
184
 
185
185
  Do not represent media as a URL/source string or split its metadata across
186
186
  primitive props. Preserve the media object through the public contract so the
187
- component can consume all of its supported data. Inspect the installed media
188
- type declaration only if a needed field is not covered here or a typecheck
189
- reports an error.
187
+ component can consume all of its supported data.
188
+
189
+ Before using fields not documented here, inspect the relevant app-resolved
190
+ `@wix/editor-react-types` declaration and only needed type references. Never
191
+ infer one type's fields from another type's example. Recheck documented fields
192
+ only if a related typecheck error reveals a mismatch; follow the installed
193
+ declaration for the field shape while retaining editor rules. Preserve required
194
+ fields. Do not bypass errors with `any`, casts, or replacement media types.
190
195
 
191
196
  ## Defaults and Resources
192
197
 
193
- Export `defaultProps` from `<component-name>.props.ts`. Both `component.tsx` and
194
- the extension consume this object; never duplicate fallbacks in JSX.
198
+ Export `defaultProps` from `<component-name>.props.ts`, including defaults for
199
+ root and nested `a11y` fields. Both `component.tsx` and the extension consume
200
+ this object; never duplicate these defaults in destructuring or JSX.
195
201
 
196
202
  All rendered media must come from Wix-hosted services, local assets, or props.
197
203
  No external hosts or third-party runtime dependencies.
@@ -254,4 +260,5 @@ Do not extract tiny fragments merely to satisfy a line-count threshold.
254
260
  - [ ] Array elements are objects with semantic named fields. No separate `id` field added to item types; React keys use item fields (stable unique → slug → index), not a typed `id`.
255
261
  - [ ] Authored media uses the corresponding Wix media type, not URL/source strings or flattened metadata.
256
262
  - [ ] Defaults live only in the props file (no JSX fallbacks).
263
+ - [ ] Every visible text is a prop with a named part; no JSX text literals.
257
264
  - [ ] Resources are Wix-hosted, prop-supplied, or locally bundled.
@@ -1,9 +1,7 @@
1
1
  # CSS Guidelines
2
2
 
3
3
  Use these rules for the scaffolded `<component-name>.module.css` file and any
4
- colocated CSS Modules owned by internal sub-components. These rules keep the component
5
- editable by zero config, responsive to its Wix-owned container, and safe in
6
- both LTR and RTL layouts.
4
+ colocated CSS Modules owned by internal sub-components.
7
5
 
8
6
  **Visual intent.** When the request specifies how the component should look —
9
7
  mood, palette, layout style, or a reference — follow that direction. Default to a modern, refined look — intentional layout, pleasing proportions, polished and deliberate styling.
@@ -31,18 +29,18 @@ Apply classes with `classnames`:
31
29
  | Structural/decorative non-part | Module class only |
32
30
 
33
31
  The global class lets zero config create an editor element. Prefix every inner
34
- part with the component name to prevent collisions between components. The
32
+ part with the component name to avoid collisions. The
35
33
  module class carries the component's default CSS. Preserve the scaffolded root
36
34
  pattern. For a new named part, add only the wiring the scaffold cannot infer:
37
35
  spread its `elementProps` entry and merge the injected class.
38
36
 
39
37
  ```tsx
40
38
  <h2
41
- {...elementProps?.heading}
39
+ {...elementProps?.profileCardHeading}
42
40
  className={classNames(
43
41
  'profile-card-heading',
44
42
  styles.heading,
45
- elementProps?.heading?.className,
43
+ elementProps?.profileCardHeading?.className,
46
44
  )}
47
45
  >
48
46
  {heading}
@@ -96,9 +94,8 @@ height or the requested behavior requires a bounded height. Omit it when the
96
94
  extension uses `LAYOUT.SIZING_TYPE.content`; the component's content must then
97
95
  establish its block size.
98
96
 
99
- Set `--display` on the root; do not set root `display` directly. The platform
100
- resolves and overrides this custom property. Inner elements use `display`
101
- normally.
97
+ Set `--display` on the root; do not set root `display` directly. Inner
98
+ elements use `display` normally.
102
99
 
103
100
  Choose the simplest root shape that fits the component:
104
101
 
@@ -152,8 +149,7 @@ Use logical inline-axis properties so layout flips automatically in RTL:
152
149
  ```
153
150
 
154
151
  Avoid `left`, `right`, `margin-left`, `padding-right`, and similar physical
155
- inline-axis properties. Physical block-axis properties such as `top` and
156
- `margin-bottom` are fine.
152
+ inline-axis properties. Physical block-axis properties are fine.
157
153
 
158
154
  ## Editable Values
159
155
 
@@ -161,7 +157,8 @@ Keep static styling in the CSS Module, not JSX `style` objects. Use literal CSS
161
157
  values when no interpolation is needed; do not create a React prop or CSS custom
162
158
  property for routine values that zero config already surfaces.
163
159
 
164
- Use this pattern:
160
+ Write each spacing value as one `px`, `%`, `vh` or `vw` number (`px` by
161
+ default), not `clamp()`, `calc()`, `min()` or `max()`.
165
162
 
166
163
  ```css
167
164
  .root {
@@ -176,31 +173,50 @@ Use this pattern:
176
173
  }
177
174
  ```
178
175
 
179
- A dynamic runtime value that cannot be represented statically may use a narrowly
180
- scoped CSS custom property set from JSX, but keep the actual style rule in CSS
181
- and do not expose a visual prop solely for that purpose.
176
+ A dynamic runtime value may use a narrowly scoped custom property set from
177
+ JSX; keep the style rule in CSS and expose no visual prop for it.
182
178
 
183
179
  ```css
184
- /* Typography: zero config builds the `font` control from both longhands.
185
- A part with a size but no family gets a control with no default. */
180
+ /* Typography: set both longhands; a size without a family gives the
181
+ `font` control no default. */
186
182
  .cta {
187
183
  font-family: 'Inter', sans-serif;
188
184
  font-size: 14px;
189
185
  font-weight: 600;
190
186
  }
191
187
 
192
- /* Avoid: a module-only wrapper is not an editor element. A size here is
193
- uneditable and silently overrides the parent's typography control. */
188
+ /* Avoid: a module-only wrapper isn't editable; its size silently
189
+ overrides the parent's typography control. */
194
190
  .cta-label {
195
191
  font-size: 14px;
196
192
  }
197
193
  ```
198
194
 
199
- The same override risk applies to paintable properties. A layout-only inner
200
- wrapper must stay visually transparent; if it isn't, promote it to its own
201
- named part instead of hardcoding an opaque style on an unexposed node, since
202
- that style would otherwise mask the parent part's own
203
- `background`/`border`/`box-shadow`.
195
+ The same applies to paint: a layout-only wrapper stays transparent or becomes
196
+ a named part, so it can't mask the parent's `background`/`border`/`box-shadow`.
197
+
198
+ ### SVG Icons
199
+
200
+ The part owning an icon declares `--icon-size` and `--icon-color`, prefixed
201
+ per icon (`--start-icon-size`), applied via `inline-size`/`block-size` and
202
+ `fill` or `stroke`.
203
+
204
+ - **Inline** (chevron, play/pause): the `svg` applies them through a module
205
+ class, its paths carrying no colour attributes; no rotation property, since
206
+ state and direction own its transform.
207
+
208
+ ```css
209
+ .toggleButton {
210
+ --icon-size: 16px;
211
+ --icon-color: #1e293b;
212
+ }
213
+
214
+ .chevron {
215
+ inline-size: var(--icon-size);
216
+ block-size: var(--icon-size);
217
+ fill: var(--icon-color);
218
+ }
219
+ ```
204
220
 
205
221
  ## Interaction and Motion
206
222
 
@@ -232,7 +248,7 @@ request or existing design provides better values:
232
248
 
233
249
  ### Foreground and Background Ownership
234
250
 
235
- If the component is a self-contained block (card, panel, banner, accordion item), give the root a background. If it is an inline control meant to blend in (link, ghost button, icon button), control may leave the root transparent instead.
251
+ If the component is a self-contained block (card, panel, banner, accordion item), give the root a background. An inline control meant to blend in (link, ghost button, icon button) may leave it transparent.
236
252
 
237
253
  - On a transparent root, don't hardcode text or icon colors; inherit them from the parent.
238
254
  - Set the background and main text/icon color together on the same element. Any secondary text (captions, hints, icons) must still be readable against that same background.
@@ -243,7 +259,6 @@ A neutral owned surface may use a light background with dark primary and
243
259
  secondary foregrounds, plus one accessible accent. The exact colors are not a
244
260
  contract; the contrast relationship is.
245
261
 
246
-
247
262
  ## Checklist
248
263
 
249
264
  - [ ] The scaffolded component and each extracted internal sub-component own
@@ -261,6 +276,5 @@ contract; the contrast relationship is.
261
276
  - [ ] Visual containers have deliberate hierarchy rather than bare scaffolding.
262
277
  - [ ] Every explicit foreground has a known contrasting background; transparent
263
278
  components inherit foregrounds from their host.
264
- - [ ] No unexposed descendant inside a named part paints its own opaque
265
- `background`/`border`/`box-shadow`; a wrapper needing its own surface is
266
- promoted to a named part instead.
279
+ - [ ] No unexposed descendant paints an opaque surface; promote it to a named
280
+ part instead.