@wix/agent-skills 1.14.0 → 1.15.1

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 (268) hide show
  1. package/README.md +12 -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/DATA_COLLECTION.md +5 -3
  10. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +25 -9
  11. package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
  12. package/skills/wix-app/references/STORES_VERSIONING.md +9 -211
  13. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
  14. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
  15. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
  16. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
  17. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
  18. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
  19. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
  20. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
  21. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
  22. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
  23. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
  24. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
  25. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
  26. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
  27. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
  28. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
  29. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
  30. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
  31. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
  32. package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
  33. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +5 -0
  34. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
  35. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +151 -0
  36. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
  37. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
  38. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +57 -0
  39. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +23 -105
  40. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
  41. package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
  42. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +18 -16
  43. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
  44. package/skills/wix-app/references/stores/CATEGORIES.md +22 -0
  45. package/skills/wix-app/references/stores/GET_PRODUCT.md +99 -0
  46. package/skills/wix-app/references/stores/INVENTORY.md +37 -0
  47. package/skills/wix-app/references/stores/QUERY.md +87 -0
  48. package/skills/wix-app/references/stores/WRITE.md +55 -0
  49. package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
  50. package/skills/wix-auth/SKILL.md +12 -0
  51. package/skills/wix-auth/references/device-flow.md +140 -0
  52. package/skills/wix-docs/SKILL.md +188 -0
  53. package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
  54. package/skills/wix-docs/references/EXTRACTING.md +120 -0
  55. package/skills/wix-headless/SKILL.md +89 -130
  56. package/skills/wix-headless/entry/bootstrap.mjs +93 -0
  57. package/skills/wix-headless/entry/skill.md +76 -0
  58. package/skills/wix-headless/references/AI_FEATURES.md +178 -0
  59. package/skills/wix-headless/references/CAPABILITIES.md +86 -0
  60. package/skills/wix-headless/references/DISCOVERY.md +34 -56
  61. package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
  62. package/skills/wix-headless/references/FEEDBACK.md +129 -0
  63. package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
  64. package/skills/wix-headless/references/SDK_HANDOFF.md +99 -0
  65. package/skills/wix-headless/references/SEED.md +45 -187
  66. package/skills/wix-headless/references/SETUP.md +32 -103
  67. package/skills/wix-headless/references/astro.md +98 -0
  68. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
  69. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
  70. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
  71. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
  72. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
  73. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
  74. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
  75. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
  76. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
  77. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
  78. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
  79. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
  80. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +213 -0
  81. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
  82. package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
  83. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +232 -0
  84. package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
  85. package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
  86. package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
  87. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +192 -0
  88. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +155 -0
  89. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
  90. package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +73 -0
  91. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +197 -0
  92. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +136 -0
  93. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
  94. package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
  95. package/skills/wix-headless/references/managed/CONNECT.md +74 -0
  96. package/skills/wix-headless/references/managed/CREATE.md +130 -0
  97. package/skills/wix-headless/references/managed/DEPLOYMENT.md +79 -0
  98. package/skills/wix-headless/references/non-astro.md +59 -0
  99. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
  100. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +15 -0
  101. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
  102. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +71 -0
  103. package/skills/wix-manage/SKILL.md +29 -3
  104. package/skills/wix-manage/references/analytics/query-site-analytics.md +298 -0
  105. package/skills/wix-manage/references/app-installation/install-wix-apps.md +3 -0
  106. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
  107. package/skills/wix-manage/references/bookings/create-booking-service-from-prompt.md +6 -5
  108. package/skills/wix-manage/references/bookings/create-course-service.md +30 -5
  109. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +299 -0
  110. package/skills/wix-manage/references/cms/cms-schema-management.md +6 -0
  111. package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +30 -7
  112. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +517 -0
  113. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +218 -0
  114. package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
  115. package/skills/wix-manage/references/sites/site-import.md +270 -0
  116. package/skills/wix-manage/references/stores/create-product-from-image.md +8 -6
  117. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +57 -0
  118. package/skills/wix-vibe-headless/SKILL.md +142 -0
  119. package/skills/wix-vibe-headless/platforms/README.md +22 -0
  120. package/skills/wix-vibe-headless/platforms/base44.md +142 -0
  121. package/skills/wix-vibe-headless/platforms/generic.md +87 -0
  122. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
  123. package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
  124. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +157 -0
  125. package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
  126. package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +217 -0
  127. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
  128. package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
  129. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
  130. package/skills/wix-vibe-headless/references/events/wix-events-browse.js +136 -0
  131. package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
  132. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
  133. package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
  134. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
  135. package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +223 -0
  136. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
  137. package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
  138. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
  139. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
  140. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
  141. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
  142. package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
  143. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +164 -0
  144. package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
  145. package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +146 -0
  146. package/skills/wix-headless/references/BUILD-astro.md +0 -253
  147. package/skills/wix-headless/references/BUILD-own-build.md +0 -167
  148. package/skills/wix-headless/references/BUILD.md +0 -105
  149. package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
  150. package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
  151. package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
  152. package/skills/wix-headless/references/PLAN-connect.md +0 -19
  153. package/skills/wix-headless/references/PLAN-create.md +0 -17
  154. package/skills/wix-headless/references/PLAN.md +0 -92
  155. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
  156. package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
  157. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
  158. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
  159. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
  160. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
  161. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
  162. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
  163. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
  164. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
  165. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
  166. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
  167. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
  168. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
  169. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
  170. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
  171. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
  172. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
  173. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
  174. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
  175. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
  176. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
  177. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  178. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  179. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  180. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  181. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  182. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  183. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  184. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  185. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  186. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  187. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  188. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  189. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  190. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  191. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  192. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  193. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  194. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  195. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  196. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  197. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  198. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  199. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  200. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  201. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  202. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  203. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  204. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  205. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  206. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  207. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  208. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  209. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  210. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  211. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  212. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  213. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  214. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  215. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  216. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  217. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  218. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  219. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  220. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  221. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  222. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  223. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  224. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  225. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  226. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  227. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  228. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  229. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  230. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  231. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  232. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  233. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  234. package/skills/wix-headless/references/seed-recipes.md +0 -49
  235. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  236. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  237. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  238. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  239. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  240. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  241. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  242. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  243. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  244. package/skills/wix-headless/references/shared/STYLING.md +0 -140
  245. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  246. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  247. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  248. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  249. package/skills/wix-headless/references/verticals/blog.md +0 -31
  250. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  251. package/skills/wix-headless/references/verticals/cms.md +0 -30
  252. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  253. package/skills/wix-headless/references/verticals/forms.md +0 -26
  254. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  255. package/skills/wix-headless/references/verticals/stores.md +0 -33
  256. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  257. package/skills/wix-headless/scripts/compose.mjs +0 -520
  258. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  259. package/skills/wix-headless/scripts/flatten.sh +0 -61
  260. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  261. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -154
  262. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  263. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  264. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  265. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  266. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  267. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  268. package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
