@wix/agent-skills 1.14.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/package.json +1 -1
- package/skills/README.md +23 -0
- package/skills/wix-app/SKILL.md +10 -2
- package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
- package/skills/wix-app/references/CODE_QUALITY.md +1 -0
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
- package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +23 -9
- package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
- package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
- package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
- package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
- package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
- package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
- package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
- package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
- package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
- package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
- package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
- package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +17 -105
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +15 -15
- package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
- package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
- package/skills/wix-auth/SKILL.md +12 -0
- package/skills/wix-auth/references/device-flow.md +140 -0
- package/skills/wix-docs/SKILL.md +188 -0
- package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
- package/skills/wix-docs/references/EXTRACTING.md +120 -0
- package/skills/wix-headless/SKILL.md +84 -130
- package/skills/wix-headless/entry/bootstrap.mjs +93 -0
- package/skills/wix-headless/entry/skill.md +78 -0
- package/skills/wix-headless/references/AI_FEATURES.md +178 -0
- package/skills/wix-headless/references/CAPABILITIES.md +84 -0
- package/skills/wix-headless/references/DISCOVERY.md +34 -56
- package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
- package/skills/wix-headless/references/FEEDBACK.md +118 -0
- package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
- package/skills/wix-headless/references/SDK_HANDOFF.md +97 -0
- package/skills/wix-headless/references/SEED.md +44 -188
- package/skills/wix-headless/references/SETUP.md +32 -103
- package/skills/wix-headless/references/astro.md +98 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +173 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
- package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
- package/skills/wix-headless/references/inline-recipes/setup-bookings.md +228 -0
- package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
- package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
- package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
- package/skills/wix-headless/references/inline-recipes/setup-online-store.md +176 -0
- package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +153 -0
- package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +161 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +117 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
- package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
- package/skills/wix-headless/references/managed/CONNECT.md +74 -0
- package/skills/wix-headless/references/managed/CREATE.md +130 -0
- package/skills/wix-headless/references/managed/DEPLOYMENT.md +57 -0
- package/skills/wix-headless/references/non-astro.md +59 -0
- package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
- package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +7 -0
- package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
- package/skills/wix-headless/references/stripe/DEPLOYMENT.md +63 -0
- package/skills/wix-manage/SKILL.md +24 -1
- package/skills/wix-manage/references/analytics/query-site-analytics.md +241 -0
- package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
- package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +265 -0
- package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +436 -0
- package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +209 -0
- package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
- package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +51 -0
- package/skills/wix-vibe-headless/SKILL.md +136 -0
- package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
- package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +153 -0
- package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
- package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +215 -0
- package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
- package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
- package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
- package/skills/wix-vibe-headless/references/events/wix-events-browse.js +135 -0
- package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
- package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
- package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
- package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
- package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +194 -0
- package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
- package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
- package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
- package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
- package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
- package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +155 -0
- package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
- package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +142 -0
- package/skills/wix-headless/references/BUILD-astro.md +0 -253
- package/skills/wix-headless/references/BUILD-own-build.md +0 -167
- package/skills/wix-headless/references/BUILD.md +0 -105
- package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
- package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
- package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
- package/skills/wix-headless/references/PLAN-connect.md +0 -19
- package/skills/wix-headless/references/PLAN-create.md +0 -17
- package/skills/wix-headless/references/PLAN.md +0 -92
- package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
- package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
- package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
- package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
- package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
- package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
- package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
- package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
- package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
- package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
- package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
- package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
- package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
- package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
- package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
- package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
- package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
- package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
- package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
- package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
- package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
- package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
- package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
- package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
- package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
- package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
- package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
- package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
- package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
- package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
- package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
- package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
- package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
- package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
- package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
- package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
- package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
- package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
- package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
- package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
- package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
- package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
- package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
- package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
- package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
- package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
- package/skills/wix-headless/references/astro/templates/global.css +0 -288
- package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
- package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
- package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
- package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
- package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
- package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
- package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
- package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
- package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
- package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
- package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
- package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
- package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
- package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
- package/skills/wix-headless/references/bookings/FLOW.md +0 -246
- package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
- package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
- package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
- package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
- package/skills/wix-headless/references/commands/known-apps.json +0 -6
- package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
- package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
- package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
- package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
- package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
- package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
- package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
- package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
- package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
- package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
- package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
- package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
- package/skills/wix-headless/references/seed-recipes.md +0 -49
- package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
- package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
- package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
- package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
- package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
- package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
- package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
- package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
- package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
- package/skills/wix-headless/references/shared/STYLING.md +0 -140
- package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
- package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
- package/skills/wix-headless/references/verticals/_schema.json +0 -74
- package/skills/wix-headless/references/verticals/_schema.md +0 -95
- package/skills/wix-headless/references/verticals/blog.md +0 -31
- package/skills/wix-headless/references/verticals/bookings.md +0 -41
- package/skills/wix-headless/references/verticals/cms.md +0 -30
- package/skills/wix-headless/references/verticals/ecom.md +0 -25
- package/skills/wix-headless/references/verticals/forms.md +0 -26
- package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
- package/skills/wix-headless/references/verticals/stores.md +0 -33
- package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
- package/skills/wix-headless/scripts/compose.mjs +0 -520
- package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
- package/skills/wix-headless/scripts/flatten.sh +0 -61
- package/skills/wix-headless/scripts/generate-images.mjs +0 -242
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -154
- package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
- package/skills/wix-headless/scripts/scaffold.sh +0 -139
- package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
- package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
- package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
- package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
- package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
|
@@ -7,23 +7,17 @@ Rules and patterns for props structure, elementProps, data types, file structure
|
|
|
7
7
|
## Should This Use elementProps or CSS?
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
|
|
11
|
-
- Configuration/data beyond styling
|
|
12
|
-
- Direction override
|
|
13
|
-
- State management
|
|
14
|
-
- Event handlers
|
|
15
|
-
|
|
10
|
+
Is this element a named part (carries a global class string)?
|
|
16
11
|
│
|
|
17
12
|
├─ YES
|
|
18
|
-
│ └─ ✅
|
|
13
|
+
│ └─ ✅ It gets an elementProps entry — spread it + merge its className.
|
|
14
|
+
│ Add config fields inside the entry only as needed
|
|
15
|
+
│ (data, direction, event handlers).
|
|
19
16
|
│
|
|
20
|
-
└─ NO →
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
│
|
|
25
|
-
└─ NO
|
|
26
|
-
└─ Re-evaluate: likely needs elementProps
|
|
17
|
+
└─ NO → purely visual/decorative non-part
|
|
18
|
+
(icons, separators, decorations, layout wrappers,
|
|
19
|
+
elements only hidden/shown via CSS)
|
|
20
|
+
└─ ❌ CSS class only — no elementProps entry
|
|
27
21
|
```
|
|
28
22
|
|
|
29
23
|
---
|
|
@@ -58,23 +52,53 @@ interface ComponentProps {
|
|
|
58
52
|
}
|
|
59
53
|
```
|
|
60
54
|
|
|
61
|
-
###
|
|
55
|
+
### Propagate `elementProps` to inner elements
|
|
56
|
+
|
|
57
|
+
`elementProps` is a map keyed by the manifest's inner-element keys; each entry
|
|
58
|
+
carries that element's `className` (the editor sets it — this is how design
|
|
59
|
+
states reach the element) plus any data.
|
|
60
|
+
|
|
61
|
+
**Every named inner element — every element that carries a global class
|
|
62
|
+
string — gets an `elementProps` entry, and you spread that entry onto the
|
|
63
|
+
element.** This is mandatory, even when the element needs no other config:
|
|
64
|
+
without it the editor cannot style that element or drive its states.
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
How `className` gets merged depends on what the element is:
|
|
67
|
+
|
|
68
|
+
- **Raw HTML element** (`<button>`, `<li>`, `<div>`): merge
|
|
69
|
+
`elementProps?.<key>.className` inline, alongside the global string and module
|
|
70
|
+
class — there's no component to do it.
|
|
71
|
+
- **Sub-component built with this skill** (`<Inner/>`): the spread alone is
|
|
72
|
+
enough. `className` rides along inside it, and the sub-component merges it onto
|
|
73
|
+
its own root (every skill component merges its incoming `className`). Don't
|
|
74
|
+
merge it again at the call site.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
interface PlanCardProps {
|
|
78
|
+
className?: string;
|
|
79
|
+
elementProps?: {
|
|
80
|
+
cta?: { className?: string; href?: string };
|
|
81
|
+
};
|
|
82
|
+
}
|
|
64
83
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
84
|
+
// Raw HTML element — spread + merge className inline.
|
|
85
|
+
// Note: the elementProps key is the short part name (`cta`), while the global
|
|
86
|
+
// class is prefixed with the component name (`plan-card-cta`). Keep them as-is.
|
|
87
|
+
<button {...elementProps?.cta} className={classNames('plan-card-cta', styles.cta, elementProps?.cta?.className)}>
|
|
88
|
+
{label}
|
|
89
|
+
</button>
|
|
69
90
|
|
|
70
|
-
|
|
91
|
+
// Sub-component built with this skill — spread is enough (it merges className itself):
|
|
92
|
+
<PlanRow {...elementProps?.planRow} />
|
|
93
|
+
```
|
|
71
94
|
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
- Elements that would only have `className` — skip them entirely
|
|
75
|
-
- Icons, decorations, separators
|
|
95
|
+
**Non-parts** (module-class-only elements: icons, decorations, separators,
|
|
96
|
+
layout wrappers — no global class) get no entry. Style them with CSS.
|
|
76
97
|
|
|
77
|
-
**
|
|
98
|
+
**Inside each entry**, add only the config the element needs (data, direction,
|
|
99
|
+
event handlers). Never add a bare `className?` as the *only* field to decide
|
|
100
|
+
whether an element qualifies — `className` always flows through; the entry
|
|
101
|
+
exists because the element is a named part.
|
|
78
102
|
|
|
79
103
|
### What Qualifies as a Part
|
|
80
104
|
|
|
@@ -178,8 +202,8 @@ editor) or imported local assets bundled with the component.
|
|
|
178
202
|
|
|
179
203
|
### Default values for `Image` props
|
|
180
204
|
|
|
181
|
-
Image defaults belong in the
|
|
182
|
-
constant (
|
|
205
|
+
Image defaults belong in the `<componentName>.props.ts` file's exported
|
|
206
|
+
`defaultProps` constant (consumed by `withDefaults(Component, defaultProps)` in
|
|
183
207
|
`component.tsx`). Use a Wix-hosted image from the Free-from-Wix public
|
|
184
208
|
media catalog and populate **only** `uri`, `url`, and `alt` — leave
|
|
185
209
|
`width`, `height`, `focalPoint`, etc. unset so the editor fills them when
|
|
@@ -426,7 +450,7 @@ elementProps?: {
|
|
|
426
450
|
// Style via CSS classes directly
|
|
427
451
|
```
|
|
428
452
|
|
|
429
|
-
**Why:**
|
|
453
|
+
**Why:** Don't declare a `className?:` field — `className` already flows through each named inner element's `elementProps` entry (see "Propagate `elementProps` to inner elements"). Conditional display is controlled via CSS, not React props.
|
|
430
454
|
|
|
431
455
|
### Using T[] array syntax
|
|
432
456
|
|
|
@@ -452,3 +476,4 @@ interface ComponentProps {
|
|
|
452
476
|
```
|
|
453
477
|
|
|
454
478
|
See also: [Array Element Types: Always Objects with Named Keys](#array-element-types-always-objects-with-named-keys) — items must be objects with named keys.
|
|
479
|
+
|
|
@@ -128,14 +128,14 @@ resizeDirection: LAYOUT.RESIZE_DIRECTION.aspectRatio,
|
|
|
128
128
|
|
|
129
129
|
## 3. Wiring defaults into the manifest
|
|
130
130
|
|
|
131
|
-
1. **
|
|
131
|
+
1. **Define and export `defaultProps` from `<componentName>.props.ts`** — this is the single source of truth used by both `component.tsx` and the extension file.
|
|
132
132
|
2. **Import `componentUrl` from `'./component.tsx?url'`** (the wrapped component), not from `'./ComponentName.tsx?url'` (the raw component).
|
|
133
133
|
3. **Wrap `editorElement` with `withEditorElementDefaults`** using the same `defaultProps`.
|
|
134
134
|
|
|
135
135
|
```ts
|
|
136
136
|
import { withEditorElementDefaults } from '@wix/react-component-utils';
|
|
137
137
|
import componentUrl from './component.tsx?url';
|
|
138
|
-
import { defaultProps } from '
|
|
138
|
+
import { defaultProps } from './<componentName>.props';
|
|
139
139
|
|
|
140
140
|
// in the extension:
|
|
141
141
|
editorElement: withEditorElementDefaults({
|
|
@@ -16,10 +16,12 @@ There are two kinds of classes, determined by whether the element is a named par
|
|
|
16
16
|
|
|
17
17
|
| Element type | className | Why |
|
|
18
18
|
|---|---|---|
|
|
19
|
-
| Named part | `classNames('heading', styles.heading)` | Global string → zeroConfig creates an editor element; module class → applies the component's own CSS |
|
|
19
|
+
| Named part | `classNames('profile-card-heading', styles.heading)` | Global string → zeroConfig creates an editor element; module class → applies the component's own CSS |
|
|
20
20
|
| Non-part (layout/structural) | `styles.contentWrapper` | Module class only — invisible to zeroConfig, no spurious editor element created |
|
|
21
21
|
|
|
22
|
-
**Named parts** get both a global plain string and a module class. The global string
|
|
22
|
+
**Named parts** get both a global plain string and a module class. The global string is what zeroConfig scans: use `'<component-name>'` for the root and **`'<component-name>-<part-name>'` for every inner part** (kebab-case) — always prefix inner parts with the component name. The module class is what carries the component's structural CSS for that element; it stays short (`styles.heading`) because module classes are hashed and scoped, so they never need the prefix.
|
|
23
|
+
|
|
24
|
+
**Why prefix inner parts:** the global string is a literal class that ends up on the live page, and its design-state variants are derived from it (`<component-name>-<part>--<state>`, e.g. `profile-card-cta--hover`). Those state classes are applied at runtime as global literals, so they must be unique across every component that can share a page — a bare `cta--hover` would collide between two different components. Prefixing with the component name guarantees uniqueness.
|
|
23
25
|
|
|
24
26
|
**Non-part elements** (layout wrappers, grouping containers, structural helpers) get only a module class. CSS module classes are mangled and invisible to zeroConfig.
|
|
25
27
|
|
|
@@ -34,18 +36,18 @@ import styles from './ProfileCard.module.css';
|
|
|
34
36
|
// ✅ Root: global string + module class + consumer className
|
|
35
37
|
<div className={classNames(className, 'profile-card', styles.root)} id={id}>
|
|
36
38
|
|
|
37
|
-
{/* ✅ Named part: global string + module class */}
|
|
38
|
-
<h2 className={classNames('heading', styles.heading)}>{heading}</h2>
|
|
39
|
+
{/* ✅ Named part: prefixed global string + short module class */}
|
|
40
|
+
<h2 className={classNames('profile-card-heading', styles.heading)}>{heading}</h2>
|
|
39
41
|
|
|
40
42
|
{/* ✅ Non-part layout wrapper: module class only */}
|
|
41
43
|
<div className={styles.contentWrapper}>
|
|
42
|
-
<span className={classNames('label', styles.label)}>{label}</span>
|
|
44
|
+
<span className={classNames('profile-card-label', styles.label)}>{label}</span>
|
|
43
45
|
</div>
|
|
44
46
|
</div>
|
|
45
47
|
|
|
46
48
|
// ✅ Internal sub-components — same pattern on part slots
|
|
47
|
-
<CardHeader className={classNames('header', styles.header)}>
|
|
48
|
-
<CardTitle className={classNames('title', styles.title)}>{title}</CardTitle>
|
|
49
|
+
<CardHeader className={classNames('profile-card-header', styles.header)}>
|
|
50
|
+
<CardTitle className={classNames('profile-card-title', styles.title)}>{title}</CardTitle>
|
|
49
51
|
</CardHeader>
|
|
50
52
|
```
|
|
51
53
|
|
|
@@ -64,6 +66,9 @@ on context — either way the editor cannot decide which rule to
|
|
|
64
66
|
modify when a user changes a property. CSS nesting compiles to
|
|
65
67
|
descendant selectors and has the same effect.
|
|
66
68
|
|
|
69
|
+
A state modifier on the element's own class (`.title:hover`,
|
|
70
|
+
`.title:global(.profile-card-title--featured)`) is allowed — see [`DESIGN-STATES.md`](DESIGN-STATES.md).
|
|
71
|
+
|
|
67
72
|
```css
|
|
68
73
|
/* ✅ Do: Single-class selector — unambiguous mapping to an editor control */
|
|
69
74
|
.profile-card {
|
|
@@ -417,102 +422,10 @@ refined default costs nothing.
|
|
|
417
422
|
| Hierarchy | Interactive elements visually distinct from static via weight, fill, or elevation |
|
|
418
423
|
| Touch targets | Interactive elements ≥ 44×44 px |
|
|
419
424
|
|
|
420
|
-
###
|
|
421
|
-
|
|
422
|
-
State pseudo-classes and state attribute selectors are not allowed
|
|
423
|
-
in component CSS. That includes `:hover`, `:focus`, `:focus-visible`,
|
|
424
|
-
`:active`, `:disabled`, and attribute selectors like
|
|
425
|
-
`[data-state='open']` or `[aria-selected='true']`.
|
|
426
|
-
|
|
427
|
-
**Why:** the editor owns state styling. Hover, focus, disabled, and
|
|
428
|
-
similar interaction states are exposed to the site owner as
|
|
429
|
-
editable visual states — the platform writes those rules itself
|
|
430
|
-
based on what the user configures. State styles authored in the
|
|
431
|
-
component compete with the platform's rules and produce two
|
|
432
|
-
sources of truth for the same state.
|
|
433
|
-
|
|
434
|
-
```css
|
|
435
|
-
/* ❌ Don't: hover/focus/disabled state — platform owns these */
|
|
436
|
-
.button:hover {
|
|
437
|
-
background-color: #f0f0f0;
|
|
438
|
-
}
|
|
439
|
-
.button:focus {
|
|
440
|
-
outline: 2px solid blue;
|
|
441
|
-
}
|
|
442
|
-
.button:disabled {
|
|
443
|
-
opacity: 0.5;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/* ❌ Don't: state attribute selectors — same problem */
|
|
447
|
-
.panel[data-state='open'] {
|
|
448
|
-
background-color: #fafafa;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/* ✅ Do: Style the resting state only — platform layers state styling on top */
|
|
452
|
-
.button {
|
|
453
|
-
background-color: #ffffff;
|
|
454
|
-
color: #111;
|
|
455
|
-
}
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### Express selection / mode variants with JS-toggled modifier classes
|
|
459
|
-
|
|
460
|
-
The previous rule banned **interaction states** (`:hover`, `:focus`,
|
|
461
|
-
`:focus-visible`, `:active`, `:disabled`, `[data-state]`,
|
|
462
|
-
`[aria-selected]`) — those are user-controlled and platform-owned.
|
|
463
|
-
**Selection / mode variants** (`selected`, `active`, `current`,
|
|
464
|
-
`open`, `expanded`) are different: they are part of the component's
|
|
465
|
-
own data model and the component owns their styling.
|
|
425
|
+
### Design states
|
|
466
426
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
modifier — is its own **single-class** CSS rule. The decision of
|
|
470
|
-
which class applies is made in JSX from props/state, not by a CSS
|
|
471
|
-
selector.
|
|
472
|
-
|
|
473
|
-
**Why:** the modifier class is decided in JSX, not in CSS. zeroConfig
|
|
474
|
-
still sees one selector per rule (both classes are single-class
|
|
475
|
-
rules), so the editor's mapping stays unambiguous. `PARTS.md`
|
|
476
|
-
excludes "state or variant" from the named-parts taxonomy — the
|
|
477
|
-
modifier is CSS-only, not a part.
|
|
478
|
-
|
|
479
|
-
```tsx
|
|
480
|
-
/* ✅ Do: JS-toggled modifier class, applied alongside the base */
|
|
481
|
-
<button
|
|
482
|
-
className={classNames(
|
|
483
|
-
styles.toggleSegment,
|
|
484
|
-
isSelected && styles.toggleSegmentSelected,
|
|
485
|
-
)}
|
|
486
|
-
/>
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
```css
|
|
490
|
-
/* ✅ Do: each class is its own single-class rule */
|
|
491
|
-
.toggleSegment {
|
|
492
|
-
background: transparent;
|
|
493
|
-
color: #475569;
|
|
494
|
-
font-weight: 500;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
.toggleSegmentSelected {
|
|
498
|
-
background: #ffffff;
|
|
499
|
-
color: #0f172a;
|
|
500
|
-
font-weight: 600;
|
|
501
|
-
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.1);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/* ❌ Don't: compound selector — banned by the single-class-selector rule */
|
|
505
|
-
.toggleSegment.selected {
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
/* ❌ Don't: attribute selector keyed on ARIA — banned by the no-state-CSS rule */
|
|
509
|
-
.toggleSegment[aria-selected='true'] {
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/* ❌ Don't: pseudo-class — that's an interaction state, platform-owned */
|
|
513
|
-
.toggleSegment:checked {
|
|
514
|
-
}
|
|
515
|
-
```
|
|
427
|
+
Style interaction and selection states (`hover`, `focus`, `disabled`,
|
|
428
|
+
`selected`, …) per [`DESIGN-STATES.md`](DESIGN-STATES.md).
|
|
516
429
|
|
|
517
430
|
### Don't add transitions or animations unless functionally required
|
|
518
431
|
|
|
@@ -528,9 +441,7 @@ shorthand (`transition: 0.2s ease`).
|
|
|
528
441
|
configures the component — colors, font, padding, border width,
|
|
529
442
|
even layout properties on parent classes. Animating those mutations
|
|
530
443
|
makes the editor visibly laggy: values meant to update instantly
|
|
531
|
-
slide instead.
|
|
532
|
-
the platform (see the rule above), so the component shouldn't
|
|
533
|
-
author them either.
|
|
444
|
+
slide instead.
|
|
534
445
|
|
|
535
446
|
```css
|
|
536
447
|
/* ❌ Don't: decorative transition with no functional reason */
|
|
@@ -574,3 +485,4 @@ published site, where the wrapper is gone.
|
|
|
574
485
|
pointer-events: auto;
|
|
575
486
|
}
|
|
576
487
|
```
|
|
488
|
+
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Design States
|
|
2
|
+
|
|
3
|
+
A design state styles an element differently per interaction (`hover`,
|
|
4
|
+
`focus`, `disabled`, `invalid`) or per a selectable value in its data
|
|
5
|
+
(`selected`, `active`, `open`, …). Author states in the component's `.tsx`
|
|
6
|
+
and `.module.css`.
|
|
7
|
+
|
|
8
|
+
## 1. Which states each element supports
|
|
9
|
+
|
|
10
|
+
| Element | Author these states |
|
|
11
|
+
|---|---|
|
|
12
|
+
| Interactive — `button`/`a`/`input`/`select`/`textarea`/`summary`, an interactive `role` (`button`/`link`/`tab`/`switch`/`checkbox`/`radio`/`menuitem`/`option`), or an interactive handler (`onClick`/`onMouseEnter`/`onFocus`/…) | `hover`, `focus` |
|
|
13
|
+
| Disableable — `button`/`input`/`select`/`textarea`/`fieldset` or a disableable role | `disabled` (+ `invalid` for `input`/`select`/`textarea`) |
|
|
14
|
+
| Has a selectable/variant value in its data — `selected`/`active`/`current`/`open`/`expanded`/`checked`/`featured` | that custom state |
|
|
15
|
+
| None of the above | no states — resting style only |
|
|
16
|
+
|
|
17
|
+
A custom state may also be driven by a root-level boolean prop (e.g.
|
|
18
|
+
`isFeatured`) instead of by markup or item data — see §5.
|
|
19
|
+
|
|
20
|
+
## 2. Name the state class
|
|
21
|
+
|
|
22
|
+
Flat: the element's own global class + `--<state>`. Because inner-part
|
|
23
|
+
global classes are prefixed with the component name (see
|
|
24
|
+
[`CSS-GUIDELINES.md`](CSS-GUIDELINES.md)), the state class is prefixed too —
|
|
25
|
+
e.g. `pricing-card-cta--hover`, `pricing-card-plan-row--selected`. Never bare
|
|
26
|
+
(`cta--hover` would collide with other components on the page) and never
|
|
27
|
+
nested (`card__row--selected`).
|
|
28
|
+
|
|
29
|
+
## 3. CSS
|
|
30
|
+
|
|
31
|
+
Put the resting value in the bare class; put only the state override in the
|
|
32
|
+
state selector.
|
|
33
|
+
|
|
34
|
+
- **Native** — pair the pseudo-class with the `:global` modifier.
|
|
35
|
+
- **Custom** — the `:global` modifier alone.
|
|
36
|
+
|
|
37
|
+
The bare selector is the short **module** class (`.cta`); the `:global(...)`
|
|
38
|
+
state class is the **prefixed** global one.
|
|
39
|
+
|
|
40
|
+
```css
|
|
41
|
+
.cta {
|
|
42
|
+
background: #6366f1;
|
|
43
|
+
} /* resting */
|
|
44
|
+
.cta:global(.pricing-card-cta--hover),
|
|
45
|
+
.cta:hover {
|
|
46
|
+
background: #4f46e5;
|
|
47
|
+
}
|
|
48
|
+
.cta:global(.pricing-card-cta--disabled) {
|
|
49
|
+
opacity: 0.5;
|
|
50
|
+
}
|
|
51
|
+
.plan-row:global(.pricing-card-plan-row--selected) {
|
|
52
|
+
border-color: #6366f1;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 4. React
|
|
57
|
+
|
|
58
|
+
- **Native** — render the correct interactive element (`<button>`, an
|
|
59
|
+
interactive `role`, or a handler). Nothing else needed.
|
|
60
|
+
- **Custom** — toggle the global state class from the element's data.
|
|
61
|
+
- **Inner elements** — every named inner element gets an `elementProps` entry;
|
|
62
|
+
spread it so editor-driven states reach it. On a raw HTML element also merge
|
|
63
|
+
`elementProps?.<key>.className` inline; on a skill-built sub-component the
|
|
64
|
+
spread alone suffices (it merges `className` itself). The `elementProps` key
|
|
65
|
+
stays the **short** part name (`cta`) even though the element's global class
|
|
66
|
+
is prefixed (`pricing-card-cta`) — don't rename the key to match the class.
|
|
67
|
+
See [`COMPONENT-API.md`](COMPONENT-API.md).
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
<button
|
|
71
|
+
type="button"
|
|
72
|
+
{...elementProps?.cta}
|
|
73
|
+
className={classNames('pricing-card-cta', styles.cta, elementProps?.cta?.className)}
|
|
74
|
+
>
|
|
75
|
+
{label}
|
|
76
|
+
</button>
|
|
77
|
+
|
|
78
|
+
<li className={classNames('pricing-card-plan-row', styles.planRow, row.selected && 'pricing-card-plan-row--selected')}>
|
|
79
|
+
{row.label}
|
|
80
|
+
</li>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 5. Prop-triggered states (root only)
|
|
84
|
+
|
|
85
|
+
A **prop-triggered** state is a custom state switched by a single boolean
|
|
86
|
+
**prop**, rather than by interactive markup (native) or a per-item data flag
|
|
87
|
+
(class-triggered). Use it only when one component-level boolean should flip the
|
|
88
|
+
whole component's appearance — e.g. `isLoading`, `isFeatured`.
|
|
89
|
+
|
|
90
|
+
Mark the prop with the `ElementState<boolean>` type from
|
|
91
|
+
`@wix/react-component-utils`. It is an identity alias — the prop still behaves
|
|
92
|
+
as a plain `boolean` at runtime and stays a normal boolean in the component's
|
|
93
|
+
data — but the manifest generator detects the marker and emits a custom state
|
|
94
|
+
on the **root element**.
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import type { ElementState } from '@wix/react-component-utils';
|
|
98
|
+
|
|
99
|
+
export type PricingCardProps = {
|
|
100
|
+
// …other props…
|
|
101
|
+
isFeatured?: ElementState<boolean>;
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Rules:
|
|
106
|
+
|
|
107
|
+
- **Boolean only, root only.** A prop trigger always attaches to the component
|
|
108
|
+
root — never to an inner element. Inner-element states must be native or
|
|
109
|
+
class-triggered (§1–§4).
|
|
110
|
+
- The state name is the prop name in **kebab-case** (`isFeatured` →
|
|
111
|
+
`is-featured`; no `is`/`has` stripping). The manifest records
|
|
112
|
+
`props: { isFeatured: true }` as the trigger.
|
|
113
|
+
- To give the state styling, pair the root's **module** class with a prefixed
|
|
114
|
+
`:global(.<component-name>--<state>)` rule. With a matching class the manifest
|
|
115
|
+
entry carries that `className`; with none it is props-only (the editor still
|
|
116
|
+
toggles the prop, but nothing restyles).
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
.pricingCard:global(.pricing-card--is-featured) {
|
|
120
|
+
border-color: #f5a623;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Prefer a native state (interactive markup) or a class trigger (per-item data
|
|
125
|
+
such as `row.selected`) whenever one fits — those are the common cases and work
|
|
126
|
+
at any depth. Reach for a prop trigger only for a root-level boolean switch.
|
|
127
|
+
|
|
@@ -9,7 +9,7 @@ An element deserves its own named part if a site owner would plausibly need to i
|
|
|
9
9
|
|
|
10
10
|
## Mandatory filter — apply to every candidate element
|
|
11
11
|
|
|
12
|
-
- ❌ **State or variant** (`active`, `selected`, `current`, `disabled`, `open`, `checked`) — not a part. Implement as a
|
|
12
|
+
- ❌ **State or variant** (`active`, `selected`, `current`, `disabled`, `open`, `checked`) — not a part, it's a **design state** of a part. Implement it per [`DESIGN-STATES.md`](DESIGN-STATES.md): native states from interactive markup; custom states as a flat global modifier on the element's own (component-name-prefixed) class (e.g. `carousel-slide--active`, toggled in JSX) plus a `:global(.carousel-slide--active)` CSS rule. The modifier is a state, not a named part.
|
|
13
13
|
- ❌ **Hidden/shown state of an existing part** — the hidden and shown states of a part are not separate parts. The element itself should be a named part (so the editor can control its visibility per breakpoint); creating an additional part to represent its hidden or shown variant is wrong.
|
|
14
14
|
- ❌ **Pure grouping wrapper** — not a part. A `<div>` whose only role is to hold already-named siblings has no independent editor surface; let layout live in the parent's CSS.
|
|
15
15
|
- ❌ **Child with no independent editor surface** — not a part if its styling and data are already fully owned by the parent. This applies regardless of how many siblings it has. Two ways a child's editor surface can already be covered by the parent: (1) its CSS properties are inherited or set via the parent's rule; (2) its data is defined on the parent. **Canonical example:** an `<img>` inside a carousel slide whose `src` and `alt` come from the parent slide's data, and whose visual properties (object-fit, border-radius) could equally be set on the slide's own CSS rule — the slide already owns both data and styling, so the `<img>` is not a named part. Use a CSS module class for any structural CSS it needs.
|
|
@@ -23,3 +23,4 @@ Before finalising, verify each proposed part against its parent:
|
|
|
23
23
|
> Would the editor controls generated for this part be a strict subset of its parent's controls?
|
|
24
24
|
|
|
25
25
|
If yes — the part adds no independent editor surface and should be removed. This catches rationalisation after-the-fact ("the parent *could* expose this CSS property too, but so could the child separately"). When in doubt, fewer parts is usully better.
|
|
26
|
+
|
|
@@ -4,12 +4,12 @@ This guide defines rules and guidance on **how to implement** production-quality
|
|
|
4
4
|
|
|
5
5
|
**Topic reference files:**
|
|
6
6
|
- [`PARTS.md`](PARTS.md) — What qualifies as a named part (mandatory filter)
|
|
7
|
+
- [`DESIGN-STATES.md`](DESIGN-STATES.md) — Which design states a part supports, and how to author them
|
|
7
8
|
- [`ACCESSIBILITY.md`](ACCESSIBILITY.md) — ARIA/a11y rules and patterns
|
|
8
9
|
- [`DIRECTIONALITY.md`](DIRECTIONALITY.md) — RTL/LTR rules and patterns
|
|
9
10
|
- [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) — What should be a React prop vs CSS
|
|
10
11
|
- [`COMPONENT-API.md`](COMPONENT-API.md) — Props structure, elementProps, data types, file splitting, containers, array props
|
|
11
|
-
- [`
|
|
12
|
-
- [`REACT-PATTERNS.md`](REACT-PATTERNS.md) — CSS rules, common mistakes
|
|
12
|
+
- [`REACT-PATTERNS.md`](REACT-PATTERNS.md) — SSR-safe patterns, CSS rules, common mistakes
|
|
13
13
|
|
|
14
14
|
## React 18 features are not supported
|
|
15
15
|
|
|
@@ -24,8 +24,9 @@ Understand the component and infer its behavior. Extract what is provided; use r
|
|
|
24
24
|
1. **Identity** — Component name.
|
|
25
25
|
2. **Structure** — Identify named parts by applying the mandatory filter in [`PARTS.md`](PARTS.md) to every candidate element before accepting it as a part. Include content/data props (labels, items, types, required vs optional) and configuration (toggles, choices, ranges, modes).
|
|
26
26
|
3. **Interactions** — Clicks, hover/focus; what is exposed as event props vs handled internally.
|
|
27
|
+
4. **States** — For every part, decide which design states it supports (native: `hover`/`focus`/`disabled`/`invalid`; custom: `selected`/`active`/`open`/… ) by applying the heuristic in [`DESIGN-STATES.md`](DESIGN-STATES.md), and record them in the plan. These become the editor's per-element state styling controls.
|
|
27
28
|
|
|
28
|
-
**Understanding → implementation (checklist):** For every part, decide `elementProps` vs CSS-only; build the props interface (data + behavior); wire interaction in React (`useState`, `useEffect`, refs, native event handlers); generate TS + CSS. Infer reasonable defaults where anything is unspecified.
|
|
29
|
+
**Understanding → implementation (checklist):** For every part, decide `elementProps` vs CSS-only and which design states it supports ([`DESIGN-STATES.md`](DESIGN-STATES.md)); build the props interface (data + behavior); wire interaction in React (`useState`, `useEffect`, refs, native event handlers); give every named inner element an `elementProps` entry and spread it + merge its `className` ([`COMPONENT-API.md`](COMPONENT-API.md)); generate TS + CSS. Infer reasonable defaults where anything is unspecified.
|
|
29
30
|
|
|
30
31
|
# Part 1: Standards & Conventions
|
|
31
32
|
|
|
@@ -43,10 +44,6 @@ Direction support is mandatory — see [`DIRECTIONALITY.md`](DIRECTIONALITY.md).
|
|
|
43
44
|
|
|
44
45
|
See [`ACCESSIBILITY.md`](ACCESSIBILITY.md) for full rules and patterns.
|
|
45
46
|
|
|
46
|
-
### SSR Safety
|
|
47
|
-
|
|
48
|
-
Components are server-rendered, then hydrated — they MUST render correctly, completely, and identically on the server. See [`SSR.md`](SSR.md) for full rules and patterns.
|
|
49
|
-
|
|
50
47
|
### TypeScript
|
|
51
48
|
|
|
52
49
|
- All components must be fully typed
|
|
@@ -72,11 +69,11 @@ All components MUST follow these patterns:
|
|
|
72
69
|
|
|
73
70
|
**1. SSR-Safe Implementation**
|
|
74
71
|
|
|
75
|
-
- NO browser APIs at module scope
|
|
76
|
-
-
|
|
77
|
-
-
|
|
72
|
+
- NO browser APIs at module scope (window, document, navigator, etc.)
|
|
73
|
+
- Guard browser APIs with typeof checks or useEffect
|
|
74
|
+
- All browser-dependent logic must run client-side only
|
|
78
75
|
|
|
79
|
-
See [`
|
|
76
|
+
See [`REACT-PATTERNS.md`](REACT-PATTERNS.md) §1.1 for code examples.
|
|
80
77
|
|
|
81
78
|
**2. Clean Code**
|
|
82
79
|
|
|
@@ -139,6 +136,8 @@ For each part of the component, decide:
|
|
|
139
136
|
- ✅ Has state or behavior
|
|
140
137
|
- ✅ Needs event handlers
|
|
141
138
|
|
|
139
|
+
For the same part, also decide which **design states** it supports (native + custom) per [`DESIGN-STATES.md`](DESIGN-STATES.md).
|
|
140
|
+
|
|
142
141
|
See [`COMPONENT-API.md`](COMPONENT-API.md) and [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) for the decision trees.
|
|
143
142
|
|
|
144
143
|
### Step 2: Build Props Interface
|
|
@@ -152,7 +151,7 @@ Combine:
|
|
|
152
151
|
|
|
153
152
|
### Step 3: Implement
|
|
154
153
|
|
|
155
|
-
Follow Part 2 templates with mandatory patterns applied.
|
|
154
|
+
Follow Part 2 templates with mandatory patterns applied. For each part's supported design states, author the interactive markup / class toggles and the state CSS per [`DESIGN-STATES.md`](DESIGN-STATES.md).
|
|
156
155
|
|
|
157
156
|
# Part 2: CSS Rules
|
|
158
157
|
|
|
@@ -165,8 +164,9 @@ See [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) and [`COMPONENT-API.md`](COMPONENT-API.
|
|
|
165
164
|
|
|
166
165
|
## 3.1 Implementation Checklist
|
|
167
166
|
|
|
168
|
-
**Phase 1: Analysis** — Parse information, map component structure (see Part 0)
|
|
167
|
+
**Phase 1: Analysis** — Parse information, map component structure and supported design states (see Part 0)
|
|
168
|
+
|
|
169
|
+
**Phase 2: Component File** — Apply all §1.1 mandatory features and §1.2 implementation standards; toggle custom-state classes from data ([`DESIGN-STATES.md`](DESIGN-STATES.md))
|
|
169
170
|
|
|
170
|
-
**Phase
|
|
171
|
+
**Phase 3: Styles** — Apply Part 2 SCSS rules, including state styles ([`DESIGN-STATES.md`](DESIGN-STATES.md))
|
|
171
172
|
|
|
172
|
-
**Phase 3: Styles** — Apply Part 2 SCSS rules
|
|
@@ -6,7 +6,23 @@ Code patterns and common mistakes for Editor React components.
|
|
|
6
6
|
|
|
7
7
|
## 1.1 SSR-Safe Implementation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Avoid browser-only APIs at module scope or during render; use them inside `useEffect` with `typeof window !== 'undefined'`.
|
|
10
|
+
|
|
11
|
+
**❌ Wrong:**
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
const userAgent = window.navigator.userAgent;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**✅ Correct:**
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (typeof window !== "undefined") {
|
|
22
|
+
const userAgent = window.navigator.userAgent;
|
|
23
|
+
}
|
|
24
|
+
}, []);
|
|
25
|
+
```
|
|
10
26
|
|
|
11
27
|
## 1.2 Element Visibility (Platform-Managed)
|
|
12
28
|
|
|
@@ -23,71 +39,26 @@ Authoritative SCSS rules: `REACT-GUIDELINES.md` Part 2. For RTL/logical CSS patt
|
|
|
23
39
|
```scss
|
|
24
40
|
// ❌ NEVER include:
|
|
25
41
|
|
|
26
|
-
// State CSS
|
|
27
|
-
&:hover { ... } // ❌
|
|
28
|
-
&:focus { ... } // ❌
|
|
29
|
-
&:disabled { ... } // ❌
|
|
30
|
-
&[data-state='open'] { ... } // ❌
|
|
31
|
-
|
|
32
42
|
// Transitions/Animations
|
|
33
43
|
transition: all 0.3s; // ❌
|
|
34
44
|
animation: fadeIn 0.5s; // ❌
|
|
35
45
|
```
|
|
36
46
|
|
|
47
|
+
> Design states (`hover`, `focus`, `selected`, …) are authored per
|
|
48
|
+
> [`DESIGN-STATES.md`](DESIGN-STATES.md).
|
|
49
|
+
|
|
37
50
|
---
|
|
38
51
|
|
|
39
52
|
# Part 3: Common Mistakes
|
|
40
53
|
|
|
41
|
-
## 3.1
|
|
42
|
-
|
|
43
|
-
The resting visual (background, color, border-radius, padding, font)
|
|
44
|
-
belongs in the component's CSS — see `CSS-GUIDELINES.md` §"Keep all
|
|
45
|
-
styling in CSS". What does NOT belong is **interaction-state CSS**
|
|
46
|
-
(`:hover`, `:focus`, `:focus-visible`, `:active`, `:disabled`,
|
|
47
|
-
`[data-state]`, `[aria-selected]`) — the platform owns those.
|
|
48
|
-
Selection / mode variants (`selected`, `active`, `open`) are
|
|
49
|
-
different — they go through a JS-toggled modifier class; see
|
|
50
|
-
`CSS-GUIDELINES.md` §"Express selection / mode variants".
|
|
54
|
+
## 3.1 Custom-state classes
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
.button {
|
|
56
|
-
background-color: #ffffff;
|
|
57
|
-
color: #0f172a;
|
|
58
|
-
border-radius: 8px;
|
|
59
|
-
padding-block: 8px;
|
|
60
|
-
padding-inline: 16px;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.button:hover { /* ❌ Interaction state — platform owns this */
|
|
64
|
-
background-color: #f0f0f0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.button:disabled { /* ❌ Interaction state — platform owns this */
|
|
68
|
-
opacity: 0.5;
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**✅ Correct — keep the resting visual; drop the pseudo-class rules:**
|
|
73
|
-
|
|
74
|
-
```scss
|
|
75
|
-
.button {
|
|
76
|
-
display: flex;
|
|
77
|
-
align-items: center;
|
|
78
|
-
background-color: #ffffff;
|
|
79
|
-
color: #0f172a;
|
|
80
|
-
border-radius: 8px;
|
|
81
|
-
padding-block: 8px;
|
|
82
|
-
padding-inline: 16px;
|
|
83
|
-
box-sizing: border-box;
|
|
84
|
-
}
|
|
85
|
-
```
|
|
56
|
+
For a custom design state, toggle the element's **global** state class from
|
|
57
|
+
its data in JSX (e.g. `isSelected && 'pricing-card-row--selected'`, using the
|
|
58
|
+
component-name-prefixed class) — don't express it as a module-scoped class. State styling lives in [`DESIGN-STATES.md`](DESIGN-STATES.md).
|
|
86
59
|
|
|
87
60
|
## 3.2 Browser APIs at module scope
|
|
88
61
|
|
|
89
|
-
See [`SSR.md`](SSR.md) for the full SSR rules.
|
|
90
|
-
|
|
91
62
|
**❌ Wrong:**
|
|
92
63
|
|
|
93
64
|
```typescript
|
|
@@ -121,3 +92,4 @@ For lists, breadcrumbs, tabs, menus, and similar collection-style UI, render the
|
|
|
121
92
|
```
|
|
122
93
|
|
|
123
94
|
Handle separators with CSS pseudo-elements or inside each item.
|
|
95
|
+
|