@wix/agent-skills 1.16.3 → 1.18.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 (283) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +115 -12
  3. package/skills/wix-app/references/APP_MARKET_REVIEW.md +1 -1
  4. package/skills/wix-app/references/BACKEND_API.md +18 -0
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +6 -0
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +10 -2
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +32 -70
  8. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +145 -127
  9. package/skills/wix-app/references/SITE_PLUGIN.md +14 -2
  10. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +74 -68
  11. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +2 -2
  12. package/skills/wix-app/references/dashboard-page/COLLECTION_TOOLKIT.md +79 -0
  13. package/skills/wix-app/references/dashboard-page/ENTITY_PAGE_TOOLKIT.md +73 -0
  14. package/skills/wix-app/references/dashboard-page/PATTERNS_BUNDLE_READING.md +52 -0
  15. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +184 -0
  16. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +182 -99
  17. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +94 -49
  18. package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +16 -6
  19. package/skills/wix-app/references/editor-react-component/BROWSER-SUPPORT.md +56 -0
  20. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +275 -0
  21. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +35 -40
  22. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +167 -445
  23. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +56 -29
  24. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +53 -158
  25. package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +78 -0
  26. package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +42 -134
  27. package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +11 -3
  28. package/skills/wix-app/references/editor-react-component/PARTS.md +46 -24
  29. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +63 -179
  30. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +79 -163
  31. package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +36 -21
  32. package/skills/wix-app/references/editor-react-component/SSR.md +30 -99
  33. package/skills/wix-base44-connector/SKILL.md +156 -50
  34. package/skills/wix-base44-connector/references/CAPABILITY_MAP.md +78 -0
  35. package/skills/wix-base44-connector/scripts/utils.js +239 -45
  36. package/skills/wix-headless/entry/bootstrap.mjs +9 -2
  37. package/skills/wix-headless/entry/skill.md +1 -1
  38. package/skills/wix-headless/references/CAPABILITIES.md +9 -1
  39. package/skills/wix-headless/references/DESIGN.md +1 -0
  40. package/skills/wix-headless/references/DISCOVERY.md +2 -1
  41. package/skills/wix-headless/references/IMAGE_GENERATION.md +1 -0
  42. package/skills/wix-headless/references/SDK_HANDOFF.md +5 -2
  43. package/skills/wix-headless/references/SEED.md +2 -1
  44. package/skills/wix-headless/references/SETUP.md +1 -0
  45. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +2 -2
  46. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +68 -31
  47. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +26 -10
  48. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +8 -8
  49. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +1 -1
  50. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +1 -1
  51. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +10 -8
  52. package/skills/wix-headless/references/inline-recipes/how-to-code-rentals.md +254 -0
  53. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +27 -24
  54. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +13 -0
  55. package/skills/wix-headless/references/inline-recipes/setup-rentals.md +254 -0
  56. package/skills/wix-headless/references/managed/AUTHENTICATION.md +5 -0
  57. package/skills/wix-headless/references/non-astro.md +1 -1
  58. package/skills/wix-headless-fast/SKILL.md +166 -0
  59. package/skills/wix-headless-fast/entry/skill.md +99 -0
  60. package/skills/wix-headless-fast/install/deploy.mjs +433 -0
  61. package/skills/wix-headless-fast/install/fast-path.mjs +141 -0
  62. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +137 -0
  63. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +137 -0
  64. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +113 -0
  65. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +42 -0
  66. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +123 -0
  67. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +70 -0
  68. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +99 -0
  69. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +76 -0
  70. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +62 -0
  71. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +40 -0
  72. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +99 -0
  73. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +24 -0
  74. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +16156 -0
  75. package/skills/wix-headless-fast/references/blog/seed/SEED.md +72 -0
  76. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +287 -0
  77. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +129 -0
  78. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +143 -0
  79. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +119 -0
  80. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +138 -0
  81. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +54 -0
  82. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +206 -0
  83. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +96 -0
  84. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +70 -0
  85. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +40 -0
  86. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +76 -0
  87. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +22 -0
  88. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +11962 -0
  89. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +61 -0
  90. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +302 -0
  91. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +179 -0
  92. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +83 -0
  93. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +57 -0
  94. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +151 -0
  95. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +75 -0
  96. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +41 -0
  97. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +11262 -0
  98. package/skills/wix-headless-fast/references/cms/seed/SEED.md +103 -0
  99. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +324 -0
  100. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +149 -0
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +66 -0
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +176 -0
  103. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +118 -0
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +117 -0
  105. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +59 -0
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +136 -0
  107. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +128 -0
  108. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +61 -0
  109. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +40 -0
  110. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +12 -0
  111. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +80 -0
  112. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +21 -0
  113. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +11884 -0
  114. package/skills/wix-headless-fast/references/events/seed/SEED.md +86 -0
  115. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +276 -0
  116. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +150 -0
  117. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +317 -0
  118. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +269 -0
  119. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +231 -0
  120. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +135 -0
  121. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +10593 -0
  122. package/skills/wix-headless-fast/references/forms/seed/SEED.md +108 -0
  123. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +320 -0
  124. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +63 -0
  125. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +60 -0
  126. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +155 -0
  127. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +78 -0
  128. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +47 -0
  129. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +66 -0
  130. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +88 -0
  131. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +53 -0
  132. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +122 -0
  133. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +50 -0
  134. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +21 -0
  135. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +42 -0
  136. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +10 -0
  137. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +11 -0
  138. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +10329 -0
  139. package/skills/wix-headless-fast/references/members/seed/SEED.md +39 -0
  140. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +94 -0
  141. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +134 -0
  142. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +110 -0
  143. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +90 -0
  144. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +115 -0
  145. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +59 -0
  146. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +39 -0
  147. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +58 -0
  148. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +165 -0
  149. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +55 -0
  150. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +40 -0
  151. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +30 -0
  152. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +21 -0
  153. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +29 -0
  154. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +10197 -0
  155. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +78 -0
  156. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +258 -0
  157. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +133 -0
  158. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +58 -0
  159. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +126 -0
  160. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +37 -0
  161. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +39 -0
  162. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +75 -0
  163. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +45 -0
  164. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +30 -0
  165. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +41 -0
  166. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +40 -0
  167. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +21 -0
  168. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +11226 -0
  169. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +71 -0
  170. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +279 -0
  171. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +165 -0
  172. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +142 -0
  173. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +26 -0
  174. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +121 -0
  175. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +155 -0
  176. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +55 -0
  177. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +43 -0
  178. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +177 -0
  179. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +165 -0
  180. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +103 -0
  181. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +254 -0
  182. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +146 -0
  183. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +168 -0
  184. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +47 -0
  185. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +22 -0
  186. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +12 -0
  187. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +12560 -0
  188. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +81 -0
  189. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +479 -0
  190. package/skills/wix-headless-fast/references/shared/CONTENT.md +22 -0
  191. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +73 -0
  192. package/skills/wix-headless-fast/references/shared/DESIGN.md +26 -0
  193. package/skills/wix-headless-fast/references/shared/app/styles/global.css +52 -0
  194. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +15 -0
  195. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +27 -0
  196. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +24 -0
  197. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +76 -0
  198. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +46 -0
  199. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +46 -0
  200. package/skills/wix-headless-fast/references/shared/seed/images.mjs +145 -0
  201. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +149 -0
  202. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +26 -0
  203. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +121 -0
  204. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductCard.tsx +100 -0
  205. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductDetailView.tsx +130 -0
  206. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductGrid.tsx +48 -0
  207. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ShopView.tsx +66 -0
  208. package/skills/wix-headless-fast/references/storefront/app/components/storefront/VariantPicker.tsx +103 -0
  209. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +48 -0
  210. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +140 -0
  211. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +80 -0
  212. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +101 -0
  213. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +221 -0
  214. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +215 -0
  215. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +109 -0
  216. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +46 -0
  217. package/skills/wix-headless-fast/references/storefront/app-astro/pages/products/[slug].astro +56 -0
  218. package/skills/wix-headless-fast/references/storefront/app-astro/pages/shop.astro +23 -0
  219. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +12247 -0
  220. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +85 -0
  221. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +415 -0
  222. package/skills/wix-manage/SKILL.md +28 -2
  223. package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +20 -13
  224. package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +24 -11
  225. package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +5 -5
  226. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +141 -0
  227. package/skills/wix-manage/references/google-business-profile/connect-google-business-profile.md +134 -0
  228. package/skills/wix-manage/references/google-business-profile/manage-google-business-profile-locations.md +182 -0
  229. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +3 -0
  230. package/skills/wix-manage/references/seo/manage-seo-tags.md +315 -0
  231. package/skills/wix-manage/references/seo/manage-url-redirects.md +250 -0
  232. package/skills/wix-manage/references/sites/query-sites.md +72 -161
  233. package/skills/wix-manage/references/stores/create-product-catalog-v3.md +21 -6
  234. package/skills/wix-manage/references/stores/update-product-with-options.md +83 -0
  235. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +5 -6
  236. package/skills/wix-vibe-headless/SKILL.md +18 -4
  237. package/skills/wix-vibe-headless/install/deploy.cjs +12 -4
  238. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +2 -1
  239. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +16 -10
  240. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +13 -8
  241. package/skills/wix-vibe-headless/platforms/base44.md +27 -62
  242. package/skills/wix-vibe-headless/platforms/generic.md +6 -3
  243. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +45 -0
  244. package/skills/wix-vibe-headless/references/bookings/app/components/RentalDurationPicker.jsx +67 -0
  245. package/skills/wix-vibe-headless/references/bookings/app/hooks/useRentalDuration.js +128 -0
  246. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +5 -3
  247. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js +9 -8
  248. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-rentals.js +250 -0
  249. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-services.js +12 -5
  250. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +41 -0
  251. package/skills/wix-vibe-headless/references/bookings/seed/seed-rentals.js +267 -0
  252. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +6 -3
  253. package/skills/wix-vibe-headless/references/forms/INSTRUCTIONS.md +470 -0
  254. package/skills/wix-vibe-headless/references/forms/app/hooks/useWixForm.js +425 -0
  255. package/skills/wix-vibe-headless/references/forms/app/lib/wix-form-schema-utils.js +187 -0
  256. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms-submissions.js +238 -0
  257. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms.js +108 -0
  258. package/skills/wix-vibe-headless/references/forms/seed/SEED.md +1762 -0
  259. package/skills/wix-vibe-headless/references/rentals/INSTRUCTIONS.md +13 -0
  260. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +4 -1
  261. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +23 -11
  262. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +1 -1
  263. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +29 -31
  264. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +152 -92
  265. package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +37 -38
  266. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +2 -2
  267. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +15 -8
  268. package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +37 -0
  269. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js +35 -35
  270. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-catalog.js +18 -6
  271. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +30 -7
  272. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +46 -10
  273. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +0 -172
  274. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +0 -143
  275. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +0 -516
  276. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +0 -225
  277. package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +0 -6
  278. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +0 -95
  279. package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +0 -110
  280. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGallery.jsx +0 -51
  281. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +0 -49
  282. package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +0 -92
  283. package/skills/wix-vibe-headless/references/storefront/app/pages/ProductDetail.jsx +0 -139
