@salla.sa/twilight-components 2.14.352 → 2.14.354

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 (325) hide show
  1. package/dist/cjs/bell-ring-BfKPinNo.js +13 -0
  2. package/dist/cjs/{interfaces-CX9-6aLf.js → camera-DytepEoK.js} +0 -11
  3. package/dist/cjs/cancel-De6vslRA.js +13 -0
  4. package/dist/cjs/cart-s-x1Fshk.js +13 -0
  5. package/dist/cjs/check-circle2-BDvlT4_n.js +13 -0
  6. package/dist/cjs/{check-CLRvuniI.js → check-x3w3-gpj.js} +2 -2
  7. package/dist/cjs/{filepond-XtsZ6xtH.js → filepond-CuKErtOy.js} +1 -1
  8. package/dist/cjs/{filepond-plugin-file-poster-Bj84Ypvg.js → filepond-plugin-file-poster-d-8BSuST.js} +1 -1
  9. package/dist/cjs/{filepond-plugin-file-validate-size-aYfb4yYH.js → filepond-plugin-file-validate-size-zgI_JcqY.js} +1 -1
  10. package/dist/cjs/{filepond-plugin-file-validate-type-CJsd6rXl.js → filepond-plugin-file-validate-type-Cy8IgG2P.js} +1 -1
  11. package/dist/cjs/{filepond-plugin-image-edit-DRlBSg36.js → filepond-plugin-image-edit-9ZAUzCvh.js} +1 -1
  12. package/dist/cjs/{filepond-plugin-image-exif-orientation-SY8c6DzI.js → filepond-plugin-image-exif-orientation-DzNe_tY2.js} +1 -1
  13. package/dist/cjs/{filepond-plugin-image-preview-iqhJmUmU.js → filepond-plugin-image-preview-Cfna6xTB.js} +1 -1
  14. package/dist/{esm/gift-C0JNGIpa.js → cjs/gift-CJ-3Yw_x.js} +4 -2
  15. package/dist/cjs/image-BoZ6Hums.js +13 -0
  16. package/dist/cjs/{index-Z-cyrNSM.js → index-Ce40E8tZ.js} +136 -12
  17. package/dist/cjs/{index-C7-280f4.js → index-ff-xJfhj.js} +1 -1
  18. package/dist/cjs/interfaces-CRqrf5RX.js +15 -0
  19. package/dist/cjs/keyboard_arrow_down-DHJ3FFZq.js +13 -0
  20. package/dist/cjs/keyboard_arrow_right-BayM_Il2.js +21 -0
  21. package/dist/cjs/loader.cjs.js +2 -2
  22. package/dist/cjs/minus-CCryh1qf.js +21 -0
  23. package/dist/cjs/salla-accordion-body_3.cjs.entry.js +775 -0
  24. package/dist/cjs/salla-accordion_6.cjs.entry.js +768 -0
  25. package/dist/cjs/salla-add-product-button_4.cjs.entry.js +2389 -0
  26. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-alert_2.cjs.entry.js +194 -0
  28. package/dist/cjs/salla-app-install-alert.cjs.entry.js +8 -3
  29. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  30. package/dist/cjs/salla-booking-field_7.cjs.entry.js +1565 -0
  31. package/dist/cjs/{salla-cart-item-offers.cjs.entry.js → salla-cart-item-offers_2.cjs.entry.js} +104 -5
  32. package/dist/cjs/salla-comment-form_8.cjs.entry.js +1661 -0
  33. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-contacts.cjs.entry.js +3 -3
  35. package/dist/cjs/salla-count-down_2.cjs.entry.js +302 -0
  36. package/dist/cjs/salla-custom-fields.cjs.entry.js +4 -3
  37. package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
  38. package/dist/cjs/salla-filters.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-gifting.cjs.entry.js +488 -0
  40. package/dist/cjs/salla-hook.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-infinite-scroll.cjs.entry.js +91 -0
  42. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  43. package/dist/cjs/salla-list-tile.cjs.entry.js +34 -0
  44. package/dist/cjs/salla-localization-modal.cjs.entry.js +137 -0
  45. package/dist/cjs/salla-login-modal.cjs.entry.js +320 -0
  46. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  47. package/dist/cjs/salla-loyalty-program.cjs.entry.js +3 -3
  48. package/dist/cjs/salla-loyalty.cjs.entry.js +211 -0
  49. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +40 -0
  50. package/dist/cjs/salla-menu.cjs.entry.js +139 -0
  51. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +220 -0
  53. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +598 -0
  54. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +69 -0
  55. package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
  56. package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
  57. package/dist/cjs/salla-offer-modal.cjs.entry.js +206 -0
  58. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  59. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  61. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-order-summary.cjs.entry.js +3 -3
  63. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-placeholder.cjs.entry.js +51 -0
  67. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  68. package/dist/cjs/salla-product-size-guide.cjs.entry.js +66 -0
  69. package/dist/cjs/salla-products-list.cjs.entry.js +762 -0
  70. package/dist/cjs/salla-products-slider.cjs.entry.js +115 -0
  71. package/dist/cjs/salla-progress-bar.cjs.entry.js +73 -0
  72. package/dist/cjs/salla-quick-order.cjs.entry.js +239 -0
  73. package/dist/cjs/salla-rating-modal.cjs.entry.js +453 -0
  74. package/dist/cjs/salla-scopes.cjs.entry.js +180 -0
  75. package/dist/cjs/salla-search.cjs.entry.js +153 -0
  76. package/dist/cjs/salla-skeleton.cjs.entry.js +36 -0
  77. package/dist/cjs/salla-slider.cjs.entry.js +10389 -0
  78. package/dist/cjs/salla-social-share.cjs.entry.js +165 -0
  79. package/dist/cjs/salla-social.cjs.entry.js +3 -3
  80. package/dist/cjs/salla-tab-content_3.cjs.entry.js +157 -0
  81. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  82. package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
  83. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  84. package/dist/cjs/salla-user-menu.cjs.entry.js +275 -0
  85. package/dist/cjs/salla-user-profile.cjs.entry.js +145 -0
  86. package/dist/cjs/salla-user-settings.cjs.entry.js +88 -0
  87. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  88. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  89. package/dist/cjs/search-c7Aa7lM9.js +13 -0
  90. package/dist/cjs/{special-discount-OVG_9Kf9.js → special-discount-DC2oXurL.js} +0 -8
  91. package/dist/cjs/star-DGcH7Yso.js +13 -0
  92. package/dist/cjs/star2-R146a27p.js +13 -0
  93. package/dist/cjs/twilight.cjs.js +2 -2
  94. package/dist/cjs/{vanilla-picker-Dq7F5bE1.js → vanilla-picker-zQsXQIff.js} +1 -1
  95. package/dist/cjs/{whatsapp2-D7Sbg8Ey.js → whatsapp2-BdMd5Gx1.js} +2 -2
  96. package/dist/collection/collection-manifest.json +55 -1
  97. package/dist/collection/components/salla-add-product-button/salla-add-product-button.js +18 -6
  98. package/dist/collection/components/salla-app-install-alert/salla-app-install-alert.js +7 -2
  99. package/dist/collection/components/salla-color-picker/salla-color-picker.js +39 -8
  100. package/dist/collection/components/salla-maintenance-alert/salla-maintenance-alert.js +4 -2
  101. package/dist/collection/components/salla-product-options/salla-product-options.js +36 -3
  102. package/dist/collection/components/salla-products-list/salla-products-list.js +17 -11
  103. package/dist/components/index.js +2 -2
  104. package/dist/components/salla-add-product-button2.js +18 -6
  105. package/dist/components/salla-app-install-alert.js +7 -2
  106. package/dist/components/salla-color-picker2.js +38 -7
  107. package/dist/components/salla-maintenance-alert.js +4 -2
  108. package/dist/components/salla-product-options2.js +19 -2
  109. package/dist/components/salla-products-list2.js +17 -11
  110. package/dist/esm/bell-ring-D3mWkc-3.js +11 -0
  111. package/dist/esm/{interfaces-CBT_Nxny.js → camera-C6jIkM-X.js} +1 -12
  112. package/dist/esm/cancel-BsLF_HK7.js +11 -0
  113. package/dist/esm/cart-DY4LZmNP.js +11 -0
  114. package/dist/esm/{check-uTyAzPSy.js → check-BsXh13x8.js} +2 -2
  115. package/dist/esm/check-circle2-BV4kqbdL.js +11 -0
  116. package/dist/esm/{filepond-Dg4ZKM-u.js → filepond-DEzyRrdH.js} +1 -1
  117. package/dist/esm/{filepond-plugin-file-poster-BUIjdsnA.js → filepond-plugin-file-poster-DyLcCcHM.js} +1 -1
  118. package/dist/esm/{filepond-plugin-file-validate-size-DgZMMqmi.js → filepond-plugin-file-validate-size-Cxp5Yzea.js} +1 -1
  119. package/dist/esm/{filepond-plugin-file-validate-type-DA9tDSFr.js → filepond-plugin-file-validate-type-D2qNOQP4.js} +1 -1
  120. package/dist/esm/{filepond-plugin-image-edit-dotdnN4Z.js → filepond-plugin-image-edit-DndTlA7m.js} +1 -1
  121. package/dist/esm/{filepond-plugin-image-exif-orientation-oSI8aLU-.js → filepond-plugin-image-exif-orientation-CiT1CQoK.js} +1 -1
  122. package/dist/esm/{filepond-plugin-image-preview-DEefQK61.js → filepond-plugin-image-preview-DBG7keFZ.js} +1 -1
  123. package/dist/{cjs/gift-BPDUPIY_.js → esm/gift-BChI23pG.js} +2 -4
  124. package/dist/esm/image-C-tzSDxw.js +11 -0
  125. package/dist/esm/{index-D2-TtAhI.js → index-B74h9G6a.js} +137 -13
  126. package/dist/esm/{index-B7E8Tmgi.js → index-BLw7mdtM.js} +1 -1
  127. package/dist/esm/interfaces-OF8QcbMM.js +15 -0
  128. package/dist/esm/keyboard_arrow_down-DCZbpt2a.js +11 -0
  129. package/dist/esm/keyboard_arrow_right-Vqpj4CWE.js +18 -0
  130. package/dist/esm/loader.js +3 -3
  131. package/dist/esm/minus-DfeagqF1.js +18 -0
  132. package/dist/esm/salla-accordion-body_3.entry.js +771 -0
  133. package/dist/esm/salla-accordion_6.entry.js +761 -0
  134. package/dist/esm/salla-add-product-button_4.entry.js +2384 -0
  135. package/dist/esm/salla-advertisement.entry.js +1 -1
  136. package/dist/esm/salla-alert_2.entry.js +191 -0
  137. package/dist/esm/salla-app-install-alert.entry.js +8 -3
  138. package/dist/esm/salla-apps-icons.entry.js +1 -1
  139. package/dist/esm/salla-booking-field_7.entry.js +1539 -0
  140. package/dist/esm/{salla-cart-item-offers.entry.js → salla-cart-item-offers_2.entry.js} +104 -6
  141. package/dist/esm/salla-comment-form_8.entry.js +1652 -0
  142. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  143. package/dist/esm/salla-contacts.entry.js +3 -3
  144. package/dist/esm/salla-count-down_2.entry.js +299 -0
  145. package/dist/esm/salla-custom-fields.entry.js +3 -2
  146. package/dist/esm/salla-filters-widget.entry.js +1 -1
  147. package/dist/esm/salla-filters.entry.js +1 -1
  148. package/dist/esm/salla-gifting.entry.js +486 -0
  149. package/dist/esm/salla-hook.entry.js +1 -1
  150. package/dist/esm/salla-infinite-scroll.entry.js +89 -0
  151. package/dist/esm/salla-installment.entry.js +1 -1
  152. package/dist/esm/salla-list-tile.entry.js +32 -0
  153. package/dist/esm/salla-localization-modal.entry.js +135 -0
  154. package/dist/esm/salla-login-modal.entry.js +318 -0
  155. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  156. package/dist/esm/salla-loyalty-program.entry.js +3 -3
  157. package/dist/esm/salla-loyalty.entry.js +209 -0
  158. package/dist/esm/salla-maintenance-alert.entry.js +38 -0
  159. package/dist/esm/salla-menu.entry.js +137 -0
  160. package/dist/esm/salla-metadata.entry.js +1 -1
  161. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +217 -0
  162. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +595 -0
  163. package/dist/esm/salla-multiple-bundle-product.entry.js +67 -0
  164. package/dist/esm/salla-notification-item.entry.js +1 -1
  165. package/dist/esm/salla-notifications.entry.js +1 -1
  166. package/dist/esm/salla-offer-modal.entry.js +204 -0
  167. package/dist/esm/salla-offer.entry.js +1 -1
  168. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  169. package/dist/esm/salla-order-details-options.entry.js +1 -1
  170. package/dist/esm/salla-order-details.entry.js +1 -1
  171. package/dist/esm/salla-order-summary.entry.js +3 -3
  172. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  173. package/dist/esm/salla-orders.entry.js +1 -1
  174. package/dist/esm/salla-payments.entry.js +1 -1
  175. package/dist/esm/salla-placeholder.entry.js +49 -0
  176. package/dist/esm/salla-price-range.entry.js +1 -1
  177. package/dist/esm/salla-product-size-guide.entry.js +64 -0
  178. package/dist/esm/salla-products-list.entry.js +760 -0
  179. package/dist/esm/salla-products-slider.entry.js +113 -0
  180. package/dist/esm/salla-progress-bar.entry.js +71 -0
  181. package/dist/esm/salla-quick-order.entry.js +237 -0
  182. package/dist/esm/salla-rating-modal.entry.js +451 -0
  183. package/dist/esm/salla-scopes.entry.js +178 -0
  184. package/dist/esm/salla-search.entry.js +151 -0
  185. package/dist/esm/salla-skeleton.entry.js +34 -0
  186. package/dist/esm/salla-slider.entry.js +10387 -0
  187. package/dist/esm/salla-social-share.entry.js +163 -0
  188. package/dist/esm/salla-social.entry.js +2 -2
  189. package/dist/esm/salla-tab-content_3.entry.js +153 -0
  190. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  191. package/dist/esm/salla-tooltip.entry.js +1 -1
  192. package/dist/esm/salla-trust-badges.entry.js +1 -1
  193. package/dist/esm/salla-user-menu.entry.js +273 -0
  194. package/dist/esm/salla-user-profile.entry.js +143 -0
  195. package/dist/esm/salla-user-settings.entry.js +86 -0
  196. package/dist/esm/salla-verify.entry.js +1 -1
  197. package/dist/esm/salla-wallet.entry.js +1 -1
  198. package/dist/esm/search-BscTeWDc.js +11 -0
  199. package/dist/esm/{special-discount-yRO-ZESF.js → special-discount-Ctkfc4K-.js} +1 -8
  200. package/dist/esm/star-ZT7ehBBk.js +11 -0
  201. package/dist/esm/star2-D4oPi1Ov.js +11 -0
  202. package/dist/esm/twilight.js +3 -3
  203. package/dist/esm/{vanilla-picker-DkUGzUrx.js → vanilla-picker-CtwkXTap.js} +1 -1
  204. package/dist/esm/{whatsapp2-DWksgowB.js → whatsapp2-CgR-T_ZS.js} +2 -2
  205. package/dist/twilight/{p-7b3ca138.entry.js → p-0134b4fd.entry.js} +1 -1
  206. package/dist/twilight/{p-0effc34b.entry.js → p-01daaaa6.entry.js} +1 -1
  207. package/dist/twilight/p-07da7390.entry.js +4 -0
  208. package/dist/twilight/{p-6ce3f119.entry.js → p-08badc32.entry.js} +1 -1
  209. package/dist/twilight/{p-4a594c06.entry.js → p-0aa5a12a.entry.js} +1 -1
  210. package/dist/twilight/{p-e73c28a8.entry.js → p-10dcd981.entry.js} +1 -1
  211. package/dist/twilight/{p-81df7a2e.entry.js → p-212a0710.entry.js} +1 -1
  212. package/dist/twilight/p-229275db.entry.js +4 -0
  213. package/dist/twilight/{p-fea62668.entry.js → p-232185ec.entry.js} +1 -1
  214. package/dist/twilight/{p-e5c01983.entry.js → p-2a927eac.entry.js} +1 -1
  215. package/dist/twilight/p-2d880232.entry.js +4 -0
  216. package/dist/twilight/p-2de9df64.entry.js +4 -0
  217. package/dist/twilight/p-309a0ba4.entry.js +4 -0
  218. package/dist/twilight/{p-6d886b96.entry.js → p-32732ca7.entry.js} +1 -1
  219. package/dist/twilight/{p-9d35196f.entry.js → p-32ca34ec.entry.js} +1 -1
  220. package/dist/twilight/{p-2aa0a4e2.entry.js → p-33093880.entry.js} +1 -1
  221. package/dist/twilight/p-3cffa4c9.entry.js +4 -0
  222. package/dist/twilight/p-3d0bb451.entry.js +4 -0
  223. package/dist/twilight/p-3e0d814c.entry.js +4 -0
  224. package/dist/twilight/p-4036d5dc.entry.js +4 -0
  225. package/dist/twilight/p-40fe4b01.entry.js +4 -0
  226. package/dist/twilight/p-47ac0ca5.entry.js +4 -0
  227. package/dist/twilight/{p-b9d0212c.entry.js → p-4cd9da44.entry.js} +1 -1
  228. package/dist/twilight/p-5c9281d3.entry.js +4 -0
  229. package/dist/twilight/p-5d044466.entry.js +4 -0
  230. package/dist/twilight/p-5d21334a.entry.js +4 -0
  231. package/dist/twilight/{p-e26cc25b.entry.js → p-654429df.entry.js} +1 -1
  232. package/dist/twilight/p-6b8453be.entry.js +4 -0
  233. package/dist/twilight/p-6be7bbb0.entry.js +4 -0
  234. package/dist/twilight/{p-67c327a8.entry.js → p-6c8f5c94.entry.js} +1 -1
  235. package/dist/twilight/{p-9b8f5399.entry.js → p-6fa02770.entry.js} +1 -1
  236. package/dist/twilight/p-7040ea33.entry.js +4 -0
  237. package/dist/twilight/p-8c189d76.entry.js +4 -0
  238. package/dist/twilight/p-8f1f052c.entry.js +4 -0
  239. package/dist/twilight/{p-6b0a03f6.entry.js → p-9051a540.entry.js} +1 -1
  240. package/dist/twilight/p-9f1c561f.entry.js +4 -0
  241. package/dist/twilight/{p-B0ba6Gec.js → p-B69XOH6h.js} +2 -2
  242. package/dist/twilight/{p-D2-TtAhI.js → p-B74h9G6a.js} +2 -2
  243. package/dist/twilight/{p-C0JNGIpa.js → p-BChI23pG.js} +1 -1
  244. package/dist/twilight/{p-DhcC83-2.js → p-BCxm-ISm.js} +1 -1
  245. package/dist/twilight/{p-Cmkcwiop.js → p-BPqZ249Z.js} +1 -1
  246. package/dist/twilight/p-BV4kqbdL.js +4 -0
  247. package/dist/twilight/p-BsLF_HK7.js +4 -0
  248. package/dist/twilight/{p-uTyAzPSy.js → p-BsXh13x8.js} +1 -1
  249. package/dist/twilight/p-BscTeWDc.js +4 -0
  250. package/dist/twilight/p-C-tzSDxw.js +4 -0
  251. package/dist/twilight/p-C6jIkM-X.js +4 -0
  252. package/dist/twilight/p-CO-PeZ27.js +4 -0
  253. package/dist/twilight/{p-DPqkW1aD.js → p-CQq81yb5.js} +2 -2
  254. package/dist/twilight/{p-DWksgowB.js → p-CgR-T_ZS.js} +1 -1
  255. package/dist/twilight/p-Ctkfc4K-.js +4 -0
  256. package/dist/twilight/p-D3mWkc-3.js +4 -0
  257. package/dist/twilight/p-D4oPi1Ov.js +4 -0
  258. package/dist/twilight/p-DCZbpt2a.js +4 -0
  259. package/dist/twilight/p-DY4LZmNP.js +4 -0
  260. package/dist/twilight/p-DfeagqF1.js +4 -0
  261. package/dist/twilight/{p-DJ557xys.js → p-DpsbV3x1.js} +1 -1
  262. package/dist/twilight/p-OF8QcbMM.js +4 -0
  263. package/dist/twilight/p-Vqpj4CWE.js +4 -0
  264. package/dist/twilight/p-ZT7ehBBk.js +4 -0
  265. package/dist/twilight/{p-q-O0srMP.js → p-_-aXm0Wb.js} +1 -1
  266. package/dist/twilight/p-a100bd38.entry.js +4 -0
  267. package/dist/twilight/{p-cf66ab4d.entry.js → p-a2756650.entry.js} +1 -1
  268. package/dist/twilight/{p-b1af2aca.entry.js → p-aab45a16.entry.js} +1 -1
  269. package/dist/twilight/p-aae761ff.entry.js +4 -0
  270. package/dist/twilight/p-afd61e47.entry.js +4 -0
  271. package/dist/twilight/p-b1fc6dfc.entry.js +4 -0
  272. package/dist/twilight/p-b206a0a1.entry.js +4 -0
  273. package/dist/twilight/p-b2332516.entry.js +4 -0
  274. package/dist/twilight/{p-6c2807c8.entry.js → p-b588ef46.entry.js} +1 -1
  275. package/dist/twilight/p-b71fc1b5.entry.js +4 -0
  276. package/dist/twilight/{p-_JhF_Kvb.js → p-bVqtOl1F.js} +1 -1
  277. package/dist/twilight/{p-a858523c.entry.js → p-bf65b263.entry.js} +1 -1
  278. package/dist/twilight/{p-d4faa0f6.entry.js → p-c56a47b0.entry.js} +1 -1
  279. package/dist/twilight/p-c73189e3.entry.js +4 -0
  280. package/dist/twilight/p-d1203242.entry.js +4 -0
  281. package/dist/twilight/p-d4edfed4.entry.js +4 -0
  282. package/dist/twilight/{p-f6ffc708.entry.js → p-d86ce978.entry.js} +1 -1
  283. package/dist/twilight/{p-8e7fa4a9.entry.js → p-d9e7973d.entry.js} +1 -1
  284. package/dist/twilight/p-e3e33238.entry.js +4 -0
  285. package/dist/twilight/p-e6bb7362.entry.js +4 -0
  286. package/dist/twilight/{p-30403778.entry.js → p-e7813c80.entry.js} +1 -1
  287. package/dist/twilight/p-ec2fd37e.entry.js +4 -0
  288. package/dist/twilight/{p-ed60a726.entry.js → p-ec77c523.entry.js} +1 -1
  289. package/dist/twilight/{p-b208650b.entry.js → p-efc18ce6.entry.js} +1 -1
  290. package/dist/twilight/p-f4039c40.entry.js +4 -0
  291. package/dist/twilight/p-f47b130c.entry.js +4 -0
  292. package/dist/twilight/{p-db526796.entry.js → p-f57ca123.entry.js} +1 -1
  293. package/dist/twilight/{p-933881d3.entry.js → p-f5ad6572.entry.js} +1 -1
  294. package/dist/twilight/p-fc65084f.entry.js +4 -0
  295. package/dist/twilight/p-fd81a311.entry.js +4 -0
  296. package/dist/twilight/{p-9fa5ffcf.entry.js → p-fe983809.entry.js} +1 -1
  297. package/dist/twilight/{p-Czq4p9Qp.js → p-i5J7XGS6.js} +1 -1
  298. package/dist/twilight/{p-C2bMx7q5.js → p-shFpk0H3.js} +1 -1
  299. package/dist/twilight/twilight.esm.js +1 -1
  300. package/dist/types/components/salla-add-product-button/salla-add-product-button.d.ts +5 -0
  301. package/dist/types/components/salla-app-install-alert/salla-app-install-alert.d.ts +3 -1
  302. package/dist/types/components/salla-color-picker/salla-color-picker.d.ts +10 -0
  303. package/dist/types/components/salla-product-options/salla-product-options.d.ts +8 -1
  304. package/dist/types/components/salla-products-list/salla-products-list.d.ts +2 -0
  305. package/dist/types/components.d.ts +4 -0
  306. package/package.json +5 -5
  307. package/dist/cjs/salla-accordion_62.cjs.entry.js +0 -22420
  308. package/dist/cjs/salla-review-card.cjs.entry.js +0 -183
  309. package/dist/cjs/salla-reviews-page.cjs.entry.js +0 -695
  310. package/dist/cjs/salla-reviews.cjs.entry.js +0 -106
  311. package/dist/esm/salla-accordion_62.entry.js +0 -22339
  312. package/dist/esm/salla-review-card.entry.js +0 -181
  313. package/dist/esm/salla-reviews-page.entry.js +0 -693
  314. package/dist/esm/salla-reviews.entry.js +0 -104
  315. package/dist/twilight/p-01bccbf2.entry.js +0 -4
  316. package/dist/twilight/p-22d83528.entry.js +0 -4
  317. package/dist/twilight/p-3a74b551.entry.js +0 -4
  318. package/dist/twilight/p-4e416704.entry.js +0 -4
  319. package/dist/twilight/p-5dbf4cec.entry.js +0 -4
  320. package/dist/twilight/p-CBT_Nxny.js +0 -4
  321. package/dist/twilight/p-Dz7o69vX.js +0 -4
  322. package/dist/twilight/p-a42d626d.entry.js +0 -4
  323. package/dist/twilight/p-yRO-ZESF.js +0 -4
  324. package/dist/cjs/{twitter-pOrUNjXi.js → facebook-DbXua6B9.js} +2 -2
  325. package/dist/esm/{twitter-Dz7o69vX.js → facebook-CO-PeZ27.js} +2 -2
