@wix/agent-skills 1.32.0 → 1.33.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 +40 -41
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +11 -6
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +2 -3
- package/skills/wix-app/references/editor-react-component/DISABLED-INVALID.md +31 -0
- package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +14 -1
- package/skills/wix-app/references/editor-react-component/PARTS.md +32 -3
- package/skills/wix-app/references/editor-react-component/SSR.md +6 -3
- package/skills/wix-headless-kit/install/pins.json +1 -1
package/package.json
CHANGED
|
@@ -19,6 +19,24 @@ Keep the Wix CLI scaffold and file roles:
|
|
|
19
19
|
|
|
20
20
|
Supplementary files are allowed; keep scaffold roles intact.
|
|
21
21
|
|
|
22
|
+
## Required Reading (blocking)
|
|
23
|
+
|
|
24
|
+
Before writing code, open and read in full every reference in the matching
|
|
25
|
+
row. An unopened one is a failed run. Open paths directly; never skim or
|
|
26
|
+
grep instead.
|
|
27
|
+
|
|
28
|
+
| Scope | Required references |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| Creating a component | [`REACT-GUIDELINES.md`](editor-react-component/REACT-GUIDELINES.md), [`COMPONENT-CONTRACT.md`](editor-react-component/COMPONENT-CONTRACT.md), [`PARTS.md`](editor-react-component/PARTS.md), [`PROPS-VS-CSS.md`](editor-react-component/PROPS-VS-CSS.md), [`CSS-GUIDELINES.md`](editor-react-component/CSS-GUIDELINES.md), [`DIRECTIONALITY.md`](editor-react-component/DIRECTIONALITY.md), [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md), [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md), [`EDITOR-EXTENSION-CONFIGURATION.md`](editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md), [`OVERFLOW.md`](editor-react-component/OVERFLOW.md) |
|
|
31
|
+
| Editing React or JSX | [`REACT-GUIDELINES.md`](editor-react-component/REACT-GUIDELINES.md), [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md) |
|
|
32
|
+
| Changing public contract, semantic root, or named parts | [`COMPONENT-CONTRACT.md`](editor-react-component/COMPONENT-CONTRACT.md), [`PARTS.md`](editor-react-component/PARTS.md), [`PROPS-VS-CSS.md`](editor-react-component/PROPS-VS-CSS.md) |
|
|
33
|
+
| Changing public data props or elected root global class | [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md) |
|
|
34
|
+
| Item array where only one body is visible | [`COMPONENT-CONTRACT.md`](editor-react-component/COMPONENT-CONTRACT.md), [`PROPS-VS-CSS.md`](editor-react-component/PROPS-VS-CSS.md), [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md), [`DESIGN-STATES.md`](editor-react-component/DESIGN-STATES.md) |
|
|
35
|
+
| Creating or changing CSS | [`CSS-GUIDELINES.md`](editor-react-component/CSS-GUIDELINES.md) |
|
|
36
|
+
| Creating or changing layout/content | [`OVERFLOW.md`](editor-react-component/OVERFLOW.md) |
|
|
37
|
+
| Root direction contract, direction-sensitive behavior, or `ReactNode` slot | [`DIRECTIONALITY.md`](editor-react-component/DIRECTIONALITY.md) |
|
|
38
|
+
| Sizing, installation, or manifest overrides | [`EDITOR-EXTENSION-CONFIGURATION.md`](editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md) |
|
|
39
|
+
|
|
22
40
|
## Workflow
|
|
23
41
|
|
|
24
42
|
1. **Scaffold only when creating.** Run in the Wix app (`wix.config.json`).
|
|
@@ -31,9 +49,9 @@ Supplementary files are allowed; keep scaffold roles intact.
|
|
|
31
49
|
Never rerun the scaffold for an existing component.
|
|
32
50
|
Write a meaningful `description` in 1-2 plain sentences (max 300 chars): what
|
|
33
51
|
the user sees, when to use it, and capabilities that affect that choice.
|
|
34
|
-
Don't repeat the
|
|
52
|
+
Don't repeat the name or add implementation details.
|
|
35
53
|
|
|
36
|
-
2. **Run the dependency preflight.**
|
|
54
|
+
2. **Run the dependency preflight.**
|
|
37
55
|
|
|
38
56
|
```bash
|
|
39
57
|
deps=(@wix/react-component-schema @wix/react-component-utils @wix/editor-react-types)
|
|
@@ -56,16 +74,15 @@ Supplementary files are allowed; keep scaffold roles intact.
|
|
|
56
74
|
}
|
|
57
75
|
```
|
|
58
76
|
|
|
59
|
-
3. **Plan.** Identify props, root, parts, and states;
|
|
60
|
-
Use the scaffold
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
3. **Plan.** Identify props, root, parts, and states; open all required references first.
|
|
78
|
+
Use them and the scaffold before inspecting package declarations; inspect
|
|
79
|
+
only for undocumented APIs or fields, or typecheck failures. Declarations
|
|
80
|
+
govern API shapes; retain editor rules.
|
|
63
81
|
|
|
64
82
|
4. **Implement.** Keep props, logic, and styles in their scaffolded editable
|
|
65
|
-
files. Format edited source files with the app's
|
|
66
|
-
checking formatting. Never edit or format `*.generated.ts`.
|
|
83
|
+
files. Format edited source files with the app's formatter. Never edit or format `*.generated.ts`.
|
|
67
84
|
|
|
68
|
-
5. **Run the accessibility review.** Once the JSX is complete, run from the
|
|
85
|
+
5. **Run the accessibility review (mandatory).** Once the JSX is complete, run from the
|
|
69
86
|
same folder (`<SKILL_ROOT>` is the directory containing the active `SKILL.md`):
|
|
70
87
|
|
|
71
88
|
```bash
|
|
@@ -89,43 +106,30 @@ Supplementary files are allowed; keep scaffold roles intact.
|
|
|
89
106
|
```
|
|
90
107
|
|
|
91
108
|
Run `npx tsc --noEmit`, relevant tests/lint, and the accessibility review.
|
|
92
|
-
If later edits affect a check, rerun that
|
|
93
|
-
|
|
94
|
-
failures with
|
|
109
|
+
If later edits affect a check, rerun that check. Inspect the manifest when generated; never hand-repair it.
|
|
110
|
+
Diagnose failures with
|
|
95
111
|
[`editor-react-component/MANIFEST-ERRORS.md`](editor-react-component/MANIFEST-ERRORS.md).
|
|
96
112
|
|
|
97
113
|
For creation/layout changes, complete the routed overflow resize review.
|
|
98
114
|
|
|
99
|
-
8. **Report.** Summarize files, checks, blockers,
|
|
115
|
+
8. **Report.** Summarize files, checks, blockers, unrun checks.
|
|
116
|
+
List required references as read/unread; read any unread one and fix first.
|
|
100
117
|
|
|
101
118
|
## Reference Policy
|
|
102
119
|
|
|
103
|
-
Read
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
### Required References
|
|
107
|
-
|
|
108
|
-
| Scope | Required references |
|
|
109
|
-
| --- | --- |
|
|
110
|
-
| Creating a component | [`REACT-GUIDELINES.md`](editor-react-component/REACT-GUIDELINES.md), [`COMPONENT-CONTRACT.md`](editor-react-component/COMPONENT-CONTRACT.md), [`PARTS.md`](editor-react-component/PARTS.md), [`PROPS-VS-CSS.md`](editor-react-component/PROPS-VS-CSS.md), [`CSS-GUIDELINES.md`](editor-react-component/CSS-GUIDELINES.md), [`DIRECTIONALITY.md`](editor-react-component/DIRECTIONALITY.md), [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md), [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md), [`EDITOR-EXTENSION-CONFIGURATION.md`](editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md) |
|
|
111
|
-
| Editing React or JSX | [`REACT-GUIDELINES.md`](editor-react-component/REACT-GUIDELINES.md), [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md) |
|
|
112
|
-
| Changing public contract, semantic root, or named parts | [`COMPONENT-CONTRACT.md`](editor-react-component/COMPONENT-CONTRACT.md), [`PARTS.md`](editor-react-component/PARTS.md), [`PROPS-VS-CSS.md`](editor-react-component/PROPS-VS-CSS.md) |
|
|
113
|
-
| Changing public data props or elected root global class | [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md) |
|
|
114
|
-
| Item array where only one body is visible | [`COMPONENT-CONTRACT.md`](editor-react-component/COMPONENT-CONTRACT.md), [`PROPS-VS-CSS.md`](editor-react-component/PROPS-VS-CSS.md), [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md), [`DESIGN-STATES.md`](editor-react-component/DESIGN-STATES.md) |
|
|
115
|
-
| Creating or changing CSS | [`CSS-GUIDELINES.md`](editor-react-component/CSS-GUIDELINES.md) |
|
|
116
|
-
| Creating or changing layout/content | [`OVERFLOW.md`](editor-react-component/OVERFLOW.md) |
|
|
117
|
-
| Root direction contract, direction-sensitive behavior, or `ReactNode` slot | [`DIRECTIONALITY.md`](editor-react-component/DIRECTIONALITY.md) |
|
|
118
|
-
| Sizing, installation, or manifest overrides | [`EDITOR-EXTENSION-CONFIGURATION.md`](editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md) |
|
|
120
|
+
Read every required reference for the matched scope, optional ones only on
|
|
121
|
+
trigger. Preserve unrelated behavior. References are leaves.
|
|
119
122
|
|
|
120
123
|
### Optional References
|
|
121
124
|
|
|
122
125
|
| Trigger | Read |
|
|
123
126
|
| --- | --- |
|
|
124
127
|
| Interactive/selectable part, custom state, or open/reveal toggle | [`DESIGN-STATES.md`](editor-react-component/DESIGN-STATES.md) |
|
|
128
|
+
| Disabled or invalid state | [`DISABLED-INVALID.md`](editor-react-component/DISABLED-INVALID.md) |
|
|
125
129
|
| Creating interactive components or changing interactions/callbacks | [`FUNCTION-HANDLERS.md`](editor-react-component/FUNCTION-HANDLERS.md) |
|
|
126
130
|
| Browser APIs, effects, or time-dependent output | [`SSR.md`](editor-react-component/SSR.md) |
|
|
127
131
|
| Non-established CSS feature or DOM API, or user asks for one by name | [`BROWSER-SUPPORT.md`](editor-react-component/BROWSER-SUPPORT.md) |
|
|
128
|
-
| `npx wix build` or manifest generation
|
|
132
|
+
| `npx wix build` or manifest generation errors or warns | [`MANIFEST-ERRORS.md`](editor-react-component/MANIFEST-ERRORS.md) |
|
|
129
133
|
| Animation, video, carousel, or other playable/looped/autoplaying content | [`ANIMATED-COMPONENTS.md`](editor-react-component/ANIMATED-COMPONENTS.md), [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md) |
|
|
130
134
|
| Site/runtime/editor context hooks needed | [`SITE-CONTEXT-HOOKS.md`](editor-react-component/SITE-CONTEXT-HOOKS.md) (+ [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md) when design-mode behavior differs) |
|
|
131
135
|
| Branded, themed, or brand-aware component requested | [`BRANDED-COMPONENTS.md`](editor-react-component/BRANDED-COMPONENTS.md) |
|
|
@@ -137,9 +141,7 @@ references are leaves.
|
|
|
137
141
|
- Elected root: `dir={direction}`, fallback-direction class, logical CSS for
|
|
138
142
|
direction-sensitive layout.
|
|
139
143
|
- Deterministic render; no browser globals during render.
|
|
140
|
-
-
|
|
141
|
-
roots inherit from the host.
|
|
142
|
-
- Baseline Widely Available CSS/DOM only, or supported fallbacks.
|
|
144
|
+
- Baseline Widely Available CSS/DOM only, or fallbacks.
|
|
143
145
|
- Accessibility per part, per [`ACCESSIBILITY.md`](editor-react-component/ACCESSIBILITY.md):
|
|
144
146
|
read only `a11y.ariaLabel`, and only for a control without a visible name;
|
|
145
147
|
never spread the `a11y` object or add one-off ARIA props.
|
|
@@ -149,17 +151,14 @@ references are leaves.
|
|
|
149
151
|
- Native design states: interactive elements only, never a non-interactive root
|
|
150
152
|
or part; pair selectors with injected modifiers; toggle custom state classes
|
|
151
153
|
from data, each with a matching `:global()` rule.
|
|
152
|
-
- Open/close/reveal
|
|
154
|
+
- Open/close/reveal: props-only root
|
|
153
155
|
`isOpen: ElementState<boolean>` synced to state; module classes, no `--open` class.
|
|
154
156
|
- Single-visible-body arrays: `name` per item, `ActiveItemIndex<'prop'>`, render
|
|
155
157
|
all bodies, hide inactive accessibly.
|
|
156
158
|
- No arrays inside array items; keep group fields flat (no object props).
|
|
157
159
|
- Autoplay/loop: play/pause control, honor reduced motion, suppress autoplay in
|
|
158
160
|
editor design mode.
|
|
159
|
-
- Resizable layout: keep required content usable at 320px
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
`withDefaults(withFallbackPlaceholder(PreviewOrComponent, options), defaultProps)`.
|
|
164
|
-
Keep `withDefaults` outermost; use one crucial data field and match the root
|
|
165
|
-
class.
|
|
161
|
+
- Resizable layout: keep required content usable at 320px, per
|
|
162
|
+
[`OVERFLOW.md`](editor-react-component/OVERFLOW.md).
|
|
163
|
+
- Preview: `withDefaults` outermost, one crucial data field, matching root
|
|
164
|
+
class, per [`COMPONENT-PREVIEW.md`](editor-react-component/COMPONENT-PREVIEW.md).
|
|
@@ -64,19 +64,24 @@ export interface MyAnimationProps {
|
|
|
64
64
|
direction?: Direction;
|
|
65
65
|
a11y?: A11y;
|
|
66
66
|
|
|
67
|
-
/** Start playing on load.
|
|
67
|
+
/** Start playing on load. */
|
|
68
68
|
autoPlay?: boolean;
|
|
69
69
|
|
|
70
|
-
/** Repeat when finished.
|
|
70
|
+
/** Repeat when finished. */
|
|
71
71
|
loop?: boolean;
|
|
72
72
|
|
|
73
|
-
/** Show play/pause button. Default `'showOnHover'`. */
|
|
74
73
|
pauseButtonVisibility?: 'showAlways' | 'showOnHover';
|
|
75
74
|
|
|
76
75
|
elementProps?: {
|
|
77
76
|
myAnimationPlayButton?: { className?: string };
|
|
78
77
|
};
|
|
79
78
|
}
|
|
79
|
+
|
|
80
|
+
export const defaultProps = {
|
|
81
|
+
autoPlay: true,
|
|
82
|
+
loop: true,
|
|
83
|
+
pauseButtonVisibility: 'showAlways',
|
|
84
|
+
} as const;
|
|
80
85
|
```
|
|
81
86
|
|
|
82
87
|
Omit `loop` when repeat is unsupported.
|
|
@@ -183,7 +188,7 @@ Set the visibility data attribute on the existing elected root, preserving its
|
|
|
183
188
|
full root contract:
|
|
184
189
|
|
|
185
190
|
```tsx
|
|
186
|
-
data-pause-button-visibility={pauseButtonVisibility
|
|
191
|
+
data-pause-button-visibility={pauseButtonVisibility}
|
|
187
192
|
```
|
|
188
193
|
|
|
189
194
|
Wire the named part completely:
|
|
@@ -210,7 +215,7 @@ Wire the named part completely:
|
|
|
210
215
|
/* Narrow behavior-only exception documented in CSS-GUIDELINES.md. Keep editable
|
|
211
216
|
appearance on .playButton and use this relationship only for visibility. */
|
|
212
217
|
|
|
213
|
-
/* showOnHover
|
|
218
|
+
/* showOnHover */
|
|
214
219
|
.root[data-pause-button-visibility="showOnHover"] .playButton {
|
|
215
220
|
opacity: 0;
|
|
216
221
|
pointer-events: none;
|
|
@@ -222,7 +227,7 @@ Wire the named part completely:
|
|
|
222
227
|
pointer-events: auto;
|
|
223
228
|
}
|
|
224
229
|
|
|
225
|
-
/* showAlways — no extra CSS needed; button is visible by default */
|
|
230
|
+
/* showAlways (default) — no extra CSS needed; button is visible by default */
|
|
226
231
|
```
|
|
227
232
|
|
|
228
233
|
## 4. Suppress Autoplay in `component.preview.tsx`
|
|
@@ -23,7 +23,8 @@ in the component's `.tsx` and `.module.css`.
|
|
|
23
23
|
| Interactive — `button`/`a`/`input`/`select`/`textarea`/`summary`, an interactive `role`, or an interactive handler (`onClick`/`onMouseEnter`/`onFocus`/…) | `hover` |
|
|
24
24
|
| Input field — `select`/`textarea`; `input` except `hidden`/`button`/`submit`/`reset`/`image`; or an input-widget `role` (`checkbox`/`radio`/`switch`/`slider`/`spinbutton`/`textbox`/`searchbox`/`combobox`/`listbox`) | `focus` |
|
|
25
25
|
| Other interactive element whose editable focus appearance the user explicitly requests | `focus` |
|
|
26
|
-
|
|
|
26
|
+
| `button`/`input`/`select`/`textarea`/`fieldset` when asked or its action can be unavailable | `disabled` |
|
|
27
|
+
| `input`/`select`/`textarea` with a constraint or `setCustomValidity`; a `form`/`fieldset` with one | `invalid` |
|
|
27
28
|
| Has a selectable/variant value in its data — `selected`/`active`/`current`/`checked`/`featured` | that custom state |
|
|
28
29
|
| Whole component opens/collapses or reveals content (expandable panel, disclosure, dropdown, drawer, popup, tooltip) on click, hover or focus | root `isOpen` state, no part `open` state (§6) |
|
|
29
30
|
| None of the above, incl. a non-interactive root or part | no states, and no `:hover`/`:active`/`:focus` rules, even decorative; resting style only |
|
|
@@ -110,8 +111,6 @@ The local static accessibility scan cannot measure rendered color contrast.
|
|
|
110
111
|
spread alone suffices (it merges `className` itself). The key is the global
|
|
111
112
|
class in camelCase (`COMPONENT-CONTRACT.md`).
|
|
112
113
|
|
|
113
|
-
Wire native and custom states as follows:
|
|
114
|
-
|
|
115
114
|
```tsx
|
|
116
115
|
<button
|
|
117
116
|
type="button"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Disabled and Invalid Wiring
|
|
2
|
+
|
|
3
|
+
Use after DESIGN-STATES.md §1 decides a part exposes `disabled` or `invalid`. A
|
|
4
|
+
native element's `:disabled` or `:invalid`, paired with the `:global` modifier in
|
|
5
|
+
the §3 rule, is what generates the state.
|
|
6
|
+
|
|
7
|
+
## Disabled
|
|
8
|
+
|
|
9
|
+
Author it when asked, or when the control stays visible but its action can be
|
|
10
|
+
unavailable (unmet precondition, request in progress, sold out). Otherwise author
|
|
11
|
+
no `disabled` binding and no `--disabled` rule.
|
|
12
|
+
|
|
13
|
+
## Invalid
|
|
14
|
+
|
|
15
|
+
Author it only for a native field with a constraint (`required`, `pattern`,
|
|
16
|
+
`type="email"`, …) or a `setCustomValidity` message. An unconstrained field is
|
|
17
|
+
never invalid.
|
|
18
|
+
|
|
19
|
+
For validity from outside the field (a server check, a password confirmation),
|
|
20
|
+
call `setCustomValidity` in the component file, on the field itself: through a
|
|
21
|
+
ref bound with `ref={confirmRef}`, a callback ref, or `event.currentTarget` in an
|
|
22
|
+
`on*` handler (inline, or a function of the component passed by name). The field may be in a component of the same file
|
|
23
|
+
that renders it. Not from a custom hook, a function outside the component, or
|
|
24
|
+
another file, and not through a ref given to a custom component. A field in a loop
|
|
25
|
+
or rendered conditionally is detected when every field with that `ref` or handler
|
|
26
|
+
prop calls it. If only some do, the ones that do may not be detected: give them a
|
|
27
|
+
constraint prop instead, otherwise leave `invalid` off them.
|
|
28
|
+
|
|
29
|
+
A `form` or `fieldset` is invalid when a field inside it is
|
|
30
|
+
(`.form:global(.signup-form--invalid), .form:invalid`), with no constraint of its
|
|
31
|
+
own; with no constrained field it is never invalid.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Manifest Build Errors
|
|
2
2
|
|
|
3
3
|
Use this reference only when `npx wix build` or `npx wix generate manifest`
|
|
4
|
-
exits with an error.
|
|
4
|
+
exits with an error or prints a warning. For an error, read the error name from the first token before the colon
|
|
5
5
|
(`IoError:`, `ParseError:`, or `NotFoundError:`), then apply the matching fix.
|
|
6
6
|
|
|
7
7
|
| Error | Fix |
|
|
@@ -20,6 +20,19 @@ exits with an error. Read the error name from the first token before the colon
|
|
|
20
20
|
|
|
21
21
|
After each fix, re-run `npx wix build && npx wix generate manifest` to confirm.
|
|
22
22
|
|
|
23
|
+
## Warnings
|
|
24
|
+
|
|
25
|
+
The build can also print non-fatal warnings such as
|
|
26
|
+
`[css] … styles selectors that matched no element in the extraction render`.
|
|
27
|
+
Read every warning and fix it; this is mandatory, with one exception below.
|
|
28
|
+
|
|
29
|
+
- **A part's own class** (`.errorMessage`, `.item`) means the part is not
|
|
30
|
+
mounted in the extraction render. Keep it mounted per `PARTS.md`, then
|
|
31
|
+
re-run build and manifest generation.
|
|
32
|
+
- **A class applied only by state** (`.contentOpen` from `open && styles.contentOpen`)
|
|
33
|
+
is expected: the part is mounted and only the state look is absent. Leave the
|
|
34
|
+
markup and CSS unchanged; do not force the state on or remove the styling.
|
|
35
|
+
|
|
23
36
|
## Checklist
|
|
24
37
|
|
|
25
38
|
- [ ] The fix matches the reported error name and message.
|
|
@@ -46,9 +46,38 @@ Apply this filter to every candidate:
|
|
|
46
46
|
share the same semantic editor surface. Distinguish position with data or a
|
|
47
47
|
module-only helper class, not separate part names.
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
## Keep Every Part Mounted
|
|
50
|
+
|
|
51
|
+
The manifest is generated from a single server-side render of the component
|
|
52
|
+
with mock props. Effects do not run and `useState` keeps its initial value, so
|
|
53
|
+
markup that is not mounted in that render, and the CSS that styles it, never
|
|
54
|
+
reaches the manifest. The source is not changed afterwards: write it so every
|
|
55
|
+
part is mounted regardless of state.
|
|
56
|
+
|
|
57
|
+
- Mount every phase (loading, error, empty, question, result) and hide the
|
|
58
|
+
inactive ones with the `hidden` attribute. Never write
|
|
59
|
+
`phase === 'x' && <Part />`. Give a `hidden` element no author `display`
|
|
60
|
+
rule: it would override `hidden`.
|
|
61
|
+
- While data is missing, render one static placeholder item inside a hidden
|
|
62
|
+
wrapper so the item parts exist. It is never visible.
|
|
63
|
+
- Mutually exclusive messages (loading, error, empty) are one part whose text
|
|
64
|
+
switches by phase, not several parts with the same name.
|
|
65
|
+
- A modifier toggled by state (`correct`, `incorrect`) is a design state; see
|
|
66
|
+
`DESIGN-STATES.md`.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const item = current ?? placeholderItem; // placeholder shows only while hidden
|
|
70
|
+
|
|
71
|
+
<div hidden={phase !== 'question'}>
|
|
72
|
+
<h3
|
|
73
|
+
{...elementProps?.quizQuestion}
|
|
74
|
+
className={classNames('quiz-question', styles.question, elementProps?.quizQuestion?.className)}
|
|
75
|
+
>
|
|
76
|
+
{item.question}
|
|
77
|
+
</h3>
|
|
78
|
+
</div>
|
|
79
|
+
```
|
|
80
|
+
|
|
52
81
|
After generating the manifest, confirm that its `elements` include every
|
|
53
82
|
intended named part and that each `elementProps.<key>` read in code equals the
|
|
54
83
|
camelCase of that part's global class.
|
|
@@ -29,9 +29,11 @@ const items = buildItems(props.items);
|
|
|
29
29
|
return <ul>{items.map(renderItem)}</ul>;
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
This does not require every data branch to render simultaneously
|
|
33
|
-
|
|
34
|
-
and the same on server and client.
|
|
32
|
+
This does not require every data branch to render simultaneously: loading,
|
|
33
|
+
empty, and error states may be conditional when their initial value is stable
|
|
34
|
+
and the same on server and client. A branch that contains a named part must
|
|
35
|
+
still be mounted in the first render, or the manifest omits that part (see
|
|
36
|
+
`PARTS.md`).
|
|
35
37
|
|
|
36
38
|
## Deterministic Output
|
|
37
39
|
|
|
@@ -47,4 +49,5 @@ format, or a client-only enhancement that does not replace the initial markup.
|
|
|
47
49
|
|
|
48
50
|
- [ ] No browser globals are accessed at module scope or during render.
|
|
49
51
|
- [ ] Initial server/client markup is complete and identical.
|
|
52
|
+
- [ ] Every named part is mounted in the first render.
|
|
50
53
|
- [ ] Render output does not depend on random, clock, locale, or timezone state.
|