@athoscommerce/snap-preact 1.11.0 → 1.12.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 (275) hide show
  1. package/dist/cjs/components/src/components/Atoms/Dropdown/Dropdown.js +18 -10
  2. package/dist/cjs/components/src/components/Atoms/Image/Image.js +10 -2
  3. package/dist/cjs/components/src/components/Atoms/ProductDetail/ProductDetail.js +98 -0
  4. package/dist/cjs/components/src/components/Atoms/ProductDetail/index.js +7 -0
  5. package/dist/cjs/components/src/components/Atoms/TemplateSelect/TemplateSelect.js +13 -4
  6. package/dist/cjs/components/src/components/Molecules/CalloutBadge/CalloutBadge.js +4 -1
  7. package/dist/cjs/components/src/components/Molecules/Gallery/Gallery.js +298 -0
  8. package/dist/cjs/components/src/components/Molecules/Gallery/index.js +17 -0
  9. package/dist/cjs/components/src/components/Molecules/Modal/Modal.js +21 -2
  10. package/dist/cjs/components/src/components/Molecules/OverlayBadge/OverlayBadge.js +1 -1
  11. package/dist/cjs/components/src/components/Molecules/ProductDetailTable/ProductDetailTable.js +115 -0
  12. package/dist/cjs/components/src/components/Molecules/ProductDetailTable/index.js +17 -0
  13. package/dist/cjs/components/src/components/Molecules/QuantityPicker/QuantityPicker.js +136 -0
  14. package/dist/cjs/components/src/components/Molecules/QuantityPicker/index.js +17 -0
  15. package/dist/cjs/components/src/components/Molecules/Result/Result.js +43 -4
  16. package/dist/cjs/components/src/components/Molecules/Slideout/Slideout.js +5 -2
  17. package/dist/cjs/components/src/components/Molecules/Slideshow/Slideshow.js +38 -5
  18. package/dist/cjs/components/src/components/Molecules/Swatches/Swatches.js +1 -1
  19. package/dist/cjs/components/src/components/Molecules/VariantSelection/VariantSelection.js +7 -1
  20. package/dist/cjs/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.js +8 -8
  21. package/dist/cjs/components/src/components/Organisms/Facet/Facet.js +1 -5
  22. package/dist/cjs/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.js +612 -0
  23. package/dist/cjs/components/src/components/Organisms/QuickviewLayout/index.js +17 -0
  24. package/dist/cjs/components/src/components/Templates/AutocompleteFixed/AutocompleteFixed.js +3 -3
  25. package/dist/cjs/components/src/components/Templates/AutocompleteModal/AutocompleteModal.js +3 -3
  26. package/dist/cjs/components/src/components/Templates/AutocompleteSlideout/AutocompleteSlideout.js +2 -2
  27. package/dist/cjs/components/src/components/Templates/QuickviewModal/QuickviewModal.js +153 -0
  28. package/dist/cjs/components/src/components/Templates/QuickviewModal/index.js +17 -0
  29. package/dist/cjs/components/src/components/Templates/QuickviewSlideout/QuickviewSlideout.js +124 -0
  30. package/dist/cjs/components/src/components/Templates/QuickviewSlideout/index.js +17 -0
  31. package/dist/cjs/components/src/components/Templates/Recommendation/Recommendation.js +2 -1
  32. package/dist/cjs/components/src/components/Templates/RecommendationBundle/RecommendationBundle.js +2 -1
  33. package/dist/cjs/components/src/components/Templates/RecommendationGrid/RecommendationGrid.js +2 -1
  34. package/dist/cjs/components/src/hooks/useA11y.js +3 -1
  35. package/dist/cjs/components/src/hooks/useAcRenderedInput.js +1 -1
  36. package/dist/cjs/components/src/hooks/useClickOutside.js +6 -3
  37. package/dist/cjs/components/src/hooks/useTracking.js +14 -8
  38. package/dist/cjs/components/src/index.js +6 -0
  39. package/dist/cjs/components/src/providers/themeComponents.js +4 -0
  40. package/dist/cjs/components/src/setupTests.js +10 -0
  41. package/dist/cjs/components/src/utilities/createImpressionObserver.js +1 -1
  42. package/dist/cjs/components/src/utilities/index.js +1 -0
  43. package/dist/cjs/components/src/utilities/lazyRenderMinSize.js +10 -0
  44. package/dist/cjs/src/Instantiators/RecommendationInstantiator.js +2 -1
  45. package/dist/cjs/src/Snap.js +41 -0
  46. package/dist/cjs/src/Templates/SnapTemplates.js +51 -0
  47. package/dist/cjs/src/Templates/Stores/LibraryStore.js +77 -9
  48. package/dist/cjs/src/Templates/Stores/TemplateEditor/TemplateEditorStore.js +6 -1
  49. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.js +2 -5
  50. package/dist/cjs/src/Templates/Stores/TemplateStore.js +26 -10
  51. package/dist/cjs/src/Templates/Stores/library/components/QuickviewModal.js +5 -0
  52. package/dist/cjs/src/Templates/Stores/library/components/QuickviewSlideout.js +5 -0
  53. package/dist/cjs/src/Templates/Stores/library/currencies/currencies.js +1433 -0
  54. package/dist/cjs/src/Templates/Stores/library/languages/ar.js +487 -0
  55. package/dist/cjs/src/Templates/Stores/library/languages/de.js +487 -0
  56. package/dist/cjs/src/Templates/Stores/library/languages/en.js +1 -0
  57. package/dist/cjs/src/Templates/Stores/library/languages/es.js +84 -41
  58. package/dist/cjs/src/Templates/Stores/library/languages/fr.js +85 -40
  59. package/dist/cjs/src/Templates/Stores/library/languages/hi.js +487 -0
  60. package/dist/cjs/src/Templates/Stores/library/languages/it.js +487 -0
  61. package/dist/cjs/src/Templates/Stores/library/languages/ja.js +487 -0
  62. package/dist/cjs/src/Templates/Stores/library/languages/ko.js +487 -0
  63. package/dist/cjs/src/Templates/Stores/library/languages/nl.js +487 -0
  64. package/dist/cjs/src/Templates/Stores/library/languages/pt.js +487 -0
  65. package/dist/cjs/src/Templates/Stores/library/languages/ru.js +487 -0
  66. package/dist/cjs/src/Templates/Stores/library/languages/tr.js +487 -0
  67. package/dist/cjs/src/Templates/Stores/library/languages/vi.js +487 -0
  68. package/dist/cjs/src/Templates/Stores/library/languages/zh.js +487 -0
  69. package/dist/cjs/src/Templates/index.js +3 -1
  70. package/dist/cjs/src/create/createAutocompleteController.js +1 -0
  71. package/dist/cjs/src/create/createRecommendationController.js +1 -0
  72. package/dist/cjs/src/create/createSearchController.js +1 -0
  73. package/dist/cjs/src/index.js +3 -1
  74. package/dist/esm/components/src/components/Atoms/Button/Button.d.ts +1 -1
  75. package/dist/esm/components/src/components/Atoms/Button/Button.d.ts.map +1 -1
  76. package/dist/esm/components/src/components/Atoms/Dropdown/Dropdown.d.ts.map +1 -1
  77. package/dist/esm/components/src/components/Atoms/Dropdown/Dropdown.js +19 -11
  78. package/dist/esm/components/src/components/Atoms/Image/Image.d.ts +5 -0
  79. package/dist/esm/components/src/components/Atoms/Image/Image.d.ts.map +1 -1
  80. package/dist/esm/components/src/components/Atoms/Image/Image.js +10 -2
  81. package/dist/esm/components/src/components/Atoms/ProductDetail/ProductDetail.d.ts +18 -0
  82. package/dist/esm/components/src/components/Atoms/ProductDetail/ProductDetail.d.ts.map +1 -0
  83. package/dist/esm/components/src/components/Atoms/ProductDetail/ProductDetail.js +89 -0
  84. package/dist/esm/components/src/components/Atoms/ProductDetail/index.d.ts +3 -0
  85. package/dist/esm/components/src/components/Atoms/ProductDetail/index.d.ts.map +1 -0
  86. package/dist/esm/components/src/components/Atoms/ProductDetail/index.js +3 -0
  87. package/dist/esm/components/src/components/Atoms/TemplateSelect/TemplateSelect.d.ts +1 -1
  88. package/dist/esm/components/src/components/Atoms/TemplateSelect/TemplateSelect.d.ts.map +1 -1
  89. package/dist/esm/components/src/components/Atoms/TemplateSelect/TemplateSelect.js +13 -4
  90. package/dist/esm/components/src/components/Molecules/CalloutBadge/CalloutBadge.d.ts.map +1 -1
  91. package/dist/esm/components/src/components/Molecules/CalloutBadge/CalloutBadge.js +4 -1
  92. package/dist/esm/components/src/components/Molecules/Gallery/Gallery.d.ts +28 -0
  93. package/dist/esm/components/src/components/Molecules/Gallery/Gallery.d.ts.map +1 -0
  94. package/dist/esm/components/src/components/Molecules/Gallery/Gallery.js +292 -0
  95. package/dist/esm/components/src/components/Molecules/Gallery/index.d.ts +2 -0
  96. package/dist/esm/components/src/components/Molecules/Gallery/index.d.ts.map +1 -0
  97. package/dist/esm/components/src/components/Molecules/Gallery/index.js +1 -0
  98. package/dist/esm/components/src/components/Molecules/Modal/Modal.d.ts.map +1 -1
  99. package/dist/esm/components/src/components/Molecules/Modal/Modal.js +22 -3
  100. package/dist/esm/components/src/components/Molecules/OverlayBadge/OverlayBadge.d.ts.map +1 -1
  101. package/dist/esm/components/src/components/Molecules/OverlayBadge/OverlayBadge.js +1 -1
  102. package/dist/esm/components/src/components/Molecules/ProductDetailTable/ProductDetailTable.d.ts +14 -0
  103. package/dist/esm/components/src/components/Molecules/ProductDetailTable/ProductDetailTable.d.ts.map +1 -0
  104. package/dist/esm/components/src/components/Molecules/ProductDetailTable/ProductDetailTable.js +109 -0
  105. package/dist/esm/components/src/components/Molecules/ProductDetailTable/index.d.ts +2 -0
  106. package/dist/esm/components/src/components/Molecules/ProductDetailTable/index.d.ts.map +1 -0
  107. package/dist/esm/components/src/components/Molecules/ProductDetailTable/index.js +1 -0
  108. package/dist/esm/components/src/components/Molecules/QuantityPicker/QuantityPicker.d.ts +43 -0
  109. package/dist/esm/components/src/components/Molecules/QuantityPicker/QuantityPicker.d.ts.map +1 -0
  110. package/dist/esm/components/src/components/Molecules/QuantityPicker/QuantityPicker.js +130 -0
  111. package/dist/esm/components/src/components/Molecules/QuantityPicker/index.d.ts +2 -0
  112. package/dist/esm/components/src/components/Molecules/QuantityPicker/index.d.ts.map +1 -0
  113. package/dist/esm/components/src/components/Molecules/QuantityPicker/index.js +1 -0
  114. package/dist/esm/components/src/components/Molecules/Result/Result.d.ts +3 -0
  115. package/dist/esm/components/src/components/Molecules/Result/Result.d.ts.map +1 -1
  116. package/dist/esm/components/src/components/Molecules/Result/Result.js +43 -4
  117. package/dist/esm/components/src/components/Molecules/Slideout/Slideout.d.ts.map +1 -1
  118. package/dist/esm/components/src/components/Molecules/Slideout/Slideout.js +6 -3
  119. package/dist/esm/components/src/components/Molecules/Slideshow/Slideshow.d.ts +1 -0
  120. package/dist/esm/components/src/components/Molecules/Slideshow/Slideshow.d.ts.map +1 -1
  121. package/dist/esm/components/src/components/Molecules/Slideshow/Slideshow.js +38 -5
  122. package/dist/esm/components/src/components/Molecules/Swatches/Swatches.js +1 -1
  123. package/dist/esm/components/src/components/Molecules/VariantSelection/VariantSelection.d.ts.map +1 -1
  124. package/dist/esm/components/src/components/Molecules/VariantSelection/VariantSelection.js +7 -1
  125. package/dist/esm/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.js +8 -8
  126. package/dist/esm/components/src/components/Organisms/Facet/Facet.d.ts.map +1 -1
  127. package/dist/esm/components/src/components/Organisms/Facet/Facet.js +1 -5
  128. package/dist/esm/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.d.ts +53 -0
  129. package/dist/esm/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.d.ts.map +1 -0
  130. package/dist/esm/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.js +605 -0
  131. package/dist/esm/components/src/components/Organisms/QuickviewLayout/index.d.ts +2 -0
  132. package/dist/esm/components/src/components/Organisms/QuickviewLayout/index.d.ts.map +1 -0
  133. package/dist/esm/components/src/components/Organisms/QuickviewLayout/index.js +1 -0
  134. package/dist/esm/components/src/components/Templates/AutocompleteFixed/AutocompleteFixed.js +3 -3
  135. package/dist/esm/components/src/components/Templates/AutocompleteModal/AutocompleteModal.js +3 -3
  136. package/dist/esm/components/src/components/Templates/AutocompleteSlideout/AutocompleteSlideout.js +2 -2
  137. package/dist/esm/components/src/components/Templates/QuickviewModal/QuickviewModal.d.ts +12 -0
  138. package/dist/esm/components/src/components/Templates/QuickviewModal/QuickviewModal.d.ts.map +1 -0
  139. package/dist/esm/components/src/components/Templates/QuickviewModal/QuickviewModal.js +147 -0
  140. package/dist/esm/components/src/components/Templates/QuickviewModal/index.d.ts +2 -0
  141. package/dist/esm/components/src/components/Templates/QuickviewModal/index.d.ts.map +1 -0
  142. package/dist/esm/components/src/components/Templates/QuickviewModal/index.js +1 -0
  143. package/dist/esm/components/src/components/Templates/QuickviewSlideout/QuickviewSlideout.d.ts +16 -0
  144. package/dist/esm/components/src/components/Templates/QuickviewSlideout/QuickviewSlideout.d.ts.map +1 -0
  145. package/dist/esm/components/src/components/Templates/QuickviewSlideout/QuickviewSlideout.js +118 -0
  146. package/dist/esm/components/src/components/Templates/QuickviewSlideout/index.d.ts +2 -0
  147. package/dist/esm/components/src/components/Templates/QuickviewSlideout/index.d.ts.map +1 -0
  148. package/dist/esm/components/src/components/Templates/QuickviewSlideout/index.js +1 -0
  149. package/dist/esm/components/src/components/Templates/Recommendation/Recommendation.d.ts.map +1 -1
  150. package/dist/esm/components/src/components/Templates/Recommendation/Recommendation.js +3 -2
  151. package/dist/esm/components/src/components/Templates/RecommendationBundle/RecommendationBundle.d.ts.map +1 -1
  152. package/dist/esm/components/src/components/Templates/RecommendationBundle/RecommendationBundle.js +3 -2
  153. package/dist/esm/components/src/components/Templates/RecommendationGrid/RecommendationGrid.d.ts.map +1 -1
  154. package/dist/esm/components/src/components/Templates/RecommendationGrid/RecommendationGrid.js +3 -2
  155. package/dist/esm/components/src/hooks/useA11y.d.ts.map +1 -1
  156. package/dist/esm/components/src/hooks/useA11y.js +3 -1
  157. package/dist/esm/components/src/hooks/useAcRenderedInput.js +1 -1
  158. package/dist/esm/components/src/hooks/useClickOutside.d.ts +1 -1
  159. package/dist/esm/components/src/hooks/useClickOutside.d.ts.map +1 -1
  160. package/dist/esm/components/src/hooks/useClickOutside.js +6 -3
  161. package/dist/esm/components/src/hooks/useTracking.d.ts +9 -3
  162. package/dist/esm/components/src/hooks/useTracking.d.ts.map +1 -1
  163. package/dist/esm/components/src/hooks/useTracking.js +14 -8
  164. package/dist/esm/components/src/index.d.ts +6 -0
  165. package/dist/esm/components/src/index.d.ts.map +1 -1
  166. package/dist/esm/components/src/index.js +6 -0
  167. package/dist/esm/components/src/providers/langComponents.d.ts +6 -0
  168. package/dist/esm/components/src/providers/langComponents.d.ts.map +1 -1
  169. package/dist/esm/components/src/providers/themeComponents.d.ts +104 -57
  170. package/dist/esm/components/src/providers/themeComponents.d.ts.map +1 -1
  171. package/dist/esm/components/src/providers/themeComponents.js +4 -0
  172. package/dist/esm/components/src/setupTests.js +10 -0
  173. package/dist/esm/components/src/utilities/createImpressionObserver.js +1 -1
  174. package/dist/esm/components/src/utilities/index.d.ts +1 -0
  175. package/dist/esm/components/src/utilities/index.d.ts.map +1 -1
  176. package/dist/esm/components/src/utilities/index.js +1 -0
  177. package/dist/esm/components/src/utilities/lazyRenderMinSize.d.ts +5 -0
  178. package/dist/esm/components/src/utilities/lazyRenderMinSize.d.ts.map +1 -0
  179. package/dist/esm/components/src/utilities/lazyRenderMinSize.js +7 -0
  180. package/dist/esm/src/Instantiators/RecommendationInstantiator.d.ts +4 -2
  181. package/dist/esm/src/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  182. package/dist/esm/src/Instantiators/RecommendationInstantiator.js +2 -1
  183. package/dist/esm/src/Snap.d.ts +7 -0
  184. package/dist/esm/src/Snap.d.ts.map +1 -1
  185. package/dist/esm/src/Snap.js +43 -2
  186. package/dist/esm/src/Templates/SnapTemplates.d.ts +25 -0
  187. package/dist/esm/src/Templates/SnapTemplates.d.ts.map +1 -1
  188. package/dist/esm/src/Templates/SnapTemplates.js +48 -0
  189. package/dist/esm/src/Templates/Stores/LibraryStore.d.ts +22 -2
  190. package/dist/esm/src/Templates/Stores/LibraryStore.d.ts.map +1 -1
  191. package/dist/esm/src/Templates/Stores/LibraryStore.js +76 -8
  192. package/dist/esm/src/Templates/Stores/TemplateEditor/TemplateEditorStore.d.ts.map +1 -1
  193. package/dist/esm/src/Templates/Stores/TemplateEditor/TemplateEditorStore.js +6 -1
  194. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.d.ts.map +1 -1
  195. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.js +2 -5
  196. package/dist/esm/src/Templates/Stores/TemplateStore.d.ts +14 -6
  197. package/dist/esm/src/Templates/Stores/TemplateStore.d.ts.map +1 -1
  198. package/dist/esm/src/Templates/Stores/TemplateStore.js +26 -10
  199. package/dist/esm/src/Templates/Stores/library/components/QuickviewModal.d.ts +2 -0
  200. package/dist/esm/src/Templates/Stores/library/components/QuickviewModal.d.ts.map +1 -0
  201. package/dist/esm/src/Templates/Stores/library/components/QuickviewModal.js +1 -0
  202. package/dist/esm/src/Templates/Stores/library/components/QuickviewSlideout.d.ts +2 -0
  203. package/dist/esm/src/Templates/Stores/library/components/QuickviewSlideout.d.ts.map +1 -0
  204. package/dist/esm/src/Templates/Stores/library/components/QuickviewSlideout.js +1 -0
  205. package/dist/esm/src/Templates/Stores/library/currencies/currencies.d.ts +1270 -0
  206. package/dist/esm/src/Templates/Stores/library/currencies/currencies.d.ts.map +1 -0
  207. package/dist/esm/src/Templates/Stores/library/currencies/currencies.js +1430 -0
  208. package/dist/esm/src/Templates/Stores/library/languages/ar.d.ts +3 -0
  209. package/dist/esm/src/Templates/Stores/library/languages/ar.d.ts.map +1 -0
  210. package/dist/esm/src/Templates/Stores/library/languages/ar.js +484 -0
  211. package/dist/esm/src/Templates/Stores/library/languages/de.d.ts +3 -0
  212. package/dist/esm/src/Templates/Stores/library/languages/de.d.ts.map +1 -0
  213. package/dist/esm/src/Templates/Stores/library/languages/de.js +484 -0
  214. package/dist/esm/src/Templates/Stores/library/languages/en.d.ts.map +1 -1
  215. package/dist/esm/src/Templates/Stores/library/languages/en.js +1 -0
  216. package/dist/esm/src/Templates/Stores/library/languages/es.d.ts.map +1 -1
  217. package/dist/esm/src/Templates/Stores/library/languages/es.js +84 -41
  218. package/dist/esm/src/Templates/Stores/library/languages/fr.d.ts.map +1 -1
  219. package/dist/esm/src/Templates/Stores/library/languages/fr.js +85 -40
  220. package/dist/esm/src/Templates/Stores/library/languages/hi.d.ts +3 -0
  221. package/dist/esm/src/Templates/Stores/library/languages/hi.d.ts.map +1 -0
  222. package/dist/esm/src/Templates/Stores/library/languages/hi.js +484 -0
  223. package/dist/esm/src/Templates/Stores/library/languages/it.d.ts +3 -0
  224. package/dist/esm/src/Templates/Stores/library/languages/it.d.ts.map +1 -0
  225. package/dist/esm/src/Templates/Stores/library/languages/it.js +484 -0
  226. package/dist/esm/src/Templates/Stores/library/languages/ja.d.ts +3 -0
  227. package/dist/esm/src/Templates/Stores/library/languages/ja.d.ts.map +1 -0
  228. package/dist/esm/src/Templates/Stores/library/languages/ja.js +484 -0
  229. package/dist/esm/src/Templates/Stores/library/languages/ko.d.ts +3 -0
  230. package/dist/esm/src/Templates/Stores/library/languages/ko.d.ts.map +1 -0
  231. package/dist/esm/src/Templates/Stores/library/languages/ko.js +484 -0
  232. package/dist/esm/src/Templates/Stores/library/languages/nl.d.ts +3 -0
  233. package/dist/esm/src/Templates/Stores/library/languages/nl.d.ts.map +1 -0
  234. package/dist/esm/src/Templates/Stores/library/languages/nl.js +484 -0
  235. package/dist/esm/src/Templates/Stores/library/languages/pt.d.ts +3 -0
  236. package/dist/esm/src/Templates/Stores/library/languages/pt.d.ts.map +1 -0
  237. package/dist/esm/src/Templates/Stores/library/languages/pt.js +484 -0
  238. package/dist/esm/src/Templates/Stores/library/languages/ru.d.ts +3 -0
  239. package/dist/esm/src/Templates/Stores/library/languages/ru.d.ts.map +1 -0
  240. package/dist/esm/src/Templates/Stores/library/languages/ru.js +484 -0
  241. package/dist/esm/src/Templates/Stores/library/languages/tr.d.ts +3 -0
  242. package/dist/esm/src/Templates/Stores/library/languages/tr.d.ts.map +1 -0
  243. package/dist/esm/src/Templates/Stores/library/languages/tr.js +484 -0
  244. package/dist/esm/src/Templates/Stores/library/languages/vi.d.ts +3 -0
  245. package/dist/esm/src/Templates/Stores/library/languages/vi.d.ts.map +1 -0
  246. package/dist/esm/src/Templates/Stores/library/languages/vi.js +484 -0
  247. package/dist/esm/src/Templates/Stores/library/languages/zh.d.ts +3 -0
  248. package/dist/esm/src/Templates/Stores/library/languages/zh.d.ts.map +1 -0
  249. package/dist/esm/src/Templates/Stores/library/languages/zh.js +484 -0
  250. package/dist/esm/src/Templates/index.d.ts +1 -1
  251. package/dist/esm/src/Templates/index.d.ts.map +1 -1
  252. package/dist/esm/src/Templates/index.js +1 -1
  253. package/dist/esm/src/create/createAutocompleteController.js +1 -0
  254. package/dist/esm/src/create/createRecommendationController.js +1 -0
  255. package/dist/esm/src/create/createSearchController.js +1 -0
  256. package/dist/esm/src/index.d.ts +1 -1
  257. package/dist/esm/src/index.d.ts.map +1 -1
  258. package/dist/esm/src/index.js +1 -1
  259. package/dist/esm/src/types.d.ts +2 -1
  260. package/dist/esm/src/types.d.ts.map +1 -1
  261. package/eslint/src/index.cjs +5 -0
  262. package/eslint/src/validate-config.cjs +473 -0
  263. package/package.json +16 -14
  264. package/dist/cjs/src/Templates/Stores/library/currencies/aud.js +0 -10
  265. package/dist/cjs/src/Templates/Stores/library/currencies/eur.js +0 -10
  266. package/dist/cjs/src/Templates/Stores/library/currencies/usd.js +0 -10
  267. package/dist/esm/src/Templates/Stores/library/currencies/aud.d.ts +0 -8
  268. package/dist/esm/src/Templates/Stores/library/currencies/aud.d.ts.map +0 -1
  269. package/dist/esm/src/Templates/Stores/library/currencies/aud.js +0 -7
  270. package/dist/esm/src/Templates/Stores/library/currencies/eur.d.ts +0 -8
  271. package/dist/esm/src/Templates/Stores/library/currencies/eur.d.ts.map +0 -1
  272. package/dist/esm/src/Templates/Stores/library/currencies/eur.js +0 -7
  273. package/dist/esm/src/Templates/Stores/library/currencies/usd.d.ts +0 -8
  274. package/dist/esm/src/Templates/Stores/library/currencies/usd.d.ts.map +0 -1
  275. package/dist/esm/src/Templates/Stores/library/currencies/usd.js +0 -7
