@wix/agent-skills 1.24.0 → 1.26.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 +1 -0
- package/package.json +2 -1
- package/skills/wix-app/SKILL.md +16 -14
- package/skills/wix-app/references/BUSINESS_MANAGER_THEME.md +107 -0
- package/skills/wix-app/references/BUSINESS_MANAGER_TOKENS.md +81 -0
- package/skills/wix-app/references/DASHBOARD_MODAL.md +41 -0
- package/skills/wix-app/references/DASHBOARD_PAGE.md +13 -11
- package/skills/wix-app/references/DASHBOARD_PLUGIN.md +19 -4
- package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +3 -2
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +66 -68
- package/skills/wix-app/references/dashboard-page/DYNAMIC_PARAMETERS.md +21 -38
- package/skills/wix-app/references/data-collection/LIFECYCLE.md +6 -4
- package/skills/wix-headless/SKILL.md +0 -1
- package/skills/wix-headless/references/CAPABILITIES.md +3 -3
- package/skills/wix-headless/references/DISCOVERY.md +1 -1
- package/skills/wix-headless/references/SDK_HANDOFF.md +1 -1
- package/skills/wix-headless/references/SEED.md +1 -1
- package/skills/wix-headless/references/SETUP.md +1 -1
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +1 -1
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +2 -2
- package/skills/wix-headless/references/managed/AUTHENTICATION.md +3 -14
- package/skills/wix-headless/scripts/bootstrap.mjs +156 -0
- package/skills/wix-headless-kit/SKILL.md +4 -4
- package/skills/wix-headless-kit/install/AGENTS.md +2 -2
- package/skills/wix-headless-kit/install/bootstrap.mjs +156 -0
- package/skills/wix-headless-kit/install/check.mjs +1 -1
- package/skills/wix-manage/SKILL.md +2 -8
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +250 -18
- package/skills/wix-manage/references/cms/cms-schema-management.md +52 -1
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +0 -184
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +0 -203
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +0 -44
- package/skills/wix-manage/references/cms/cms-data-operations-extended.md +0 -263
- package/skills/wix-manage/references/cms/cms-references-and-relationships.md +0 -162
package/README.md
CHANGED
|
@@ -58,6 +58,7 @@ npx skills add wix/skills -g
|
|
|
58
58
|
| [wix-app](skills/wix-app/SKILL.md) | Build Wix app extensions | Adding any extension — dashboard pages, site widgets, backend events, service plugins, embedded scripts, data collections, and more |
|
|
59
59
|
| [wix-design-system](skills/wix-design-system/SKILL.md) | Wix Design System reference | Looking up WDS component props, examples, icons |
|
|
60
60
|
| [wix-manage](skills/wix-manage/SKILL.md) | Wix business solution management | REST API operations for configuring and managing Wix business solutions |
|
|
61
|
+
| [wix-headless-kit](skills/wix-headless-kit/SKILL.md) | Build and release a Wix Headless site on shipped, verified per-solution code | Building a new headless site for a business from a brief — store, bookings, blog, events, restaurants, members, donations and more — fast, with the integration code already written |
|
|
61
62
|
| [wix-headless](skills/wix-headless/SKILL.md) | Connect Wix business services to a headless frontend (SDK + Wix CLI), and optionally build & host the site | Setting up a Wix Headless backend or adding Wix business features (Stores, Bookings, CMS, Blog, Events, Forms, Members, Restaurants, Portfolio, Pricing Plans) — install apps, seed content, and produce an SDK-integration guide; for managed projects also scaffold a new site (create) or wire an existing design (connect), then build and release. Works across managed, self-managed, and stripe project types |
|
|
62
63
|
| [wix-vibe-headless](skills/wix-vibe-headless/SKILL.md) | Connect an existing front end to Wix over client-only REST | Wiring a vibe-coded / HTML / Vite app to a live Wix site (storefront, bookings, blog, events, portfolio, restaurants, CMS, pricing plans) from the browser with a public `WIX_CLIENT_ID` — no SDK, no backend |
|
|
63
64
|
| [wix-docs](skills/wix-docs/SKILL.md) | Look up the Wix API/SDK docs (shared fallback) | Confirming an exact Wix endpoint, method schema, field, or enum before writing code — `curl` doc-search + the `.md`-twin trick, or the Wix MCP tools. Referenced by the other skills as their docs-lookup fallback |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/agent-skills",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
4
4
|
"description": "Wix Skills for AI coding agents — versioned npm distribution of the wix/skills content.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"skills/**",
|
|
19
|
+
"!skills/wix-headless-cold-start/**",
|
|
19
20
|
"README.md",
|
|
20
21
|
"LICENSE"
|
|
21
22
|
],
|
package/skills/wix-app/SKILL.md
CHANGED
|
@@ -24,12 +24,12 @@ Helps build extensions for Wix CLI applications. Covers all extension types: das
|
|
|
24
24
|
- [ ] **Step 2:** Read extension reference file(s) for the chosen type(s) and the project-wide [CODE_QUALITY.md](references/CODE_QUALITY.md)
|
|
25
25
|
- [ ] **Dashboard page UI:** Translated the prompt into a workflow before choosing components — what the user must understand, focus on, investigate, act on, and see confirmed. See [UX Success Model](references/dashboard-page/UX_SUCCESS_MODEL.md), and the installed package's own `Collection Toolkit.md` guide for which component serves each need ([The Discovery Chain](references/WIX_PATTERNS_DOCS.md#the-discovery-chain)).
|
|
26
26
|
- [ ] **No `SummaryBar` unless the request asked for one** — a named total, count, or "how many / how much" figure in the prompt. Not "the page seems like it wants one": an uninvited bar pushes the rows down and puts a number on screen nobody asked to be right about. When the request did ask, the number has to come from something that counts ([QUERY_AND_PAGING.md](references/dashboard-page/QUERY_AND_PAGING.md#what-fetchtotal-is-allowed-to-call)) and be read through `useSelector`, because the state is MobX ([TABLE_STATE.md](references/dashboard-page/TABLE_STATE.md#reading-state-outside-the-table-it-is-mobx)).
|
|
27
|
-
- [ ] **A row the user can open, as a page** — `navigateToEntityPage` to an `EntityPage` when the record is editable, or to a read-only detail route when it isn't ([
|
|
27
|
+
- [ ] **A row the user can open, as a page** — `navigateToEntityPage` to an `EntityPage` when the record is editable, or to a read-only detail route when it isn't (the package's `Collection and Read-Only Detail Template`, reached from [DRAFT_TEMPLATE.md](references/dashboard-page/DRAFT_TEMPLATE.md)) — unless the prompt is explicitly a report or an export. **Never a `SidePanel`**: in Cairo that hosts a page's own panels. The template's page says why the read-only route is a WDS `Page` rather than an `EntityPage`.
|
|
28
28
|
- [ ] **Every filter reaches the query**: declared in the collection hook's `filters` and read inside `fetchData`. Filter UI that never narrows the rows is a defect that looks like a feature.
|
|
29
29
|
|
|
30
30
|
A filtered table with no drill-in and no working filters is what gets built when nobody states the requirement — the most common way a generated dashboard disappoints. The aggregate is the judgment call; the drill-in and the filters are not.
|
|
31
|
-
- [ ] **🛑 Template-First Gate (MANDATORY, dashboard UI only, comes before writing any shell/provider/router):**
|
|
32
|
-
- [ ] **🛑 Patterns Docs Gate (MANDATORY for any dashboard page UI):** Read [WIX_PATTERNS_DOCS.md](references/WIX_PATTERNS_DOCS.md) **before the first command that touches `node_modules/@wix/patterns`** — its discovery chain (`pkg-root.cjs`, the index, `Composition and Providers.md` once, `Collection Toolkit.md` for which component serves a need) lives only in that file, and this line is a summary of its step 1, not a substitute for opening it. Then **probe** `dist/docs/index.json` with `grep`/`python3` — never a whole-file `Read`, which truncates it silently. It is the one file that says, per symbol, where to import it from (`importPath`), whether its props live in the doc or in a `.d.ts` (`bundle`), and which worked examples exist (`examples`). Upgrade `@wix/patterns` if that file is missing. Patterns API facts come only from the published `dist/docs/` (pages), `dist/examples/` (worked calls)
|
|
31
|
+
- [ ] **🛑 Template-First Gate (MANDATORY, dashboard UI only, comes before writing any shell/provider/router):** Followed [DRAFT_TEMPLATE.md](references/dashboard-page/DRAFT_TEMPLATE.md): found the page templates the installed `@wix/patterns` ships, chose one with its `Page Templates.md` guide — which pages the workflow above needs, **and where the rows come from** (your own fetch, or a CMS collection) — read that template's page, and copied every file in its `templateFiles`. Composing the page shell, provider nesting, or router wiring from scratch when a template already shows it is the failure mode this gate exists to prevent — the Patterns/Component Docs gates below are for what the template doesn't cover, not a replacement for starting there. The reverse holds too: a template replaces composing the shell, never the discovery chain, so every symbol it doesn't show still goes through the next gate.
|
|
32
|
+
- [ ] **🛑 Patterns Docs Gate (MANDATORY for any dashboard page UI):** Read [WIX_PATTERNS_DOCS.md](references/WIX_PATTERNS_DOCS.md) **before the first command that touches `node_modules/@wix/patterns`** — its discovery chain (`pkg-root.cjs`, the index, `Composition and Providers.md` once, `Collection Toolkit.md` for which component serves a need) lives only in that file, and this line is a summary of its step 1, not a substitute for opening it. Then **probe** `dist/docs/index.json` with `grep`/`python3` — never a whole-file `Read`, which truncates it silently. It is the one file that says, per symbol, where to import it from (`importPath`), whether its props live in the doc or in a `.d.ts` (`bundle`), and which worked examples exist (`examples`). Upgrade `@wix/patterns` if that file is missing. Patterns API facts come only from the published `dist/docs/` (pages), `dist/examples/` (worked calls), `dist/dts-bundle/` (types) and `dist/templates/` (whole pages) trees — never from `src/`, `dist/esm/`, or any other path inside the package, with one named exception: `dist/types/` when a bundle has stubbed the prop you need (WIX_PATTERNS_DOCS.md step 5).
|
|
33
33
|
- [ ] **🛑 Component Docs Gate (MANDATORY, dashboard UI only):** For each patterns symbol you are about to write, decided **from the index** which single artifact answers the question you actually have — `importPath`, `examples`, or `bundle` — and read only that one, per [Component Selection Order](#component-selection-order)'s "the short version". State which artifact you read per symbol, and why, before the first line of JSX. Reading a doc *and* its bundle for the same symbol, or opening a page for an `importPath` the index already gave you, is the failure this gate exists to prevent.
|
|
34
34
|
|
|
35
35
|
For the object `useTableCollection()` returns, read [TABLE_STATE.md](references/dashboard-page/TABLE_STATE.md) — a state object you receive rather than construct, whose members are unobvious and several plausible ones absent.
|
|
@@ -43,8 +43,9 @@ Helps build extensions for Wix CLI applications. Covers all extension types: das
|
|
|
43
43
|
- [ ] **Compile as you go:** ran `npx tsc --noEmit` after the first file that imports `@wix/patterns`, not only at Step 5. Patterns' state and filter APIs are the most common source of errors, and finding twenty of them in one batch after the page is written costs far more than finding two early.
|
|
44
44
|
- [ ] **🛑 Component Selection Gate (MANDATORY, dashboard UI only):** For every UI element on a Dashboard Page, resolved it against `@wix/patterns` BEFORE reaching for `@wix/design-system` — and never hand-rolled a component either library already provides. See [Component Selection Order](#component-selection-order).
|
|
45
45
|
- [ ] Invoked `wix-design-system` skill ONLY before editing the first `.tsx`/`.jsx` file that imports `@wix/design-system`. Skip for backend-only or data-only extensions.
|
|
46
|
-
- [ ] WDS:
|
|
47
|
-
- [ ]
|
|
46
|
+
- [ ] WDS: the design-system stylesheets are imported in exactly one place per app — `BusinessManagerTheme.tsx` for a dashboard surface (see the next item), or the main component entry file for a site/editor extension. Never in child, tab or helper files, and never twice.
|
|
47
|
+
- [ ] **🛑 Business Manager theme (every dashboard surface — page, modal AND plugin):** wrote `BusinessManagerTheme.tsx` once (both stylesheets, including `themes/odeditor.global.css`, plus `WixDesignSystemProvider` → `WixDesignSystemIconThemeProvider` → `IconThemeProvider theme="odeditor"` → `WixDesignSystemDefaultPropsProvider`), and wrapped **each** extension's root in it — above `WixPatternsProvider` and above `CustomModalLayout`. Every extension is a separate iframe that inherits none of the redesign, so theming the page does nothing for a modal it opens or a plugin in a slot; each one needs its own wrapper. Also: every icon from `@wix/wix-ui-icons-common/lazy`, and `--wds-*` tokens or `skin`/`size` props rather than hardcoded colours, font sizes or inline `style` ([BUSINESS_MANAGER_TOKENS.md](references/BUSINESS_MANAGER_TOKENS.md) — note the theme rebases the `SP*` spacing unit from 6px to 4px). `tsc`, `wix build` and `wix preview` all pass on an unthemed surface — only looking at it catches this. See [BUSINESS_MANAGER_THEME.md](references/BUSINESS_MANAGER_THEME.md).
|
|
48
|
+
- [ ] **Step 4c (dashboard page UI only):** Re-opened and read the page file(s) just written — not recalled intent — and confirmed against the actual code: no `SummaryBar` unless the request asked for one, a routed drill-in (`navigateToEntityPage`) for every row and no `SidePanel` used as one, every declared filter name also appearing inside `fetchData`, and — for every template with a router — the entry file both passes and guards `location`. See [UX Completeness Self-Audit](#step-4c-ux-completeness-self-audit).
|
|
48
49
|
- [ ] **Step 5:** Ran validation (see [Validation](#validation))
|
|
49
50
|
- [ ] Dependencies installed
|
|
50
51
|
- [ ] TypeScript compiled
|
|
@@ -88,7 +89,7 @@ Helps build extensions for Wix CLI applications. Covers all extension types: das
|
|
|
88
89
|
|
|
89
90
|
## Component Selection Order
|
|
90
91
|
|
|
91
|
-
**For the page shell, provider nesting, and routing — the part every dashboard page needs — start from [DRAFT_TEMPLATE.md](references/dashboard-page/DRAFT_TEMPLATE.md), not this section.** It
|
|
92
|
+
**For the page shell, provider nesting, and routing — the part every dashboard page needs — start from [DRAFT_TEMPLATE.md](references/dashboard-page/DRAFT_TEMPLATE.md), not this section.** It finds the page templates the installed `@wix/patterns` ships (read-only list, list with create/edit, settings only, and a CMS collection on its schema); copy the one the request matches and adapt it. What follows here is for individual UI elements the template doesn't already show — a filter type, a column renderer, a component the request needs that isn't in it.
|
|
92
93
|
|
|
93
94
|
Dashboard pages at Wix are built from two libraries. For **every** UI element not already covered by the template, resolve in this order and stop at the first hit. Never skip a step, and never decide a component is missing from memory — check.
|
|
94
95
|
|
|
@@ -105,8 +106,10 @@ up rather than assembling it from WDS parts.
|
|
|
105
106
|
that answer as guides inside the installed package, with every component name in them checked
|
|
106
107
|
against the real package at build time. Walk them: [The Discovery Chain](references/WIX_PATTERNS_DOCS.md#the-discovery-chain).
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
Whole pages are the package's too: the router wiring for a multi-page extension, and a
|
|
110
|
+
**collection whose fields the CMS owns** — `useCmsSchemaSource` from `@wix/patterns-cms`, with
|
|
111
|
+
`@wix/patterns/schema`, where the schema supplies fetch, filters, columns and the form — both ship
|
|
112
|
+
as page templates. See [DRAFT_TEMPLATE.md](references/dashboard-page/DRAFT_TEMPLATE.md).
|
|
110
113
|
|
|
111
114
|
The short version — probe `<pkgRoot>/dist/docs/index.json` first (`grep`/`python3`, not a
|
|
112
115
|
whole-file `Read`), then the guides it lists. From
|
|
@@ -209,11 +212,10 @@ Use a Dashboard Modal for dialogs that neither write nor display a listed record
|
|
|
209
212
|
| Wix Stores Versioning (V1/V3) | [STORES_VERSIONING.md](references/STORES_VERSIONING.md) |
|
|
210
213
|
| Official Documentation Links | [DOCUMENTATION.md](references/DOCUMENTATION.md) |
|
|
211
214
|
| Wix Patterns Dashboard Pages | [WIX_PATTERNS_DOCS.md](references/WIX_PATTERNS_DOCS.md) |
|
|
215
|
+
| Business Manager theme — the wrapper every dashboard page, modal and plugin needs | [BUSINESS_MANAGER_THEME.md](references/BUSINESS_MANAGER_THEME.md) |
|
|
216
|
+
| Business Manager tokens — `--wds-*` replacements, the rebased spacing unit, per-component adjustments | [BUSINESS_MANAGER_TOKENS.md](references/BUSINESS_MANAGER_TOKENS.md) |
|
|
212
217
|
| Dashboard UX Success Model (what a good dashboard contains) | [UX_SUCCESS_MODEL.md](references/dashboard-page/UX_SUCCESS_MODEL.md) |
|
|
213
|
-
| Draft template — start here for any dashboard page
|
|
214
|
-
| Draft template — collection page for Cases A/B/D | [DRAFT_TEMPLATE_COLLECTION.md](references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md) |
|
|
215
|
-
| Draft template — router wiring for Cases A/B/D, incl. the read-only detail route | [DRAFT_TEMPLATE_ROUTER.md](references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md) |
|
|
216
|
-
| Draft template — settings page for Cases C/D | [DRAFT_TEMPLATE_SETTINGS.md](references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md) |
|
|
218
|
+
| Draft template — start here for any dashboard page: finding, copying and adapting the package's page templates | [DRAFT_TEMPLATE.md](references/dashboard-page/DRAFT_TEMPLATE.md) |
|
|
217
219
|
| The state object `useTableCollection()` returns | [TABLE_STATE.md](references/dashboard-page/TABLE_STATE.md) |
|
|
218
220
|
| Finding the SDK method and field names behind a page | [DATA_SOURCES.md](references/dashboard-page/DATA_SOURCES.md) |
|
|
219
221
|
| Filter paths, WQL operators and cursor paging | [QUERY_AND_PAGING.md](references/dashboard-page/QUERY_AND_PAGING.md) |
|
|
@@ -416,10 +418,10 @@ Before moving to Step 5, re-open every page file you just wrote and check the ac
|
|
|
416
418
|
- [ ] **Every row opens a page**: a `navigateToEntityPage` call literally appears in `onRowClick` — unless the prompt is explicitly a report or export-only view. A `SidePanel` in a collection page file is the defect this replaces; a display-only page routes to a read-only detail page, it does not fall back to a panel. `grep -n "<SidePanel" <page files>` should return nothing — match the JSX tag, not the bare word, or the templates' own "never a SidePanel" comments fail the check and invite someone to "fix" correct code.
|
|
417
419
|
- [ ] Every filter name declared in the toolbar also appears inside `fetchData`'s query construction — grep for the name in both places if unsure.
|
|
418
420
|
- [ ] The table wires `errorState` — without it a failed query is indistinguishable from a slow one, and the page you just shipped cannot tell you which it is.
|
|
419
|
-
- [ ] **
|
|
421
|
+
- [ ] **Routed templates only (all but the settings one) — the entry file both passes and guards `location`.** `PatternsReactRouter` throws at open when `location` is missing *or* still `undefined` on the first render, and `tsc`, `wix build` and even a green build all pass regardless. Both halves are required — the `location={location}` prop **and** the `location ? … : null` guard around it, since `observeState` has not fired yet on the first render. Grep the entry file rather than trusting recall:
|
|
420
422
|
|
|
421
423
|
```bash
|
|
422
|
-
grep -n "observeState\|location={location}\|location ?" src/extensions/dashboard/pages/<page>/<page>.tsx
|
|
424
|
+
grep -n "observeState\|location={location}\|location ?" src/extensions/dashboard/pages/<page>/<page>.tsx # the file the builder's `component` points at
|
|
423
425
|
```
|
|
424
426
|
|
|
425
427
|
Three hits is correct. A missing guard is the failure mode that has actually shipped: a measured run produced a page whose plumbing looked present and still crashed on open, while a re-run of the same prompt produced a working one — so this is intermittent, and re-running is not a check.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Business Manager theme — one wrapper, every dashboard surface
|
|
2
|
+
|
|
3
|
+
Business Manager (the Wix site dashboard) was redesigned with the Harmony theme. **A dashboard extension runs in its own iframe and inherits none of it.** `WixDesignSystemProvider` alone gives the pre-redesign look — classic icons, pre-redesign button sizes and skins — rendered inside redesigned platform chrome.
|
|
4
|
+
|
|
5
|
+
**No automated check catches this.** `tsc`, `wix build` and `wix preview` all pass on an unthemed surface — every import resolves and every component renders. The failure is purely visual, so wire it from the start.
|
|
6
|
+
|
|
7
|
+
Verified against `@wix/design-system` 1.330.0 and `@wix/wix-ui-icons-common` 3.189.28 — both providers are root exports, `IconTheme` is typed `'default' | 'odeditor'`, and `themes/odeditor.global.css`, `lazy`, `lazy/system` and `core` all ship.
|
|
8
|
+
|
|
9
|
+
## 1. Both packages, together
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @wix/design-system@latest @wix/wix-ui-icons-common@latest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The redesigned styles and matching icon set ship as a pair — update them together. An older `@wix/design-system` leaves a surface half-migrated however the providers are wired, since refinements ship continuously during the rollout.
|
|
16
|
+
|
|
17
|
+
## 2. The wrapper — write this file once per app
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
// src/extensions/dashboard/BusinessManagerTheme.tsx
|
|
21
|
+
import type { FC, ReactNode } from 'react';
|
|
22
|
+
import { i18n } from '@wix/essentials';
|
|
23
|
+
import {
|
|
24
|
+
WixDesignSystemProvider,
|
|
25
|
+
WixDesignSystemIconThemeProvider,
|
|
26
|
+
WixDesignSystemDefaultPropsProvider,
|
|
27
|
+
type WixDesignSystemDefaultProps,
|
|
28
|
+
} from '@wix/design-system';
|
|
29
|
+
import { IconThemeProvider } from '@wix/wix-ui-icons-common/core';
|
|
30
|
+
import '@wix/design-system/styles.global.css';
|
|
31
|
+
import '@wix/design-system/themes/odeditor.global.css';
|
|
32
|
+
|
|
33
|
+
const BUSINESS_MANAGER_DEFAULTS: WixDesignSystemDefaultProps = {
|
|
34
|
+
Button: { size: 'small', skin: 'dark' },
|
|
35
|
+
IconButton: { size: 'small', skin: 'dark', priority: 'tertiary' },
|
|
36
|
+
TextButton: { size: 'small', skin: 'standard' },
|
|
37
|
+
Input: { size: 'small' },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const BusinessManagerTheme: FC<{ children: ReactNode; locale?: string }> = ({
|
|
41
|
+
children,
|
|
42
|
+
locale = i18n.getLocale(),
|
|
43
|
+
}) => (
|
|
44
|
+
<WixDesignSystemProvider locale={locale}>
|
|
45
|
+
<WixDesignSystemIconThemeProvider>
|
|
46
|
+
<IconThemeProvider theme="odeditor">
|
|
47
|
+
<WixDesignSystemDefaultPropsProvider defaults={BUSINESS_MANAGER_DEFAULTS}>
|
|
48
|
+
{children}
|
|
49
|
+
</WixDesignSystemDefaultPropsProvider>
|
|
50
|
+
</IconThemeProvider>
|
|
51
|
+
</WixDesignSystemIconThemeProvider>
|
|
52
|
+
</WixDesignSystemProvider>
|
|
53
|
+
);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Duplicating these four providers per entry file is how one surface silently drifts out of the theme. Each piece earns its place:
|
|
57
|
+
|
|
58
|
+
| Piece | Without it |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `themes/odeditor.global.css` | `--wds-*` tokens keep pre-redesign values, so every component renders the old palette |
|
|
61
|
+
| `WixDesignSystemIconThemeProvider` + `IconThemeProvider` | Icons stay classic — heavier strokes, wrong sizes beside redesigned components |
|
|
62
|
+
| `WixDesignSystemDefaultPropsProvider` | Buttons and inputs render pre-redesign unless every call site passes `size`/`skin` by hand |
|
|
63
|
+
|
|
64
|
+
**Order is outermost-first and fixed**, and `WixPatternsProvider` goes *inside* the wrapper: the defaults provider must sit above the components it supplies defaults to, and the WDS leaf UI inside a patterns shell is exactly that.
|
|
65
|
+
|
|
66
|
+
A prop on a component still wins over the provider, so a one-off `size="medium"` is fine. **A nested `WixDesignSystemDefaultPropsProvider` replaces these defaults rather than merging**, so don't add a second for one subtree. And don't pass `features={{ newColorsBranding: true }}` — it predates the theme and is not a substitute.
|
|
67
|
+
|
|
68
|
+
## 3. Where the wrapper goes
|
|
69
|
+
|
|
70
|
+
**Write the file once per app; use it once per extension.** Every dashboard extension — page, modal, plugin — is a separate iframe, so each needs its own wrapper at its own root, in the file that owns the providers, never in a child, tab or helper file:
|
|
71
|
+
|
|
72
|
+
| Surface | File | Section |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| Page, from any `@wix/patterns` page template | `{feature}.tsx`, holding the template's `page.tsx` | [DRAFT_TEMPLATE.md § 3](dashboard-page/DRAFT_TEMPLATE.md#3-copy-it-into-the-extension) |
|
|
75
|
+
| Page with dynamic parameters | `withProviders.tsx` | [DYNAMIC_PARAMETERS.md](dashboard-page/DYNAMIC_PARAMETERS.md#provider-wrapper-implementation) |
|
|
76
|
+
| Modal | the generated `<modal>.tsx` | [DASHBOARD_MODAL.md](DASHBOARD_MODAL.md#theme) |
|
|
77
|
+
| Plugin | the generated plugin component | [DASHBOARD_PLUGIN.md](DASHBOARD_PLUGIN.md#theme) |
|
|
78
|
+
|
|
79
|
+
Each surface's own doc shows the wrapper already in place. Copy that file as-is rather than re-adding providers by hand. A plugin is the least forgiving of the three: it renders inside a redesigned first-party page, so an unthemed one is surrounded by the very styling it is missing.
|
|
80
|
+
|
|
81
|
+
## 4. Import icons from the lazy entry point
|
|
82
|
+
|
|
83
|
+
Icons imported from the package root render classic **regardless of the providers above them**. Only the lazy entry point resolves through `IconThemeProvider`:
|
|
84
|
+
|
|
85
|
+
```diff
|
|
86
|
+
- import { Add, Confirm } from '@wix/wix-ui-icons-common';
|
|
87
|
+
+ import { Add, Confirm } from '@wix/wix-ui-icons-common/lazy';
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Use `lazy` for every icon on a dashboard surface. Outside Business Manager it keeps rendering the current set, so this is the default import, not a Business-Manager-only one. An `iconKey` in a builder file names an icon for the platform rather than importing one — leave those alone.
|
|
91
|
+
|
|
92
|
+
Two things worth knowing before you convert everything:
|
|
93
|
+
|
|
94
|
+
- **`/lazy/system` is not where app icons live.** The `system` entry holds WDS's own internal component decorations (`CheckboxChecked`, `DropDownArrow`, …) — about 80 glyphs. Ordinary icons like `Add` and `Confirm` are in `/lazy` itself, so importing them from `/lazy/system` fails `tsc` with "no exported member".
|
|
95
|
+
- **A lazy icon is a network fetch.** `core/icon.js` fetches the glyph JSON from the CDN at render time and suspends, falling back to an empty state on failure. That is fine in the dashboard, but a unit test asserting icon markup synchronously will see the fallback. If you need the redesign glyphs statically inlined with no provider and no fetch, `@wix/wix-ui-icons-common/odeditor` is a real entry point — `lazy` is still the default here because one import keeps tracking the right set both inside and outside Business Manager.
|
|
96
|
+
|
|
97
|
+
## 5. Tokens and component adjustments
|
|
98
|
+
|
|
99
|
+
Everything you style yourself — which `--wds-*` token replaces a hardcoded value, which `skin`/`size` prop replaces an inline `style`, the spacing unit the theme rebases, and the per-component adjustments the wrapper can't make for you — is in [BUSINESS_MANAGER_TOKENS.md](BUSINESS_MANAGER_TOKENS.md). Read it before styling anything by hand.
|
|
100
|
+
|
|
101
|
+
## 6. Verify
|
|
102
|
+
|
|
103
|
+
- The entry file wraps the page in `BusinessManagerTheme`, and that file imports both stylesheets and nests all four providers in order.
|
|
104
|
+
- Every icon comes from `@wix/wix-ui-icons-common/lazy` (not the package root, and not `/lazy/system`).
|
|
105
|
+
- `grep -rn "style={{" src/` and `grep -rn "#[0-9A-Fa-f]\{3,6\}" src/` return nothing for the page's own files, or only lines carrying a justification comment.
|
|
106
|
+
- In devtools, a component's colours resolve from `--wds-*` properties. A literal means that element is still custom-styled.
|
|
107
|
+
- Hover, focus, disabled, selected, error, warning and success all render — a token gap usually surfaces in a state, not at rest.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Business Manager tokens — what to use instead of a hardcoded value
|
|
2
|
+
|
|
3
|
+
Companion to [BUSINESS_MANAGER_THEME.md](BUSINESS_MANAGER_THEME.md), which sets the theme up. This file covers what you style yourself once it is wired.
|
|
4
|
+
|
|
5
|
+
A hardcoded colour or font size keeps its old value while the themed components around it change — the most visible way a surface looks half migrated. Everything below was resolved against the installed `@wix/design-system` 1.330.0 `themes/odeditor.global.css` and component typings, not from a design-side migration note.
|
|
6
|
+
|
|
7
|
+
## 1. Tokens, not hardcoded values
|
|
8
|
+
|
|
9
|
+
Use a `--wds-*` custom property, or the component's own `skin`/`size` prop.
|
|
10
|
+
|
|
11
|
+
The middle column is the value each token actually resolves to under the theme.
|
|
12
|
+
|
|
13
|
+
| Use case | Resolves to | Token |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Primary action fill | `#2F5DFF` | `--wds-color-fill-standard-primary` |
|
|
16
|
+
| Dark secondary fill | `#F0EFEF` | `--wds-color-fill-dark-secondary` |
|
|
17
|
+
| Dark secondary, hover | `#E8E7E7` | `--wds-color-fill-dark-secondary-hover` |
|
|
18
|
+
| Warning / success surface | yellow / green tones | `--wds-color-fill-warning-secondary`, `--wds-color-fill-success-secondary` |
|
|
19
|
+
| Primary text | `#151414` | `--wds-color-text-standard-primary` |
|
|
20
|
+
| Interactive / link | `#2F5DFF` | `--wds-color-text-primary` |
|
|
21
|
+
| Destructive text | `#DF3336` | `--wds-color-text-destructive` |
|
|
22
|
+
| Standard border | `#767574` | `--wds-color-border-dark-primary` |
|
|
23
|
+
| Subtle border | `#DEDEDE` | `--wds-color-border-dark-secondary` |
|
|
24
|
+
| Heading / body font | Madefor Display / Text | `--wds-font-family-display`, `--wds-font-family-default` |
|
|
25
|
+
| Heading 1 size / line height | `32px` / **`40px`** | `--wds-font-size-heading-1`, `--wds-font-line-height-heading-1` |
|
|
26
|
+
| Heading 1 weight | `500` | `--wds-font-weight-heading-1` |
|
|
27
|
+
|
|
28
|
+
Two traps in that table, both of which produce a declaration the browser silently drops:
|
|
29
|
+
|
|
30
|
+
- **`--wds-font-line-height-heading-1` resolves to 40px, not 32px.** If you are replacing a hardcoded `line-height: 32px`, the token changes your layout — that is the theme working, not a mistake, but know it before you swap.
|
|
31
|
+
- **`--wds-font-letter-spacing-heading-1` is unitless** (`-0.50`), so `letter-spacing: var(--wds-font-letter-spacing-heading-1)` is invalid CSS. WDS itself emits it with a fallback; if you need it, wrap it: `calc(var(--wds-font-letter-spacing-heading-1) * 1px)`.
|
|
32
|
+
|
|
33
|
+
**For a token not in the table, do not derive the name — look it up.** Grep the installed stylesheet, which is the only authority:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
grep -oE '\-\-wds-color-fill-[a-z0-9-]+' node_modules/@wix/design-system/themes/odeditor.global.css | sort -u
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Guessing from a Figma layer name invents tokens that do not exist (`-light` variants, for instance, are not a thing — the scale is `-primary`/`-secondary`/`-tertiary` with `-hover`/`-active`/`-disabled`), and `var()` on a missing name with no fallback makes the whole declaration invalid. You get no colour at all, and nothing in the build tells you.
|
|
40
|
+
|
|
41
|
+
**On a WDS component the prop is the target, not the token:**
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
// ❌ unchanged by a theme switch
|
|
45
|
+
<Button style={{ background: '#2F5DFF' }}>Save</Button>
|
|
46
|
+
<Badge style={{ background: '#F4B8B9' }}>Error</Badge>
|
|
47
|
+
<Text style={{ color: '#DF3336' }}>Invalid email</Text>
|
|
48
|
+
<Box style={{ background: '#F7F8FA', borderColor: '#DEDEDE' }}>
|
|
49
|
+
|
|
50
|
+
// ✅
|
|
51
|
+
<Button skin="standard">Save</Button>
|
|
52
|
+
<Badge skin="danger">Error</Badge>
|
|
53
|
+
<Text skin="error">Invalid email</Text>
|
|
54
|
+
<Box backgroundColor="D75" border="1px solid" borderColor="D60">
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
A container that genuinely isn't a WDS component takes the tokens in its own CSS: `background: var(--wds-color-fill-standard-tertiary);`.
|
|
58
|
+
|
|
59
|
+
**Tokens are CSS custom properties**, so a colour copied into a JavaScript object — a chart palette, a canvas value — does not follow the theme.
|
|
60
|
+
|
|
61
|
+
**🛑 The theme rebases the spacing unit, from 6px to 4px.** `--wds-space-100` is `6px` under the default theme and `4px` under `odeditor`, and the `SP*` scale is defined against it (`SP2` is `calc(var(--wds-space-100) * 2)`). So the moment you import the theme stylesheet, `SP2` resolves to 8px rather than 12px, and numeric spacing (`<Box gap={2}>`) rebases with it. This is the one change that lands silently on every surface.
|
|
62
|
+
|
|
63
|
+
Keep expressing spacing in `SP*` or numeric units — **because** they follow the theme — and never convert them to the pixel values in [WDS_LAYOUT.md](dashboard-page/WDS_LAYOUT.md#base-unit)'s table, which are the 6px-base figures and are wrong on a themed surface. Use that table for the 12-column grid and layout rhythm, not as a px conversion chart.
|
|
64
|
+
|
|
65
|
+
No matching token? Ship it with a `// TODO: migrate when <token> exists` comment rather than bare. If you can't say in one sentence why it can't be a token, it should be one.
|
|
66
|
+
|
|
67
|
+
## 2. Adjustments the wrapper doesn't cover
|
|
68
|
+
|
|
69
|
+
| Component | Adjustment | Prop |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| Tabs | Small, no divider | `size="small" showDivider={false}` — `showDivider` defaults on, so pass it |
|
|
72
|
+
| Panel / modal headers | Smallest close/help button | `closeButtonProps={{ size: 'small' }}`, `helpButtonProps={{ size: 'small' }}` — `CloseButton` sizes are `small \| medium \| large` |
|
|
73
|
+
| Modal headers / footers | Dividers off | `showHeaderDivider={false} showFooterDivider={false}` — **both default to `'auto'`**, which shows them once content scrolls, so doing nothing ships the dividers the redesign removes |
|
|
74
|
+
| Slider | Horizontal spacing 12px, not 8px | Per call site |
|
|
75
|
+
|
|
76
|
+
Two rows from the design-side migration note have **no API to land on at 1.330.0**, so don't go looking: a modal footer's secondary slot is `secondaryButtonProps?: Omit<ButtonProps, …>` and renders a `Button`, so "secondary becomes a text button at M size" needs a hand-built footer rather than a prop (and `CustomModalLayout` has no footer-skin prop at all — the only `light` skin is `footnoteSkin`, which styles the footnote); and `AngleInput` exposes no `size`, so "medium / 38px" is not reachable. Raise those with **#wix-design-system** rather than improvising.
|
|
77
|
+
|
|
78
|
+
**Several adjustments the providers already make for you** — don't redo them by hand: a nested icon button is Dark / Tertiary from the wrapper's `IconButton` default, and `WixDesignSystemIconThemeProvider` already supplies the Accordion caret. `Accordion`, `CloseButton`, `Tooltip`, `Popover`, `Thumbnail`, `SidePanel` and ~20 more are all legal keys of `WixDesignSystemDefaultProps`, so anything you find yourself repeating per call site probably belongs in `BUSINESS_MANAGER_DEFAULTS` instead.
|
|
79
|
+
|
|
80
|
+
Two genuine author decisions remain: a **standalone** text button uses the standard (blue) skin while one beside a primary or secondary button uses Dark; and empty states are **typography only**, no legacy illustrations (on a collection page the empty state comes from the patterns shell — the page template's, [DRAFT_TEMPLATE.md](dashboard-page/DRAFT_TEMPLATE.md)).
|
|
81
|
+
|
|
@@ -28,6 +28,47 @@ wix generate --params '{"extensionType":"DASHBOARD_MODAL","title":"<title>","fol
|
|
|
28
28
|
|
|
29
29
|
The CLI generates the folder, the modal `.tsx`, the config file, the builder file, the UUID, and the `src/extensions.ts` registration. After scaffolding, implement the modal UI in the generated `.tsx`.
|
|
30
30
|
|
|
31
|
+
## Theme
|
|
32
|
+
|
|
33
|
+
A modal opens as **its own iframe, separate from the page that opened it** — so theming the page does nothing for it. A themed page opening an unthemed modal is a common and very visible split: the dialog arrives in the pre-redesign look on top of a redesigned page.
|
|
34
|
+
|
|
35
|
+
Wrap the generated `<modal>.tsx` in the app's `BusinessManagerTheme`, at the root, above `CustomModalLayout`:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import type { FC } from 'react';
|
|
39
|
+
import { CustomModalLayout } from '@wix/design-system';
|
|
40
|
+
import { BusinessManagerTheme } from '../../BusinessManagerTheme';
|
|
41
|
+
import modalConfig from './<modal>.config';
|
|
42
|
+
|
|
43
|
+
const Modal: FC = () => (
|
|
44
|
+
<BusinessManagerTheme>
|
|
45
|
+
<CustomModalLayout
|
|
46
|
+
title={modalConfig.title}
|
|
47
|
+
showHeaderDivider={false}
|
|
48
|
+
showFooterDivider={false}
|
|
49
|
+
closeButtonProps={{ size: 'small' }}
|
|
50
|
+
/* … */
|
|
51
|
+
/>
|
|
52
|
+
</BusinessManagerTheme>
|
|
53
|
+
);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The wrapper file is written once per app and reused by every extension — [BUSINESS_MANAGER_THEME.md § 2](BUSINESS_MANAGER_THEME.md#2-the-wrapper--write-this-file-once-per-app). Icons come from `@wix/wix-ui-icons-common/lazy`, and anything you style yourself uses `--wds-*` tokens or a `skin`/`size` prop — [BUSINESS_MANAGER_TOKENS.md](BUSINESS_MANAGER_TOKENS.md).
|
|
57
|
+
|
|
58
|
+
**The redesign changes modal chrome specifically**, and the wrapper cannot make these for you:
|
|
59
|
+
|
|
60
|
+
| Part | Redesign | How |
|
|
61
|
+
| --- | --- | --- |
|
|
62
|
+
| Header / footer dividers | Removed | `showHeaderDivider={false} showFooterDivider={false}`. **Both default to `'auto'`**, which shows them once content scrolls — so doing nothing ships the dividers the redesign removes |
|
|
63
|
+
| Close / help button | Smallest size | `closeButtonProps={{ size: 'small' }}`, `helpButtonProps={{ size: 'small' }}` — `CloseButton` sizes are `small \| medium \| large` |
|
|
64
|
+
| Destructive confirm | Token, not a red literal | `skin="destructive"` on the confirm `Button` |
|
|
65
|
+
|
|
66
|
+
A confirm dialog's footer is a primary `Button` plus a cancel, and because the cancel sits beside a primary it takes the **Dark** skin rather than the wrapper's `standard` default.
|
|
67
|
+
|
|
68
|
+
**One thing the design note asks for that has no API at 1.330.0:** "the footer's secondary action is a `TextButton` at M size". `CustomModalLayout`'s slot is `secondaryButtonProps?: Omit<ButtonProps, …>` and renders a `Button`; there is no footer-skin prop either (the only `light` skin is `footnoteSkin`, which styles the footnote). Achieving it means hand-building the footer — so take it to **#wix-design-system** rather than improvising, and if you do hand-build it, the cancel needs both `skin="dark"` and `size="medium"` against the wrapper's `TextButton` default of `small`.
|
|
69
|
+
|
|
70
|
+
**Nothing renders a modal until something opens it**, so an unthemed dialog survives more than the usual checks: it is invisible to `tsc` and `wix build`, and also to a careful look at the page in `wix preview`, because it isn't on screen yet. Trigger the dialog before calling it done — that is the only step that shows it.
|
|
71
|
+
|
|
31
72
|
## Quick Reference
|
|
32
73
|
|
|
33
74
|
| Task | Method | Example |
|
|
@@ -14,6 +14,8 @@ Do this first because a bare filtered table answers "what are all the records" a
|
|
|
14
14
|
|
|
15
15
|
The order, what each library owns, and how to look a name up are stated once: [SKILL.md → Component Selection Order](../SKILL.md#component-selection-order).
|
|
16
16
|
|
|
17
|
+
**Theme:** the page's iframe inherits none of the Business Manager redesign. Wrap the entry file in the app's `BusinessManagerTheme`, import icons from `@wix/wix-ui-icons-common/lazy`, and style with `--wds-*` tokens or `skin`/`size` props — [BUSINESS_MANAGER_THEME.md](BUSINESS_MANAGER_THEME.md), [BUSINESS_MANAGER_TOKENS.md](BUSINESS_MANAGER_TOKENS.md).
|
|
18
|
+
|
|
17
19
|
## Scaffold
|
|
18
20
|
|
|
19
21
|
Use `wix generate --params` with all required fields:
|
|
@@ -27,13 +29,13 @@ wix generate --params '{"extensionType":"DASHBOARD_PAGE","title":"<title>","rout
|
|
|
27
29
|
| `title` | Display name shown in the dashboard sidebar. |
|
|
28
30
|
| `route` | URL path segment (lowercase alphanumeric + hyphens). The page is served at `/dashboard/<route>`. The scaffold param is `route`; the builder file's runtime field is `routePath`. |
|
|
29
31
|
|
|
30
|
-
The CLI generates the folder,
|
|
32
|
+
The CLI generates the folder, the page's component file (`<page>.tsx`, the builder's `component`), the builder file, the UUID and the `src/extensions.ts` registration.
|
|
31
33
|
|
|
32
|
-
**
|
|
34
|
+
**After scaffolding, check `routePath`:** use `support-tickets`, not `/support-tickets`; a leading slash fails registration even if the build passes. Internal router paths stay `/`, `/:id`, `/new`, never prefixed with `<route>` — see `<pkgRoot>/dist/docs/Collection to Entity Flow.md`.
|
|
33
35
|
|
|
34
|
-
**Before writing that UI:**
|
|
36
|
+
**Before writing that UI:** copy in the installed `@wix/patterns` page template that matches, per [DRAFT_TEMPLATE.md](dashboard-page/DRAFT_TEMPLATE.md) — don't compose the shell from scratch.
|
|
35
37
|
|
|
36
|
-
**Then, for whatever the template
|
|
38
|
+
**Then, for whatever the template doesn't cover:** probe `<pkgRoot>/dist/docs/index.json` once with `grep`/`python3` — never a whole-file `Read`, which truncates silently ([Prerequisites](WIX_PATTERNS_DOCS.md#prerequisites)). Its `importPath`, `examples` and `bundle` decide whether you open anything else. Each Bash call is a fresh shell — re-set the path variable every time.
|
|
37
39
|
|
|
38
40
|
## Capabilities
|
|
39
41
|
|
|
@@ -88,15 +90,15 @@ When building a dashboard page to configure an embedded script, see [Dynamic Par
|
|
|
88
90
|
|
|
89
91
|
## Examples
|
|
90
92
|
|
|
91
|
-
Each starts from
|
|
93
|
+
Each starts from one of the package's page templates, found through [DRAFT_TEMPLATE.md](dashboard-page/DRAFT_TEMPLATE.md) — copy its files, then adapt. Only what differs per request is listed below; the wiring lives solely in the template.
|
|
92
94
|
|
|
93
|
-
| Request |
|
|
95
|
+
| Request | Template | Adapt |
|
|
94
96
|
| --- | --- | --- |
|
|
95
|
-
| "Dashboard page to manage blog posts" |
|
|
96
|
-
| "Settings page for notification preferences" |
|
|
97
|
-
| "Admin panel for customer orders" |
|
|
98
|
-
| "Settings page for the coupon popup embedded script" |
|
|
99
|
-
| "Admin page to manage fees, with an app settings section" |
|
|
97
|
+
| "Dashboard page to manage blog posts" | Collection and Entity | Columns for the post fields named; search, row actions and empty state from the collection's own APIs; add/edit navigate to the `EntityPage`; `{feature}-api.ts` calls `@wix/blog` |
|
|
98
|
+
| "Settings page for notification preferences" | Settings Page | `SettingsPage` shell with a WDS field per preference (`FormField`, `Input`, `ToggleSwitch`); save confirms with `dashboard.showToast()`, and `dashboard.onBeforeUnload()` warns on unsaved changes — no collection, no table hook, no router |
|
|
99
|
+
| "Admin panel for customer orders" | Collection and Entity | Filters, sorting and row actions from the collection APIs — **not** a hand-built WDS filter bar; status `Badge` is leaf UI in a cell; data source is `@wix/ecom`, never CMS (see [SDK-First Rule](../SKILL.md#sdk-first-rule-existing-wix-app-data-is-never-cms)); viewing or editing opens the `EntityPage`, and a Dashboard Modal appears only for the delete confirmation (see [Entity create and edit](../SKILL.md#entity-create-and-edit)) |
|
|
100
|
+
| "Settings page for the coupon popup embedded script" | Settings Page | Fields for headline, coupon code, min cart value, enable toggle; swap `fetch`/`onSave` for `embeddedScripts.getEmbeddedScript()`/`embedScript()`, string-converted both ways (see [Dynamic Parameters](dashboard-page/DYNAMIC_PARAMETERS.md)); use `withProviders` in place of the template's plain provider |
|
|
101
|
+
| "Admin page to manage fees, with an app settings section" | Collection and Entity, plus the Settings Page's settings page as one more route | One extension, not several — fee fields/calls into every route component. Skipping the router's `location` plumbing here passes `tsc`/`wix build` silently and fails only in a browser |
|
|
100
102
|
|
|
101
103
|
|
|
102
104
|
## API Spec Support
|
|
@@ -29,13 +29,28 @@ For the complete list of available slot IDs, see [Slots Reference](dashboard-plu
|
|
|
29
29
|
- **Wix Dashboard SDK** (`@wix/dashboard`) — Interact with the dashboard page's data passed to the slot
|
|
30
30
|
- **Wix Design System** (`@wix/design-system`) — Native-looking React components matching Wix's own dashboard UI
|
|
31
31
|
|
|
32
|
+
## Theme
|
|
33
|
+
|
|
34
|
+
A plugin is its own iframe, so **it inherits nothing from the host page it sits in** — not even though that page is a redesigned first-party Wix app. This makes a plugin the least forgiving dashboard surface: an unthemed one renders classic icons and pre-redesign buttons directly beside the redesigned Stores/Bookings/Blog UI framing it.
|
|
35
|
+
|
|
36
|
+
Wrap the plugin component in the app's `BusinessManagerTheme` (the example below does), import icons from `@wix/wix-ui-icons-common/lazy`, and style with `--wds-*` tokens or `skin`/`size` props — never a hardcoded colour or an inline `style` override ([BUSINESS_MANAGER_TOKENS.md](BUSINESS_MANAGER_TOKENS.md)). The wrapper file itself is written once per app: [BUSINESS_MANAGER_THEME.md § 2](BUSINESS_MANAGER_THEME.md#2-the-wrapper--write-this-file-once-per-app).
|
|
37
|
+
|
|
38
|
+
Two things to get right in a slot specifically:
|
|
39
|
+
|
|
40
|
+
- **Match the host's density, don't fight it.** The wrapper's defaults (`Button` small/dark, `IconButton` small/dark/tertiary) are what the surrounding page uses. Overriding them per call site is how a plugin starts looking like a different product.
|
|
41
|
+
- **A nested icon button inside your own card or list row is Dark / Tertiary.** The wrapper's `IconButton` default already gives you this — don't re-specify `skin="standard"` on it.
|
|
42
|
+
|
|
43
|
+
A plugin has no page of its own, so looking at it means navigating to the host app's page that carries the slot — the Blog posts or Bookings staff screen itself.
|
|
44
|
+
|
|
32
45
|
## Interacting with Dashboard Data
|
|
33
46
|
|
|
34
47
|
Use `observeState()` from the Dashboard SDK to receive data from the host dashboard page:
|
|
35
48
|
|
|
36
|
-
```
|
|
49
|
+
```tsx
|
|
37
50
|
import { dashboard } from "@wix/dashboard";
|
|
38
|
-
import { useEffect, useState } from "react";
|
|
51
|
+
import { useEffect, useState, type FC } from "react";
|
|
52
|
+
import { Card, Text } from "@wix/design-system";
|
|
53
|
+
import { BusinessManagerTheme } from "../../BusinessManagerTheme";
|
|
39
54
|
|
|
40
55
|
const Plugin: FC = () => {
|
|
41
56
|
const [params, setParams] = useState<Record<string, unknown>>({});
|
|
@@ -47,13 +62,13 @@ const Plugin: FC = () => {
|
|
|
47
62
|
}, []);
|
|
48
63
|
|
|
49
64
|
return (
|
|
50
|
-
<
|
|
65
|
+
<BusinessManagerTheme>
|
|
51
66
|
<Card>
|
|
52
67
|
<Card.Content size="medium">
|
|
53
68
|
<Text>Received data: {JSON.stringify(params)}</Text>
|
|
54
69
|
</Card.Content>
|
|
55
70
|
</Card>
|
|
56
|
-
</
|
|
71
|
+
</BusinessManagerTheme>
|
|
57
72
|
);
|
|
58
73
|
};
|
|
59
74
|
```
|
|
@@ -12,7 +12,7 @@ Then check the install, two ways: `ls <pkgRoot>/dist/dts-bundle/index.json`, and
|
|
|
12
12
|
|
|
13
13
|
**If either fails, stop and upgrade `@wix/patterns`.** "Which component serves this need" now lives in the package, so proceeding means guessing names; do not hunt elsewhere in `node_modules` for a substitute. Everything below degrades by version rather than breaking, so probe rather than version-check.
|
|
14
14
|
|
|
15
|
-
**Patterns API facts come from
|
|
15
|
+
**Patterns API facts come from four published trees only:** `dist/docs/` (pages), `dist/dts-bundle/` (types), `dist/examples/` (worked calls), `dist/templates/` (whole pages). Never take a component, prop or type from `src/`, `dist/esm/` or `dist/cjs/`, or a deep path a bundle mentions — internals change without notice. `dist/types/` is one narrow exception, used only where step 5 says: `package.json` points `types` at it, so it is what `tsc` enforces.
|
|
16
16
|
|
|
17
17
|
## The Discovery Chain
|
|
18
18
|
|
|
@@ -38,6 +38,7 @@ Start here rather than the bundle index: it carries every documented name *and*
|
|
|
38
38
|
|
|
39
39
|
| Building | Guide |
|
|
40
40
|
| --- | --- |
|
|
41
|
+
| A whole page | `dist/docs/Page Templates.md`, via [DRAFT_TEMPLATE.md](dashboard-page/DRAFT_TEMPLATE.md) |
|
|
41
42
|
| Anything collection-shaped — tables, filters, search, aggregates, row and bulk actions, empty states | `dist/docs/Collection Toolkit.md` |
|
|
42
43
|
| The path from a listed row to one record, and its form | `dist/docs/Collection to Entity Flow.md` |
|
|
43
44
|
|
|
@@ -53,7 +54,7 @@ Each guide's index entry carries `relatedComponents`; every name in it resolves,
|
|
|
53
54
|
| What props, and which are optional? | the **example** first; then the **`.d.ts`** *or* the doc — never both | `bundle` present: `dist/dts-bundle/<bundle>` · absent: `dist/docs/<file>` |
|
|
54
55
|
| A setup requirement or gotcha? | the **doc's** prose | `dist/docs/<file>` |
|
|
55
56
|
|
|
56
|
-
Prefix the index's bare values with their tree — `file` → `dist/docs/`, `examples` → `dist/examples/`, `bundle` → `dist/dts-bundle/` — and never rebuild a path from a symbol name.
|
|
57
|
+
Prefix the index's bare values with their tree — `file` → `dist/docs/`, `examples` → `dist/examples/`, `bundle` → `dist/dts-bundle/`, `templateFiles` → `dist/templates/` — and never rebuild a path from a symbol name.
|
|
57
58
|
|
|
58
59
|
**Those two middle rows are one question in practice.** You ask how to call it, start writing, and the question turns prop-shaped mid-call — where the second row sends you to a `.d.ts` that may be stubbed (step 5). Take the props off the example first; go to the `.d.ts` only for what it cannot show — optionality, union members, an exact callback signature.
|
|
59
60
|
|