@wix/agent-skills 1.18.1 → 1.18.2
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/SKILL.md +4 -4
- package/skills/wix-app/references/APP_VALIDATION.md +7 -33
- package/skills/wix-app/references/DASHBOARD_PAGE.md +18 -14
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +6 -3
- package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +23 -26
- package/skills/wix-app/references/dashboard-page/COLLECTION_TOOLKIT.md +7 -6
- package/skills/wix-app/references/dashboard-page/ENTITY_PAGE_TOOLKIT.md +71 -4
- package/skills/wix-app/references/dashboard-page/PATTERNS_BUNDLE_READING.md +67 -7
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -1
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +9 -6
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +59 -89
- package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +23 -4
- package/skills/wix-base44-connector/SKILL.md +168 -48
- package/skills/wix-base44-connector/scripts/{utils.js → utils.cjs} +69 -48
- package/skills/wix-docs/SKILL.md +109 -111
- package/skills/wix-docs/references/API_SPEC_SEARCH.md +35 -23
- package/skills/wix-docs/references/CALLING.md +91 -0
- package/skills/wix-docs/references/EXTRACTING.md +5 -3
- package/skills/wix-headless/references/DOC_DISCOVERY.md +9 -3
- package/skills/wix-manage/SKILL.md +7 -1
- package/skills/wix-manage/references/seo/manage-content-plan.md +247 -0
- package/skills/wix-manage/references/seo/manage-seo-tags.md +59 -6
- package/skills/wix-manage/references/stores/change-store-currency.md +10 -0
- package/skills/wix-manage/references/stores/update-product-with-options.md +9 -0
- package/skills/wix-vibe-headless/SKILL.md +17 -18
- package/skills/wix-vibe-headless/install/pin-agents-md.cjs +1 -1
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed-with-install.md +118 -0
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +55 -62
- package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +31 -29
- package/skills/wix-vibe-headless/platforms/base44.md +8 -5
- package/skills/wix-vibe-headless/platforms/generic.md +13 -12
- package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +4 -13
- package/skills/wix-vibe-headless/references/blog/seed/SEED.md +4 -8
- package/skills/wix-vibe-headless/references/blog/seed/{seed-blog.js → seed-blog.cjs} +2 -3
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +5 -14
- package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +5 -9
- package/skills/wix-vibe-headless/references/bookings/seed/{seed-bookings.js → seed-bookings.cjs} +2 -2
- package/skills/wix-vibe-headless/references/bookings/seed/{seed-rentals.js → seed-rentals.cjs} +3 -3
- package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +1 -1
- package/skills/wix-vibe-headless/references/cms/seed/SEED.md +2 -2
- package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +4 -13
- package/skills/wix-vibe-headless/references/events/seed/SEED.md +3 -7
- package/skills/wix-vibe-headless/references/events/seed/{seed-events.js → seed-events.cjs} +2 -2
- package/skills/wix-vibe-headless/references/forms/INSTRUCTIONS.md +2 -1
- package/skills/wix-vibe-headless/references/forms/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +4 -13
- package/skills/wix-vibe-headless/references/members/seed/SEED.md +2 -3
- package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +4 -13
- package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectMedia.jsx +1 -1
- package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +3 -7
- package/skills/wix-vibe-headless/references/portfolio/seed/{seed-portfolio.js → seed-portfolio.cjs} +2 -2
- package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +5 -14
- package/skills/wix-vibe-headless/references/pricing-plans/app/components/OrderCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +3 -7
- package/skills/wix-vibe-headless/references/pricing-plans/seed/{seed-pricing-plans.js → seed-pricing-plans.cjs} +2 -2
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +5 -15
- package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +3 -7
- package/skills/wix-vibe-headless/references/restaurants/seed/{seed-restaurants.js → seed-restaurants.cjs} +2 -2
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +359 -327
- package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +1 -0
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +2 -2
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useShop.js +63 -78
- package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-catalog.js +59 -43
- package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +46 -10
- package/skills/wix-vibe-headless/references/storefront/seed/{seed-store.js → seed-store.cjs} +163 -25
- package/skills/wix-vibe-headless/references/storefront/app/pages/Shop.jsx +0 -75
package/package.json
CHANGED
package/skills/wix-app/SKILL.md
CHANGED
|
@@ -117,7 +117,7 @@ Patterns owns the page shell and everything collection-shaped. These concepts ar
|
|
|
117
117
|
| Filters, search, sorting, view presets/tabs | the collection's filter and view APIs |
|
|
118
118
|
| Row actions, bulk actions, drag-and-drop | the collection's feature APIs |
|
|
119
119
|
| Multiple pages inside one extension | `PatternsReactRouter`, `PatternsReactRoute`, `usePatternsNavigate` |
|
|
120
|
-
| **Add / edit / view one item from a collection** | `EntityPage` + `useEntityPage` (fetch + save + validation), reached with `usePatternsNavigate().navigateToEntityPage`. Form state via `useForm` / `useController` from `@wix/patterns/form
|
|
120
|
+
| **Add / edit / view one item from a collection** | `EntityPage` + `useEntityPage` (fetch + save + validation), reached with `usePatternsNavigate().navigateToEntityPage`. Form state via `useForm` / `useController` from `@wix/patterns/form` (`useController`, never `register`). **Not** a dashboard modal — see [Entity create and edit](#entity-create-and-edit) |
|
|
121
121
|
| Overlays tied to a collection (item picker, bulk-action confirm) | `PickerModal` / `usePickerModal`, `bulkActionModal` |
|
|
122
122
|
|
|
123
123
|
**Looking a component up is two direct file reads** — no script, never `node_modules` browsed by hand. Resolve the installed package root once per session ([Prerequisites](references/WIX_PATTERNS_DOCS.md#prerequisites)), then reuse it. Start with what exists:
|
|
@@ -163,7 +163,7 @@ This is the most common place the selection order gets dropped: the collection g
|
|
|
163
163
|
|
|
164
164
|
The documented flow:
|
|
165
165
|
|
|
166
|
-
1. From the collection page's action cell or primary action, call `navigateToEntityPage({ path, entity })` from `usePatternsNavigate()`. (The patterns docs give this exact use case — "navigate to an entity page on an action cell click on a collection page" — and it renders the entity header immediately, before the fetch resolves.)
|
|
166
|
+
1. From the collection page's action cell or primary action, call `navigateToEntityPage({ path, entity })` from `usePatternsNavigate()`. (The patterns docs give this exact use case — "navigate to an entity page on an action cell click on a collection page" — and it renders the entity header immediately, before the fetch resolves.) On the **create** route there is no record to pass: omit `entity` and see [ENTITY_PAGE_TOOLKIT.md § Create route](references/dashboard-page/ENTITY_PAGE_TOOLKIT.md#create-route), which is what the whole "add new" flow turns on.
|
|
167
167
|
2. Register the route with `PatternsReactRoute` inside `PatternsReactRouter`.
|
|
168
168
|
3. In the entity page, `useEntityPage({ fetch, onSave })` owns fetching, saving, validation, dirty state, loading skeletons, and error states. Form state comes from `useForm` / `useController` in `@wix/patterns/form`. The call itself — both generics, what `onSave` receives, which params exist — is in [ENTITY_PAGE_TOOLKIT.md](references/dashboard-page/ENTITY_PAGE_TOOLKIT.md).
|
|
169
169
|
4. Compose the body from `EntityPage.Header`, `EntityPage.MainContent`, `EntityPage.AdditionalContent`, and `EntityPage.Card`. **WDS goes inside those cards** — `FormField`, `Input`, `Text` for the individual fields.
|
|
@@ -443,7 +443,7 @@ Open every path returned in `newFiles` and replace stubbed handler bodies / UI /
|
|
|
443
443
|
After all implementation is complete, you MUST run validation. See [APP_VALIDATION.md](references/APP_VALIDATION.md) for the complete validation workflow:
|
|
444
444
|
|
|
445
445
|
1. Package installation (detect package manager, run install)
|
|
446
|
-
2. TypeScript compilation check (`npx tsc --noEmit
|
|
446
|
+
2. TypeScript compilation check (`npx tsc --noEmit -p .`)
|
|
447
447
|
3. Build validation (`npx wix build`)
|
|
448
448
|
4. Preview deployment (`npx wix preview`)
|
|
449
449
|
|
|
@@ -506,7 +506,7 @@ The following actions need to be done manually by you:
|
|
|
506
506
|
Execute these steps sequentially after all implementation is complete. See [APP_VALIDATION.md](references/APP_VALIDATION.md) for the complete guide.
|
|
507
507
|
|
|
508
508
|
1. **Package Installation** — Detect package manager, run install
|
|
509
|
-
2. **TypeScript Compilation** — `npx tsc --noEmit
|
|
509
|
+
2. **TypeScript Compilation** — `npx tsc --noEmit -p .`
|
|
510
510
|
3. **Build** — `npx wix build`
|
|
511
511
|
4. **Preview** — `npx wix preview`
|
|
512
512
|
|
|
@@ -46,41 +46,15 @@ pnpm install
|
|
|
46
46
|
|
|
47
47
|
Run TypeScript compiler to check for type errors.
|
|
48
48
|
|
|
49
|
-
**Full project check:**
|
|
50
49
|
```bash
|
|
51
|
-
npx tsc --noEmit
|
|
50
|
+
npx tsc --noEmit -p .
|
|
52
51
|
```
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# Check specific directory
|
|
60
|
-
npx tsc --noEmit src/extensions/dashboard/pages/survey/**/*.ts src/extensions/dashboard/pages/survey/**/*.tsx
|
|
61
|
-
|
|
62
|
-
# Check dashboard pages only
|
|
63
|
-
npx tsc --noEmit src/extensions/dashboard/pages/**/*.ts src/extensions/dashboard/pages/**/*.tsx
|
|
64
|
-
|
|
65
|
-
# Check custom element widgets only
|
|
66
|
-
npx tsc --noEmit src/extensions/site/widgets/**/*.ts src/extensions/site/widgets/**/*.tsx
|
|
67
|
-
|
|
68
|
-
# Check dashboard modals only
|
|
69
|
-
npx tsc --noEmit src/extensions/dashboard/modals/**/*.ts src/extensions/dashboard/modals/**/*.tsx
|
|
70
|
-
|
|
71
|
-
# Check backend only
|
|
72
|
-
npx tsc --noEmit src/extensions/backend/**/*.ts
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**When to use targeted checks:**
|
|
76
|
-
- After implementing a single extension (faster feedback)
|
|
77
|
-
- When debugging type errors in a specific area
|
|
78
|
-
- During iterative development
|
|
79
|
-
|
|
80
|
-
**When to use full project check:**
|
|
81
|
-
- Before final validation
|
|
82
|
-
- When changes affect shared types
|
|
83
|
-
- Before building/deploying
|
|
53
|
+
Run it from the app root, and check the whole project rather than just the files you
|
|
54
|
+
generated — a type error in generated code usually surfaces in the file that consumes
|
|
55
|
+
it. `-p .` is what holds that line: adding a file path to it is an error, whereas adding
|
|
56
|
+
one to a bare `npx tsc --noEmit` silently discards `tsconfig.json` (`strict`, `paths`,
|
|
57
|
+
`jsx`) and checks against compiler defaults instead.
|
|
84
58
|
|
|
85
59
|
**Success criteria:**
|
|
86
60
|
- Exit code 0
|
|
@@ -162,7 +136,7 @@ Read: .wix/debug.log (with offset to the end)
|
|
|
162
136
|
| Issue | Cause | Solution |
|
|
163
137
|
|-------|-------|----------|
|
|
164
138
|
| Package installation fails | Missing lock file, network issues, or corrupted node_modules | Delete `node_modules` and lock file, then reinstall |
|
|
165
|
-
| TypeScript compilation fails | Type mismatches, missing declarations, or incorrect types | Fix TypeScript errors shown in `npx tsc --noEmit
|
|
139
|
+
| TypeScript compilation fails | Type mismatches, missing declarations, or incorrect types | Fix TypeScript errors shown in `npx tsc --noEmit -p .` output |
|
|
166
140
|
| Build fails | TypeScript errors, missing dependencies, or internal CLI error | Fix TypeScript errors in source; for non-obvious failures, check `.wix/debug.log` |
|
|
167
141
|
| Preview fails to start | Port conflict, config issue, or internal CLI error | Check `wix.config.json`; if unclear, check `.wix/debug.log` for details |
|
|
168
142
|
| Console errors in preview | Runtime exceptions | Check browser console output |
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Wix Dashboard Page Builder
|
|
2
2
|
|
|
3
|
-
Dashboard pages appear in the site owner's Wix dashboard, where
|
|
3
|
+
Dashboard pages appear in the site owner's Wix dashboard, where admins manage data and configure settings.
|
|
4
4
|
|
|
5
5
|
## Plan the Workflow Before the Components
|
|
6
6
|
|
|
7
|
-
A dashboard page is a workflow, not a screen. The site owner has to understand the situation, focus on what needs attention, investigate one record, act, and see the result confirmed — so translate the prompt into those needs before choosing any component
|
|
7
|
+
A dashboard page is a workflow, not a screen. The site owner has to understand the situation, focus on what needs attention, investigate one record, act, and see the result confirmed — so translate the prompt into those needs before choosing any component.
|
|
8
8
|
|
|
9
9
|
Do this first because a bare filtered table answers "what are all the records" and none of "how many", "which one needs my attention", or "why did this happen" — and a table is what you get by default if the workflow was never named. Read [UX Success Model](dashboard-page/UX_SUCCESS_MODEL.md) now, and run its evaluation checklist before calling the page done. Which component serves each need: [Collection Toolkit](dashboard-page/COLLECTION_TOOLKIT.md).
|
|
10
10
|
|
|
@@ -33,7 +33,9 @@ wix generate --params '{"extensionType":"DASHBOARD_PAGE","title":"<title>","rout
|
|
|
33
33
|
|
|
34
34
|
The CLI generates the folder, `page.tsx`, the builder file, the UUID, and the `src/extensions.ts` registration. After scaffolding, implement the page UI in the generated `page.tsx`.
|
|
35
35
|
|
|
36
|
-
**
|
|
36
|
+
**Never reuse `<route>` as a path prefix inside this page's `PatternsReactRouter`** — its location is already page-scoped, so a page scaffolded `route: "shifts"` still routes from `path="/"`, and `path="/shifts"` silently never matches. Page-relative paths: [Entity Page Toolkit](dashboard-page/ENTITY_PAGE_TOOLKIT.md).
|
|
37
|
+
|
|
38
|
+
**Then, before writing UI:** resolve the package root and `Read <pkgRoot>/dist/dts-bundle/index.json` once, per [Prerequisites](WIX_PATTERNS_DOCS.md#prerequisites). Each Bash call is a fresh shell — re-set the path variable in every call.
|
|
37
39
|
|
|
38
40
|
## Capabilities
|
|
39
41
|
|
|
@@ -41,7 +43,7 @@ A dashboard page runs as the **Wix user** — see [Identity and Elevation Requir
|
|
|
41
43
|
|
|
42
44
|
### Data Operations (Wix Data SDK)
|
|
43
45
|
|
|
44
|
-
See [Wix Data Reference](data-collection/WIX_DATA.md)
|
|
46
|
+
See [Wix Data Reference](data-collection/WIX_DATA.md).
|
|
45
47
|
|
|
46
48
|
- Read: `items.query('Collection').filter/sort.limit.find()` → `{ items, totalCount, hasNext }`
|
|
47
49
|
- Write: `items.insert | update | remove`. Ensure collection permissions allow the action
|
|
@@ -50,7 +52,7 @@ See [Wix Data Reference](data-collection/WIX_DATA.md) in the Data Collection ref
|
|
|
50
52
|
|
|
51
53
|
### Dashboard APIs
|
|
52
54
|
|
|
53
|
-
See [Dashboard API Reference](dashboard-page/DASHBOARD_API.md) for
|
|
55
|
+
See [Dashboard API Reference](dashboard-page/DASHBOARD_API.md) for all methods, page IDs, and examples.
|
|
54
56
|
|
|
55
57
|
**Key methods**, all on the `dashboard` object from `@wix/dashboard` (signatures, page IDs, and examples in the reference above):
|
|
56
58
|
|
|
@@ -62,13 +64,15 @@ See [Dashboard API Reference](dashboard-page/DASHBOARD_API.md) for complete docu
|
|
|
62
64
|
|
|
63
65
|
**CRITICAL: Using Modals in Dashboard Pages**
|
|
64
66
|
|
|
65
|
-
Dashboard Pages cannot use `<Modal />`. For a true dialog overlay you **MUST** use a dashboard modal extension — never a React modal
|
|
67
|
+
Dashboard Pages cannot use `<Modal />`. For a true dialog overlay you **MUST** use a dashboard modal extension — never a React modal or the WDS `Modal` component. Reserve it for dialogs that neither write nor display a listed record (delete/discard confirmations, unsaved-changes prompts, notices), plus any dialog on a page that lists nothing (settings, config). They open via `dashboard.openModal()` — see [Dashboard Modal reference](DASHBOARD_MODAL.md).
|
|
66
68
|
|
|
67
|
-
> **🛑 The test — does the dialog create, update, or display one record this page lists?** If yes, it is an `EntityPage`, not a modal — whether those records come from a CMS collection or an existing Wix app's SDK. **A create / "add new" form is included**: it writes the record, so it is an `EntityPage` even though nothing is being edited yet. "It's a simple data-entry dialog, not an entity edit" is the wrong reading
|
|
69
|
+
> **🛑 The test — does the dialog create, update, or display one record this page lists?** If yes, it is an `EntityPage`, not a modal — whether those records come from a CMS collection or an existing Wix app's SDK. **A create / "add new" form is included**: it writes the record, so it is an `EntityPage` even though nothing is being edited yet. "It's a simple data-entry dialog, not an entity edit" is the wrong reading — the most common way the patterns-first rule gets dropped after the table is already correct.
|
|
70
|
+
>
|
|
71
|
+
> The `EntityPage` comes from `@wix/patterns`, reached via `usePatternsNavigate().navigateToEntityPage`, with `useEntityPage` owning fetch/save/validation and `@wix/patterns/form` owning form state. Its route is registered with `PatternsReactRoute` inside `PatternsReactRouter` — so do not hand-roll page location state to fake a second view (`useState<PageLocation>` as a stand-in for a route); that is the router's job, and needing it is the signal you skipped one.
|
|
68
72
|
>
|
|
69
|
-
>
|
|
73
|
+
> That's not a rule against `withDashboard`: the router **requires** it above itself and a `location` prop, which the page gets from `dashboard.observeState` (a Wix CLI app passes no props to dashboard pages). Skip it and `PatternsReactRouter` throws at open, though typecheck, bundling, and `wix preview` all pass. Read `<pkgRoot>/dist/docs/withDashboard.md` (ships from 1.465.0; on older installs, `PatternsReactRouter.md`'s **Requirements**).
|
|
70
74
|
>
|
|
71
|
-
> **If this page lists nothing**
|
|
75
|
+
> **If this page lists nothing** (settings, config) the rule doesn't apply. But "I built the list without `@wix/patterns`" is not an exception: a page that lists records should be a `CollectionPage`.
|
|
72
76
|
>
|
|
73
77
|
> See [Entity create and edit](../SKILL.md#entity-create-and-edit) and [WIX_PATTERNS_DOCS.md](WIX_PATTERNS_DOCS.md); for the `useEntityPage` call itself, [Entity Page Toolkit](dashboard-page/ENTITY_PAGE_TOOLKIT.md).
|
|
74
78
|
|
|
@@ -76,7 +80,7 @@ Dashboard Pages cannot use `<Modal />`. For a true dialog overlay you **MUST** u
|
|
|
76
80
|
|
|
77
81
|
### Embedded Script Configuration API
|
|
78
82
|
|
|
79
|
-
When building a dashboard page to configure an embedded script, see [Dynamic Parameters Reference](dashboard-page/DYNAMIC_PARAMETERS.md)
|
|
83
|
+
When building a dashboard page to configure an embedded script, see [Dynamic Parameters Reference](dashboard-page/DYNAMIC_PARAMETERS.md).
|
|
80
84
|
|
|
81
85
|
**Key points:**
|
|
82
86
|
|
|
@@ -92,7 +96,7 @@ Each output below names the library that owns each part. Confirm every patterns
|
|
|
92
96
|
|
|
93
97
|
**Request:** "Create a dashboard page to manage blog posts"
|
|
94
98
|
|
|
95
|
-
**Output:** A `@wix/patterns` `CollectionPage`
|
|
99
|
+
**Output:** A `@wix/patterns` `CollectionPage` wrapping a `Table` driven by `useTableCollection`, with search, row actions, and empty state from the collection's own APIs. Add and edit navigate to an `EntityPage`. WDS only for leaf UI inside cells and entity-page cards; the provider sits in a parent component, in its own file.
|
|
96
100
|
|
|
97
101
|
### Settings Form
|
|
98
102
|
|
|
@@ -104,13 +108,13 @@ Each output below names the library that owns each part. Confirm every patterns
|
|
|
104
108
|
|
|
105
109
|
**Request:** "Create an admin panel for customer orders"
|
|
106
110
|
|
|
107
|
-
**Output:** A `@wix/patterns` `CollectionPage` + `Table`, with filters, sorting, and row actions from the collection APIs — **not** a hand-built WDS filter bar. Status badges are WDS leaf UI
|
|
111
|
+
**Output:** A `@wix/patterns` `CollectionPage` + `Table`, with filters, sorting, and row actions from the collection APIs — **not** a hand-built WDS filter bar. Status badges are WDS leaf UI in a cell. Viewing or editing an order opens an `EntityPage` via `navigateToEntityPage`, not a modal; a Dashboard Modal appears only for the delete confirmation.
|
|
108
112
|
|
|
109
113
|
### Embedded Script Configuration
|
|
110
114
|
|
|
111
115
|
**Request:** "Create a settings page for the coupon popup embedded script"
|
|
112
116
|
|
|
113
|
-
**Output:** A `@wix/patterns` `SettingsPage`
|
|
117
|
+
**Output:** A `@wix/patterns` `SettingsPage` with WDS form fields (popup headline, coupon code, minimum cart value, enable toggle). `embeddedScripts.getEmbeddedScript()` loads the parameters on mount, `embeddedScripts.embedScript()` saves them back — both sides string-converted, per [Dynamic Parameters](dashboard-page/DYNAMIC_PARAMETERS.md).
|
|
114
118
|
|
|
115
119
|
|
|
116
120
|
## API Spec Support
|
|
@@ -122,4 +126,4 @@ When an API specification is provided, you can call those endpoints — see [API
|
|
|
122
126
|
|
|
123
127
|
Content layout inside the page shell — the 6px base unit, the 12-column grid, spacing tokens, form/display/marketing/wizard layouts: see [WDS Layout Reference](dashboard-page/WDS_LAYOUT.md).
|
|
124
128
|
|
|
125
|
-
Remember the split: `@wix/patterns` owns the
|
|
129
|
+
Remember the split: `@wix/patterns` owns the shell and anything collection-shaped; that reference covers only content placed inside.
|
|
@@ -131,6 +131,9 @@ extension configuration, and supporting files.
|
|
|
131
131
|
all bodies, hide inactive accessibly.
|
|
132
132
|
- Autoplay/loop: play/pause control, honor reduced motion, suppress autoplay in
|
|
133
133
|
editor design mode.
|
|
134
|
-
- `component.preview.tsx`:
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
- `component.preview.tsx`: preserve this outer-to-inner composition, inline or
|
|
135
|
+
through component variables:
|
|
136
|
+
`withDefaults(withFallbackPlaceholder(PreviewOrComponent, options), defaultProps)`.
|
|
137
|
+
Keep `withDefaults` outermost, wrap the preview adapter when present, use one
|
|
138
|
+
crucial `requiredDataFields` entry, and match `rootClassName` to the root
|
|
139
|
+
global class.
|
|
@@ -33,7 +33,7 @@ try {
|
|
|
33
33
|
"
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
A bare `require.resolve` without the PnP-activation step throws in a Yarn Berry project even when
|
|
36
|
+
A bare `require.resolve` without the PnP-activation step throws in a Yarn Berry project even when installed — run the whole snippet, not a shortened version.
|
|
37
37
|
|
|
38
38
|
Then confirm the installed version actually ships the bundle index:
|
|
39
39
|
|
|
@@ -41,9 +41,9 @@ Then confirm the installed version actually ships the bundle index:
|
|
|
41
41
|
ls <pkgRoot>/dist/dts-bundle/index.json
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
**If it's missing, stop — do not look elsewhere for types or docs.** The installed `@wix/patterns` predates the index
|
|
44
|
+
**If it's missing, stop — do not look elsewhere for types or docs.** The installed `@wix/patterns` predates the index (ships from **1.458.0**); upgrade and re-run the check. Prefer **1.465.0**+ — the lookups below assume it (`OffsetQuery`, `useEntityPage`'s create route, `withDashboard.md`, a deprecation `status` in `dist/docs/index.json`, page-relative router paths). A missing *file* isn't the same as a name not being covered (see below).
|
|
45
45
|
|
|
46
|
-
**Never inspect `node_modules` by hand** — no `ls`,
|
|
46
|
+
**Never inspect `node_modules` by hand** — no `ls`, `find`, or `cat` of an arbitrary path, not even `dist/dts-bundle/` or `dist/docs/`. Every lookup below names the exact file to `Read` — go straight to it.
|
|
47
47
|
|
|
48
48
|
## Library Architecture
|
|
49
49
|
|
|
@@ -75,18 +75,17 @@ Common types only; `dist/dts-bundle/index.json` has the authoritative set. Creat
|
|
|
75
75
|
| Provider | When to Use |
|
|
76
76
|
| --- | --- |
|
|
77
77
|
| `WixPatternsProvider` | **Default — start here.** Auto-detects the environment (BM, Essentials, Giza). |
|
|
78
|
-
| `WixPatternsBMProvider` | Optional
|
|
79
|
-
| `WixPatternsGizaProvider` | Optional alternative for Yoshi BM Flow over Giza. |
|
|
78
|
+
| `WixPatternsBMProvider` / `WixPatternsGizaProvider` | Optional alternatives for Yoshi BM Flow (Business Manager / Giza). |
|
|
80
79
|
| `WixPatternsEssentialsProvider` | Yoshi Fullstack. |
|
|
81
80
|
| `WixPatternsBaseProvider` | App does **not** run under Giza/WixEssentials and you inject services (i18n, sentry) yourself. |
|
|
82
81
|
|
|
83
|
-
**Confirm the import path in the provider's own bundle** —
|
|
82
|
+
**Confirm the import path in the provider's own bundle** — not all share a subpath (`WixPatternsEssentialsProvider`, `WixPatternsBaseProvider` live under `@wix/patterns/essentials`).
|
|
84
83
|
|
|
85
84
|
### Keep Provider and Page Separate
|
|
86
85
|
|
|
87
|
-
The provider **must**
|
|
86
|
+
The provider **must** be a parent of the page content: hooks like `useTableCollection` need its context above them in the tree.
|
|
88
87
|
|
|
89
|
-
**Wrong:** calling `useTableCollection` in the
|
|
88
|
+
**Wrong:** calling `useTableCollection` in the component that renders `WixPatternsProvider` — the hook runs before the provider exists, so it throws at runtime even though the JSX looks right.
|
|
90
89
|
|
|
91
90
|
**Correct — provider in root, page in a separate file:**
|
|
92
91
|
```tsx
|
|
@@ -102,7 +101,7 @@ function App() {
|
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
// MyCollectionPage.tsx
|
|
105
|
-
import { Table, useTableCollection } from '@wix/patterns';
|
|
104
|
+
import { Table, useTableCollection, OffsetQuery } from '@wix/patterns';
|
|
106
105
|
import { CollectionPage } from '@wix/patterns/page';
|
|
107
106
|
|
|
108
107
|
function MyCollectionPage() {
|
|
@@ -111,7 +110,7 @@ function MyCollectionPage() {
|
|
|
111
110
|
queryName: 'my-items',
|
|
112
111
|
itemKey: (item) => item.id,
|
|
113
112
|
itemName: (item) => item.name,
|
|
114
|
-
fetchData: async () => ({ items: [], total: 0 }),
|
|
113
|
+
fetchData: async (query: OffsetQuery) => ({ items: [], total: 0 }),
|
|
115
114
|
filters: {},
|
|
116
115
|
});
|
|
117
116
|
return (
|
|
@@ -124,7 +123,7 @@ function MyCollectionPage() {
|
|
|
124
123
|
|
|
125
124
|
Keep the provider (and router, if any) in the app's root component and each page in its own file.
|
|
126
125
|
|
|
127
|
-
For **multiple pages**, use the `@wix/patterns` routing solution (`PatternsReactRouter`, `PatternsReactRoute`, `usePatternsNavigate`) rather than a separate router
|
|
126
|
+
For **multiple pages**, use the `@wix/patterns` routing solution (`PatternsReactRouter`, `PatternsReactRoute`, `usePatternsNavigate`) rather than a separate router. Read `PatternsReactRouter.md` and `withDashboard.md` for setup — the router reads page location from the dashboard context `withDashboard` renders, so it needs that wrapper above it with a `location` prop, and throws at render time without them. (it ships from **1.465.0**; no entry in `dist/docs/index.json` means an older install — use `PatternsReactRouter.md`'s **Requirements**.)
|
|
128
127
|
|
|
129
128
|
## How to Look Things Up
|
|
130
129
|
|
|
@@ -132,47 +131,45 @@ For **multiple pages**, use the `@wix/patterns` routing solution (`PatternsReact
|
|
|
132
131
|
|
|
133
132
|
### Finding the right name
|
|
134
133
|
|
|
135
|
-
`Read <pkgRoot>/dist/dts-bundle/index.json` — one entry per name, grouped implicitly by its `category` field. Lookup is **exact-match only
|
|
134
|
+
`Read <pkgRoot>/dist/dts-bundle/index.json` — one entry per name, grouped implicitly by its `category` field. Lookup is **exact-match only** — no fuzzy matching. If the exact key isn't there, scan the index you already hold for something close before concluding the name isn't covered.
|
|
136
135
|
|
|
137
|
-
Not every real
|
|
136
|
+
Not every real export is in this index — only names these guides reference. If a needed name genuinely isn't there, **stop and say so rather than falling back to `node_modules`.**
|
|
138
137
|
|
|
139
138
|
### Reading doc files
|
|
140
139
|
|
|
141
|
-
`Read <pkgRoot>/dist/docs/index.json` to resolve a name to its doc file — or a `symbols` alias, for
|
|
140
|
+
`Read <pkgRoot>/dist/docs/index.json` to resolve a name to its doc file — or a `symbols` alias, for cases where the Storybook title doesn't match the export (`ExportTo.md` documents `ExportButton`) — then `Read <pkgRoot>/dist/docs/<file>.md` directly, the whole file, not piped through `head`. It covers more names than the bundle index above — every documented component, not just the curated ones.
|
|
142
141
|
|
|
143
|
-
**Always check the import statement inside the doc** — not everything comes from `@wix/patterns` (some use subpaths
|
|
142
|
+
**Always check the import statement inside the doc** — not everything comes from `@wix/patterns` (some use subpaths, e.g. `@wix/patterns/provider`).
|
|
143
|
+
|
|
144
|
+
A doc whose index entry has a `bundle` field does **not** list its props — its `### Props` points at that bundle. One without it carries its own table. Either way the doc owns prose, variations, BI events, and the import line.
|
|
144
145
|
|
|
145
146
|
### Reading the file the index names
|
|
146
147
|
|
|
147
|
-
The mechanics of the file an index names —
|
|
148
|
+
The mechanics of the file an index names — batching the reads, types docs don't cover, one-line stubs that are answers rather than truncation, subpath entry points, cross-references, split compound docs — are in [Reading bundles and docs](dashboard-page/PATTERNS_BUNDLE_READING.md). Read it before your first `dist/dts-bundle/*.d.ts` of the session.
|
|
148
149
|
|
|
149
150
|
## The Collection → Entity Flow
|
|
150
151
|
|
|
151
|
-
A collection page and its item form are **two patterns pages**, not a page plus a modal.
|
|
152
|
+
A collection page and its item form are **two patterns pages**, not a page plus a modal. Reserve modals for dialogs that neither write nor display a listed record (a delete or discard confirmation, an unsaved-changes prompt); **a create / "add new" form is not one of them** — it writes the record, so it's an `EntityPage` regardless of size. A page that lists nothing is outside this rule — full test in [SKILL.md](../SKILL.md#entity-create-and-edit).
|
|
152
153
|
|
|
153
154
|
| Step | What owns it |
|
|
154
155
|
| --- | --- |
|
|
155
156
|
| Navigate from a row / primary action to the item | `usePatternsNavigate()` → `navigateToEntityPage({ path, entity })` |
|
|
156
157
|
| Register the route | `PatternsReactRoute` inside `PatternsReactRouter` |
|
|
157
158
|
| Fetch, save, validation, dirty state, skeletons, errors | `useEntityPage({ fetch, onSave })` |
|
|
158
|
-
| Form state and field binding | `useForm` / `useController` from `@wix/patterns/form` |
|
|
159
|
+
| Form state and field binding | `useForm` / `useController` from `@wix/patterns/form` — `useController`, never `register` |
|
|
159
160
|
| Body layout | `EntityPage.Header`, `.MainContent`, `.AdditionalContent`, `.Card` |
|
|
160
161
|
| The individual fields inside those cards | `@wix/design-system` (`FormField`, `Input`, `Text`) |
|
|
161
162
|
|
|
162
|
-
Prefer `navigateToEntityPage` over a plain route change
|
|
163
|
-
|
|
164
|
-
Read `EntityPage.md`, `useEntityPage.md`, and `usePatternsNavigate.md` before implementing — and note `useCreateCollection` is **not** about creating items; it returns a function that initializes collection state.
|
|
165
|
-
|
|
166
|
-
Three things about the `useEntityPage` call are worth getting right first time — both generics, what `onSave` receives, which params exist: [ENTITY_PAGE_TOOLKIT.md](dashboard-page/ENTITY_PAGE_TOOLKIT.md).
|
|
163
|
+
Prefer `navigateToEntityPage` over a plain route change — the entity header renders before the fetch resolves. **Every `path` above is page-relative**: the router roots at `path="/"` even on a page scaffolded `route: "shifts"`, so never repeat that name in a `path`, `parentPath`, or `navigateToEntityPage` call — it fails silently. See [ENTITY_PAGE_TOOLKIT.md](dashboard-page/ENTITY_PAGE_TOOLKIT.md).
|
|
167
164
|
|
|
168
|
-
|
|
165
|
+
Read `EntityPage.md`, `useEntityPage.md` and `usePatternsNavigate.md` before implementing, plus [ENTITY_PAGE_TOOLKIT.md](dashboard-page/ENTITY_PAGE_TOOLKIT.md) for the `useEntityPage` call itself (generics, `onSave`, params). Note `useCreateCollection` is **not** about creating items: it returns a function that initializes collection state.
|
|
169
166
|
|
|
170
167
|
## When Patterns Has No Equivalent
|
|
171
168
|
|
|
172
|
-
A concept is only "missing" from patterns after you've checked `dist/dts-bundle/index.json` and `dist/docs/index.json` **and** searched by keyword within what you've read. Then
|
|
169
|
+
A concept is only "missing" from patterns after you've checked `dist/dts-bundle/index.json` and `dist/docs/index.json` **and** searched by keyword within what you've read. Then:
|
|
173
170
|
|
|
174
171
|
1. Look the component up in `@wix/design-system` via the `wix-design-system` skill.
|
|
175
172
|
2. Render it *inside* the patterns page shell / collection, not as a replacement for it.
|
|
176
173
|
3. If WDS lacks it too, compose from WDS primitives (`Box`, `Card`, `Text`) — never restyle patterns internals, never add another UI library.
|
|
177
174
|
|
|
178
|
-
Anything page- or collection-shaped (
|
|
175
|
+
Anything page- or collection-shaped (shell, header, table, grid, filters, sorting, paging, row/bulk actions) is patterns' territory. Building one from WDS parts means a skipped lookup.
|
|
@@ -34,9 +34,9 @@ Everything below is a real name in the installed `@wix/patterns`. Confirm the pr
|
|
|
34
34
|
| A fixed in-memory option list for a filter | `useStaticListFilterCollection` |
|
|
35
35
|
| Sorting | `Sortable Columns`, `MultiLevelSorting` |
|
|
36
36
|
|
|
37
|
-
**
|
|
37
|
+
**Read the index once, then go straight to files.** `dist/dts-bundle/index.json` answers every name in this table in a single read — resolve it once per session and keep it, rather than re-reading it per lookup. Each entry names the exact file to open next.
|
|
38
38
|
|
|
39
|
-
**A factory or hook's doc is often empty where its signature should be** — `
|
|
39
|
+
**A factory or hook's doc is often empty where its signature should be** — the props table is generated for components, so `idNameArrayFilter`'s doc shows an `## API` heading with nothing under it. Its bundle has the signature: `<T extends { id: string; name: string }>(params?) => ArrayFilterState<T>`. That holds for every `use…` hook and every `…Filter` factory in the table above, and it is the difference between knowing a name and being able to call it — so for these, read the bundle the index names, not the doc.
|
|
40
40
|
|
|
41
41
|
**A filter must narrow the result.** Declare it in the collection hook's `filters` map and read it inside `fetchData`, so the value reaches the query. Filter UI that renders but never changes the rows is a defect that looks like a feature — and it is the failure mode these components exist to prevent.
|
|
42
42
|
|
|
@@ -49,7 +49,7 @@ Everything below is a real name in the installed `@wix/patterns`. Confirm the pr
|
|
|
49
49
|
| **Expanded row** | A couple of extra fields, no separate workspace needed. | The collection's own row expansion |
|
|
50
50
|
| **Picker / bulk confirm** | Choosing records, or confirming an action on many. | `PickerModal` + `usePickerModal`, `bulkActionModal` |
|
|
51
51
|
|
|
52
|
-
A dialog that creates, updates or displays one listed record is **not** a dashboard modal — a create / "add new" form included, since it writes the record. See [DASHBOARD_MODAL.md](../DASHBOARD_MODAL.md). A row the user cannot open is the second most common failure after the missing aggregate.
|
|
52
|
+
A dialog that creates, updates or displays one listed record is **not** a dashboard modal — a create / "add new" form included, since it writes the record. See [DASHBOARD_MODAL.md](../DASHBOARD_MODAL.md); for the create route itself — registering it, and the four params that differ from the edit call — [ENTITY_PAGE_TOOLKIT.md § Create route](ENTITY_PAGE_TOOLKIT.md#create-route). A row the user cannot open is the second most common failure after the missing aggregate.
|
|
53
53
|
|
|
54
54
|
**Form state on an entity page** comes from `@wix/patterns/form` — `useForm` for the form, `useController` for a single field. That subpath re-exports `@wix/bex-core/form`, which wraps `react-hook-form`, so its API is react-hook-form's and only a handful of its names appear in the patterns docs: `FieldValues`, `ControllerProps` and most of the rest are documented by react-hook-form, not here. `Read <pkgRoot>/dist/dts-bundle/exports/form.d.ts` to see what the subpath actually gives you.
|
|
55
55
|
|
|
@@ -57,10 +57,11 @@ A dialog that creates, updates or displays one listed record is **not** a dashbo
|
|
|
57
57
|
|
|
58
58
|
| Need | Component |
|
|
59
59
|
| --- | --- |
|
|
60
|
-
|
|
|
61
|
-
|
|
|
60
|
+
| Page header actions | `PrimaryActions`, `SecondaryActions`, `More Actions` — passed to the page header's `primaryAction`, `secondaryActions` and `moreActions` slots |
|
|
61
|
+
| Table toolbar button | `PrimaryActionButton` — the table's own `primaryActionButton` prop |
|
|
62
|
+
| Row actions | `deleteSecondaryAction`, in the row's `actionCell` |
|
|
62
63
|
| Acting on a multi-row selection | `MultiBulkActionToolbar`, `bulkActionModal` |
|
|
63
|
-
| Immediate feedback, then reconcile | `useOptimisticActions
|
|
64
|
+
| Immediate feedback, then reconcile | `useOptimisticActions(state.collection)` ✅ — not `useOptimisticActions(state)` ❌: `useTableCollection()` returns `TableState<T, F>`, and the hook takes the `CollectionState<T, F>` that state exposes as `state.collection`. Returns `CollectionOptimisticActions` |
|
|
64
65
|
| A banner above the table | `TableTopNotification` |
|
|
65
66
|
|
|
66
67
|
## The states that are not the happy path
|
|
@@ -26,10 +26,29 @@ const state = useEntityPage<Shift, ShiftFormFields>({
|
|
|
26
26
|
.updateShift(shiftId, { ...form.getValues(), ...widgetsFormData })
|
|
27
27
|
.then((updatedEntity) => ({ updatedEntity })),
|
|
28
28
|
form,
|
|
29
|
-
parentPath: '/
|
|
29
|
+
parentPath: '/',
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
**`parentPath` is relative to the router's own mount point — the dashboard page's
|
|
34
|
+
own root, not the page's `route` value.** A dashboard page scaffolded with
|
|
35
|
+
`{"route": "shifts"}` is served at `/dashboard/shifts`, but `PatternsReactRouter`
|
|
36
|
+
still sees its own location start fresh at `/` inside that page — so `parentPath`,
|
|
37
|
+
every `PatternsReactRoute`'s `path`, and the `path` passed to
|
|
38
|
+
`navigateToEntityPage()` / `navigateToCollectionPage()` must never repeat the
|
|
39
|
+
page's own `route`/name. `parentPath: '/shifts'` on a page whose `route` is
|
|
40
|
+
`"shifts"` is the single most common way this gets copied wrong — it looks like a
|
|
41
|
+
reasonable guess (name the parent after the page) and compiles, but the
|
|
42
|
+
collection route it points back to is registered at `path="/"`, not
|
|
43
|
+
`path="/shifts"`, so `parentPath` must match that: `'/'`. See [Create
|
|
44
|
+
route](#create-route) below for the full route registration.
|
|
45
|
+
|
|
46
|
+
From **1.465.0** the library's own docs state this rule — `PatternsReactRouter.md`,
|
|
47
|
+
`usePatternsNavigate.md` and `useEntityPage.md`'s **Create route**. On an older
|
|
48
|
+
install they don't, and their examples *demonstrate* the mistake
|
|
49
|
+
(`navigateToEntityPage({ path: '/shifts/new' })`, `navigateToCollectionPage({ path:
|
|
50
|
+
'/entities' })`); prefer this rule over what those examples show.
|
|
51
|
+
|
|
33
52
|
`EntityPage` and `useEntityPage` are **root** exports. `@wix/patterns/page` holds `CollectionPage` and `WidgetsFormProvider` only, so importing the entity page from there is `TS2305: has no exported member` — the collection page and the entity page do not live in the same place. `Read <pkgRoot>/dist/dts-bundle/exports/page.d.ts` to see what that subpath actually gives you.
|
|
34
53
|
|
|
35
54
|
## Name both generics
|
|
@@ -54,9 +73,22 @@ Reaching for a `values`-shaped key on the `onSave` argument is the usual first g
|
|
|
54
73
|
|
|
55
74
|
## The params are a `Pick`
|
|
56
75
|
|
|
57
|
-
`UseEntityPageParams` picks a fixed set off `EntityPageStateParams` — `fetch`, `onSave`, `saveSuccessToast`, `saveErrorToast`, `deleteAction`, `transformEntityToCollectionItem`, `isNewEntity
|
|
76
|
+
`UseEntityPageParams` picks a fixed set off `EntityPageStateParams` — `fetch`, `onSave`, `saveSuccessToast`, `saveErrorToast`, `deleteAction`, `transformEntityToCollectionItem`, `isNewEntity` (create vs edit — [Create route](#create-route)), `form`, `parentPageId`, `parentPath`, `parentReferrer`, `schemaSource`. Anything outside that list is an excess-property error on the object literal. `container` is the common guess and is not one of them: the hook calls `useWixPatternsContainer()` itself.
|
|
77
|
+
|
|
78
|
+
Confirm the shape rather than guessing — the hook's doc ends by pointing at the bundle rather than tabulating props, because props tables only exist for components. `Read <pkgRoot>/dist/dts-bundle/index.json`, then `Read` the bundled `.d.ts` for each of `useEntityPage`, `UseEntityPageParams`, and `OnSaveParams` at exactly the `file` path the index gives.
|
|
79
|
+
|
|
80
|
+
## Create route
|
|
81
|
+
|
|
82
|
+
The example above is edit-only. "Add new" is an `EntityPage` too, and it is not the same call with the id left out. Four things differ, and three of them fail silently if you guess:
|
|
83
|
+
|
|
84
|
+
- The route is its own `PatternsReactRoute type="createEntity"`. One component can serve both entity routes; the route is what tells them apart.
|
|
85
|
+
- `navigateToEntityPage({ path })` — omit `entity`. It exists so the header can render a title before the fetch resolves, and a create route has no record to give it. A placeholder is worse than nothing: until `fetch` resolves it *is* `state.entity`.
|
|
86
|
+
- `fetch` is required on the create route too, and `{ entity: undefined }` is the create case built into its return type — not a loading state, and there is no `fetch`-less variant.
|
|
87
|
+
- `isNewEntity` is the only param that tells the page which route it is on. Omitted, a create page that seeds defaults through `fetch` is announced to the collection as an *update*: the collection changes a row it does not have, the new record never appears in the list, and the only trace is a `Fetched page info for updated entity not found` console error.
|
|
58
88
|
|
|
59
|
-
|
|
89
|
+
`Read <pkgRoot>/dist/docs/useEntityPage.md` before writing one — its **Create route** section carries the worked component that serves both routes off one `useParams` answer, and the `boolean | (() => boolean)` getter form for `isNewEntity`.
|
|
90
|
+
|
|
91
|
+
**If that file has no `Create route` heading, the installed `@wix/patterns` predates 1.464.0.** Upgrade and re-read rather than working around it: on those versions `navigateToEntityPage` types `entity` as required, so omitting it does not compile, and passing the placeholder that satisfies it is the failure the bullet above describes.
|
|
60
92
|
|
|
61
93
|
## Around the call
|
|
62
94
|
|
|
@@ -64,10 +96,45 @@ Confirm the shape rather than guessing — the hook's doc has an empty API secti
|
|
|
64
96
|
| --- | --- |
|
|
65
97
|
| Getting here from the collection page | `usePatternsNavigate()` → `navigateToEntityPage({ path, entity })` |
|
|
66
98
|
| Registering the route | `PatternsReactRoute` inside `PatternsReactRouter` |
|
|
67
|
-
| Form state and field binding | `useForm` / `useController` from `@wix/patterns/form` |
|
|
99
|
+
| Form state and field binding | `useForm` / `useController` from `@wix/patterns/form` — `useController`, never `register` |
|
|
68
100
|
| Body layout | `EntityPage.Header`, `.MainContent`, `.AdditionalContent`, `.Card` |
|
|
69
101
|
| The fields inside those cards | `@wix/design-system` (`FormField`, `Input`, `Text`) |
|
|
70
102
|
|
|
103
|
+
Every `path` in that first row — the route's own `path`, `parentPath`, and the `path` argument to `navigateToEntityPage`/`navigateToCollectionPage` — is relative to the page's own root, never to its `route`/name. See the `parentPath` note under [The call](#the-call) above; it is the same rule everywhere a path appears in this table.
|
|
104
|
+
|
|
71
105
|
`@wix/patterns/form` re-exports `@wix/bex-core/form`, which wraps `react-hook-form` — so `form.getValues()`, `form.reset()` and the rest are react-hook-form's API, documented there rather than in the patterns docs.
|
|
72
106
|
|
|
107
|
+
## Binding a field: `useController`, never `register`
|
|
108
|
+
|
|
109
|
+
`register` returns props for a plain `<input>`, and WDS components are not one. Two ways it fails:
|
|
110
|
+
|
|
111
|
+
`<Input {...register('qty')} />` does not compile — `register` always returns `min`/`max` as `string | number`, whatever options you passed, and WDS types them `number | undefined`. The error names `InputProps`, which reads like a WDS bug and isn't.
|
|
112
|
+
|
|
113
|
+
`<Input ref={register('qty').ref} />` **does** compile and is wrong. `Input`'s `ref` is its imperative handle (`Ref<InputImperativeActions>`); `register`'s ref is `(instance: any) => void`, so it accepts that and binds the handle rather than the `<input>`. The field never registers, validation never sees it, and nothing reports it.
|
|
114
|
+
|
|
115
|
+
Bind through value/onChange instead:
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { useController, useForm } from '@wix/patterns/form';
|
|
119
|
+
import { FormField, Input } from '@wix/design-system';
|
|
120
|
+
|
|
121
|
+
type ProductForm = { name: string; qty: number };
|
|
122
|
+
|
|
123
|
+
function NameField({ form }: { form: ReturnType<typeof useForm<ProductForm>> }) {
|
|
124
|
+
const { field, fieldState } = useController({
|
|
125
|
+
name: 'name',
|
|
126
|
+
control: form.control,
|
|
127
|
+
rules: { required: 'Name is required' },
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<FormField label="Name" required status={fieldState.error ? 'error' : undefined} statusMessage={fieldState.error?.message}>
|
|
132
|
+
<Input value={field.value} onChange={field.onChange} onBlur={field.onBlur} />
|
|
133
|
+
</FormField>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Rules live in `rules`, not on the WDS component. If you need `register` for a DOM concern such as input masking, `Input` takes `inputRef?: React.Ref<HTMLInputElement>` — pass the ref there, never to `ref`.
|
|
139
|
+
|
|
73
140
|
A dialog that creates, updates or displays one listed record is **not** a dashboard modal — a create / "add new" form included, since it writes the record. See [DASHBOARD_MODAL.md](../DASHBOARD_MODAL.md).
|