@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.
Files changed (247) hide show
  1. package/README.md +4 -1
  2. package/package.json +1 -1
  3. package/skills/README.md +23 -0
  4. package/skills/wix-app/SKILL.md +10 -2
  5. package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
  6. package/skills/wix-app/references/CODE_QUALITY.md +1 -0
  7. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
  8. package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
  9. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +23 -9
  10. package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
  11. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
  12. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
  13. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
  14. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
  15. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
  16. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
  17. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
  18. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
  19. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
  20. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
  21. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
  22. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
  23. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
  24. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
  25. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
  26. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
  27. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
  28. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
  29. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
  30. package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
  31. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
  32. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
  33. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
  34. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +17 -105
  35. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
  36. package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
  37. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +15 -15
  38. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
  39. package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
  40. package/skills/wix-auth/SKILL.md +12 -0
  41. package/skills/wix-auth/references/device-flow.md +140 -0
  42. package/skills/wix-docs/SKILL.md +188 -0
  43. package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
  44. package/skills/wix-docs/references/EXTRACTING.md +120 -0
  45. package/skills/wix-headless/SKILL.md +84 -130
  46. package/skills/wix-headless/entry/bootstrap.mjs +93 -0
  47. package/skills/wix-headless/entry/skill.md +78 -0
  48. package/skills/wix-headless/references/AI_FEATURES.md +178 -0
  49. package/skills/wix-headless/references/CAPABILITIES.md +84 -0
  50. package/skills/wix-headless/references/DISCOVERY.md +34 -56
  51. package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
  52. package/skills/wix-headless/references/FEEDBACK.md +118 -0
  53. package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
  54. package/skills/wix-headless/references/SDK_HANDOFF.md +97 -0
  55. package/skills/wix-headless/references/SEED.md +44 -188
  56. package/skills/wix-headless/references/SETUP.md +32 -103
  57. package/skills/wix-headless/references/astro.md +98 -0
  58. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
  59. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
  60. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
  61. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
  62. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
  63. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
  64. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
  65. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
  66. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
  67. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
  68. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
  69. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
  70. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +173 -0
  71. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
  72. package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
  73. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +228 -0
  74. package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
  75. package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
  76. package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
  77. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +176 -0
  78. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +153 -0
  79. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
  80. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +161 -0
  81. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +117 -0
  82. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
  83. package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
  84. package/skills/wix-headless/references/managed/CONNECT.md +74 -0
  85. package/skills/wix-headless/references/managed/CREATE.md +130 -0
  86. package/skills/wix-headless/references/managed/DEPLOYMENT.md +57 -0
  87. package/skills/wix-headless/references/non-astro.md +59 -0
  88. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
  89. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +7 -0
  90. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
  91. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +63 -0
  92. package/skills/wix-manage/SKILL.md +24 -1
  93. package/skills/wix-manage/references/analytics/query-site-analytics.md +241 -0
  94. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
  95. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +265 -0
  96. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +436 -0
  97. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +209 -0
  98. package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
  99. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +51 -0
  100. package/skills/wix-vibe-headless/SKILL.md +136 -0
  101. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
  102. package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
  103. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +153 -0
  104. package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
  105. package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +215 -0
  106. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
  107. package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
  108. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
  109. package/skills/wix-vibe-headless/references/events/wix-events-browse.js +135 -0
  110. package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
  111. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
  112. package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
  113. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
  114. package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +194 -0
  115. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
  116. package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
  117. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
  118. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
  119. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
  120. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
  121. package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
  122. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +155 -0
  123. package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
  124. package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +142 -0
  125. package/skills/wix-headless/references/BUILD-astro.md +0 -253
  126. package/skills/wix-headless/references/BUILD-own-build.md +0 -167
  127. package/skills/wix-headless/references/BUILD.md +0 -105
  128. package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
  129. package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
  130. package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
  131. package/skills/wix-headless/references/PLAN-connect.md +0 -19
  132. package/skills/wix-headless/references/PLAN-create.md +0 -17
  133. package/skills/wix-headless/references/PLAN.md +0 -92
  134. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
  135. package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
  136. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
  137. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
  138. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
  139. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
  140. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
  141. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
  142. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
  143. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
  144. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
  145. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
  146. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
  147. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
  148. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
  149. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
  150. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
  151. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
  152. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
  153. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
  154. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
  155. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
  156. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  157. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  158. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  159. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  160. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  161. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  162. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  163. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  164. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  165. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  166. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  167. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  168. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  169. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  170. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  171. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  172. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  173. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  174. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  175. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  176. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  177. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  178. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  179. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  180. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  181. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  182. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  183. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  184. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  185. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  186. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  187. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  188. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  189. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  190. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  191. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  192. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  193. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  194. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  195. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  196. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  197. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  198. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  199. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  200. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  201. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  202. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  203. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  204. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  205. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  206. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  207. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  208. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  209. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  210. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  211. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  212. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  213. package/skills/wix-headless/references/seed-recipes.md +0 -49
  214. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  215. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  216. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  217. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  218. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  219. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  220. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  221. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  222. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  223. package/skills/wix-headless/references/shared/STYLING.md +0 -140
  224. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  225. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  226. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  227. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  228. package/skills/wix-headless/references/verticals/blog.md +0 -31
  229. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  230. package/skills/wix-headless/references/verticals/cms.md +0 -30
  231. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  232. package/skills/wix-headless/references/verticals/forms.md +0 -26
  233. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  234. package/skills/wix-headless/references/verticals/stores.md +0 -33
  235. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  236. package/skills/wix-headless/scripts/compose.mjs +0 -520
  237. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  238. package/skills/wix-headless/scripts/flatten.sh +0 -61
  239. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  240. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -154
  241. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  242. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  243. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  244. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  245. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  246. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  247. 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