@@ -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.
466
-
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.
425
+ ### Design states
472
426
 
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 */
@@ -554,6 +465,12 @@ author them either.
554
465
  }
555
466
  ```
556
467
 
468
+ **Media playback is functional, not decorative.** When the component's content
469
+ *is* a playing animation (Lottie/JSON, animated GIF/SVG, canvas/WebGL, video),
470
+ letting it play is allowed — the motion is the content. Such components get a
471
+ play/pause control positioned in CSS. See
472
+ [`ANIMATED-COMPONENTS.md`](ANIMATED-COMPONENTS.md).
473
+
557
474
  ### Set `pointer-events: auto` on the root and every interactive element
558
475
 
559
476
  The root selector and every nested class that the user can click,
@@ -574,3 +491,4 @@ published site, where the wrapper is gone.
574
491
  pointer-events: auto;
575
492
  }
576
493
  ```
494
+
@@ -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,14 @@ 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
+ - [`ANIMATED-COMPONENTS.md`](ANIMATED-COMPONENTS.md) — Play/pause control and autoplay for animated/playable components
13
+ - [`COMPONENT-PREVIEW.md`](COMPONENT-PREVIEW.md) — `component.preview.tsx` patterns and `useIsEditMode()` usage
14
+ - [`REACT-PATTERNS.md`](REACT-PATTERNS.md) — SSR-safe patterns, CSS rules, common mistakes
13
15
 
14
16
  ## React 18 features are not supported
15
17
 
@@ -23,9 +25,10 @@ Understand the component and infer its behavior. Extract what is provided; use r
23
25
 
24
26
  1. **Identity** — Component name.
25
27
  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
