@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.
- package/README.md +4 -12
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +39 -15
- package/skills/wix-app/references/BACKEND_API.md +1 -1
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +11 -8
- package/skills/wix-app/references/SDK_MODULE_MAP.md +1 -1
- package/skills/wix-app/references/STORES_VERSIONING.md +24 -2
- package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +9 -13
- package/skills/wix-app/references/dashboard-page/IMAGE_RENDERING.md +61 -0
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +54 -64
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +14 -21
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +37 -30
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +43 -29
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +40 -39
- package/skills/wix-app/references/editor-react-component/PARTS.md +8 -6
- package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +22 -2
- package/skills/wix-app/scripts/scan-a11y-eslint.cjs +39 -16
- package/skills/wix-app/scripts/sdk-curated.json +45 -0
- package/skills/wix-app/scripts/sdk-lookup.cjs +1180 -0
- package/skills/wix-base44-connector/SKILL.md +4 -2
- package/skills/wix-base44-connector/scripts/utils.cjs +5 -2
- package/skills/wix-headless-kit/SKILL.md +4 -1
- package/skills/wix-headless-kit/guides/api-run.md +14 -20
- package/skills/wix-headless-kit/install/pins.json +1 -1
- package/skills/wix-manage/SKILL.md +30 -8
- package/skills/wix-manage/references/automations/actions.md +134 -0
- package/skills/wix-manage/references/automations/activation-status.md +64 -48
- package/skills/wix-manage/references/automations/api-catalog.md +213 -77
- package/skills/wix-manage/references/automations/automation-model.md +199 -0
- package/skills/wix-manage/references/automations/bracket-expressions.md +132 -0
- package/skills/wix-manage/references/automations/build-and-manage-automations.md +305 -26
- package/skills/wix-manage/references/automations/triggers.md +190 -0
- package/skills/wix-manage/references/collaborators/manage-site-collaborators.md +128 -0
- package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +3 -1
- package/skills/wix-manage/references/forms/read-forms-and-submissions.md +277 -0
- package/skills/wix-manage/references/forms/update-form.md +5 -0
- package/skills/wix-manage/references/seo/manage-url-redirects.md +33 -4
- package/skills/wix-manage/references/sites/create-headless-site.md +14 -5
- package/skills/wix-manage/references/sites/upload-static-site.md +373 -302
- 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
|
-
|
|
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?: {
|
|
37
|
+
export type ToggleProps = {
|
|
38
|
+
elementProps?: { toggleButton?: { className?: string; a11y?: A11y } };
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
|
84
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
129
|
-
|
|
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 |
|
|
157
|
-
| Medium | Props or partial
|
|
158
|
-
| Low |
|
|
159
|
-
| Unknown |
|
|
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
|
-
|
|
162
|
-
|
|
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
|
|
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
|
|
178
|
-
resolved
|
|
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
|
-
|
|
184
|
-
|
|
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
|
|
206
|
-
|
|
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,
|
|
236
|
-
|
|
237
|
-
|
|
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 && !
|
|
46
|
+
- `isPlaying = isPlayOn && !isHovered && !isFocusWithin`. Reduced motion
|
|
47
47
|
starts paused; editor mode, `autoPlay={false}`, and pause set it false.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
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
|
|
128
|
+
slider, or gallery also uses hover and focus state:
|
|
130
129
|
|
|
131
130
|
```tsx
|
|
132
|
-
const isPlaying = isPlayOn && !isHovered && !
|
|
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.
|
|
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.
|
|
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?.
|
|
194
|
+
{...elementProps?.myAnimationPlayButton}
|
|
202
195
|
className={classNames(
|
|
203
196
|
'my-animation-play-button',
|
|
204
197
|
styles.playButton,
|
|
205
|
-
elementProps?.
|
|
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
|
|
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
|
|
9
|
-
|
|
7
|
+
Keep identity, platform props, data, and behavior together. Add `children` only
|
|
8
|
+
for an explicit container.
|
|
10
9
|
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
47
|
-
|
|
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 (
|
|
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`.
|
|
76
|
-
|
|
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?.
|
|
77
|
+
{...elementProps?.planCardCta}
|
|
81
78
|
className={classNames(
|
|
82
79
|
'plan-card-cta',
|
|
83
80
|
styles.cta,
|
|
84
|
-
elementProps?.
|
|
81
|
+
elementProps?.planCardCta?.className,
|
|
85
82
|
)}
|
|
86
83
|
>
|
|
87
84
|
{label}
|
|
88
85
|
</a>
|
|
89
86
|
```
|
|
90
87
|
|
|
91
|
-
|
|
92
|
-
|
|
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?.
|
|
92
|
+
<PlanRow {...elementProps?.planCardPlanRow} item={plan} />
|
|
96
93
|
```
|
|
97
94
|
|
|
98
|
-
|
|
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
|
|
104
|
-
numeric types
|
|
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
|
|
109
|
-
(`label`, `title
|
|
110
|
-
(`
|
|
111
|
-
|
|
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.
|
|
188
|
-
|
|
189
|
-
|
|
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
|
|
194
|
-
|
|
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.
|
|
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
|
|
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?.
|
|
39
|
+
{...elementProps?.profileCardHeading}
|
|
42
40
|
className={classNames(
|
|
43
41
|
'profile-card-heading',
|
|
44
42
|
styles.heading,
|
|
45
|
-
elementProps?.
|
|
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.
|
|
100
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
180
|
-
|
|
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:
|
|
185
|
-
|
|
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
|
|
193
|
-
|
|
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
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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.
|
|
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
|
|
265
|
-
|
|
266
|
-
promoted to a named part instead.
|
|
279
|
+
- [ ] No unexposed descendant paints an opaque surface; promote it to a named
|
|
280
|
+
part instead.
|