@@ -77,9 +77,15 @@ exports.Dropdown = (0, mobx_react_lite_1.observer)((properties) => {
77
77
  onToggle && onToggle(e, false);
78
78
  }
79
79
  }
80
- });
80
+ // capture phase so outside clicks close the dropdown even inside the quickview wrapper,
81
+ // which stops click propagation; the contentRef guard above covers the portaled options
82
+ }, true);
81
83
  }
82
- (0, hooks_1.useEffect)(() => {
84
+ // Position the portal BEFORE the browser paints — with a regular effect the dropdown
85
+ // options would flash at (0,0) until the effect runs and computes the real button position.
86
+ // Resize / scroll listeners stay on a regular effect — they only need to run after
87
+ // the initial layout pass is committed.
88
+ (0, hooks_1.useLayoutEffect)(() => {
83
89
  if (usePortal && dropdownOpen) {
84
90
  const updateCoords = () => {
85
91
  if (buttonRef.current) {
@@ -168,12 +174,14 @@ exports.Dropdown = (0, mobx_react_lite_1.observer)((properties) => {
168
174
  }, children: (0, utilities_1.cloneWithProps)(button, { open: dropdownOpen, toggleOpen: toggleOpenDropdown, treePath }) }), !usePortal
169
175
  ? (content || children) && contentElement
170
176
  : (content || children) &&
171
- (0, compat_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('ss__dropdown__portal', className, internalClassName, { 'ss__dropdown__portal--open': dropdownOpen }), css: styling.css, style: {
172
- position: 'absolute',
173
- top: coords.top,
174
- left: coords.left,
175
- width: coords.width,
176
- zIndex: 9999,
177
- pointerEvents: dropdownOpen ? 'auto' : 'none',
178
- }, children: contentElement }), document.body)] }) }));
177
+ (0, compat_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: globalTheme.name ? `ss__theme__${globalTheme.name}` : 'ss__theme__global', children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('ss__dropdown__portal', className, internalClassName, { 'ss__dropdown__portal--open': dropdownOpen }), css: styling.css, style: {
178
+ position: 'absolute',
179
+ top: coords.top,
180
+ left: coords.left,
181
+ width: coords.width,
182
+ // 10007: above the quickview modal content (10006) so variant dropdowns paint over it,
183
+ // below the Gallery lightbox (10010). Full ladder: see QuickviewModal defaultStyles.
184
+ zIndex: 10007,
185
+ pointerEvents: dropdownOpen ? 'auto' : 'none',
186
+ }, children: contentElement }) }), document.body)] }) }));
179
187
  });