- 3. **Interactions** — Clicks, hover/focus; what is exposed as event props vs handled internally.
28
+ 3. **Interactions** — Clicks, hover/focus; what is exposed as event props vs handled internally. If the component's primary content is a **playable animation** (Lottie/JSON, animated GIF/SVG, canvas/WebGL loop, video-like surface), it gets a play/pause control — follow [`ANIMATED-COMPONENTS.md`](ANIMATED-COMPONENTS.md).
29
+ 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
30
 
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.
31
+ **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
32
 
30
33
  # Part 1: Standards & Conventions
31
34
 
@@ -43,10 +46,6 @@ Direction support is mandatory — see [`DIRECTIONALITY.md`](DIRECTIONALITY.md).
43
46
 
44
47
  See [`ACCESSIBILITY.md`](ACCESSIBILITY.md) for full rules and patterns.
45
48
 
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
49
  ### TypeScript
51
50
 
52
51
  - All components must be fully typed
@@ -72,11 +71,11 @@ All components MUST follow these patterns:
72
71
 
73
72
  **1. SSR-Safe Implementation**
74
73
 
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`
74
+ - NO browser APIs at module scope (window, document, navigator, etc.)
75
+ - Guard browser APIs with typeof checks or useEffect
76
+ - All browser-dependent logic must run client-side only
78
77
 
79
- See [`SSR.md`](SSR.md) for full rules and code examples.
78
+ See [`REACT-PATTERNS.md`](REACT-PATTERNS.md) §1.1 for code examples.
80
79
 
81
80
  **2. Clean Code**
82
81
 
@@ -139,6 +138,8 @@ For each part of the component, decide:
139
138
  - ✅ Has state or behavior
140
139
  - ✅ Needs event handlers
141
140
 
141
+ For the same part, also decide which **design states** it supports (native + custom) per [`DESIGN-STATES.md`](DESIGN-STATES.md).
142
+
142
143
  See [`COMPONENT-API.md`](COMPONENT-API.md) and [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) for the decision trees.
143
144
 
144
145
  ### Step 2: Build Props Interface
@@ -152,7 +153,7 @@ Combine:
152
153
 
153
154
  ### Step 3: Implement
154
155
 
155
- Follow Part 2 templates with mandatory patterns applied.
156
+ 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
157
 
157
158
  # Part 2: CSS Rules
158
159
 
@@ -165,8 +166,9 @@ See [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) and [`COMPONENT-API.md`](COMPONENT-API.
165
166
 
166
167
  ## 3.1 Implementation Checklist
167
168
 
168
- **Phase 1: Analysis** — Parse information, map component structure (see Part 0)
169
+ **Phase 1: Analysis** — Parse information, map component structure and supported design states (see Part 0)
170
+
171
+ **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
172
 
170
- **Phase 2: Component File** — Apply all §1.1 mandatory features and §1.2 implementation standards; verify SSR safety against [`SSR.md`](SSR.md)
173
+ **Phase 3: Styles** — Apply Part 2 SCSS rules, including state styles ([`DESIGN-STATES.md`](DESIGN-STATES.md))
171
174
 
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
+
@@ -0,0 +1,22 @@
1
+ # Stores — Collections (V1) ↔ Categories (V3)
2
+
3
+ ```typescript
4
+ // V1 write ops (createCollection, updateCollection, addProductsToCollection, …)
5
+ // live on the `products` namespace, NOT `collections`. The `collections` namespace is read-only.
6
+ import { products } from '@wix/stores';
7
+ import { categories } from '@wix/categories';
8
+
9
+ if (v === 'V3_CATALOG') {
10
+ // V3 createCategory(category, options). treeReference is REQUIRED and goes in `options`.
11
+ // For Wix Stores categories: appNamespace MUST be the literal "@wix/stores", treeKey is null.
12
+ const category = await categories.createCategory(
13
+ { name: 'Sale' },
14
+ { treeReference: { appNamespace: '@wix/stores', treeKey: null } },
15
+ );
16
+ return category;
17
+ }
18
+ const { collection } = await products.createCollection({ name: 'Sale' }); // V1 returns { collection }
19
+ return collection;
20
+ ```
21
+
22
+ V3 categories are tree-structured. Reference them on a product via `directCategories[]`, not `collectionIds[]`. **All Stores category API calls must pass `treeReference: { appNamespace: '@wix/stores', treeKey: null }` in `options`** — applies to `createCategory`, `updateCategory`, `queryCategories`, etc.
@@ -0,0 +1,99 @@
1
+ # Stores — Get Product
2
+
3
+ ## Get a single product
4
+
5
+ ```typescript
6
+ if (v === 'V3_CATALOG') {
7
+ const product = await productsV3.getProduct(id); // returns Product directly
8
+ return product;
9
+ }
10
+ const { product } = await products.getProduct(id); // V1 wraps in { product }
11
+ return product;
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Read product options and choices (V1 vs V3)
17
+
18
+ V1 and V3 differ in **both where choices live and what the choice fields are named**. Getting this wrong causes `TS2339` at validate time.
19
+
20
+ | | V1 | V3 |
21
+ |---|---|---|
22
+ | Options array on product | `product.productOptions` | `product.options` |
23
+ | Option name | `option.name` | `option.name` |
24
+ | Option type | `option.optionType` (`"color"` / `"drop_down"`) | `option.optionRenderType` (`"SWATCH_CHOICES"` / `"TEXT_CHOICES"`) |
25
+ | **Choices array** | `option.choices` ← **directly on the option** | `option.choicesSettings?.choices` ← **nested** |
26
+ | Choice display value | `choice.value` | `choice.name` |
27
+ | Choice color | `choice.value` (hex string) | `choice.colorCode` |
28
+
29
+ ```typescript
30
+ if (v === 'V3_CATALOG') {
31
+ const product = await productsV3.getProduct(id);
32
+ for (const option of product.options ?? []) {
33
+ const choices = option.choicesSettings?.choices ?? []; // ✅ nested — NOT option.choices / option.optionValues (TS2339)
34
+ for (const choice of choices) {
35
+ render(option.name, choice.name, choice.colorCode); // name = label; colorCode = hex for SWATCH_CHOICES
36
+ }
37
+ }
38
+ } else {
39
+ const res = await products.getProduct(id);
40
+ const product = res.product!; // product is optional in the raw type; ! matches SDK's strict-mode guarantee
41
+ for (const option of product.productOptions ?? []) {
42
+ for (const choice of option.choices ?? []) { // ✅ direct in V1
43
+ render(option.name, choice.value); // value = label or hex string
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ **In a site plugin on a product page**: get `productId` from `widget.getProp('product-id')`, then call the appropriate version's `getProduct` — same pattern as above.
50
+
51
+ ---
52
+
53
+ ## Modifiers (V1 `manageVariants=false` options)
54
+
55
+ In V3, options that **don't** create variants (V1 `manageVariants=false`) live on `product.modifiers`, not `product.options`. They use the identical `choicesSettings.choices` pattern. Reading only `product.options` silently misses these.
56
+
57
+ ```typescript
58
+ if (v === 'V3_CATALOG') {
59
+ const product = await productsV3.getProduct(id);
60
+ // variant-creating options
61
+ for (const option of product.options ?? []) {
62
+ for (const choice of option.choicesSettings?.choices ?? []) {
63
+ render(option.name, choice.name, choice.colorCode);
64
+ }
65
+ }
66
+ // display-only / free-text customizations (formerly manageVariants=false)
67
+ for (const modifier of product.modifiers ?? []) {
68
+ for (const choice of modifier.choicesSettings?.choices ?? []) {
69
+ render(modifier.name, choice.name, choice.colorCode);
70
+ }
71
+ }
72
+ }
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Variant choices (V1 object map → V3 array)
78
+
79
+ V1 `variant.choices` was a plain object map `{ "Size": "Small" }`. V3 restructures it as an array — accessing it with a key returns `undefined` silently.
80
+
81
+ ```typescript
82
+ if (v === 'V3_CATALOG') {
83
+ const product = await productsV3.getProduct(id);
84
+ // variants are NOT returned by queryProducts — use getProduct or Read-Only Variants API
85
+ for (const variant of product.variantsInfo?.variants ?? []) {
86
+ for (const c of variant.choices ?? []) {
87
+ render(c.optionChoiceNames?.optionName, c.optionChoiceNames?.choiceName);
88
+ }
89
+ // ❌ variant.choices['Size'] — always undefined in V3 (object map is gone)
90
+ }
91
+ } else {
92
+ const res = await products.getProduct(id);
93
+ const product = res.product!; // product is optional in the raw type; ! matches SDK's strict-mode guarantee
94
+ for (const variant of product.variants ?? []) {
95
+ // V1: choices is { [optionName]: value }
96
+ render(Object.entries(variant.choices ?? {}).map(([k, v]) => `${k}:${v}`).join(', '));
97
+ }
98
+ }
99
+ ```