@@ -0,0 +1,1652 @@
1
+ /*!
2
+ * Crafted with ❤ by Salla
3
+ */
4
+ import { r as registerInstance, h, H as Host, a as getElement, f as require_root, i as requireIsObject, j as requireIsSymbol, d as getDefaultExportFromCjs } from './index-B74h9G6a.js';
5
+ import { i as iconCheck } from './check-BsXh13x8.js';
6
+ import { a as anime } from './anime.es-CgtvEd63.js';
7
+ import { H as Helper } from './Helper-B5RLi6Xo.js';
8
+ import { S as Star } from './star2-D4oPi1Ov.js';
9
+ import { a as arrowLeft } from './arrow-left-BedNk7k1.js';
10
+ import { S as ShoppingBag } from './shopping-bag-DiKTtDW5.js';
11
+
12
+ const sallaCommentFormCss = ":host{display:block}";
13
+
14
+ const SallaCommentForm = class {
15
+ constructor(hostRef) {
16
+ registerInstance(this, hostRef);
17
+ this.placeholder = salla.lang.get('blocks.comments.placeholder');
18
+ this.submitText = salla.lang.get('blocks.comments.submit');
19
+ salla.lang.onLoaded(() => {
20
+ this.placeholder = salla.lang.get('blocks.comments.placeholder');
21
+ this.submitText = salla.lang.get('blocks.comments.submit');
22
+ });
23
+ salla.onReady(() => {
24
+ this.canComment = salla.config.get('user.can_comment');
25
+ this.itemId = salla.config.get('page.id');
26
+ this.type = salla.url.is_page('page-single') ? 'page' : salla.url.is_page('blog.single') ? 'blog' : 'product';
27
+ });
28
+ }
29
+ submit() {
30
+ if (!this.commentForm.reportValidity()) {
31
+ salla.log('CommentForm:: validation error!');
32
+ return;
33
+ }
34
+ this.submitBtn.load()
35
+ .then(() => salla.comment.add({ id: this.itemId, comment: this.commentField.value, type: this.type }))
36
+ .finally(() => this.submitBtn.stop);
37
+ }
38
+ render() {
39
+ return (h(Host, { key: 'fbea28507c188a338ee066b5198bcf93de2fbda2' }, !!this.canComment ? h("form", { ref: frm => this.commentForm = frm }, h("div", { class: "s-comment-form-wrapper" }, this.showAvatar ?
40
+ h("img", { class: "s-comment-form-avatar", src: salla.config.get('user.avatar'), alt: "user avatar" }) : '', h("div", { class: "s-comment-form-content" }, h("textarea", { cols: 30, rows: 5, minlength: "4", maxlength: "500", ref: field => this.commentField = field, placeholder: this.placeholder, class: "s-comment-form-input", required: true }), h("br", null), h("div", { class: "s-comment-form-action" }, h("salla-button", { ref: btn => this.submitBtn = btn, "loader-position": 'center', onClick: () => this.submit() }, this.submitText))))) : ''));
41
+ }
42
+ };
43
+ SallaCommentForm.style = sallaCommentFormCss;
44
+
45
+ var Reply = `<!-- Generated by IcoMoon.io -->
46
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
47
+ <title>reply</title>
48
+ <path d="M20 14.667h-12.609l9.401-6.927c0.592-0.436 0.72-1.271 0.283-1.863-0.439-0.595-1.273-0.72-1.864-0.283l-12.667 9.333c-0.343 0.251-0.544 0.649-0.544 1.072s0.201 0.821 0.543 1.073l12.667 9.333c0.237 0.176 0.515 0.26 0.789 0.26 0.409 0 0.813-0.188 1.075-0.543 0.437-0.592 0.309-1.427-0.283-1.863l-9.4-6.928h12.609c4.412 0 8 3.588 8 8 0 0.737 0.597 1.333 1.333 1.333s1.333-0.596 1.333-1.333c0-5.881-4.785-10.667-10.667-10.667z"></path>
49
+ </svg>
50
+ `;
51
+
52
+ var ThumbsUp = `<!-- Generated by IcoMoon.io -->
53
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
54
+ <title>thumbs-up</title>
55
+ <path d="M26.667 10.667h-8.261l1.279-3.38c0.723-1.911 0.087-4.051-1.549-5.203-0.909-0.639-2.004-0.881-3.085-0.684-1.101 0.203-2.061 0.837-2.703 1.787l-5.452 8.067c-0.148 0.22-0.228 0.48-0.228 0.747v12c0 3.676 2.991 6.667 6.667 6.667h8.688c2.535 0 4.817-1.407 5.955-3.671l2.548-5.063c0.093-0.187 0.143-0.392 0.143-0.6v-6.667c0-2.205-1.795-4-4-4zM28 21.017l-2.405 4.78c-0.683 1.359-2.052 2.203-3.573 2.203h-8.688c-2.205 0-4-1.795-4-4v-11.592l5.223-7.728c0.237-0.352 0.584-0.585 0.975-0.657 0.367-0.067 0.749 0.017 1.068 0.241 0.631 0.444 0.879 1.317 0.591 2.079l-1.963 5.185c-0.156 0.409-0.099 0.869 0.149 1.229s0.66 0.576 1.099 0.576h10.192c0.735 0 1.333 0.599 1.333 1.333zM2.667 10.667c-0.736 0-1.333 0.597-1.333 1.333v16c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-16c0-0.736-0.597-1.333-1.333-1.333z"></path>
56
+ </svg>
57
+ `;
58
+
59
+ const sallaCommentsCss$1 = ":host{display:block}";
60
+
61
+ const SallaCommentItem = class {
62
+ constructor(hostRef) {
63
+ registerInstance(this, hostRef);
64
+ // Translations
65
+ this.has_bought_trans = salla.lang.get('blocks.comments.has_bought');
66
+ this.rated_trans = salla.lang.get('pages.rating.rated');
67
+ this.waiting_approval_trans = salla.lang.get('blocks.comments.waiting_approval');
68
+ this.has_order_trans = salla.lang.get('blocks.comments.has_order');
69
+ this.allowLikes = salla.config.get('store.settings.rating.allow_likes');
70
+ this.allowAttachImages = salla.config.get('store.settings.rating.allow_attach_images');
71
+ this.helpfulLabel = salla.lang.getWithDefault('blocks.comments.helpful', 'مفيد');
72
+ this.likesCount = 0;
73
+ this.likedComments = [];
74
+ salla.lang.onLoaded(() => {
75
+ const setNestedAsync = (lang, key, value) => {
76
+ return new Promise((resolve) => {
77
+ salla.helpers.setNested(salla.lang.messages[lang], key, value);
78
+ resolve(true);
79
+ });
80
+ };
81
+ const setTranslations = async () => {
82
+ await setNestedAsync('ar.trans', 'blocks.comments.helpful', 'مفيد');
83
+ await setNestedAsync('en.trans', 'blocks.comments.helpful', 'Helpful');
84
+ this.helpfulLabel = salla.lang.getWithDefault('blocks.comments.helpful', 'مفيد');
85
+ };
86
+ this.has_bought_trans = salla.lang.get('blocks.comments.has_bought');
87
+ this.rated_trans = salla.lang.get('pages.rating.rated');
88
+ this.waiting_approval_trans = salla.lang.get('blocks.comments.waiting_approval');
89
+ this.has_order_trans = salla.lang.get('blocks.comments.has_order');
90
+ setTranslations();
91
+ });
92
+ }
93
+ componentDidLoad() {
94
+ this.likesCount = this.comment.likes_count;
95
+ try {
96
+ this.likedComments = JSON.parse(localStorage.getItem('liked_comments') || '[]');
97
+ if (this.likedComments.includes(this.comment.id)) {
98
+ this.likeBtn.classList.add('liked');
99
+ this.likeBtn.fill = "solid";
100
+ }
101
+ }
102
+ catch {
103
+ salla.log('Bad json for liked_comments');
104
+ }
105
+ }
106
+ getReplies() {
107
+ return Array.isArray(this.comment.replies) ? this.comment.replies : [this.comment.replies];
108
+ }
109
+ getDate(dateString) {
110
+ const [datePart] = dateString.split(' ');
111
+ const [year, month, day] = datePart.split('-');
112
+ const formattedDate = `${parseInt(day, 10)}/${parseInt(month, 10)}/${parseInt(year, 10)}`;
113
+ return formattedDate;
114
+ }
115
+ getTime(dateString) {
116
+ const [, timePart] = dateString.split(' ');
117
+ const [hours, minutes] = timePart.split(':');
118
+ const formattedTime = `${parseInt(hours, 10)}:${parseInt(minutes, 10)}`;
119
+ return formattedTime;
120
+ }
121
+ async toggleLike() {
122
+ if (salla.config.isGuest()) {
123
+ return salla.notify.error(salla.lang.get('common.messages.must_login'));
124
+ }
125
+ this.likedComments = JSON.parse(localStorage.getItem('liked_comments') || '[]');
126
+ const isLiked = this.likedComments.includes(this.comment.id);
127
+ try {
128
+ const endpoint = isLiked ? `rating/${this.comment.id}/unlike` : `rating/${this.comment.id}/like`;
129
+ const res = await salla.api.request(endpoint, '', 'put');
130
+ salla.log(res.message);
131
+ if (isLiked) {
132
+ this.likeBtn.classList.remove('liked');
133
+ this.likeBtn.fill = 'outline';
134
+ this.updateLikedComments(this.comment.id, false);
135
+ this.likesCount--;
136
+ }
137
+ else {
138
+ this.likeBtn.classList.add('liked');
139
+ this.likeBtn.fill = 'solid';
140
+ this.updateLikedComments(this.comment.id, true);
141
+ this.likesCount++;
142
+ }
143
+ }
144
+ catch (e) {
145
+ if (e.response.status == 409) {
146
+ if (this.likeBtn.classList.contains('liked')) {
147
+ this.likeBtn.fill = 'outline';
148
+ this.likeBtn.classList.remove('liked');
149
+ this.updateLikedComments(this.comment.id, false);
150
+ this.likesCount--;
151
+ }
152
+ else {
153
+ this.likeBtn.fill = 'solid';
154
+ this.likeBtn.classList.add('liked');
155
+ salla.logger.warn('Like already exists');
156
+ this.updateLikedComments(this.comment.id, true);
157
+ }
158
+ }
159
+ }
160
+ }
161
+ updateLikedComments(commentId, add) {
162
+ this.likedComments = JSON.parse(localStorage.getItem('liked_comments') || '[]');
163
+ if (add) {
164
+ if (!this.likedComments.includes(commentId)) {
165
+ this.likedComments.push(commentId);
166
+ }
167
+ }
168
+ else {
169
+ this.likedComments = this.likedComments.filter(id => id !== commentId);
170
+ }
171
+ localStorage.setItem('liked_comments', JSON.stringify(this.likedComments));
172
+ }
173
+ PinnedIcon() {
174
+ return (h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "16", height: "16", color: "#555555", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M12 16V21" }), h("path", { d: "M8 5.2918C8 5.02079 8 4.88529 8.01312 4.77132C8.1194 3.84789 8.84789 3.1194 9.77133 3.01312C9.88529 3 10.0208 3 10.2918 3H13.7082C13.9792 3 14.1147 3 14.2287 3.01312C15.1521 3.1194 15.8806 3.84789 15.9869 4.77132C16 4.88529 16 5.02079 16 5.2918C16 5.37885 16 5.42237 15.9967 5.46264C15.9708 5.78281 15.7927 6.07104 15.5179 6.2374C15.4834 6.25832 15.4444 6.27779 15.3666 6.31672L15.1055 6.44726C14.7021 6.64897 14.5003 6.74983 14.3681 6.90564C14.26 7.03286 14.1856 7.18509 14.1515 7.34846C14.1097 7.54854 14.1539 7.76968 14.2424 8.21197L15 12H15.3333C15.9533 12 16.2633 12 16.5176 12.0681C17.2078 12.2531 17.7469 12.7922 17.9319 13.4824C18 13.7367 18 14.0467 18 14.6667C18 14.9767 18 15.1317 17.9659 15.2588C17.8735 15.6039 17.6039 15.8735 17.2588 15.9659C17.1317 16 16.9767 16 16.6667 16H7.33333C7.02334 16 6.86835 16 6.74118 15.9659C6.39609 15.8735 6.12654 15.6039 6.03407 15.2588C6 15.1317 6 14.9767 6 14.6667C6 14.0467 6 13.7367 6.06815 13.4824C6.25308 12.7922 6.79218 12.2531 7.48236 12.0681C7.73669 12 8.04669 12 8.66667 12H9L9.75761 8.21197C9.84606 7.76968 9.89029 7.54854 9.84852 7.34846C9.81441 7.18509 9.73995 7.03286 9.63194 6.90564C9.49965 6.74983 9.29794 6.64897 8.89452 6.44726L8.63344 6.31672C8.55558 6.27779 8.51665 6.25832 8.48208 6.2374C8.20731 6.07104 8.02917 5.78281 8.00326 5.46264C8 5.42237 8 5.37885 8 5.2918Z" })));
175
+ }
176
+ render() {
177
+ let isAdmin = this.comment.type == 'admin';
178
+ return (h(Host, { key: '05979122884df06d634ab4f75f61d12cee93b228', class: isAdmin ? 's-comments-item-admin' : 's-comments-item' }, h("div", { key: 'd3be984afb159d8d6a1d4c0daf0bb72c97136a3a', class: { "s-comments-item-wrapper": !isAdmin, "s-comments-item-admin-wrapper": isAdmin }, id: `s-comments-item-${this.comment.id}` }, h("div", { key: '29a48174434b634e4afa5a1f2339b04705ea9f90', class: "s-comments-item-inner s-comments-flex-1" }, isAdmin && h("span", { key: 'b2536843c0549b2eb24759a09f51a97b68e36654', class: "s-comments-item-reply-icon", innerHTML: Reply }), h("div", { key: '553ad8fd8a3ada5cbca3c744f8b80a259ae7d2c2', class: "s-comments-item-avatar" }, h("img", { key: '57d429fa1dc545d3fe16c1f4713b960d1d7ef9f8', "data-src": this.comment?.avatar, alt: this.comment?.name, src: this.comment?.avatar, class: "s-comments-item-avatar-img lazy" })), h("div", { key: '8b2a3206dfa97c41a731baf18794e44ce096876f', class: "s-comments-flex-1" }, h("div", { key: '95ebefb4d82bb66d7cbc567554d0b9da2e4b416a', class: "s-comments-item-user-wrapper" }, h("div", { key: '1e6091d08973e5fc2ae8a982e6b09e5d349fede3', class: "s-comments-item-user-info" }, h("h3", { key: 'ee5ea0ea457fc43ee49cae033097297ab8358f76', class: this.comment.is_pinned ? "s-comments-item-user-info-name" : "s-comments-item-user-info-name-with-margin" }, this.comment?.name), this.comment.is_pinned ?
179
+ h("div", { class: "s-comments-item-pinned-icon-with-margin" }, this.PinnedIcon())
180
+ : null, (this.comment.has_order || !!this.comment.rating) && !this.comment.is_pending && !this.hideBought ?
181
+ h("div", { class: "s-comments-flex" }, this.comment.has_order ?
182
+ [h("span", { class: "s-comments-item-has-order-check-icon", innerHTML: iconCheck }), h("span", { class: "s-comments-item-has-order-check-text" }, this.has_bought_trans, " ", this.comment.rating ? ', ' : '')] : null, !!this.comment.rating ?
183
+ h("span", { class: "s-comments-item-rated-widget" }, this.rated_trans) : null)
184
+ : null), h("p", { key: '80c430d77b6ae3e959db9bc089fd7fe834e56bd2', class: "s-comments-item-timestamp s-ltr" }, this.getDate(this.comment.created_at?.date), h("span", { key: '49a1b26309490d6252f0fbd53b50374cbf10071d', class: "s-comments-item-time" }, " - ", this.getTime(this.comment.created_at?.date))), !!this.comment.rating || !!this.comment.stars ?
185
+ h("salla-rating-stars", { size: "mini", class: "s-comments-item-stars", value: this.comment.rating || this.comment.stars })
186
+ : null), h("div", { key: '780bee1166000b296e6956921c71cfd4f48e8153', class: "s-comments-item-content" }, h("p", { key: '9ff2a32cbd551ff911300ce6cfa1065770117a18', innerHTML: this.comment.content }), this.allowAttachImages && h("div", { key: 'f47022f4916c3d4e0641273612b4a5f7c69a4595', class: "s-comments-item-images" }, this.comment.images.map((image, index) => (h("img", { key: index, src: image, alt: "", onClick: () => this.modal.open() }))), h("salla-modal", { key: '8e70ec00301d369bbed5c1f11a1887a0498e2b0c', ref: modal => this.modal = modal, width: "sm" }, h("salla-slider", { key: '65cb35fd60869f64780fbb5bfc61fbc3cddc49c9', id: `s-comments-item-${this.comment.id}-images`, class: "s-comments-item-images-slider", type: "thumbs", "auto-height": true, showControls: this.comment.images.length > 1 ? true : false, "show-thumbs-controls": "false" }, h("div", { key: 'bb0cf465f99ecfe9ee10dfb96949cd7b5793da90', slot: 'items' }, this.comment.images.map((image, index) => (h("img", { key: index, src: image, alt: "" })))), h("div", { key: 'e195759f1df5a87b761478ac4a379411f284785c', slot: "thumbs" }, this.comment.images.map((image, index) => (h("div", { class: "s-comments-item-images-slider-thumb" }, h("img", { key: index, src: image, alt: "" })))))))), this.allowLikes && !isAdmin && salla.url.is_page('product.single') ? h("salla-button", { ref: el => this.likeBtn = el, class: `s-comments-item-like-btn ${this.likedComments.includes(this.comment.id) ? 'liked' : ''}`, loaderPosition: 'center', fill: 'outline', size: 'small', onClick: () => this.toggleLike() }, h("span", null, this.helpfulLabel, " ", this.likesCount > 0 ? `(${this.likesCount})` : ''), h("span", { innerHTML: ThumbsUp })) : '', this.comment.is_pending ?
187
+ h("span", { class: "s-comments-item-pending-text" }, this.waiting_approval_trans) : null))), !!this.getReplies().length && !isAdmin ?
188
+ this.getReplies().map((reply) => {
189
+ return h("div", null, h("salla-comment-item", { comment: reply }));
190
+ }) : null)));
191
+ }
192
+ get host() { return getElement(this); }
193
+ };
194
+ SallaCommentItem.style = sallaCommentsCss$1;
195
+
196
+ var CommentType;
197
+ (function (CommentType) {
198
+ CommentType["PAGE"] = "page";
199
+ CommentType["PRODUCT"] = "product";
200
+ CommentType["BLOG"] = "blog";
201
+ })(CommentType || (CommentType = {}));
202
+
203
+ var ChatBubbles = `<!-- Generated by IcoMoon.io -->
204
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
205
+ <title>chat-bubbles</title>
206
+ <path d="M15.333 17.333c4.779 0 8.667-3.888 8.667-8.667s-3.888-8.667-8.667-8.667h-6.667c-4.779 0-8.667 3.888-8.667 8.667 0 2.985 1.513 5.712 4 7.297v4.703c0 0.497 0.277 0.953 0.717 1.183 0.195 0.1 0.405 0.151 0.616 0.151 0.269 0 0.536-0.081 0.764-0.241l6.323-4.425zM11.236 14.908l-4.569 3.199v-2.913c0-0.5-0.28-0.959-0.725-1.187-2.020-1.035-3.275-3.080-3.275-5.34 0-3.308 2.692-6 6-6h6.667c3.308 0 6 2.692 6 6s-2.692 6-6 6h-3.333c-0.273 0-0.54 0.084-0.764 0.241zM29.196 12.964c-0.543-0.5-1.388-0.464-1.884 0.077-0.5 0.541-0.465 1.385 0.077 1.884 1.253 1.156 1.944 2.72 1.944 4.408 0 2.26-1.255 4.305-3.275 5.339-0.445 0.228-0.725 0.687-0.725 1.188v2.572l-5.441-2.939c-0.195-0.104-0.412-0.16-0.633-0.16h-2.592c-1.688 0-3.309-0.724-4.451-1.988-0.492-0.545-1.335-0.591-1.883-0.096-0.547 0.493-0.589 1.336-0.096 1.883 1.644 1.823 3.988 2.868 6.429 2.868h2.255l7.111 3.84c0.199 0.107 0.417 0.16 0.635 0.16 0.236 0 0.472-0.063 0.683-0.188 0.404-0.241 0.651-0.676 0.651-1.145v-4.036c2.487-1.585 4-4.311 4-7.297 0-2.407-1.023-4.727-2.804-6.369z"></path>
207
+ </svg>
208
+ `;
209
+
210
+ const sallaCommentsCss = ":host{display:block}";
211
+
212
+ const SallaComments = class {
213
+ constructor(hostRef) {
214
+ registerInstance(this, hostRef);
215
+ /**
216
+ * Comment Type
217
+ */
218
+ this.type = CommentType.PAGE;
219
+ /**
220
+ * Show or hide avatar
221
+ */
222
+ this.showFormAvatar = false;
223
+ /**
224
+ * Hide Bought
225
+ */
226
+ this.hideBought = false;
227
+ /**
228
+ * Determines if the comments are testimonials
229
+ */
230
+ this.testimonials = false;
231
+ // Translations
232
+ this.noComments = salla.lang.get('blocks.comments.no_comments');
233
+ this.comment_title = salla.lang.get('blocks.comments.title');
234
+ this.comment_name = salla.lang.get('blocks.comments.comment');
235
+ this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
236
+ this.allowLikes = salla.config.get('store.settings.rating.allow_likes');
237
+ salla.onReady(() => {
238
+ this.allowLikes = salla.config.get('store.settings.rating.allow_likes');
239
+ this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
240
+ });
241
+ salla.lang.onLoaded(() => {
242
+ this.comment_title = salla.lang.get('blocks.comments.title');
243
+ this.comment_name = salla.lang.get('blocks.comments.comment');
244
+ this.noComments = salla.lang.get('pages.rating.no_ratings');
245
+ const setNestedAsync = (lang, key, value) => {
246
+ return new Promise((resolve) => {
247
+ salla.helpers.setNested(salla.lang.messages[lang], key, value);
248
+ resolve(true);
249
+ });
250
+ };
251
+ const setTranslations = async () => {
252
+ await setNestedAsync('ar.trans', 'blocks.comments.most_helpful', 'الأكثر إفادة');
253
+ await setNestedAsync('en.trans', 'blocks.comments.most_helpful', 'Most helpful');
254
+ this.mostHelpfulLabel = salla.lang.get('blocks.comments.most_helpful');
255
+ this.comment_title = salla.lang.get('blocks.comments.title');
256
+ this.comment_name = salla.lang.get('blocks.comments.comment');
257
+ this.noComments = salla.lang.get('pages.rating.no_ratings');
258
+ };
259
+ setTranslations();
260
+ });
261
+ }
262
+ // TOOD: it's a good idea to move this into lang.js
263
+ // Pluralize a string based on the count
264
+ pluralize(phrases, count) {
265
+ const options = phrases.split('|');
266
+ const conditions = [
267
+ { condition: count === 0, index: 0 },
268
+ { condition: count === 1, index: 1 },
269
+ { condition: count === 2, index: 2 },
270
+ { condition: count > 2 && count <= 10, index: 3 },
271
+ { condition: count >= 11, index: 4 }
272
+ ];
273
+ const { index } = conditions.find(({ condition }) => condition) || { index: options.length - 1 };
274
+ const selectedOption = options[index];
275
+ return selectedOption.replace(':count', salla.helpers.number(count.toString()))
276
+ .replace(/\{[0-9]+\}/g, '')
277
+ .replace(/\[\d+,\d+\]|\[11,\*\]/g, '');
278
+ }
279
+ wrapConsoleError() {
280
+ if (Salla.infiniteScroll.errorWrapped) {
281
+ return;
282
+ }
283
+ (() => {
284
+ const orig = console.error.bind(console);
285
+ console.error = (...args) => {
286
+ const msg = args[0];
287
+ // only rewrite the noisy one
288
+ if (typeof msg === 'string' && msg.toLowerCase().replace(/\s/g, '').includes('infinitescroll')) {
289
+ return console.log(...args); // downgrade to log
290
+ }
291
+ return orig(...args); // keep real errors
292
+ };
293
+ })();
294
+ Salla.infiniteScroll.errorWrapped = true;
295
+ }
296
+ // Initiate infinite scroll
297
+ initiateInfiniteScroll() {
298
+ if (!this.wrapper) {
299
+ console.error('Wrapper is undefined. Cannot initiate infinite scroll.');
300
+ return;
301
+ }
302
+ this.wrapConsoleError();
303
+ this.infiniteScroll = salla.infiniteScroll.initiate(this.wrapper, this.wrapper, {
304
+ path: () => this.nextPage,
305
+ history: false,
306
+ nextPage: this.nextPage,
307
+ scrollThreshold: false,
308
+ }, true);
309
+ this.infiniteScroll?.on('request', _response => {
310
+ this.loading();
311
+ });
312
+ this.infiniteScroll?.on('load', response => {
313
+ this.pagination = response.pagination;
314
+ this.nextPage = typeof response.pagination.links === 'object' && !!response.pagination.links.next ? response.pagination.links.next : null;
315
+ for (const card of this.handleResponse(response)) {
316
+ this.wrapper.append(card);
317
+ }
318
+ const items = this.host.querySelectorAll('salla-comment-item:not(.animated):not(.s-comments-item-admin)');
319
+ this.animateItems(items);
320
+ this.loading(false);
321
+ });
322
+ this.infiniteScroll?.on('error', (e) => {
323
+ salla.console.error('Error loading more comments:', e);
324
+ });
325
+ }
326
+ // Show/hide loading
327
+ loading(isLoading = true) {
328
+ const btnText = this.status?.querySelector('.s-button-text');
329
+ if (btnText) {
330
+ Helper.toggleElementClassIf(btnText, 's-button-hide', 's-button-show', () => isLoading);
331
+ this.btnLoader.style.display = isLoading ? 'inherit' : 'none';
332
+ }
333
+ }
334
+ // Animate newly added items
335
+ animateItems(items) {
336
+ anime({
337
+ targets: items,
338
+ opacity: [0, 1],
339
+ duration: 1200,
340
+ translateY: [20, 0],
341
+ delay: (_el, i) => i * 100,
342
+ easing: 'easeOutExpo',
343
+ complete: (_anim) => {
344
+ for (const item of items) {
345
+ item.classList.add('animated');
346
+ }
347
+ }
348
+ });
349
+ }
350
+ /**
351
+ * Reloads the comments data from the server
352
+ */
353
+ async reload() {
354
+ this.showPlaceholder = false;
355
+ if (this.wrapper) {
356
+ this.wrapper.innerHTML = "";
357
+ const loading = document.createElement('salla-loading');
358
+ this.wrapper.append(loading);
359
+ }
360
+ this.nextPage = null;
361
+ this.loadInitialData();
362
+ }
363
+ // Get comment item HTML
364
+ getCommentHTML(comment) {
365
+ const commentItem = document.createElement('salla-comment-item');
366
+ commentItem.comment = comment;
367
+ commentItem.hideBought = this.hideBought;
368
+ return commentItem;
369
+ }
370
+ // Parse response and return an array of comment items to be appended to the wrapper
371
+ handleResponse(response) {
372
+ return response.data?.map(comment => this.getCommentHTML(comment)) || [];
373
+ }
374
+ componentWillLoad() {
375
+ return salla.onReady()
376
+ .then(() => {
377
+ this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
378
+ })
379
+ .then(() => this.loading())
380
+ .then(() => {
381
+ this.hideTitle = this.hideTitle || this.testimonials;
382
+ this.hideForm = this.hideForm || this.testimonials;
383
+ return this.loadInitialData();
384
+ });
385
+ }
386
+ // Load initial data
387
+ async loadInitialData() {
388
+ try {
389
+ let resp = { data: [], pagination: {} };
390
+ const searchParams = new URLSearchParams(window.location.search);
391
+ if (searchParams.has('sort')) {
392
+ this.sort = searchParams.get('sort');
393
+ }
394
+ if (this.testimonials) {
395
+ const params = {
396
+ sort: this.sort,
397
+ type: "store"
398
+ };
399
+ resp = await salla.api.request('reviews', { params }, 'get');
400
+ }
401
+ else {
402
+ // Ensure sort is passed for regular comments as well
403
+ resp = await salla.api.comment.getComments(this.type, this.itemId, 1, 5, this.sort);
404
+ }
405
+ if (!resp.data || !resp.data.length) {
406
+ this.showPlaceholder = false;
407
+ this.loading(false);
408
+ return;
409
+ }
410
+ if (this.wrapper) {
411
+ this.wrapper.innerHTML = "";
412
+ }
413
+ this.comments = resp.data;
414
+ this.pagination = resp.pagination;
415
+ this.total = resp.pagination.total;
416
+ this.nextPage = typeof resp.pagination.links === 'object' && !!resp.pagination.links.next ? resp.pagination.links.next : null;
417
+ // Preserve sort param in next page URL for infinite scroll
418
+ if (this.nextPage && this.sort) {
419
+ try {
420
+ const url = new URL(this.nextPage, window.location.origin);
421
+ if (!url.searchParams.get('sort')) {
422
+ url.searchParams.set('sort', this.sort);
423
+ this.nextPage = url.toString();
424
+ }
425
+ }
426
+ catch (_e) {
427
+ // fallback for relative next links
428
+ const hasQuery = this.nextPage.includes('?');
429
+ const hasSort = /[?&]sort=/.test(this.nextPage);
430
+ if (!hasSort) {
431
+ this.nextPage = this.nextPage + (hasQuery ? '&' : '?') + `sort=${this.sort}`;
432
+ }
433
+ }
434
+ }
435
+ setTimeout(() => {
436
+ for (const card of this.handleResponse(resp)) {
437
+ this.wrapper.append(card);
438
+ }
439
+ this.initiateInfiniteScroll(); // Initiate infinite scroll after the initial data is loaded
440
+ const items = this.wrapper.querySelectorAll('salla-comment-item:not(.animated)');
441
+ this.animateItems(items);
442
+ }, 100);
443
+ }
444
+ catch (error) {
445
+ console.error('Error loading initial data:', error);
446
+ this.showPlaceholder = true;
447
+ this.loading(false);
448
+ }
449
+ }
450
+ // Get next page
451
+ async loadMore() {
452
+ this.infiniteScroll?.loadNextPage();
453
+ }
454
+ render() {
455
+ // We should show a different placeholder for pages and products (WIP)
456
+ if (this.showPlaceholder) {
457
+ return (h("div", null, !!this.total && !this.hideTitle ? h("h2", { class: "s-comments-title" }, this.blockTitle ? this.blockTitle : this.comment_title) : '', !this.hideForm && !this.testimonials ? h("salla-comment-form", { showAvatar: this.showFormAvatar, type: this.type, "item-id": this.itemId }) : '', h("div", { class: "s-comments-placeholder" }, h("span", { innerHTML: ChatBubbles }), h("p", null, this.noComments))));
458
+ }
459
+ return (h("div", { class: `s-comments s-comments-${this.testimonials ? 'testimonials' : this.type}` }, h("div", { class: `${this.type === CommentType.PAGE ? "s-comments-page-container" : "s-comments-container"}` }, !!this.total && !this.hideTitle ? h("h2", { class: "s-comments-title" }, this.blockTitle ? this.blockTitle : this.comment_title) : '', !this.hideForm && h("salla-comment-form", { showAvatar: this.showFormAvatar, type: this.type, "item-id": this.itemId }), salla.url.is_page('product.single') ? h("salla-reviews-summary", { itemId: this.itemId }) : '', h("div", { class: `s-comments-header ${this.total ? "has-total" : ""}` }, !!this.total && h("span", { class: "s-comments-count-label", innerHTML: this.pluralize(this.comment_name, this.total) }), !!this.total && !this.testimonials && this.type !== CommentType.BLOG ?
460
+ h("div", { class: "s-comments-filter-wrapper" }, h("label", { class: "s-comments-filter-label", htmlFor: "comments-filter" }, salla.lang.get('pages.categories.sorting')), h("select", { id: "comments-filter", "aria-label": salla.lang.get('pages.categories.sorting'), class: "s-form-control s-comments-sort-input", onChange: (e) => {
461
+ this.sort = e.target.value;
462
+ this.reload();
463
+ } }, h("option", { value: "latest", selected: true }, salla.lang.get("pages.testimonials.sort_by_date_desc")), h("option", { value: "oldest" }, salla.lang.get("pages.testimonials.sort_by_date_asc")), this.allowLikes && h("option", { value: "most_helpful" }, this.mostHelpfulLabel)))
464
+ : ''), h("div", { ref: wrapper => {
465
+ this.wrapper = wrapper;
466
+ } }), this.nextPage && (h("div", { class: "s-infinite-scroll-wrapper", ref: status => {
467
+ this.status = status;
468
+ } }, h("button", { onClick: () => this.loadMore(), class: "s-infinite-scroll-btn s-button-btn s-button-primary", type: "button" }, h("span", { class: "s-button-text s-infinite-scroll-btn-text" }, this.loadMoreText ? this.loadMoreText : salla.lang.get('common.elements.load_more')), h("span", { class: "s-button-loader s-button-loader-center s-infinite-scroll-btn-loader", ref: btnLoader => {
469
+ this.btnLoader = btnLoader;
470
+ }, style: { "display": "none" } })))))));
471
+ }
472
+ get host() { return getElement(this); }
473
+ };
474
+ SallaComments.style = sallaCommentsCss;
475
+
476
+ const sallaRatingStarsCss = "";
477
+
478
+ const SallaRatingStars = class {
479
+ constructor(hostRef) {
480
+ registerInstance(this, hostRef);
481
+ this.translationsLoaded = false;
482
+ this.labels = [];
483
+ this.reviewLabel = '';
484
+ this.selectedStar = 0;
485
+ /**
486
+ * Sets input name.
487
+ */
488
+ this.name = 'rating';
489
+ /**
490
+ * Sets the height and width of the component. Defaults to medium.
491
+ */
492
+ this.size = 'medium';
493
+ /**
494
+ * Number of reviews to display.
495
+ */
496
+ this.reviews = 0;
497
+ /**
498
+ * Allows the rating to be editable.
499
+ */
500
+ this.editable = false;
501
+ }
502
+ async componentWillLoad() {
503
+ await new Promise(resolve => {
504
+ salla.lang.onLoaded(() => {
505
+ this.labels = [
506
+ salla.lang.get('pages.rating.poor'),
507
+ salla.lang.get('pages.rating.average'),
508
+ salla.lang.get('pages.rating.good'),
509
+ salla.lang.get('pages.rating.very_good'),
510
+ salla.lang.get('pages.rating.excellent')
511
+ ];
512
+ if (this.value && this.withLabel) {
513
+ this.reviewLabel = this.labels[this.value - 1];
514
+ }
515
+ if (this.reviewsElement) {
516
+ this.reviewsElement.innerText = `(${salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.reviews))})`;
517
+ }
518
+ this.translationsLoaded = true;
519
+ resolve();
520
+ });
521
+ });
522
+ }
523
+ initiateRating() {
524
+ this.host.addEventListener('click', this.handleRating.bind(this));
525
+ }
526
+ handleRating() {
527
+ if (!this.starsElem)
528
+ return;
529
+ let activeStars = this.starsElem.querySelectorAll('.s-rating-stars-hovered');
530
+ let selected = activeStars[activeStars.length - 1];
531
+ if (!selected)
532
+ return;
533
+ let selectedIndex = parseInt(selected.getAttribute('data-star'));
534
+ this.starsElem.querySelector('.rating_hidden_input').value = selectedIndex.toString();
535
+ this.starsElem.querySelectorAll('.s-rating-stars-btn-star')
536
+ .forEach((star, index) => Helper.toggleElementClassIf(star, 's-rating-stars-selected', 's-rating-stars-unselected', () => index < selectedIndex));
537
+ this.starsElem.querySelectorAll('[aria-pressed]').forEach(star => star.removeAttribute('aria-pressed'));
538
+ selected.setAttribute('aria-pressed', 'true');
539
+ this.selectedStar = selectedIndex;
540
+ this.withLabel && (this.reviewLabel = this.labels[selectedIndex - 1]);
541
+ }
542
+ triggerRatingProgrammatically(index) {
543
+ if (!this.starsElem)
544
+ return;
545
+ const stars = this.starsElem.querySelectorAll('.s-rating-stars-btn-star');
546
+ if (stars && index >= 0 && index <= stars.length) {
547
+ // Simulate the hovering effect
548
+ stars.forEach((s, i) => {
549
+ s.classList.toggle('s-rating-stars-hovered', i <= index);
550
+ });
551
+ // Trigger the same logic as clicking
552
+ this.handleRating();
553
+ }
554
+ }
555
+ highlightSelectedStars() {
556
+ let hoveredClass = 's-rating-stars-hovered', stars = this.starsElem?.querySelectorAll('.s-rating-stars-btn-star');
557
+ stars?.forEach((star, index) => {
558
+ star.addEventListener('mouseover', () => {
559
+ for (let i = 0; i <= index; i++) {
560
+ stars[i].classList.add(hoveredClass);
561
+ }
562
+ this.withLabel && (this.reviewLabel = this.labels[index]);
563
+ });
564
+ star.addEventListener('mouseout', () => {
565
+ star.classList.remove(hoveredClass);
566
+ this.withLabel && (this.reviewLabel = this.selectedStar ? this.labels[this.selectedStar - 1] : '');
567
+ });
568
+ });
569
+ this.starsElem?.addEventListener('mouseout', () => stars.forEach(star => star.classList.remove(hoveredClass)));
570
+ }
571
+ createStars(n) {
572
+ let stars = [];
573
+ for (let i = 0; i < 5; i++) {
574
+ stars.push(h("span", { class: {
575
+ 's-rating-stars-btn-star': true,
576
+ ['s-rating-stars-' + this.size]: true,
577
+ 's-rating-stars-selected': i < n
578
+ }, innerHTML: Star }));
579
+ }
580
+ if (this.reviews > 0) {
581
+ stars.push(h("span", { class: "s-rating-stars-reviews", ref: el => this.reviewsElement = el }, "(", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.reviews)), ")"));
582
+ }
583
+ return stars;
584
+ }
585
+ render() {
586
+ return this.translationsLoaded ? (this.host.closest('.swiper-slide')?.classList.contains('swiper-slide-duplicate')
587
+ ? ''
588
+ : (h(Host, null, (this.value || this.value == 0) && !this.editable ?
589
+ h("div", { class: "s-rating-stars-wrapper" }, this.createStars(this.value), this.withLabel && this.reviewLabel ? h("span", { class: "s-rating-stars-label" }, this.reviewLabel) : '')
590
+ :
591
+ h("div", { class: "s-rating-stars-wrapper" }, h("div", { class: "s-rating-stars-element", ref: (el) => this.starsElem = el }, h("input", { type: "hidden", class: "rating_hidden_input", name: this.name, value: "" }), [1, 2, 3, 4, 5].map(star => h("button", { class: `s-rating-stars-btn-star s-rating-stars-` + this.size, "data-star": star }, h("span", { innerHTML: Star })))), this.withLabel && this.reviewLabel ? h("span", { class: "s-rating-stars-label" }, this.reviewLabel) : '')))) : (h(Host, null));
592
+ }
593
+ componentDidLoad() {
594
+ this.initiateRating();
595
+ this.highlightSelectedStars();
596
+ if (this.value && this.editable) {
597
+ const stars = this.starsElem?.querySelectorAll('.s-rating-stars-btn-star');
598
+ if (stars && this.value >= 0 && this.value <= stars.length) {
599
+ this.triggerRatingProgrammatically(this.value - 1);
600
+ }
601
+ }
602
+ }
603
+ get host() { return getElement(this); }
604
+ };
605
+ SallaRatingStars.style = sallaRatingStarsCss;
606
+
607
+ var IconStar2 = ` <svg width="18" height="17" view-box="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
608
+ <path d="M9.00045 13.6951L3.71036 16.6563L4.89186 10.71L0.440918 6.59397L6.4612 5.88017L9.00045 0.375122L11.5396 5.88017L17.5599 6.59397L13.109 10.71L14.2905 16.6563L9.00045 13.6951Z" fill="currentcolor" />
609
+ </svg>`;
610
+
611
+ var IconStar2Muted = ` <svg width="18" height="17" view-box="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
612
+ <path d="M9.00045 13.6951L3.71036 16.6563L4.89186 10.71L0.440918 6.59397L6.4612 5.88017L9.00045 0.375122L11.5396 5.88017L17.5599 6.59397L13.109 10.71L14.2905 16.6563L9.00045 13.6951Z" fill="#DDDDDD" />
613
+ </svg>`;
614
+
615
+ var IconFire2 = ` <svg width="12" height="17" view-box="0 0 12 17" fill="none" xmlns="http://www.w3.org/2000/svg">
616
+ <path d="M6 16.2501C9.10658 16.2501 11.625 13.7317 11.625 10.6251C11.625 9.976 11.4523 9.35252 11.25 8.77232C9.99998 10.0075 9.05002 10.6251 8.4 10.6251C11.3966 5.37512 9.75 3.12512 5.25 0.125122C5.625 3.87475 3.15302 5.58043 2.14634 6.52757C1.0559 7.5535 0.375 9.00977 0.375 10.6251C0.375 13.7317 2.89339 16.2501 6 16.2501ZM6.53205 2.92636C8.96333 4.98908 8.97495 6.59185 7.09725 9.88157C6.5265 10.8815 7.2486 12.1251 8.4 12.1251C8.9163 12.1251 9.43807 11.9745 9.98917 11.6789C9.52342 13.4466 7.91393 14.7501 6 14.7501C3.72182 14.7501 1.875 12.9033 1.875 10.6251C1.875 9.47072 2.34959 8.39582 3.17419 7.62002C3.2687 7.53115 3.74812 7.1062 3.76858 7.08782C4.08646 6.8017 4.34835 6.54985 4.60718 6.2727C5.52998 5.28461 6.19283 4.18735 6.53205 2.92636Z" fill="currentcolor" />
617
+ </svg>`;
618
+
619
+ const sallaReviewCardCss = ":host{display:block}";
620
+
621
+ const SallaReviewCard = class {
622
+ constructor(hostRef) {
623
+ registerInstance(this, hostRef);
624
+ this.currentSlide = 0;
625
+ this.showPurchaseCount = false;
626
+ this.startPoint = { x: 0, y: 0 };
627
+ this.isSwiping = false;
628
+ this.isRTL = "rtl";
629
+ this.handlePointerDown = (e) => {
630
+ // Only handle primary pointer (first touch/mouse)
631
+ if (!e.isPrimary)
632
+ return;
633
+ this.sliderElement?.setPointerCapture(e.pointerId);
634
+ this.startSwipe(e.clientX, e.clientY);
635
+ e.preventDefault();
636
+ };
637
+ this.handlePointerMove = (e) => {
638
+ if (!this.isSwiping || !e.isPrimary)
639
+ return;
640
+ e.preventDefault();
641
+ };
642
+ this.handlePointerUp = (e) => {
643
+ if (!this.isSwiping || !e.isPrimary)
644
+ return;
645
+ this.sliderElement?.releasePointerCapture(e.pointerId);
646
+ this.endSwipe(e.clientX, e.clientY);
647
+ };
648
+ this.handlePointerCancel = (e) => {
649
+ if (!this.isSwiping || !e.isPrimary)
650
+ return;
651
+ this.sliderElement?.releasePointerCapture(e.pointerId);
652
+ this.isSwiping = false;
653
+ };
654
+ this.goToSlide = (index) => {
655
+ this.currentSlide = Math.max(0, Math.min(index, this.images.length - 1));
656
+ };
657
+ }
658
+ async componentDidLoad() {
659
+ await salla.onReady();
660
+ this.showPurchaseCount = !!salla.config.get('store.settings.product.total_sold_enabled', false);
661
+ this.isRTL = salla.config.get('theme.is_rtl', true);
662
+ this.purchasedCount = salla.lang.getWithDefault('blocks.home.reviews.purchased_count', this.isRTL ? ` تم شراءه ${this.review.product?.sold_quantity} مرة`
663
+ : `Purchased ${this.review.product.sold_quantity} times`, { count: this.review.product?.sold_quantity });
664
+ this.initializeSlider();
665
+ }
666
+ disconnectedCallback() {
667
+ this.removeEventListeners();
668
+ }
669
+ get images() {
670
+ const { review } = this;
671
+ return review?.images?.length > 1
672
+ ? review.images.map((image, idx) => ({ url: image, alt: '', id: idx }))
673
+ : review?.product?.images || [];
674
+ }
675
+ get hasMultipleImages() {
676
+ return this.images.length > 1;
677
+ }
678
+ get slideTransform() {
679
+ const direction = this.isRTL ? 1 : -1;
680
+ return `translateX(${this.currentSlide * 100 * direction}%)`;
681
+ }
682
+ initializeSlider() {
683
+ if (!this.hasMultipleImages)
684
+ return;
685
+ this.sliderElement = this.el.querySelector(".s-review-card-slider-container");
686
+ if (!this.sliderElement)
687
+ return;
688
+ // Enable pointer events and set touch-action
689
+ this.sliderElement.style.touchAction = 'pan-y pinch-zoom';
690
+ this.addEventListeners();
691
+ }
692
+ addEventListeners() {
693
+ if (!this.sliderElement)
694
+ return;
695
+ this.sliderElement.addEventListener("pointerdown", this.handlePointerDown, { passive: false });
696
+ this.sliderElement.addEventListener("pointermove", this.handlePointerMove, { passive: false });
697
+ this.sliderElement.addEventListener("pointerup", this.handlePointerUp, { passive: true });
698
+ this.sliderElement.addEventListener("pointercancel", this.handlePointerCancel, { passive: true });
699
+ }
700
+ removeEventListeners() {
701
+ if (!this.sliderElement)
702
+ return;
703
+ this.sliderElement.removeEventListener("pointerdown", this.handlePointerDown);
704
+ this.sliderElement.removeEventListener("pointermove", this.handlePointerMove);
705
+ this.sliderElement.removeEventListener("pointerup", this.handlePointerUp);
706
+ this.sliderElement.removeEventListener("pointercancel", this.handlePointerCancel);
707
+ }
708
+ startSwipe(x, y) {
709
+ this.startPoint = { x, y };
710
+ this.isSwiping = true;
711
+ }
712
+ componentDidRender() {
713
+ this.removeEventListeners();
714
+ this.addEventListeners();
715
+ }
716
+ endSwipe(x, y) {
717
+ this.isSwiping = false;
718
+ const dx = x - this.startPoint.x;
719
+ const dy = y - this.startPoint.y;
720
+ this.processSwipe(dx, dy);
721
+ }
722
+ processSwipe(dx, dy) {
723
+ const MIN_SWIPE_DISTANCE = 10;
724
+ if (Math.abs(dx) < MIN_SWIPE_DISTANCE || Math.abs(dy) > Math.abs(dx))
725
+ return;
726
+ const isLeftSwipe = dx < 0;
727
+ const shouldGoNext = this.isRTL ? !isLeftSwipe : isLeftSwipe;
728
+ if (shouldGoNext) {
729
+ this.goToNextSlide();
730
+ }
731
+ else {
732
+ this.goToPrevSlide();
733
+ }
734
+ }
735
+ goToNextSlide() {
736
+ if (this.currentSlide < this.images.length - 1) {
737
+ this.currentSlide++;
738
+ }
739
+ }
740
+ goToPrevSlide() {
741
+ if (this.currentSlide > 0) {
742
+ this.currentSlide--;
743
+ }
744
+ }
745
+ renderStars() {
746
+ return Array(5)
747
+ .fill(null)
748
+ .map((_, index) => h("span", { key: index, innerHTML: this.review.stars >= index + 1 ? IconStar2 : IconStar2Muted }));
749
+ }
750
+ renderDots() {
751
+ return this.images.map(({ url }, index) => (h("button", { key: url || index, type: "button", class: `s-review-card-slider-dot ${this.currentSlide === index ? "active" : ""}`, onClick: () => this.goToSlide(index), "aria-label": `Go to slide ${index + 1}`, onPointerDown: () => this.goToSlide(index) })));
752
+ }
753
+ renderSlider() {
754
+ if (!this.hasMultipleImages)
755
+ return null;
756
+ return (h("div", { class: "s-review-card-slider-container" }, h("div", { class: "s-review-card-slides", style: { transform: this.slideTransform } }, this.images.map((image) => (h("div", { key: image?.id, class: "s-review-card-slider-slide" }, h("img", { src: image.url, alt: image.alt || "Product image", width: 275, height: 275, loading: "lazy", draggable: false }))))), h("div", { class: "s-review-card-slider-dots" }, this.renderDots())));
757
+ }
758
+ renderSingleImage() {
759
+ const image = this.review?.product?.image;
760
+ if (!image || this.hasMultipleImages)
761
+ return null;
762
+ return (h("img", { src: image.url, alt: image.alt || "Product image", class: "s-review-card-image", width: 275, height: 275, loading: "lazy", decoding: "async", draggable: false }));
763
+ }
764
+ renderHeader() {
765
+ return (h("div", { class: "s-review-card-header" }, h("div", { class: "s-review-card-reviewer-name" }, h("p", null, this.review?.name), this.review?.has_order && h("span", { class: "s-review-card-verified-icon", innerHTML: iconCheck })), h("div", { class: "s-review-card-stars" }, this.renderStars())));
766
+ }
767
+ renderProductInfo() {
768
+ const product = this.review?.product;
769
+ if (!product)
770
+ return null;
771
+ return (h("a", { href: this.review?.product?.url, class: "s-review-card-product-container" }, h("img", { alt: product.image?.alt || "Product", src: product.image?.url, class: "s-review-card-product-image", width: 60, height: 60, loading: "lazy", decoding: "async", draggable: false }), h("div", { class: "s-review-card-product-details" }, h("p", { class: "s-review-card-product-details-name" }, product.name), this.showPurchaseCount ? h("p", { class: "s-review-card-product-details-purchase-count" }, h("span", { innerHTML: IconFire2 }), this.purchasedCount) : null)));
772
+ }
773
+ render() {
774
+ return h("div", { key: '251b76f2f2935ab7be248f589badaebe0f297cb2', class: "s-review-card-container" }, this.renderSlider(), this.renderSingleImage(), renderDivider(), h("div", { key: '2621097a4115e278b1b99d46b6be22341a7ea064', class: "s-review-card-content" }, this.renderHeader(), h("p", { key: 'cd641970280867954f431fc3a2812080ebe32bd9', class: "s-review-card-review-content", innerHTML: this.review?.content }), renderDivider(), this.renderProductInfo()));
775
+ }
776
+ get el() { return getElement(this); }
777
+ };
778
+ const renderDivider = (className) => (h("div", { class: `s-review-card-divider ${""}` }));
779
+ SallaReviewCard.style = sallaReviewCardCss;
780
+
781
+ var IconQuoteOpen = `<!-- Generated by IcoMoon.io -->
782
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
783
+ <title>quote-open</title>
784
+ <path d="M8 12v-5.333c0-0.737-0.596-1.333-1.333-1.333-3.676 0-6.667 2.991-6.667 6.667v8c0 3.676 2.991 6.667 6.667 6.667h1.333c3.676 0 6.667-2.991 6.667-6.667v-1.333c0-3.676-2.991-6.667-6.667-6.667zM12 20c0 2.205-1.795 4-4 4h-1.333c-2.205 0-4-1.795-4-4v-8c0-1.739 1.115-3.221 2.667-3.772v5.105c0 0.737 0.596 1.333 1.333 1.333h1.333c2.205 0 4 1.795 4 4zM25.333 12v-5.333c0-0.737-0.596-1.333-1.333-1.333-3.676 0-6.667 2.991-6.667 6.667v8c0 3.676 2.991 6.667 6.667 6.667h1.333c3.676 0 6.667-2.991 6.667-6.667v-1.333c0-3.676-2.991-6.667-6.667-6.667zM29.333 20c0 2.205-1.795 4-4 4h-1.333c-2.205 0-4-1.795-4-4v-8c0-1.739 1.115-3.221 2.667-3.772v5.105c0 0.737 0.596 1.333 1.333 1.333h1.333c2.205 0 4 1.795 4 4z"></path>
785
+ </svg>
786
+ `;
787
+
788
+ const sallaReviewsCss = "";
789
+
790
+ const SallaReviews = class {
791
+ constructor(hostRef) {
792
+ registerInstance(this, hostRef);
793
+ /**
794
+ * Defines the maximum number of reviews to retrieve from the API.
795
+ *
796
+ * @type {number}
797
+ * @default 5
798
+ */
799
+ this.limit = 5;
800
+ /**
801
+ * Specifies the type of reviews to fetch.
802
+ * Available options:
803
+ * - "all": Fetches reviews from all sources.
804
+ * - "store": Fetches reviews specific to the store.
805
+ * - "products": Fetches reviews specific to products.
806
+ *
807
+ * @type {ReviewType}
808
+ * @default store
809
+ */
810
+ this.type = "store";
811
+ /**
812
+ * Specifies the sorting criteria for the fetched reviews.
813
+ * Available options:
814
+ * - "top_rating": Sorts reviews based on top ratings.
815
+ * - "random": Sorts reviews randomly.
816
+ * - "latest": Sorts reviews based on the latest ones (default).
817
+ *
818
+ * @type {SortingOption}
819
+ * @default latest
820
+ */
821
+ this.sort = "latest";
822
+ /**
823
+ * Specifies whether to hide customer information in the component.
824
+ * When set to true, customer information will be hidden.
825
+ * Defaults to false, meaning customer information will be displayed.
826
+ */
827
+ this.hideCustomerInfo = false;
828
+ this.reviews = [];
829
+ this.showReviews = false;
830
+ this.testimonialText = salla.lang.get('blocks.home.testimonials');
831
+ this.displayAllLinkText = salla.lang.get('blocks.home.display_all');
832
+ this.displayAllURL = null;
833
+ this.source = this.source;
834
+ salla.onReady(() => {
835
+ this.displayAllURL = salla.url.get('testimonials');
836
+ this.isRTL = salla.config.get('theme.is_rtl', true);
837
+ });
838
+ salla.lang.onLoaded(() => {
839
+ this.testimonialText = salla.lang.get('blocks.home.testimonials');
840
+ this.displayAllLinkText = salla.lang.get('blocks.home.display_all');
841
+ });
842
+ }
843
+ fetchReviews() {
844
+ if (this.source === 'json') {
845
+ return Promise.resolve(JSON.parse(this.sourceValue));
846
+ }
847
+ const isJsonEncoded = ['products', 'categories'].includes(this.source);
848
+ const params = {
849
+ limit: this.limit,
850
+ source: this.source,
851
+ items: isJsonEncoded ? JSON.parse(this.sourceValue) : this.sourceValue,
852
+ sort: this.sort,
853
+ type: this.type,
854
+ hide_customer_info: this.hideCustomerInfo ? 1 : 0
855
+ };
856
+ return salla.api.request('reviews', { params }, 'get');
857
+ }
858
+ componentWillLoad() {
859
+ return (new Promise(resolve => salla.onReady(resolve)))
860
+ .then(() => this.fetchReviews())
861
+ .then((resp) => resp.data || [])
862
+ .then(reviews => {
863
+ if (reviews.length) {
864
+ this.reviews = reviews;
865
+ this.showReviews = true;
866
+ Helper.generateReviewSchema(this.reviews);
867
+ }
868
+ });
869
+ }
870
+ render() {
871
+ return (h("div", { key: 'aa4937182950d1b0fbcb67aa577d6fb3c413af79', class: "s-reviews-container" }, h("div", { key: 'dbfb22a037c29a0bf88b73481aa8ea4988ef819a', class: "s-reviews-header-wrapper" }, h("h1", { key: '7b874af56f8933777942d829d1311cd0854e5a12', class: "s-reviews-header" }, this.testimonialText), !!this.displayAllLink ? (h("a", { href: this.displayAllURL, class: "s-reviews-display-all" }, this.displayAllLinkText, h("span", { class: "s-reviews-display-all-icon", innerHTML: arrowLeft }))) : null), h("salla-slider", { key: '0050aac87a3aadc858aa352ba7ac82158bb586de', centered: true, "slides-per-view": 1, type: "testimonials", class: "s-reviews-testimonials-slider", "controls-outer": true, "auto-play": true, id: `testimonials-${this.source}-slider` }, h("div", { key: '7d1801d35aeba19fa913609202128b6866ca7118', slot: "items" }, this.reviews.map((item, index) => (h("div", { key: index, class: "s-reviews-swiper-slide" }, h("div", { class: "s-reviews-testimonial" }, h("div", { class: "s-reviews-testimonial__inner" }, h("div", { class: "s-reviews-testimonial__avatar" }, h("img", { src: 'images/s-empty.png', "data-src": item.avatar, alt: item.name ? item.name : 'testimonial-' + index, class: "lazy" })), h("div", { class: "s-reviews-testimonial__text" }, h("p", { innerHTML: item.content }), h("div", { class: "s-reviews-testimonial__name_wrapper" }, h("div", { class: "s-reviews-testimonial__info" }, item.name && h("h2", null, `${item.name}`)), h("div", { class: "s-reviews-testimonial__rating" }, h("salla-rating-stars", { size: "small", value: item.stars })))), h("span", { class: "s-reviews-testimonial__icon", innerHTML: IconQuoteOpen }))))))))));
872
+ }
873
+ };
874
+ SallaReviews.style = sallaReviewsCss;
875
+
876
+ var now_1;
877
+ var hasRequiredNow;
878
+
879
+ function requireNow () {
880
+ if (hasRequiredNow) return now_1;
881
+ hasRequiredNow = 1;
882
+ var root = require_root();
883
+
884
+ /**
885
+ * Gets the timestamp of the number of milliseconds that have elapsed since
886
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
887
+ *
888
+ * @static
889
+ * @memberOf _
890
+ * @since 2.4.0
891
+ * @category Date
892
+ * @returns {number} Returns the timestamp.
893
+ * @example
894
+ *
895
+ * _.defer(function(stamp) {
896
+ * console.log(_.now() - stamp);
897
+ * }, _.now());
898
+ * // => Logs the number of milliseconds it took for the deferred invocation.
899
+ */
900
+ var now = function() {
901
+ return root.Date.now();
902
+ };
903
+
904
+ now_1 = now;
905
+ return now_1;
906
+ }
907
+
908
+ /** Used to match a single whitespace character. */
909
+
910
+ var _trimmedEndIndex;
911
+ var hasRequired_trimmedEndIndex;
912
+
913
+ function require_trimmedEndIndex () {
914
+ if (hasRequired_trimmedEndIndex) return _trimmedEndIndex;
915
+ hasRequired_trimmedEndIndex = 1;
916
+ var reWhitespace = /\s/;
917
+
918
+ /**
919
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
920
+ * character of `string`.
921
+ *
922
+ * @private
923
+ * @param {string} string The string to inspect.
924
+ * @returns {number} Returns the index of the last non-whitespace character.
925
+ */
926
+ function trimmedEndIndex(string) {
927
+ var index = string.length;
928
+
929
+ while (index-- && reWhitespace.test(string.charAt(index))) {}
930
+ return index;
931
+ }
932
+
933
+ _trimmedEndIndex = trimmedEndIndex;
934
+ return _trimmedEndIndex;
935
+ }
936
+
937
+ var _baseTrim;
938
+ var hasRequired_baseTrim;
939
+
940
+ function require_baseTrim () {
941
+ if (hasRequired_baseTrim) return _baseTrim;
942
+ hasRequired_baseTrim = 1;
943
+ var trimmedEndIndex = require_trimmedEndIndex();
944
+
945
+ /** Used to match leading whitespace. */
946
+ var reTrimStart = /^\s+/;
947
+
948
+ /**
949
+ * The base implementation of `_.trim`.
950
+ *
951
+ * @private
952
+ * @param {string} string The string to trim.
953
+ * @returns {string} Returns the trimmed string.
954
+ */
955
+ function baseTrim(string) {
956
+ return string
957
+ ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
958
+ : string;
959
+ }
960
+
961
+ _baseTrim = baseTrim;
962
+ return _baseTrim;
963
+ }
964
+
965
+ var toNumber_1;
966
+ var hasRequiredToNumber;
967
+
968
+ function requireToNumber () {
969
+ if (hasRequiredToNumber) return toNumber_1;
970
+ hasRequiredToNumber = 1;
971
+ var baseTrim = require_baseTrim(),
972
+ isObject = requireIsObject(),
973
+ isSymbol = requireIsSymbol();
974
+
975
+ /** Used as references for various `Number` constants. */
976
+ var NAN = 0 / 0;
977
+
978
+ /** Used to detect bad signed hexadecimal string values. */
979
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
980
+
981
+ /** Used to detect binary string values. */
982
+ var reIsBinary = /^0b[01]+$/i;
983
+
984
+ /** Used to detect octal string values. */
985
+ var reIsOctal = /^0o[0-7]+$/i;
986
+
987
+ /** Built-in method references without a dependency on `root`. */
988
+ var freeParseInt = parseInt;
989
+
990
+ /**
991
+ * Converts `value` to a number.
992
+ *
993
+ * @static
994
+ * @memberOf _
995
+ * @since 4.0.0
996
+ * @category Lang
997
+ * @param {*} value The value to process.
998
+ * @returns {number} Returns the number.
999
+ * @example
1000
+ *
1001
+ * _.toNumber(3.2);
1002
+ * // => 3.2
1003
+ *
1004
+ * _.toNumber(Number.MIN_VALUE);
1005
+ * // => 5e-324
1006
+ *
1007
+ * _.toNumber(Infinity);
1008
+ * // => Infinity
1009
+ *
1010
+ * _.toNumber('3.2');
1011
+ * // => 3.2
1012
+ */
1013
+ function toNumber(value) {
1014
+ if (typeof value == 'number') {
1015
+ return value;
1016
+ }
1017
+ if (isSymbol(value)) {
1018
+ return NAN;
1019
+ }
1020
+ if (isObject(value)) {
1021
+ var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
1022
+ value = isObject(other) ? (other + '') : other;
1023
+ }
1024
+ if (typeof value != 'string') {
1025
+ return value === 0 ? value : +value;
1026
+ }
1027
+ value = baseTrim(value);
1028
+ var isBinary = reIsBinary.test(value);
1029
+ return (isBinary || reIsOctal.test(value))
1030
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
1031
+ : (reIsBadHex.test(value) ? NAN : +value);
1032
+ }
1033
+
1034
+ toNumber_1 = toNumber;
1035
+ return toNumber_1;
1036
+ }
1037
+
1038
+ var debounce_1;
1039
+ var hasRequiredDebounce;
1040
+
1041
+ function requireDebounce () {
1042
+ if (hasRequiredDebounce) return debounce_1;
1043
+ hasRequiredDebounce = 1;
1044
+ var isObject = requireIsObject(),
1045
+ now = requireNow(),
1046
+ toNumber = requireToNumber();
1047
+
1048
+ /** Error message constants. */
1049
+ var FUNC_ERROR_TEXT = 'Expected a function';
1050
+
1051
+ /* Built-in method references for those with the same name as other `lodash` methods. */
1052
+ var nativeMax = Math.max,
1053
+ nativeMin = Math.min;
1054
+
1055
+ /**
1056
+ * Creates a debounced function that delays invoking `func` until after `wait`
1057
+ * milliseconds have elapsed since the last time the debounced function was
1058
+ * invoked. The debounced function comes with a `cancel` method to cancel
1059
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
1060
+ * Provide `options` to indicate whether `func` should be invoked on the
1061
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
1062
+ * with the last arguments provided to the debounced function. Subsequent
1063
+ * calls to the debounced function return the result of the last `func`
1064
+ * invocation.
1065
+ *
1066
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
1067
+ * invoked on the trailing edge of the timeout only if the debounced function
1068
+ * is invoked more than once during the `wait` timeout.
1069
+ *
1070
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
1071
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
1072
+ *
1073
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
1074
+ * for details over the differences between `_.debounce` and `_.throttle`.
1075
+ *
1076
+ * @static
1077
+ * @memberOf _
1078
+ * @since 0.1.0
1079
+ * @category Function
1080
+ * @param {Function} func The function to debounce.
1081
+ * @param {number} [wait=0] The number of milliseconds to delay.
1082
+ * @param {Object} [options={}] The options object.
1083
+ * @param {boolean} [options.leading=false]
1084
+ * Specify invoking on the leading edge of the timeout.
1085
+ * @param {number} [options.maxWait]
1086
+ * The maximum time `func` is allowed to be delayed before it's invoked.
1087
+ * @param {boolean} [options.trailing=true]
1088
+ * Specify invoking on the trailing edge of the timeout.
1089
+ * @returns {Function} Returns the new debounced function.
1090
+ * @example
1091
+ *
1092
+ * // Avoid costly calculations while the window size is in flux.
1093
+ * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
1094
+ *
1095
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
1096
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
1097
+ * 'leading': true,
1098
+ * 'trailing': false
1099
+ * }));
1100
+ *
1101
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
1102
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
1103
+ * var source = new EventSource('/stream');
1104
+ * jQuery(source).on('message', debounced);
1105
+ *
1106
+ * // Cancel the trailing debounced invocation.
1107
+ * jQuery(window).on('popstate', debounced.cancel);
1108
+ */
1109
+ function debounce(func, wait, options) {
1110
+ var lastArgs,
1111
+ lastThis,
1112
+ maxWait,
1113
+ result,
1114
+ timerId,
1115
+ lastCallTime,
1116
+ lastInvokeTime = 0,
1117
+ leading = false,
1118
+ maxing = false,
1119
+ trailing = true;
1120
+
1121
+ if (typeof func != 'function') {
1122
+ throw new TypeError(FUNC_ERROR_TEXT);
1123
+ }
1124
+ wait = toNumber(wait) || 0;
1125
+ if (isObject(options)) {
1126
+ leading = !!options.leading;
1127
+ maxing = 'maxWait' in options;
1128
+ maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
1129
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
1130
+ }
1131
+
1132
+ function invokeFunc(time) {
1133
+ var args = lastArgs,
1134
+ thisArg = lastThis;
1135
+
1136
+ lastArgs = lastThis = undefined;
1137
+ lastInvokeTime = time;
1138
+ result = func.apply(thisArg, args);
1139
+ return result;
1140
+ }
1141
+
1142
+ function leadingEdge(time) {
1143
+ // Reset any `maxWait` timer.
1144
+ lastInvokeTime = time;
1145
+ // Start the timer for the trailing edge.
1146
+ timerId = setTimeout(timerExpired, wait);
1147
+ // Invoke the leading edge.
1148
+ return leading ? invokeFunc(time) : result;
1149
+ }
1150
+
1151
+ function remainingWait(time) {
1152
+ var timeSinceLastCall = time - lastCallTime,
1153
+ timeSinceLastInvoke = time - lastInvokeTime,
1154
+ timeWaiting = wait - timeSinceLastCall;
1155
+
1156
+ return maxing
1157
+ ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
1158
+ : timeWaiting;
1159
+ }
1160
+
1161
+ function shouldInvoke(time) {
1162
+ var timeSinceLastCall = time - lastCallTime,
1163
+ timeSinceLastInvoke = time - lastInvokeTime;
1164
+
1165
+ // Either this is the first call, activity has stopped and we're at the
1166
+ // trailing edge, the system time has gone backwards and we're treating
1167
+ // it as the trailing edge, or we've hit the `maxWait` limit.
1168
+ return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
1169
+ (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
1170
+ }
1171
+
1172
+ function timerExpired() {
1173
+ var time = now();
1174
+ if (shouldInvoke(time)) {
1175
+ return trailingEdge(time);
1176
+ }
1177
+ // Restart the timer.
1178
+ timerId = setTimeout(timerExpired, remainingWait(time));
1179
+ }
1180
+
1181
+ function trailingEdge(time) {
1182
+ timerId = undefined;
1183
+
1184
+ // Only invoke if we have `lastArgs` which means `func` has been
1185
+ // debounced at least once.
1186
+ if (trailing && lastArgs) {
1187
+ return invokeFunc(time);
1188
+ }
1189
+ lastArgs = lastThis = undefined;
1190
+ return result;
1191
+ }
1192
+
1193
+ function cancel() {
1194
+ if (timerId !== undefined) {
1195
+ clearTimeout(timerId);
1196
+ }
1197
+ lastInvokeTime = 0;
1198
+ lastArgs = lastCallTime = lastThis = timerId = undefined;
1199
+ }
1200
+
1201
+ function flush() {
1202
+ return timerId === undefined ? result : trailingEdge(now());
1203
+ }
1204
+
1205
+ function debounced() {
1206
+ var time = now(),
1207
+ isInvoking = shouldInvoke(time);
1208
+
1209
+ lastArgs = arguments;
1210
+ lastThis = this;
1211
+ lastCallTime = time;
1212
+
1213
+ if (isInvoking) {
1214
+ if (timerId === undefined) {
1215
+ return leadingEdge(lastCallTime);
1216
+ }
1217
+ if (maxing) {
1218
+ // Handle invocations in a tight loop.
1219
+ clearTimeout(timerId);
1220
+ timerId = setTimeout(timerExpired, wait);
1221
+ return invokeFunc(lastCallTime);
1222
+ }
1223
+ }
1224
+ if (timerId === undefined) {
1225
+ timerId = setTimeout(timerExpired, wait);
1226
+ }
1227
+ return result;
1228
+ }
1229
+ debounced.cancel = cancel;
1230
+ debounced.flush = flush;
1231
+ return debounced;
1232
+ }
1233
+
1234
+ debounce_1 = debounce;
1235
+ return debounce_1;
1236
+ }
1237
+
1238
+ var throttle_1;
1239
+ var hasRequiredThrottle;
1240
+
1241
+ function requireThrottle () {
1242
+ if (hasRequiredThrottle) return throttle_1;
1243
+ hasRequiredThrottle = 1;
1244
+ var debounce = requireDebounce(),
1245
+ isObject = requireIsObject();
1246
+
1247
+ /** Error message constants. */
1248
+ var FUNC_ERROR_TEXT = 'Expected a function';
1249
+
1250
+ /**
1251
+ * Creates a throttled function that only invokes `func` at most once per
1252
+ * every `wait` milliseconds. The throttled function comes with a `cancel`
1253
+ * method to cancel delayed `func` invocations and a `flush` method to
1254
+ * immediately invoke them. Provide `options` to indicate whether `func`
1255
+ * should be invoked on the leading and/or trailing edge of the `wait`
1256
+ * timeout. The `func` is invoked with the last arguments provided to the
1257
+ * throttled function. Subsequent calls to the throttled function return the
1258
+ * result of the last `func` invocation.
1259
+ *
1260
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
1261
+ * invoked on the trailing edge of the timeout only if the throttled function
1262
+ * is invoked more than once during the `wait` timeout.
1263
+ *
1264
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
1265
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
1266
+ *
1267
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
1268
+ * for details over the differences between `_.throttle` and `_.debounce`.
1269
+ *
1270
+ * @static
1271
+ * @memberOf _
1272
+ * @since 0.1.0
1273
+ * @category Function
1274
+ * @param {Function} func The function to throttle.
1275
+ * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
1276
+ * @param {Object} [options={}] The options object.
1277
+ * @param {boolean} [options.leading=true]
1278
+ * Specify invoking on the leading edge of the timeout.
1279
+ * @param {boolean} [options.trailing=true]
1280
+ * Specify invoking on the trailing edge of the timeout.
1281
+ * @returns {Function} Returns the new throttled function.
1282
+ * @example
1283
+ *
1284
+ * // Avoid excessively updating the position while scrolling.
1285
+ * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
1286
+ *
1287
+ * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
1288
+ * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
1289
+ * jQuery(element).on('click', throttled);
1290
+ *
1291
+ * // Cancel the trailing throttled invocation.
1292
+ * jQuery(window).on('popstate', throttled.cancel);
1293
+ */
1294
+ function throttle(func, wait, options) {
1295
+ var leading = true,
1296
+ trailing = true;
1297
+
1298
+ if (typeof func != 'function') {
1299
+ throw new TypeError(FUNC_ERROR_TEXT);
1300
+ }
1301
+ if (isObject(options)) {
1302
+ leading = 'leading' in options ? !!options.leading : leading;
1303
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
1304
+ }
1305
+ return debounce(func, wait, {
1306
+ 'leading': leading,
1307
+ 'maxWait': wait,
1308
+ 'trailing': trailing
1309
+ });
1310
+ }
1311
+
1312
+ throttle_1 = throttle;
1313
+ return throttle_1;
1314
+ }
1315
+
1316
+ var throttleExports = requireThrottle();
1317
+ var throttle = /*@__PURE__*/getDefaultExportFromCjs(throttleExports);
1318
+
1319
+ class MasonryLayout {
1320
+ constructor(grid) {
1321
+ this.grid = grid;
1322
+ this.create = () => {
1323
+ this.mutationObserver.observe(this.grid, {
1324
+ childList: true,
1325
+ });
1326
+ for (const item of Array.from(this.grid.children)) {
1327
+ this.resizeObserver.observe(item);
1328
+ }
1329
+ };
1330
+ this.onContainerMutation = (mutations) => {
1331
+ const removedNodes = mutations.flatMap((mutation) => Array.from(mutation.removedNodes));
1332
+ const addedNodes = mutations.flatMap((mutation) => Array.from(mutation.addedNodes));
1333
+ for (const node of removedNodes) {
1334
+ if (node instanceof Element) {
1335
+ this.resizeObserver.unobserve(node);
1336
+ }
1337
+ }
1338
+ for (const node of addedNodes) {
1339
+ if (node instanceof Element) {
1340
+ this.resizeObserver.observe(node);
1341
+ }
1342
+ }
1343
+ if (removedNodes.length > 0 && addedNodes.length === 0) {
1344
+ this.update();
1345
+ }
1346
+ };
1347
+ this.onChildrenResize = (entries) => {
1348
+ const entriesToUpdate = entries.filter((entry) => entry.target.parentElement !== null);
1349
+ if (entriesToUpdate.length > 0) {
1350
+ this.update();
1351
+ }
1352
+ };
1353
+ this.update = throttle(() => {
1354
+ const computedStyle = window.getComputedStyle(this.grid);
1355
+ if (computedStyle.getPropertyValue("display").includes("grid") === false) {
1356
+ this.clean();
1357
+ return;
1358
+ }
1359
+ const columns = parseGridTemplateColumns(this.grid);
1360
+ if (columns.length <= 1) {
1361
+ this.clean();
1362
+ return;
1363
+ }
1364
+ const rowGap = Number.parseFloat(computedStyle.getPropertyValue("row-gap").trim()) || 0;
1365
+ const items = Array.from(this.grid.children);
1366
+ for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
1367
+ const firstItemInColumn = items[columnIndex];
1368
+ firstItemInColumn?.style.removeProperty("margin-top");
1369
+ }
1370
+ for (let index = 0; index < items.length; index++) {
1371
+ const prevItem = items[index - columns.length];
1372
+ const nextItem = items[index];
1373
+ if (prevItem !== undefined && nextItem !== undefined) {
1374
+ const prevBottom = prevItem.getBoundingClientRect().bottom;
1375
+ nextItem.style.removeProperty("margin-top");
1376
+ const nextTop = nextItem.getBoundingClientRect().top;
1377
+ if (nextTop - rowGap !== prevBottom) {
1378
+ const margin = Math.round((prevBottom - (nextTop - rowGap) + Number.EPSILON) * 100) / 100;
1379
+ nextItem.style.setProperty("margin-top", `${margin}px`);
1380
+ }
1381
+ }
1382
+ }
1383
+ }, 32);
1384
+ this.destroy = () => {
1385
+ this.resizeObserver.disconnect();
1386
+ this.mutationObserver.disconnect();
1387
+ this.clean();
1388
+ };
1389
+ this.clean = () => {
1390
+ for (const item of Array.from(this.grid.children)) {
1391
+ item.style.removeProperty("margin-top");
1392
+ }
1393
+ };
1394
+ this.mutationObserver = new MutationObserver(this.onContainerMutation);
1395
+ this.resizeObserver = new ResizeObserver(this.onChildrenResize);
1396
+ if (CSS.supports("grid-template-rows", "masonry") === false) {
1397
+ this.create();
1398
+ }
1399
+ }
1400
+ [Symbol.dispose]() {
1401
+ this.destroy();
1402
+ }
1403
+ }
1404
+ function parseGridTemplateColumns(grid) {
1405
+ const computedStyle = window.getComputedStyle(grid);
1406
+ const gridTemplateColumns = computedStyle.getPropertyValue("grid-template-columns");
1407
+ return gridTemplateColumns
1408
+ .trim()
1409
+ .split(/\s+(?=(?:[^()]*\([^()]*\))*[^()]*$)/);
1410
+ }
1411
+
1412
+ const sallaReviewsPageCss = ":host{display:block}";
1413
+
1414
+ const SallaReviewsPage = class {
1415
+ constructor(hostRef) {
1416
+ registerInstance(this, hostRef);
1417
+ this.reviews = [];
1418
+ this.isLoading = false;
1419
+ this.pagination = null;
1420
+ this.sort = "latest";
1421
+ }
1422
+ getUrlParams() {
1423
+ const params = new URLSearchParams(window.location.search);
1424
+ return {
1425
+ sort: params.get('sort') || null,
1426
+ page: Number.parseInt(params.get('page')) || 1
1427
+ };
1428
+ }
1429
+ updateUrlParams(params) {
1430
+ const url = new URL(window.location.href);
1431
+ for (const [key, value] of Object.entries(params)) {
1432
+ if (value) {
1433
+ url.searchParams.set(key, value.toString());
1434
+ }
1435
+ else {
1436
+ url.searchParams.delete(key);
1437
+ }
1438
+ }
1439
+ window.history.replaceState({}, '', url.toString());
1440
+ }
1441
+ fetchReviews(sort, page) {
1442
+ const urlParams = this.getUrlParams();
1443
+ return salla.api.request('reviews', {
1444
+ params: {
1445
+ type: 'products',
1446
+ format: 'lite',
1447
+ per_page: 8,
1448
+ page: page || urlParams.page || 1,
1449
+ sort: sort || urlParams.sort || null
1450
+ }
1451
+ });
1452
+ }
1453
+ async initializeMasonry() {
1454
+ const grid = this.el.querySelector('.s-reviews-page-grid');
1455
+ if (!grid)
1456
+ return;
1457
+ try {
1458
+ new MasonryLayout(grid);
1459
+ salla.logger.info('Masonry initialized successfully');
1460
+ }
1461
+ catch (error) {
1462
+ salla.logger.error('Masonry initialization failed:', error);
1463
+ }
1464
+ }
1465
+ animateReviewCards() {
1466
+ const items = this.wrapper.querySelectorAll('salla-review-card:not(.animated)');
1467
+ Helper.animateItems(items);
1468
+ }
1469
+ initiateInfiniteScroll() {
1470
+ if (!this.wrapper) {
1471
+ salla.logger.error('Wrapper is undefined. Cannot initiate infinite scroll.');
1472
+ return;
1473
+ }
1474
+ this.infiniteScroll = salla.infiniteScroll.initiate(this.wrapper, this.wrapper, {
1475
+ path: () => this.pagination?.links?.next || null,
1476
+ history: false,
1477
+ scrollThreshold: false,
1478
+ }, true);
1479
+ this.infiniteScroll?.on('request', () => {
1480
+ this.isLoading = true;
1481
+ });
1482
+ this.infiniteScroll?.on('load', response => {
1483
+ this.pagination = response.pagination;
1484
+ this.reviews = [...this.reviews, ...response.data];
1485
+ this.isLoading = false;
1486
+ // Update URL with the current page
1487
+ this.updateUrlParams({ page: response.pagination.current_page });
1488
+ });
1489
+ this.infiniteScroll?.on('error', (e) => {
1490
+ salla.logger.error('Error loading more reviews:', e);
1491
+ this.isLoading = false;
1492
+ });
1493
+ }
1494
+ componentDidRender() {
1495
+ setTimeout(() => {
1496
+ requestAnimationFrame(this.animateReviewCards.bind(this));
1497
+ }, 176);
1498
+ }
1499
+ async componentWillLoad() {
1500
+ try {
1501
+ await salla.onReady();
1502
+ // Initialize language variables
1503
+ this.langTitlesReviews = salla.lang.get("common.titles.reviews");
1504
+ this.langSorting = salla.lang.get('pages.categories.sorting');
1505
+ this.placeholderText = salla.lang.choice("pages.rating.reviews", 0);
1506
+ this.langLoadMore = salla.lang.get('common.elements.load_more');
1507
+ this.langSortByTopRating = salla.lang.get('pages.testimonials.sort_by_rating_desc');
1508
+ this.langSortByMostRecent = salla.lang.get('pages.testimonials.sort_by_date_desc');
1509
+ this.langSortByLeastRated = salla.lang.get('pages.testimonials.sort_by_rating_asc');
1510
+ this.langSortByLeastRecent = salla.lang.get('pages.testimonials.sort_by_date_asc');
1511
+ const urlParams = this.getUrlParams();
1512
+ const response = await this.fetchReviews(urlParams.sort);
1513
+ this.sort = urlParams.sort;
1514
+ this.reviews = response.data;
1515
+ this.pagination = response.pagination;
1516
+ this.langRatingReviews = salla.lang.choice("pages.rating.reviews", this.pagination?.total);
1517
+ }
1518
+ catch (error) {
1519
+ salla.logger.error('Error loading reviews:', error);
1520
+ }
1521
+ }
1522
+ async handleSorting(e) {
1523
+ const value = e.target.value;
1524
+ this.sort = value;
1525
+ this.updateUrlParams({ sort: value, page: 1 }); // Reset to page 1 when changing sort
1526
+ const response = await this.fetchReviews(value, 1);
1527
+ this.reviews = response.data;
1528
+ this.pagination = response.pagination;
1529
+ }
1530
+ async componentDidLoad() {
1531
+ await this.initializeMasonry();
1532
+ this.initiateInfiniteScroll();
1533
+ this.sort = this.getUrlParams().sort || "latest";
1534
+ this.updateUrlParams({ sort: this.sort, page: 1 });
1535
+ }
1536
+ disconnectedCallback() {
1537
+ if (this.infiniteScroll) {
1538
+ this.infiniteScroll.destroy();
1539
+ }
1540
+ }
1541
+ renderSortingOptions() {
1542
+ const options = [
1543
+ { value: 'latest', label: this.langSortByMostRecent },
1544
+ { value: 'oldest', label: this.langSortByLeastRecent },
1545
+ { value: 'top_rating', label: this.langSortByTopRating },
1546
+ { value: 'bottom_rating', label: this.langSortByLeastRated },
1547
+ ];
1548
+ return options.map(option => (h("option", { key: option.value, value: option.value, selected: option.value === this.sort }, option.label)));
1549
+ }
1550
+ render() {
1551
+ return (h("host", { key: '5e3b4042e6412dd2fdef3d776d4204c731df6c80' }, h("div", { key: 'a9daf869bac109b7c627c9fd8fd7c84cd4dd2965', class: "s-reviews-page-header-wrapper" }, h("h2", { key: '01cd6892650d8288003d79b4c12e82c4693e1cb6', class: "s-reviews-page-title" }, this.langTitlesReviews, h("span", { key: '935329858a3cc699da6fb6fb8c8515348ded9eb4', class: "s-reviews-page-count" }, "(", this.langRatingReviews, ")")), h("div", { key: 'e74312403c6dc7625c0c2090e6627a8a6b5fca9b', class: "s-reviews-page-filter-wrapper" }, h("label", { key: 'bf51576936b030ee59836861b03fa3b06471ed1f', class: "s-reviews-page-filter-label", htmlFor: "testimonials-filter" }, this.langSorting), h("select", { key: '72f09a679c5f42b08f55b908f67f3d3627b3a50c', onChange: (e) => this.handleSorting(e), disabled: !this.reviews.length, class: "s-reviews-page-filter" }, this.renderSortingOptions()))), this.reviews.length ? h("main", { class: "s-reviews-page-grid", ref: el => {
1552
+ this.wrapper = el;
1553
+ } }, this.reviews.map(review => (h("salla-review-card", { key: review.id, review: review }))))
1554
+ : h("div", { class: "s-products-list-placeholder" }, h("span", { innerHTML: ShoppingBag }), h("p", null, this.placeholderText)), this.pagination?.links?.next && this.reviews.length ? (h("div", { class: "s-reviews-page-load-more-container" }, h("salla-button", { class: "s-reviews-page-load-more-btn", loading: this.isLoading, onClick: () => this.infiniteScroll?.loadNextPage(), onKeyUp: () => this.infiniteScroll?.loadNextPage() }, this.langLoadMore))) : null));
1555
+ }
1556
+ get el() { return getElement(this); }
1557
+ };
1558
+ SallaReviewsPage.style = sallaReviewsPageCss;
1559
+
1560
+ const sallaReviewsSummaryCss = ":host{display:block}";
1561
+
1562
+ const SallaReviewsSummary = class {
1563
+ constructor(hostRef) {
1564
+ registerInstance(this, hostRef);
1565
+ this.canRender = false;
1566
+ this.showRatingSummary = false;
1567
+ this.recommendationOnly = false;
1568
+ this.showRecommendation = false;
1569
+ }
1570
+ async componentWillLoad() {
1571
+ try {
1572
+ await salla.onReady();
1573
+ this.initializeLanguages();
1574
+ this.loadConfig();
1575
+ // Only load data if component should be displayed
1576
+ if (this.showRatingSummary || this.showRecommendation) {
1577
+ await this.loadSummary();
1578
+ }
1579
+ }
1580
+ catch (error) {
1581
+ console.error('Failed to initialize reviews summary component:', error);
1582
+ }
1583
+ }
1584
+ async loadConfig() {
1585
+ this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
1586
+ this.showRecommendation = salla.config.get('store.settings.rating.show_recommendation');
1587
+ this.recommendationOnly = this.showRecommendation && !this.showRatingSummary;
1588
+ }
1589
+ initializeLanguages() {
1590
+ return Salla.lang.onLoaded(() => {
1591
+ Salla.lang.addBulk({
1592
+ "blocks.comments.based_on": { ar: "بناءً على", en: "Based on" },
1593
+ "blocks.comments.recommended": { ar: "أوصوا بالمنتج", en: "Recommended" }
1594
+ });
1595
+ this.basedOnLabel = salla.lang.get('blocks.comments.based_on');
1596
+ this.recommendedLabel = salla.lang.get('blocks.comments.recommended');
1597
+ });
1598
+ }
1599
+ async loadSummary() {
1600
+ if (!this.itemId) {
1601
+ console.error('Error loading reviews summary: itemId is not defined');
1602
+ return this.canRender = false;
1603
+ }
1604
+ try {
1605
+ const response = (await salla.api.request(`rating/summary/${this.itemId}`));
1606
+ if (!response?.data || (Array.isArray(response.data.reviews) && !response.data.reviews.length)) {
1607
+ this.canRender = false;
1608
+ this.data = null;
1609
+ return;
1610
+ }
1611
+ this.data = response.data;
1612
+ this.canRender = true;
1613
+ }
1614
+ catch (error) {
1615
+ this.canRender = false;
1616
+ this.data = null;
1617
+ console.error('Error loading reviews summary:', error);
1618
+ }
1619
+ }
1620
+ renderRecommendation() {
1621
+ if (!this.showRecommendation || !this.data?.recommendation) {
1622
+ return null;
1623
+ }
1624
+ const classes = {
1625
+ base: 's-reviews-summary-header-section',
1626
+ standalone: this.recommendationOnly ? 's-reviews-summary-recommendation-only' : ''
1627
+ };
1628
+ return (h("div", { class: `${classes.base} ${classes.standalone}`.trim() }, h("h4", { class: "s-reviews-summary-recommendation-percentage" }, "%", this.data?.recommendation), h("p", { class: "s-reviews-summary-count" }, this.recommendedLabel)));
1629
+ }
1630
+ render() {
1631
+ if (!this.canRender)
1632
+ return null;
1633
+ if (this.recommendationOnly)
1634
+ return this.renderRecommendation();
1635
+ const ratings = {
1636
+ "1": 0,
1637
+ "2": 0,
1638
+ "3": 0,
1639
+ "4": 0,
1640
+ "5": 0,
1641
+ ...this.data.reviews
1642
+ };
1643
+ const reviewElements = Object.keys(ratings).reverse().map((rating) => {
1644
+ const percentage = ratings[rating];
1645
+ return (h("div", { key: rating, class: "s-reviews-summary-row" }, h("div", { class: "s-reviews-summary-row-rate" }, rating, " ", h("span", { innerHTML: Star })), h("salla-progress-bar", { class: "s-reviews-summary-progress", value: percentage, target: 100, hideUnits: true, height: '16px' }), h("span", { class: "s-reviews-summary-percentage" }, percentage, "%")));
1646
+ });
1647
+ return (h(Host, { class: "s-reviews-summary-wrapper" }, h("div", { class: "s-reviews-summary-header" }, h("div", { class: "s-reviews-summary-header-section" }, h("h3", { class: "s-reviews-summary-average" }, this.data.rating), h("div", null, h("salla-rating-stars", { size: 'large', value: this.data.rating }), h("p", { class: "s-reviews-summary-count" }, this.basedOnLabel, " ", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.data.count))))), this.renderRecommendation()), h("div", { class: "s-reviews-summary-rows" }, reviewElements)));
1648
+ }
1649
+ };
1650
+ SallaReviewsSummary.style = sallaReviewsSummaryCss;
1651
+
1652
+ export { SallaCommentForm as salla_comment_form, SallaCommentItem as salla_comment_item, SallaComments as salla_comments, SallaRatingStars as salla_rating_stars, SallaReviewCard as salla_review_card, SallaReviews as salla_reviews, SallaReviewsPage as salla_reviews_page, SallaReviewsSummary as salla_reviews_summary };