@@ -41,7 +41,7 @@ exports.Image = (0, mobx_react_lite_1.observer)((properties) => {
41
41
  treePath: globalTreePath,
42
42
  };
43
43
  const props = (0, utilities_1.mergeProps)('image', globalTheme, defaultProps, properties);
44
- const { alt, src, fallback, title, hoverSrc, lazy, onMouseOver, onMouseOut, onError, onLoad, onClick, className, internalClassName } = props;
44
+ const { alt, src, fallback, title, hoverSrc, lazy, onMouseOver, onMouseOut, onError, onLoad, onClick, onPointerDown, onPointerMove, onPointerUp, onPointerLeave, className, internalClassName, draggable, } = props;
45
45
  const { overrideElement, shouldRenderDefault } = (0, hooks_2.useCustomComponentOverride)('image', props);
46
46
  if (!shouldRenderDefault) {
47
47
  return overrideElement;
@@ -68,5 +68,13 @@ exports.Image = (0, mobx_react_lite_1.observer)((properties) => {
68
68
  }, onMouseOut: (e) => {
69
69
  hoverSrc && setHover(false);
70
70
  onMouseOut && onMouseOut(e);
71
- } }) }) }));
71
+ }, onPointerDown: (e) => {
72
+ onPointerDown && onPointerDown(e);
73
+ }, onPointerMove: (e) => {
74
+ onPointerMove && onPointerMove(e);
75
+ }, onPointerUp: (e) => {
76
+ onPointerUp && onPointerUp(e);
77
+ }, onPointerLeave: (e) => {
78
+ onPointerLeave && onPointerLeave(e);
79
+ }, draggable: draggable }) }) }));
72
80
  });
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ProductDetail = exports.renderDetailValue = exports.getProductFieldValue = exports.isCorePriceField = void 0;
7
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
8
+ const react_1 = require("@emotion/react");
9
+ const classnames_1 = __importDefault(require("classnames"));
10
+ const mobx_react_lite_1 = require("mobx-react-lite");
11
+ const mobx_1 = require("mobx");
12
+ const providers_1 = require("../../../providers");
13
+ const utilities_1 = require("../../../utilities");
14
+ const hooks_1 = require("../../../hooks");
15
+ const snap_toolbox_1 = require("@athoscommerce/snap-toolbox");
16
+ const Price_1 = require("../Price");
17
+ // Core mapping fields whose values represent monetary amounts and should be formatted by `Price`.
18
+ const CORE_PRICE_FIELDS = ['price', 'msrp'];
19
+ // A field is a core-mapping price when its final segment is a known price field and it resolves
20
+ // from core mappings — either a bare key (which falls back to `mappings.core`) or an explicit
21
+ // `...mappings.core.<priceField>` path. `attributes.price` and the like are excluded.
22
+ const isCorePriceField = (field) => {
23
+ if (!field)
24
+ return false;
25
+ const segments = field.split('.');
26
+ const last = segments[segments.length - 1];
27
+ if (!CORE_PRICE_FIELDS.includes(last))
28
+ return false;
29
+ if (segments.length === 1)
30
+ return true;
31
+ return segments[segments.length - 2] === 'core' && segments[segments.length - 3] === 'mappings';
32
+ };
33
+ exports.isCorePriceField = isCorePriceField;
34
+ // Resolve a product field value. An explicit dot-path (e.g. `mappings.core.name` or
35
+ // `attributes.brand`) states exactly where to read from and is resolved against the variant-aware
36
+ // `display` view first, then the product itself. A bare field key (no dot) falls back to the
37
+ // legacy lookup — `mappings.core` first, then `attributes` — so config-driven field lists keep
38
+ // working. Returns the raw value (string, number, array, object); formatting is left to
39
+ // `renderDetailValue`.
40
+ const getProductFieldValue = (result, field) => {
41
+ if (!result || !field)
42
+ return undefined;
43
+ const resolvePath = (root) => field.split('.').reduce((acc, key) => (acc && typeof acc === 'object' ? acc[key] : undefined), root);
44
+ const explicit = resolvePath(result?.display) ?? resolvePath(result);
45
+ if (explicit !== undefined)
46
+ return explicit;
47
+ if (!field.includes('.')) {
48
+ const core = (result?.display?.mappings?.core || result?.mappings?.core);
49
+ const attributes = (result?.display?.attributes || result?.attributes);
50
+ return core?.[field] ?? attributes?.[field];
51
+ }
52
+ return undefined;
53
+ };
54
+ exports.getProductFieldValue = getProductFieldValue;
55
+ // Coerce a resolved value into a display string: arrays (and MobX observable arrays) are
56
+ // comma-joined, objects fall back to JSON, everything else is stringified.
57
+ const renderDetailValue = (value) => {
58
+ if (value === null || value === undefined)
59
+ return '';
60
+ if (Array.isArray(value) || (0, mobx_1.isObservableArray)(value)) {
61
+ return Array.from(value)
62
+ .map((v) => (typeof v === 'object' ? JSON.stringify(v) : String(v)))
63
+ .join(', ');
64
+ }
65
+ if (typeof value === 'object')
66
+ return JSON.stringify(value);
67
+ return String(value);
68
+ };
69
+ exports.renderDetailValue = renderDetailValue;
70
+ const defaultStyles = () => {
71
+ return (0, react_1.css)({});
72
+ };
73
+ exports.ProductDetail = (0, mobx_react_lite_1.observer)((properties) => {
74
+ const globalTheme = (0, providers_1.useTheme)();
75
+ const globalTreePath = (0, providers_1.useTreePath)();
76
+ const defaultProps = {
77
+ treePath: globalTreePath,
78
+ // the field's final segment names the component (`productDetail.<name>` theme selectors)
79
+ name: properties.field ? (0, snap_toolbox_1.fieldNameToComponentName)(properties.field.split('.').pop() || '') : undefined,
80
+ };
81
+ const props = (0, utilities_1.mergeProps)('productDetail', globalTheme, defaultProps, properties);
82
+ const { result, field, name, html, tag, className, internalClassName } = props;
83
+ const { overrideElement, shouldRenderDefault } = (0, hooks_1.useCustomComponentOverride)('productDetail', props);
84
+ if (!shouldRenderDefault) {
85
+ return overrideElement;
86
+ }
87
+ const styling = (0, utilities_1.mergeStyles)(props, defaultStyles);
88
+ const rawValue = (0, exports.getProductFieldValue)(result, field);
89
+ const value = (0, exports.renderDetailValue)(rawValue);
90
+ if (!value)
91
+ return null;
92
+ const isPrice = (0, exports.isCorePriceField)(field) && typeof rawValue === 'number';
93
+ // Theme/style modifier: the named selector suffix (`productDetail.<name>`) when present,
94
+ // otherwise the resolved field path's final segment.
95
+ const modifier = name || field.split('.').pop();
96
+ const classNames = (0, classnames_1.default)('ss__product-detail', modifier && `ss__product-detail--${modifier}`, tag && `ss__product-detail--${tag}`, className, internalClassName);
97
+ return ((0, jsx_runtime_1.jsx)(providers_1.CacheProvider, { children: html ? ((0, jsx_runtime_1.jsx)("div", { ...styling, className: classNames, dangerouslySetInnerHTML: { __html: value } })) : ((0, jsx_runtime_1.jsx)("div", { ...styling, className: classNames, children: isPrice ? (0, jsx_runtime_1.jsx)(Price_1.Price, { value: rawValue, treePath: props.treePath }) : value })) }));
98
+ });
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductDetail = void 0;
4
+ // Curated: the field-resolution helpers in ProductDetail.tsx are internal (used by
5
+ // ProductDetailTable and unit tests via direct file imports) and must not reach the package API.
6
+ var ProductDetail_1 = require("./ProductDetail");
7
+ Object.defineProperty(exports, "ProductDetail", { enumerable: true, get: function () { return ProductDetail_1.ProductDetail; } });
@@ -9,7 +9,9 @@ exports.TemplateSelect = (0, mobx_react_lite_1.observer)((properties) => {
9
9
  const { snap, templatesStore, target, controller, ...otherProps } = properties;
10
10
  const { loading } = templatesStore;
11
11
  if (!target) {
12
- controller.log.error(`Target was not provided!`);
12
+ // Quickview targets render without a controller (the quickview manager is not one), so
13
+ // fall back to the console when there is no controller logger to use.
14
+ controller ? controller.log.error(`Target was not provided!`) : console.error(`[TemplateSelect] Target was not provided!`);
13
15
  return null;
14
16
  }
15
17
  const Component = templatesStore.library.getComponent(target.type, target.component);
@@ -18,11 +20,18 @@ exports.TemplateSelect = (0, mobx_react_lite_1.observer)((properties) => {
18
20
  const theme = themeStore?.theme;
19
21
  if (!loading && !theme && !templatesStore.settings?.editMode) {
20
22
  const error = `Theme "${target.theme.name}" not found in library for target "${target.selector}"`;
21
- controller.log.error(error);
23
+ controller ? controller.log.error(error) : console.error(`[TemplateSelect] ${error}`);
22
24
  }
23
- const tabManager = controller.type === snap_controller_1.ControllerTypes.search || controller.type === snap_controller_1.ControllerTypes.autocomplete
25
+ const tabManager = controller?.type === snap_controller_1.ControllerTypes.search || controller?.type === snap_controller_1.ControllerTypes.autocomplete
24
26
  ? templatesStore.getTabManager(controller.type, snap.controllers)
25
27
  : undefined;
28
+ const tabName = tabManager?.active?.id ? tabManager.active.id.toLowerCase() : undefined;
26
29
  // ensuring that theme and component are ready to render
27
- return !loading && theme && Component ? ((0, jsx_runtime_1.jsx)(providers_1.SnapProvider, { snap: snap, children: (0, jsx_runtime_1.jsx)(providers_1.ThemeProvider, { theme: theme, children: (0, jsx_runtime_1.jsx)(providers_1.ControllerProvider, { controller: controller, children: (0, jsx_runtime_1.jsx)("div", { className: "ss__template-select", children: (0, jsx_runtime_1.jsx)(Component, { controller: controller, tabManager: tabManager, name: tabManager?.active?.id ? tabManager?.active?.id.toLowerCase() : undefined, ...otherProps }) }) }) }) })) : null;
30
+ if (loading || !theme || !Component) {
31
+ return null;
32
+ }
33
+ // Quickview targets render without a controller — the shared quickview manager arrives via
34
+ // `otherProps` instead — so the ControllerProvider is only wrapped when there is one to provide.
35
+ const content = ((0, jsx_runtime_1.jsx)("div", { className: "ss__template-select", children: (0, jsx_runtime_1.jsx)(Component, { controller: controller, tabManager: tabManager, ...(tabName !== undefined ? { name: tabName } : {}), ...otherProps }) }));
36
+ return ((0, jsx_runtime_1.jsx)(providers_1.SnapProvider, { snap: snap, children: (0, jsx_runtime_1.jsx)(providers_1.ThemeProvider, { theme: theme, children: controller ? (0, jsx_runtime_1.jsx)(providers_1.ControllerProvider, { controller: controller, children: content }) : content }) }));
28
37
  });
@@ -10,6 +10,7 @@ const classnames_1 = __importDefault(require("classnames"));
10
10
  const mobx_react_lite_1 = require("mobx-react-lite");
11
11
  const providers_1 = require("../../../providers");
12
12
  const utilities_1 = require("../../../utilities");
13
+ const snap_toolbox_1 = require("@athoscommerce/snap-toolbox");
13
14
  const hooks_1 = require("../../../hooks");
14
15
  const defaultStyles = () => {
15
16
  return (0, react_1.css)({
@@ -32,6 +33,8 @@ exports.CalloutBadge = (0, mobx_react_lite_1.observer)((properties) => {
32
33
  const globalTreePath = (0, providers_1.useTreePath)();
33
34
  const defaultProps = {
34
35
  // default props
36
+ // a custom tag names the component (`calloutBadge.<tag>` theme selectors); default usage stays unnamed
37
+ name: properties.tag ? (0, snap_toolbox_1.fieldNameToComponentName)(properties.tag) : undefined,
35
38
  tag: 'callout',
36
39
  limit: 1,
37
40
  treePath: globalTreePath,
@@ -48,7 +51,7 @@ exports.CalloutBadge = (0, mobx_react_lite_1.observer)((properties) => {
48
51
  ...props.componentMap,
49
52
  };
50
53
  const styling = (0, utilities_1.mergeStyles)(props, defaultStyles);
51
- const badges = result?.display.badges?.atLocation(tag).slice(0, limit);
54
+ const badges = result?.display?.badges?.atLocation(tag).slice(0, limit);
52
55
  if (renderEmpty || badges?.length) {
53
56
  return ((0, jsx_runtime_1.jsx)(providers_1.CacheProvider, { children: (0, jsx_runtime_1.jsx)("div", { ...styling, className: (0, classnames_1.default)('ss__callout-badge', `ss__callout-badge--${tag?.replace('/', '-')}`, className, internalClassName), children: badges.map((badge, badgeIndex) => ((0, jsx_runtime_1.jsx)(BadgeRenderer, { badge: badge, badgeComponentMap: badgeComponentMap, treePath: treePath }, `${badge.component}-${badgeIndex}`))) }) }));
54
57
  }
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Gallery = void 0;
7
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
8
+ const compat_1 = require("preact/compat");
9
+ const hooks_1 = require("preact/hooks");
10
+ const mobx_react_lite_1 = require("mobx-react-lite");
11
+ const react_1 = require("@emotion/react");
12
+ const classnames_1 = __importDefault(require("classnames"));
13
+ const deepmerge_1 = __importDefault(require("deepmerge"));
14
+ const providers_1 = require("../../../providers");
15
+ const utilities_1 = require("../../../utilities");
16
+ const hooks_2 = require("../../../hooks");
17
+ const Button_1 = require("../../Atoms/Button");
18
+ const Image_1 = require("../../Atoms/Image");
19
+ const defaultStyles = () => {
20
+ return (0, react_1.css)({
21
+ position: 'fixed',
22
+ inset: 0,
23
+ zIndex: 10010, // above the quickview modal content (10006) and the dropdown portal (10007); full ladder in QuickviewModal defaultStyles
24
+ display: 'flex',
25
+ flexDirection: 'column',
26
+ background: 'rgba(0, 0, 0, 0.9)',
27
+ '& .ss__gallery__toolbar': {
28
+ display: 'flex',
29
+ justifyContent: 'flex-end',
30
+ alignItems: 'center',
31
+ gap: '8px',
32
+ padding: '12px 16px',
33
+ },
34
+ // button and icon chrome (color, background, border) comes from Button/Icon props (not CSS)
35
+ // so that theme overrides targeting those components (e.g. `gallery button.zoom-in`) are not
36
+ // out-specified here — these rules stick to layout the sub-components have no props for
37
+ '& .ss__gallery__button': {
38
+ display: 'flex',
39
+ alignItems: 'center',
40
+ justifyContent: 'center',
41
+ padding: 0,
42
+ boxSizing: 'border-box',
43
+ borderRadius: '4px',
44
+ width: '40px',
45
+ height: '40px',
46
+ fontSize: '1.3em',
47
+ lineHeight: 1,
48
+ cursor: 'pointer',
49
+ '&.ss__button--disabled': {
50
+ opacity: 0.4,
51
+ cursor: 'default',
52
+ },
53
+ },
54
+ '& .ss__gallery__counter': {
55
+ color: '#fff',
56
+ marginRight: 'auto',
57
+ padding: '0 8px',
58
+ fontSize: '0.9em',
59
+ },
60
+ '& .ss__gallery__stage': {
61
+ position: 'relative',
62
+ flex: '1 1 auto',
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ justifyContent: 'center',
66
+ overflow: 'hidden',
67
+ },
68
+ '& .ss__gallery__image': {
69
+ maxWidth: '90vw',
70
+ maxHeight: '80vh',
71
+ objectFit: 'contain',
72
+ userSelect: 'none',
73
+ touchAction: 'none',
74
+ transformOrigin: 'center center',
75
+ transition: 'transform 0.05s linear',
76
+ },
77
+ '& .ss__gallery__nav': {
78
+ position: 'absolute',
79
+ top: 0,
80
+ bottom: 0,
81
+ height: '100%',
82
+ width: '64px',
83
+ display: 'flex',
84
+ alignItems: 'center',
85
+ justifyContent: 'center',
86
+ padding: 0,
87
+ boxSizing: 'border-box',
88
+ borderRadius: 0,
89
+ fontSize: '2em',
90
+ lineHeight: 1,
91
+ cursor: 'pointer',
92
+ zIndex: 1,
93
+ '&:hover': {
94
+ // a wash layered via backgroundImage so it composes with (rather than defeats)
95
+ // a backgroundColor set through Button props or theme overrides
96
+ backgroundImage: 'linear-gradient(rgba(255, 255, 255, 0.085), rgba(255, 255, 255, 0.085))',
97
+ },
98
+ },
99
+ '& .ss__gallery__nav--prev': {
100
+ left: 0,
101
+ },
102
+ '& .ss__gallery__nav--next': {
103
+ right: 0,
104
+ },
105
+ });
106
+ };
107
+ exports.Gallery = (0, mobx_react_lite_1.observer)((properties) => {
108
+ const globalTheme = (0, providers_1.useTheme)();
109
+ const globalTreePath = (0, providers_1.useTreePath)();
110
+ const defaultProps = {
111
+ treePath: globalTreePath,
112
+ startIndex: 0,
113
+ zoomMin: 1,
114
+ zoomMax: 4,
115
+ zoomStep: 0.5,
116
+ swipeThreshold: 40,
117
+ };
118
+ const props = (0, utilities_1.mergeProps)('gallery', globalTheme, defaultProps, properties);
119
+ const { images, open, startIndex, onClose, alt, className, internalClassName } = props;
120
+ const zoomMin = props.zoomMin;
121
+ const zoomMax = props.zoomMax;
122
+ const zoomStep = props.zoomStep;
123
+ const swipeThreshold = props.swipeThreshold;
124
+ const clampZoom = (value) => Math.min(zoomMax, Math.max(zoomMin, value));
125
+ const [index, setIndex] = (0, hooks_1.useState)(startIndex || 0);
126
+ const [zoom, setZoom] = (0, hooks_1.useState)(zoomMin);
127
+ const [pan, setPan] = (0, hooks_1.useState)({ x: 0, y: 0 });
128
+ const dragRef = (0, hooks_1.useRef)(null);
129
+ const touchRef = (0, hooks_1.useRef)(null);
130
+ const count = images?.length || 0;
131
+ //initialize lang
132
+ const defaultLang = {
133
+ gallery: {
134
+ attributes: {
135
+ 'aria-label': 'Image gallery',
136
+ },
137
+ },
138
+ zoomOutButton: {
139
+ attributes: {
140
+ 'aria-label': 'Zoom out',
141
+ },
142
+ },
143
+ zoomInButton: {
144
+ attributes: {
145
+ 'aria-label': 'Zoom in',
146
+ },
147
+ },
148
+ closeButton: {
149
+ attributes: {
150
+ 'aria-label': 'Close gallery',
151
+ },
152
+ },
153
+ prevButton: {
154
+ attributes: {
155
+ 'aria-label': 'Previous image',
156
+ },
157
+ },
158
+ nextButton: {
159
+ attributes: {
160
+ 'aria-label': 'Next image',
161
+ },
162
+ },
163
+ };
164
+ //deep merge with props.lang
165
+ const lang = (0, deepmerge_1.default)(defaultLang, props.lang || {});
166
+ const mergedLang = (0, hooks_2.useLang)(lang, {});
167
+ // Reset to the clicked image (and clear zoom/pan) whenever the gallery opens or the start changes.
168
+ (0, hooks_1.useEffect)(() => {
169
+ if (open) {
170
+ setIndex(Math.min(Math.max(startIndex || 0, 0), Math.max(count - 1, 0)));
171
+ setZoom(zoomMin);
172
+ setPan({ x: 0, y: 0 });
173
+ }
174
+ }, [open, startIndex, count]);
175
+ const goTo = (next) => {
176
+ if (count === 0)
177
+ return;
178
+ const wrapped = (next + count) % count;
179
+ setIndex(wrapped);
180
+ setZoom(zoomMin);
181
+ setPan({ x: 0, y: 0 });
182
+ };
183
+ const showPrev = () => goTo(index - 1);
184
+ const showNext = () => goTo(index + 1);
185
+ const zoomIn = () => setZoom((z) => clampZoom(z + zoomStep));
186
+ const zoomOut = () => setZoom((z) => {
187
+ const next = clampZoom(z - zoomStep);
188
+ if (next === zoomMin)
189
+ setPan({ x: 0, y: 0 });
190
+ return next;
191
+ });
192
+ // Keyboard controls while open.
193
+ (0, hooks_1.useEffect)(() => {
194
+ if (!open)
195
+ return;
196
+ const onKey = (e) => {
197
+ switch (e.key) {
198
+ case 'Escape':
199
+ onClose && onClose();
200
+ break;
201
+ case 'ArrowRight':
202
+ showNext();
203
+ break;
204
+ case 'ArrowLeft':
205
+ showPrev();
206
+ break;
207
+ case '+':
208
+ case '=':
209
+ zoomIn();
210
+ break;
211
+ case '-':
212
+ case '_':
213
+ zoomOut();
214
+ break;
215
+ }
216
+ };
217
+ window.addEventListener('keydown', onKey);
218
+ return () => window.removeEventListener('keydown', onKey);
219
+ }, [open, index, count]);
220
+ // Dialog focus management — same pattern as QuickviewModal/QuickviewSlideout:
221
+ // remember what had focus before the gallery opened (the gallery portals to document.body,
222
+ // outside any surrounding focus trap), move focus into the gallery on open, restore on close.
223
+ const rootRef = (0, hooks_1.useRef)(null);
224
+ const previousFocusRef = (0, hooks_1.useRef)(null);
225
+ const wasOpenRef = (0, hooks_1.useRef)(false);
226
+ (0, hooks_1.useEffect)(() => {
227
+ const isOpenNow = Boolean(open && count > 0);
228
+ if (isOpenNow && !wasOpenRef.current) {
229
+ previousFocusRef.current = document.activeElement || null;
230
+ const closeEl = rootRef.current?.querySelector('.ss__gallery__close');
231
+ (closeEl || rootRef.current)?.focus();
232
+ }
233
+ else if (!isOpenNow && wasOpenRef.current) {
234
+ previousFocusRef.current?.focus?.();
235
+ previousFocusRef.current = null;
236
+ }
237
+ wasOpenRef.current = isOpenNow;
238
+ });
239
+ const styling = (0, utilities_1.mergeStyles)(props, defaultStyles);
240
+ if (!open || count === 0)
241
+ return null;
242
+ // Drag-to-pan when zoomed in.
243
+ const onPointerDown = (e) => {
244
+ if (zoom <= zoomMin)
245
+ return;
246
+ // Block the browser defaults (native image drag, text selection) that would cancel the
247
+ // pointermove stream, and capture the pointer so the drag survives leaving the image bounds.
248
+ e.preventDefault();
249
+ e.currentTarget?.setPointerCapture?.(e.pointerId);
250
+ dragRef.current = { startX: e.clientX, startY: e.clientY, baseX: pan.x, baseY: pan.y };
251
+ };
252
+ const onPointerMove = (e) => {
253
+ if (!dragRef.current)
254
+ return;
255
+ setPan({ x: dragRef.current.baseX + (e.clientX - dragRef.current.startX), y: dragRef.current.baseY + (e.clientY - dragRef.current.startY) });
256
+ };
257
+ const endDrag = () => {
258
+ dragRef.current = null;
259
+ };
260
+ // Dismiss when the dark backdrop itself is clicked (not the image or a control). Works on
261
+ // the overlay root and the stage, both of which are `e.currentTarget` only for backdrop hits.
262
+ const onBackdropClick = (e) => {
263
+ if (e.target === e.currentTarget)
264
+ onClose && onClose();
265
+ };
266
+ // Mobile: horizontal touch-swipe paginates (only when not zoomed — zoom uses drag-to-pan).
267
+ const onTouchStart = (e) => {
268
+ if (e.touches && e.touches.length === 1) {
269
+ touchRef.current = { x: e.touches[0].clientX, y: e.touches[0].clientY };
270
+ }
271
+ };
272
+ const onTouchEnd = (e) => {
273
+ const start = touchRef.current;
274
+ touchRef.current = null;
275
+ if (!start || zoom > zoomMin || count <= 1)
276
+ return;
277
+ const touch = e.changedTouches && e.changedTouches[0];
278
+ if (!touch)
279
+ return;
280
+ const dx = touch.clientX - start.x;
281
+ const dy = touch.clientY - start.y;
282
+ // Require a dominantly-horizontal swipe past the threshold.
283
+ if (Math.abs(dx) > swipeThreshold && Math.abs(dx) > Math.abs(dy)) {
284
+ if (dx < 0)
285
+ showNext();
286
+ else
287
+ showPrev();
288
+ }
289
+ };
290
+ const currentSrc = images[index];
291
+ return (0, compat_1.createPortal)((0, jsx_runtime_1.jsx)(providers_1.CacheProvider, { children: (0, jsx_runtime_1.jsxs)("div", { ...styling, className: (0, classnames_1.default)('ss__gallery', className, internalClassName), role: "dialog", "aria-modal": "true", ...mergedLang.gallery?.attributes, ref: (e) => {
292
+ rootRef.current = e;
293
+ (0, hooks_2.useA11y)(e, 0, true, () => onClose && onClose());
294
+ }, onClick: onBackdropClick, children: [(0, jsx_runtime_1.jsxs)("div", { className: "ss__gallery__toolbar", children: [count > 1 && ((0, jsx_runtime_1.jsxs)("span", { className: "ss__gallery__counter", children: [index + 1, " / ", count] })), (0, jsx_runtime_1.jsx)(Button_1.Button, { name: "zoom-out", internalClassName: "ss__gallery__button ss__gallery__zoom-out", color: "#fff", backgroundColor: "rgba(255, 255, 255, 0.12)", borderColor: "transparent", icon: { icon: 'minus', color: 'currentColor' }, lang: { button: lang.zoomOutButton }, disabled: zoom <= zoomMin, onClick: zoomOut, theme: props.theme, treePath: props.treePath, ...(0, utilities_1.defined)({ disableStyles: props.disableStyles }) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { name: "zoom-in", internalClassName: "ss__gallery__button ss__gallery__zoom-in", color: "#fff", backgroundColor: "rgba(255, 255, 255, 0.12)", borderColor: "transparent", icon: { icon: 'plus', color: 'currentColor' }, lang: { button: lang.zoomInButton }, disabled: zoom >= zoomMax, onClick: zoomIn, theme: props.theme, treePath: props.treePath, ...(0, utilities_1.defined)({ disableStyles: props.disableStyles }) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { name: "close", internalClassName: "ss__gallery__button ss__gallery__close", color: "#fff", backgroundColor: "rgba(255, 255, 255, 0.12)", borderColor: "transparent", icon: { icon: 'close', color: 'currentColor' }, lang: { button: lang.closeButton }, onClick: () => onClose && onClose(), theme: props.theme, treePath: props.treePath, ...(0, utilities_1.defined)({ disableStyles: props.disableStyles }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "ss__gallery__stage", onClick: onBackdropClick, onTouchStart: onTouchStart, onTouchEnd: onTouchEnd, children: [count > 1 && ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "prev", internalClassName: "ss__gallery__nav ss__gallery__nav--prev", color: "#fff", backgroundColor: "rgba(255, 255, 255, 0.06)", borderColor: "transparent", icon: { icon: 'angle-left', color: 'currentColor' }, lang: { button: lang.prevButton }, onClick: showPrev, theme: props.theme, treePath: props.treePath, ...(0, utilities_1.defined)({ disableStyles: props.disableStyles }) })), (0, jsx_runtime_1.jsx)(Image_1.Image, { internalClassName: "ss__gallery__image", src: currentSrc, alt: alt || '', draggable: false, style: {
295
+ transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
296
+ cursor: zoom > zoomMin ? (dragRef.current ? 'grabbing' : 'grab') : 'default',
297
+ }, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: endDrag, onPointerLeave: endDrag, theme: props.theme, treePath: props.treePath, ...(0, utilities_1.defined)({ disableStyles: props.disableStyles }) }), count > 1 && ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "next", internalClassName: "ss__gallery__nav ss__gallery__nav--next", color: "#fff", backgroundColor: "rgba(255, 255, 255, 0.06)", borderColor: "transparent", icon: { icon: 'angle-right', color: 'currentColor' }, lang: { button: lang.nextButton }, onClick: showNext, theme: props.theme, treePath: props.treePath, ...(0, utilities_1.defined)({ disableStyles: props.disableStyles }) }))] })] }) }), document.body);
298
+ });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./Gallery"), exports);
@@ -118,11 +118,28 @@ exports.Modal = (0, mobx_react_lite_1.observer)((properties) => {
118
118
  document.body.style.overflow = '';
119
119
  };
120
120
  }, [showContent, lockScroll]);
121
+ // The resize listener below is registered once (on mount), so it must read the open/lock state
122
+ // through refs — capturing `showContent` directly would freeze its mount-time value in the
123
+ // listener closure. The quickview modal mounts open, so that stale `true` would re-lock the
124
+ // page on any resize after the modal was closed.
125
+ const showContentRef = (0, hooks_1.useRef)(showContent);
126
+ const lockScrollRef = (0, hooks_1.useRef)(lockScroll);
127
+ showContentRef.current = showContent;
128
+ lockScrollRef.current = lockScroll;
121
129
  (0, hooks_1.useEffect)(() => {
122
130
  const existingButton = buttonSelector ? (typeof buttonSelector === 'string' ? document.querySelector(buttonSelector) : buttonSelector) : null;
131
+ // Re-asserts the scroll lock after a resize: other components (e.g. Slideout) write
132
+ // `document.body.style.overflow` on render and can clobber the lock while the modal is open.
133
+ // The delay lets those renders settle first; `unmounted` keeps a pending re-lock from firing
134
+ // after cleanup has already released the body.
135
+ let unmounted = false;
136
+ let overflowTimeout;
123
137
  const debouncedHandleResize = (0, snap_toolbox_1.debounce)(() => {
124
- setTimeout(() => {
125
- if (showContent && lockScroll) {
138
+ clearTimeout(overflowTimeout);
139
+ overflowTimeout = setTimeout(() => {
140
+ if (unmounted)
141
+ return;
142
+ if (showContentRef.current && lockScrollRef.current) {
126
143
  document.body.style.overflow = 'hidden';
127
144
  }
128
145
  else {
@@ -141,6 +158,8 @@ exports.Modal = (0, mobx_react_lite_1.observer)((properties) => {
141
158
  }
142
159
  window.addEventListener('resize', debouncedHandleResize);
143
160
  return () => {
161
+ unmounted = true;
162
+ clearTimeout(overflowTimeout);
144
163
  window.removeEventListener('resize', debouncedHandleResize);
145
164
  if (existingButton) {
146
165
  existingButton.removeEventListener('click', clickListener);
@@ -100,7 +100,7 @@ exports.OverlayBadge = (0, mobx_react_lite_1.observer)((properties) => {
100
100
  name: slot.name,
101
101
  top: index == 0,
102
102
  bottom: index == sectionSlots.length - 1,
103
- badges: result?.display.badges?.atLocation(`${section}/${slot.tag}`).slice(0, limit),
103
+ badges: result?.display?.badges?.atLocation(`${section}/${slot.tag}`).slice(0, limit),
104
104
  }))
105
105
  .filter((slot) => slot.badges?.length);
106
106
  return {