@@ -1,225 +0,0 @@
1
- # Component Configuration
2
-
3
- After scaffolding the component and running `npx wix build && npx wix generate manifest`,
4
- configure the component's behavior in the editor by writing **partial
5
- manifest overrides** in the component's hand-edited extension file
6
- (`<ComponentName>.extension.ts`). That file imports the auto-generated
7
- manifest and spreads it; specific fields are overridden inline. Re-running
8
- this command regenerates each `<ComponentName>.generated.ts`
9
- companion but never touches the overrides authored in the extension file.
10
-
11
- ---
12
-
13
- ## 1. Verifying that height sizing type meets user needs
14
-
15
- Set `installation.initialSize.height.sizingType` based on whether the
16
- component's own content decides how tall it is.
17
-
18
- ### Heuristic — one question
19
-
20
- **Does the component's own content decide how tall it is?**
21
-
22
- - **Yes — height should grow with text the user types or children they drop inside** → `LAYOUT.SIZING_TYPE.content`. Omit `pixels`.
23
- - **No — the component is a framed visual** (a graphic, an embedded media surface, a form control with a standard height, an empty placeholder) → `LAYOUT.SIZING_TYPE.pixels`. Provide a `pixels` default that matches its natural visual size.
24
-
25
- **Tiebreaker:** if a designer would drag a handle to set the height, it's `pixels`. If the height should just fit whatever is inside, it's `content`.
26
-
27
- ### Where to write the override
28
-
29
- ```ts
30
- import { extensions } from '@wix/astro/builders';
31
- import { LAYOUT } from '@wix/react-component-schema';
32
- import { manifest } from './ComponentName.generated';
33
-
34
- const componentExtension = extensions.editorReactComponent({
35
- // …other fields…
36
- installation: {
37
- initialSize: {
38
- width: {
39
- sizingType: LAYOUT.SIZING_TYPE.pixels,
40
- pixels: 250,
41
- },
42
- height: {
43
- sizingType: LAYOUT.SIZING_TYPE.updateMe,
44
- },
45
- },
46
- },
47
- });
48
- ```
49
-
50
- ### Examples
51
-
52
- **Content-driven** (`LAYOUT.SIZING_TYPE.content`) — testimonial card,
53
- FAQ accordion, pricing tier, blog-post body, list/grid of arbitrary
54
- children:
55
-
56
- ```ts
57
- height: {
58
- sizingType: LAYOUT.SIZING_TYPE.content,
59
- }
60
- ```
61
-
62
- **Framed visual** (`LAYOUT.SIZING_TYPE.pixels`) — hero banner with a
63
- fixed image, video embed, color-picker swatch grid, OTP input, empty
64
- placeholder slot:
65
-
66
- ```ts
67
- height: {
68
- sizingType: LAYOUT.SIZING_TYPE.pixels,
69
- pixels: 320,
70
- }
71
- ```
72
-
73
- ---
74
-
75
- ## 2. Verifying that resize direction meets user needs
76
-
77
- Set `editorElement.layout.resizeDirection` based on which axes the
78
- designer should be able to control with a drag handle. Allow an axis
79
- if dragging it produces a meaningful, intended change. Disallow it if
80
- dragging would do nothing visible or would break the component's
81
- identity.
82
-
83
- ### Heuristic — which axes are meaningful?
84
-
85
- | Choice | When to use |
86
- |--------|-------------|
87
- | `horizontalAndVertical` | Content fills or stretches in both axes. Hero, carousel, gallery, card grid, embed, form control, any framed visual. **Default for most components.** |
88
- | `horizontal` | Height is rigid/intrinsic — cannot meaningfully stretch. Breadcrumb, tag row, nav bar, single-line input, slider rail. |
89
- | `vertical` | Width is rigid/intrinsic. Vertical stack, ribbon, sidebar rail. |
90
- | `aspectRatio` | Distortion breaks identity — logo, illustration, animation. |
91
- | `none` | Size fully owned by a parent layout. Never for top-level components. |
92
-
93
- **Tiebreaker:** if a drag handle on an axis would feel inert or wrong
94
- to a designer, take it away.
95
-
96
- ### Where to write the override
97
-
98
- ```ts
99
- import { extensions } from '@wix/astro/builders';
100
- import { LAYOUT } from '@wix/react-component-schema';
101
- import { manifest } from './ComponentName.generated';
102
-
103
- const componentExtension = extensions.editorReactComponent({
104
- // …other fields…
105
- editorElement: {
106
- ...manifest.editorElement,
107
- layout: {
108
- resizeDirection: LAYOUT.RESIZE_DIRECTION._selectedResizeDirection_,
109
- },
110
- },
111
- });
112
- ```
113
-
114
- ### Examples
115
-
116
- ```ts
117
- // hero, carousel, gallery, card grid, embed, form
118
- resizeDirection: LAYOUT.RESIZE_DIRECTION.horizontalAndVertical,
119
-
120
- // breadcrumb, tag row, nav bar, slider rail
121
- resizeDirection: LAYOUT.RESIZE_DIRECTION.horizontal,
122
-
123
- // logo, illustration, animation
124
- resizeDirection: LAYOUT.RESIZE_DIRECTION.aspectRatio,
125
- ```
126
-
127
- ---
128
-
129
- ## 3. Wiring defaults into the manifest
130
-
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
- 2. **Import `componentUrl` from `'./component.tsx?url'`** (the wrapped component), not from `'./ComponentName.tsx?url'` (the raw component).
133
- 3. **Wrap `editorElement` with `withEditorElementDefaults`** using the same `defaultProps`.
134
-
135
- ```ts
136
- import { withEditorElementDefaults } from '@wix/react-component-utils';
137
- import componentUrl from './component.tsx?url';
138
- import { defaultProps } from './<componentName>.props';
139
-
140
- // in the extension:
141
- editorElement: withEditorElementDefaults({
142
- ...manifest.editorElement,
143
- }, defaultProps),
144
- resources: {
145
- ...manifest.resources,
146
- client: { componentUrl },
147
- },
148
- ```
149
-
150
- ---
151
-
152
- ## 4. Enabling automatic installation on Harmony editor
153
-
154
- **Always include `"staticContainer": "HOMEPAGE"`** in `installation` so the
155
- component is automatically installed on the Harmony editor.
156
-
157
- ```ts
158
- const componentExtension = extensions.editorReactComponent({
159
- // …other fields…
160
- installation: {
161
- // …other fields…
162
- staticContainer: 'HOMEPAGE',
163
- },
164
- });
165
- ```
166
-
167
- ---
168
-
169
- ## 5. Adding range constraints for numeric props
170
-
171
- The zero-config pipeline reads `@min` and `@max` JSDoc tags on numeric props and
172
- emits them as `number: { min, max }` in the generated manifest. Add these tags
173
- directly on the prop in the component's props interface — no extension file
174
- override is needed.
175
-
176
- ### Heuristic — does this number have a fixed domain?
177
-
178
- | Scenario | Action |
179
- |----------|--------|
180
- | Rating 0–5, column count 1–6, items per row 1–4 | Add `@min` / `@max` |
181
- | Volume 0–100, playback speed 0.5–5, autoplay delay 0.5–30 | Add `@min` / `@max` |
182
- | Geo coordinates, zoom level | Add `@min` / `@max` |
183
- | Arbitrary count, free-form price, unconstrained input | Omit — leave as `number` |
184
- | Semantic index (active tab, active slide, active item) | Omit — upper bound is driven by the component's own item count, not a fixed domain |
185
-
186
- ### How to write the tags
187
-
188
- Add `@min` and `@max` inline in the JSDoc comment for the prop in `<componentName>.props.ts`:
189
-
190
- ```ts
191
- export interface RatingWidgetProps {
192
- /** @min 0 @max 5 */
193
- rating: number;
194
- }
195
- ```
196
-
197
- Zero-config picks these up during `npx wix build && npx wix generate manifest`
198
- and emits:
199
-
200
- ```ts
201
- rating: {
202
- dataType: 'number',
203
- number: { min: '0', max: '5' },
204
- }
205
- ```
206
-
207
- ### Examples
208
-
209
- ```ts
210
- // Star rating 0–5
211
- /** @min 0 @max 5 */
212
- rating: number;
213
-
214
- // Volume 0–100
215
- /** @min 0 @max 100 */
216
- volume: number;
217
-
218
- // Playback speed 0.5–5
219
- /** @min 0.5 @max 5 */
220
- speed: number;
221
-
222
- // Column count 1–6
223
- /** @min 1 @max 6 */
224
- columns: number;
225
- ```
@@ -1,6 +0,0 @@
1
- # React Site Component edition
2
-
3
- Always follow this exact workflow:
4
-
5
- 1. Make changes in the component's code
6
- 2. Run `npx wix build && npx wix generate manifest` (PascalCase)
@@ -1,95 +0,0 @@
1
- # React Component Patterns
2
-
3
- Code patterns and common mistakes for Editor React components.
4
-
5
- # Part 1: Implementation Patterns
6
-
7
- ## 1.1 SSR-Safe Implementation
8
-
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
- ```
26
-
27
- ## 1.2 Element Visibility (Platform-Managed)
28
-
29
- See [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) — element visibility is platform-managed; always render all elements, no conditional rendering.
30
-
31
- ---
32
-
33
- # Part 2: CSS/SCSS Rules
34
-
35
- Authoritative SCSS rules: `REACT-GUIDELINES.md` Part 2. For RTL/logical CSS patterns, see [`DIRECTIONALITY.md`](DIRECTIONALITY.md).
36
-
37
- ## 2.1 What NOT to Include
38
-
39
- ```scss
40
- // ❌ NEVER include:
41
-
42
- // Transitions/Animations
43
- transition: all 0.3s; // ❌
44
- animation: fadeIn 0.5s; // ❌
45
- ```
46
-
47
- > Design states (`hover`, `focus`, `selected`, …) are authored per
48
- > [`DESIGN-STATES.md`](DESIGN-STATES.md).
49
-
50
- ---
51
-
52
- # Part 3: Common Mistakes
53
-
54
- ## 3.1 Custom-state classes
55
-
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).
59
-
60
- ## 3.2 Browser APIs at module scope
61
-
62
- **❌ Wrong:**
63
-
64
- ```typescript
65
- const isMobile = window.innerWidth < 768; // ❌ SSR breaks
66
- ```
67
-
68
- **✅ Correct:**
69
-
70
- ```typescript
71
- useEffect(() => {
72
- if (typeof window !== "undefined") {
73
- setIsMobile(window.innerWidth < 768);
74
- }
75
- }, []);
76
- ```
77
-
78
- ## 3.3 Use semantic HTML for collection-style UI
79
-
80
- For lists, breadcrumbs, tabs, menus, and similar collection-style UI, render the underlying semantic HTML directly (`<ol>`/`<ul>` + `<li>`, `<nav>`, `<button role="tab">`, etc.) and own the keyboard / ARIA wiring in your own React code.
81
-
82
- ```tsx
83
- <ol className="breadcrumbs">
84
- <li>
85
- <a href="/">Home</a>
86
- </li>
87
- <li>
88
- <span aria-hidden="true">/</span>
89
- <a href="/products">Products</a>
90
- </li>
91
- </ol>
92
- ```
93
-
94
- Handle separators with CSS pseudo-elements or inside each item.
95
-
@@ -1,110 +0,0 @@
1
- // Reference implementation of a product grid tile built on useProductCard.
2
- // Styled with base44 design tokens (shadcn Tailwind classes: bg-card / text-foreground / border-border).
3
- // Build your own card on useProductCard instead — read this for inspiration, don't use it directly.
4
- import { useState } from "react";
5
- import { Link } from "react-router-dom";
6
- import { useCart } from "@/context/CartContext";
7
- import { useProductCard } from "@/hooks/useProductCard";
8
-
9
- const badge = "px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide rounded-full";
10
- const badgePromo = `${badge} bg-primary text-primary-foreground`;
11
- const badgeInfo = `${badge} bg-card text-foreground border border-border`;
12
- const badgeBlocked = `${badge} bg-destructive text-destructive-foreground`;
13
-
14
- const badgeClass = { "pre-order": badgeInfo, "sold-out": badgeBlocked, "limited-stock": badgeInfo };
15
-
16
- export default function ProductCard({ product }) {
17
- const { addToCart } = useCart();
18
- const [adding, setAdding] = useState(false);
19
-
20
- const {
21
- isSoldOut, isPreorder, leftBadges, promoBadge,
22
- priceDisplay, compareAtDisplay,
23
- colors, optionLabel,
24
- isQuickAddable, image, hoverImage,
25
- } = useProductCard(product);
26
-
27
- const quickAdd = async () => {
28
- setAdding(true);
29
- await addToCart(product.id);
30
- setAdding(false);
31
- };
32
-
33
- return (
34
- <div className="group relative flex flex-col bg-card border border-border rounded-lg overflow-hidden shadow-sm">
35
- <div className="relative aspect-square bg-background">
36
- <Link to={`/product/${product.slug}`} aria-label={product.name} className="block w-full h-full">
37
- {image ? (
38
- <>
39
- <img src={image} alt={product.name} loading="lazy"
40
- className={`w-full h-full object-cover ${hoverImage ? "transition-opacity duration-300 md:group-hover:opacity-0" : ""}`} />
41
- {hoverImage && (
42
- <img src={hoverImage} alt="" aria-hidden="true" loading="lazy"
43
- className="hidden md:block absolute inset-0 w-full h-full object-cover opacity-0 transition-opacity duration-300 group-hover:opacity-100" />
44
- )}
45
- </>
46
- ) : (
47
- <div className="w-full h-full bg-muted flex items-center justify-center" aria-hidden="true">
48
- <svg viewBox="0 0 24 24" className="w-8 h-8 text-muted-foreground/40" fill="none" stroke="currentColor" strokeWidth="1.5">
49
- <rect x="3" y="3" width="18" height="18" rx="2" /><circle cx="8.5" cy="8.5" r="1.5" /><path d="m21 15-5-5L5 21" />
50
- </svg>
51
- </div>
52
- )}
53
- </Link>
54
-
55
- <div className="absolute top-2 left-2 flex flex-col items-start gap-1 pointer-events-none">
56
- {leftBadges.map((b) => (
57
- <span key={b.type} className={badgeClass[b.type]}>{b.label}</span>
58
- ))}
59
- </div>
60
- <div className="absolute top-2 right-2 pointer-events-none">
61
- {promoBadge && <span className={badgePromo}>{promoBadge.label}</span>}
62
- </div>
63
-
64
- {(!isSoldOut || isPreorder) && (
65
- <div className="absolute inset-x-2 bottom-2 opacity-100 transition-opacity md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100">
66
- {isQuickAddable ? (
67
- <button onClick={quickAdd} disabled={adding}
68
- className="w-full py-2.5 px-4 rounded-full bg-primary text-primary-foreground border-none text-sm font-semibold cursor-pointer transition-opacity hover:opacity-90 disabled:opacity-60 disabled:cursor-wait">
69
- {adding ? "Adding…" : "Quick add"}
70
- </button>
71
- ) : (
72
- <Link to={`/product/${product.slug}`}
73
- className="block w-full text-center py-2.5 px-4 rounded-full bg-primary text-primary-foreground no-underline text-sm font-semibold">
74
- {isSoldOut ? "Pre-order" : "Choose options"}
75
- </Link>
76
- )}
77
- </div>
78
- )}
79
- </div>
80
-
81
- <div className="p-3 flex flex-col gap-1">
82
- <div className="flex flex-col gap-1 md:flex-row md:items-baseline md:justify-between md:gap-3">
83
- <h3 className="m-0 font-display text-[15px] font-semibold line-clamp-2">
84
- <Link to={`/product/${product.slug}`} className="no-underline text-foreground">{product.name}</Link>
85
- </h3>
86
- <div className="flex gap-2 items-baseline flex-wrap md:justify-end">
87
- <span className="font-semibold whitespace-nowrap">{priceDisplay}</span>
88
- {compareAtDisplay && (
89
- <span className="text-muted-foreground line-through text-[13px] whitespace-nowrap">{compareAtDisplay}</span>
90
- )}
91
- </div>
92
- </div>
93
-
94
- {(colors.length > 0 || optionLabel) && (
95
- <div className="flex items-center gap-2 text-[13px] text-muted-foreground min-h-[18px]">
96
- {colors.length > 0 && (
97
- <span className="flex items-center gap-1" aria-label={`${colors.length} colors available`}>
98
- {colors.slice(0, 5).map((c, i) => (
99
- <span key={`${c}-${i}`} className="w-3 h-3 rounded-full ring-1 ring-inset ring-black/20" style={{ backgroundColor: c }} />
100
- ))}
101
- {colors.length > 5 && <span>+{colors.length - 5}</span>}
102
- </span>
103
- )}
104
- {optionLabel && <span>{optionLabel}</span>}
105
- </div>
106
- )}
107
- </div>
108
- </div>
109
- );
110
- }
@@ -1,51 +0,0 @@
1
- // PDP image gallery — main image plus thumbnails from productGallery(product), which puts
2
- // media.main first and drops the duplicate of it that media.itemsInfo.items carries. A product with a
3
- // single image renders just the main frame, so this is safe for a one-photo catalog.
4
- // Styled with base44 design tokens (shadcn Tailwind classes).
5
- import { useEffect, useState } from "react";
6
-
7
- export default function ProductGallery({ images, name, focusUrl }) {
8
- const [index, setIndex] = useState(0);
9
- // Reset when navigating between products — the component stays mounted across a slug change.
10
- // `images` must keep a stable identity per product (the PDP memoises it), or every parent render —
11
- // a quantity bump, an option click — would land here and throw away the image the buyer picked.
12
- useEffect(() => { setIndex(0); }, [images]);
13
-
14
- // Picking a colour swatch shows that colour: focusUrl is the choice's linked photo. Runs after the
15
- // reset effect, so a first paint with a colour pre-selected opens on the right image.
16
- useEffect(() => {
17
- const i = images?.findIndex((img) => img.url === focusUrl) ?? -1;
18
- if (i >= 0) setIndex(i);
19
- }, [focusUrl, images]);
20
-
21
- const current = images?.[index];
22
-
23
- return (
24
- <div className="flex flex-col gap-3">
25
- <div className="aspect-square bg-card rounded-lg overflow-hidden">
26
- {current ? (
27
- <img src={current.url} alt={current.altText || name} className="w-full h-full object-cover" />
28
- ) : (
29
- <div className="w-full h-full bg-muted flex items-center justify-center" aria-hidden="true">
30
- <svg viewBox="0 0 24 24" className="w-10 h-10 text-muted-foreground/40" fill="none" stroke="currentColor" strokeWidth="1.5">
31
- <rect x="3" y="3" width="18" height="18" rx="2" /><circle cx="8.5" cy="8.5" r="1.5" /><path d="m21 15-5-5L5 21" />
32
- </svg>
33
- </div>
34
- )}
35
- </div>
36
-
37
- {images?.length > 1 && (
38
- <div className="flex gap-2 flex-wrap" role="group" aria-label={`${name} images`}>
39
- {images.map((img, i) => (
40
- <button key={img.url} onClick={() => setIndex(i)} aria-label={`Show image ${i + 1}`} aria-current={i === index}
41
- className={`w-16 h-16 rounded-sm overflow-hidden cursor-pointer bg-card border ${
42
- i === index ? "border-primary" : "border-border"
43
- }`}>
44
- <img src={img.url} alt="" loading="lazy" className="w-full h-full object-cover" />
45
- </button>
46
- ))}
47
- </div>
48
- )}
49
- </div>
50
- );
51
- }
@@ -1,49 +0,0 @@
1
- // Reference implementation of a product grid — 2-col mobile, auto-fill desktop, with a skeleton
2
- // loading state and a descriptive empty state. Build your own layout instead (see INSTRUCTIONS.md
3
- // STEP 3) — read this for the skeleton/empty-state patterns, don't use it directly.
4
- import ProductCard from "./ProductCard";
5
-
6
- // Skeleton tiles match ProductCard's aspect-square + two text lines, so nothing shifts when the real
7
- // products land.
8
- export function ProductGridSkeleton({ count = 8 }) {
9
- return (
10
- <div className="grid gap-4 grid-cols-2 md:[grid-template-columns:repeat(auto-fill,minmax(220px,1fr))]" aria-hidden="true">
11
- {Array.from({ length: count }).map((_, i) => (
12
- <div key={i} className="bg-card border border-border rounded-lg overflow-hidden">
13
- <div className="aspect-square bg-muted animate-pulse" />
14
- <div className="p-3 flex flex-col gap-2">
15
- <div className="flex justify-between gap-3">
16
- <div className="h-3.5 w-1/2 bg-muted rounded-sm animate-pulse" />
17
- <div className="h-3.5 w-1/5 bg-muted rounded-sm animate-pulse" />
18
- </div>
19
- <div className="h-3 w-1/3 bg-muted rounded-sm animate-pulse" />
20
- </div>
21
- </div>
22
- ))}
23
- </div>
24
- );
25
- }
26
-
27
- export default function ProductGrid({ products, loading, empty = "No products yet.", emptyHint }) {
28
- if (loading) return <ProductGridSkeleton />;
29
-
30
- if (!products?.length) {
31
- return (
32
- <div className="flex flex-col items-center justify-center text-center gap-3 py-16 px-4">
33
- <svg width="44" height="44" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"
34
- className="text-muted-foreground/40" aria-hidden="true">
35
- <path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z" /><path d="M3 6h18" />
36
- <path d="M16 10a4 4 0 0 1-8 0" />
37
- </svg>
38
- <h2 className="font-display m-0 text-lg font-semibold">{empty}</h2>
39
- {emptyHint && <p className="m-0 text-muted-foreground max-w-[46ch]">{emptyHint}</p>}
40
- </div>
41
- );
42
- }
43
-
44
- return (
45
- <div className="grid gap-4 grid-cols-2 md:[grid-template-columns:repeat(auto-fill,minmax(220px,1fr))]">
46
- {products.map((p) => <ProductCard key={p.id} product={p} />)}
47
- </div>
48
- );
49
- }
@@ -1,92 +0,0 @@
1
- // PDP choice controls built on useVariantOptions — swap this component for your own if you want
2
- // a different look; the data contract (optionGroups / modifierGroups) stays the same.
3
- // Styled with base44 design tokens (shadcn Tailwind classes).
4
- import { useVariantOptions } from "@/hooks/useVariantOptions";
5
-
6
- const chipBase = "py-1.5 px-3 cursor-pointer text-sm font-body border rounded-sm";
7
- const chipIdle = "border-border bg-card text-foreground";
8
- const chipActive = "border-primary bg-primary text-primary-foreground";
9
- const label = "block mb-1.5 text-[13px] font-semibold text-muted-foreground";
10
-
11
- export default function VariantPicker({ options, modifiers, selectedOptions, selectOption, modifierValues, setModifier }) {
12
- const { optionGroups, modifierGroups } = useVariantOptions(options, modifiers, selectedOptions, modifierValues);
13
-
14
- return (
15
- <>
16
- {optionGroups.map((group) => (
17
- <div key={group.id} className="mb-4">
18
- <label className={label}>
19
- {group.name}
20
- {group.isColor && (
21
- <span className="ml-1.5 font-normal text-foreground">
22
- {group.choices.find((c) => c.selected)?.name}
23
- </span>
24
- )}
25
- </label>
26
- <div className="flex flex-wrap gap-2">
27
- {group.choices.map((c) =>
28
- c.isColorSwatch ? (
29
- <button
30
- key={c.choiceId}
31
- type="button"
32
- disabled={!c.inStock}
33
- onClick={() => selectOption(group.id, c.choiceId)}
34
- aria-pressed={c.selected}
35
- aria-label={`${c.name}${!c.inStock ? " (out of stock)" : ""}`}
36
- title={c.name}
37
- className={`relative w-9 h-9 rounded-full cursor-pointer transition-shadow ring-1 ring-inset ring-black/15 ${
38
- c.selected ? "ring-2 ring-offset-2 ring-offset-background ring-primary" : ""
39
- } ${!c.inStock ? "opacity-40 cursor-not-allowed" : "hover:ring-2 hover:ring-offset-1 hover:ring-offset-background hover:ring-border"}`}
40
- style={{ backgroundColor: c.colorCode }}
41
- >
42
- {!c.inStock && (
43
- <span aria-hidden="true" className="absolute inset-0 grid place-items-center">
44
- <span className="w-full h-px bg-destructive rotate-45" />
45
- </span>
46
- )}
47
- </button>
48
- ) : (
49
- <button
50
- key={c.choiceId}
51
- type="button"
52
- disabled={!c.inStock}
53
- aria-pressed={c.selected}
54
- onClick={() => selectOption(group.id, c.choiceId)}
55
- className={`${chipBase} ${c.selected ? chipActive : chipIdle} ${!c.inStock ? "opacity-40 line-through" : ""}`}
56
- >
57
- {c.name}
58
- </button>
59
- )
60
- )}
61
- </div>
62
- </div>
63
- ))}
64
-
65
- {modifierGroups.map((m) => (
66
- <div key={m.key} className="mb-4">
67
- <label className={label}>{m.name}{m.mandatory && " *"}</label>
68
- {m.type === "text" ? (
69
- <input
70
- value={m.value}
71
- onChange={(e) => setModifier(m.key, e.target.value)}
72
- className="w-full py-2 px-3 font-body border border-input rounded-sm bg-background text-foreground"
73
- />
74
- ) : (
75
- <div className="flex flex-wrap gap-2">
76
- {m.choices.map((c) => (
77
- <button
78
- key={c.key}
79
- aria-pressed={c.selected}
80
- onClick={() => setModifier(m.key, c.key)}
81
- className={`${chipBase} ${c.selected ? chipActive : chipIdle}`}
82
- >
83
- {c.name}
84
- </button>
85
- ))}
86
- </div>
87
- )}
88
- </div>
89
- ))}
90
- </>
91
- );
92
- }