- Does this element need:
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
- │ └─ ✅ Use elementProps
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 → Is it purely visual/decorative (including conditionally displayed)?
21
- │
22
- ├─ YES (icons, separators, decorations, elements only hidden/shown via CSS)
23
- │ └─ ❌ CSS class only (no elementProps)
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
- ### When to Use elementProps
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
- **Use `elementProps`** for parts that need:
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
- - Configuration/data beyond just styling
66
- - Direction override
67
- - State management
68
- - Event handlers
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
- **DO NOT use `elementProps`** for:
91
+ // Sub-component built with this skill — spread is enough (it merges className itself):
92
+ <PlanRow {...elementProps?.planRow} />
93
+ ```
71
94
 
72
- - Elements with only visual styling (use CSS classes)
73
- - Elements where conditional display is the only requirement (visibility controlled via CSS for per-breakpoint hiding, not React props)
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
- **Minimal elementProps rule:** If an element would only have `className?: string` in elementProps, do NOT include it.
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 component file's exported `defaultProps`
182
- constant (the one consumed by `withDefaults(Component, defaultProps)` in
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:** If element only has `className` (even if it can be hidden/shown via CSS), skip elementProps entirely. Conditional display is controlled via CSS, not React props.
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. **Export `defaultProps` from `component.tsx`** so the extension file can import it.
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 './component';
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 (`'<component-name>'` for root, `'<part-name>'` for inner parts — kebab-case) is what zeroConfig scans. The module class is what carries the component's structural CSS for that element.
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
- ### Don't author state styles (`:hover`, `:focus`, `:disabled`, `[data-state]`)
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
- Express each variant as a **JS-toggled modifier class**, applied
468
- alongside the base class via `classNames`. Each class — base and
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. State transitions like hover and focus are owned by
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 BEM modifier class toggled in JSX (e.g. `image-carousel__slide--active`) and a single-class CSS rule. The modifier class is CSS-only; it is not a named part.
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
- - [`SSR.md`](SSR.md) — Server-side rendering rules (mandatory)
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 or during render (window, document, navigator, etc.) — guard inside `useEffect`
76
- - First render must be complete and deterministic; effects are client-only enhancement
77
- - Internal ids via `useStableId`; NO `useLayoutEffect`
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 [`SSR.md`](SSR.md) for full rules and code examples.
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 2: Component File** — Apply all §1.1 mandatory features and §1.2 implementation standards; verify SSR safety against [`SSR.md`](SSR.md)
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
- Components are server-rendered then hydrated. See [`SSR.md`](SSR.md) for the full rules and code examples (browser globals, complete first render, deterministic output, `useStableId`, no `useLayoutEffect`).
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 Adding interaction-state CSS to parts
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
- **❌ Wrong — pseudo-class rules must be removed:**
53
-
54
- ```scss
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
+