@salla.sa/twilight-components 2.14.593 → 2.14.595

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 (352) hide show
  1. package/dist/cjs/{filepond-Dh9Ih7bu.js → filepond-BmX7bEQk.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster-C6Sx5vF0.js → filepond-plugin-file-poster-Cs6e85Vn.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-DdzdetN6.js → filepond-plugin-file-validate-size-CSk66JAo.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-DRWFKOpQ.js → filepond-plugin-file-validate-type-Piu3p2Um.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-B4vaf2kZ.js → filepond-plugin-image-edit-Ba9FBal4.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-BXfm40Ut.js → filepond-plugin-image-exif-orientation-zwtgHyrT.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-DQLCCOAs.js → filepond-plugin-image-preview-BmGjui8n.js} +1 -1
  8. package/dist/cjs/{index-CLrjVXN1.js → index-DkrDtx6i.js} +21 -7
  9. package/dist/cjs/{intlTelInput-o62W18dw.js → intlTelInput-Bty1-N7J.js} +1 -1
  10. package/dist/cjs/loader.cjs.js +2 -2
  11. package/dist/cjs/salla-accordion-body_2.cjs.entry.js +1 -1
  12. package/dist/cjs/salla-accordion_6.cjs.entry.js +1 -1
  13. package/dist/cjs/salla-add-product-button_5.cjs.entry.js +1 -1
  14. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  15. package/dist/cjs/salla-alert_2.cjs.entry.js +1 -1
  16. package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
  17. package/dist/cjs/salla-applied-filters.cjs.entry.js +1 -1
  18. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  19. package/dist/cjs/salla-attachment-view_9.cjs.entry.js +10 -10
  20. package/dist/cjs/salla-badge.cjs.entry.js +1 -1
  21. package/dist/cjs/salla-basket-gap.cjs.entry.js +1 -1
  22. package/dist/cjs/salla-bullet-delivery_3.cjs.entry.js +286 -20
  23. package/dist/cjs/salla-cart-coupons.cjs.entry.js +68 -15
  24. package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-cart-summary-card.cjs.entry.js +29 -4
  26. package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-comment-factors.cjs.entry.js +1 -1
  28. package/dist/cjs/salla-comment-form_9.cjs.entry.js +1 -1
  29. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  30. package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
  31. package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-count-down.cjs.entry.js +1 -1
  33. package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-delivery-promise.cjs.entry.js +1 -1
  35. package/dist/cjs/salla-edit-order-button.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
  37. package/dist/cjs/salla-filters.cjs.entry.js +1 -1
  38. package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-gift-card-redeem_2.cjs.entry.js +1 -1
  40. package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-hook.cjs.entry.js +1 -1
  42. package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
  43. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  44. package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
  45. package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
  46. package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
  47. package/dist/cjs/salla-loyalty-banner_10.cjs.entry.js +1 -1
  48. package/dist/cjs/salla-loyalty-exchange-product-card.cjs.entry.js +1 -1
  49. package/dist/cjs/salla-loyalty-points-banner.cjs.entry.js +1 -1
  50. package/dist/cjs/salla-loyalty-points-history.cjs.entry.js +1 -1
  51. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
  53. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
  54. package/dist/cjs/salla-map_3.cjs.entry.js +1 -1
  55. package/dist/cjs/salla-menu.cjs.entry.js +1 -1
  56. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  57. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +1 -1
  58. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +1 -1
  59. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
  61. package/dist/cjs/salla-notification-item_2.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
  63. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-order-branch.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-order-cancel.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  67. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  68. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  69. package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
  70. package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +1 -1
  71. package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
  72. package/dist/cjs/salla-order-options-modal.cjs.entry.js +1 -1
  73. package/dist/cjs/salla-order-shipments.cjs.entry.js +1 -1
  74. package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
  75. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  76. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  77. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  78. package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
  79. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  80. package/dist/cjs/salla-product-card-embed.cjs.entry.js +1 -1
  81. package/dist/cjs/salla-product-card.cjs.entry.js +1 -1
  82. package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
  83. package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
  84. package/dist/cjs/salla-products-slider.cjs.entry.js +1 -1
  85. package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
  86. package/dist/cjs/salla-rating-modal-v2.cjs.entry.js +1 -1
  87. package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
  88. package/dist/cjs/salla-review-factors-tags.cjs.entry.js +1 -1
  89. package/dist/cjs/salla-review-order-item.cjs.entry.js +1 -1
  90. package/dist/cjs/salla-scopes.cjs.entry.js +1 -1
  91. package/dist/cjs/salla-search-product-card.cjs.entry.js +1 -1
  92. package/dist/cjs/salla-search.cjs.entry.js +1 -1
  93. package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
  94. package/dist/cjs/salla-social-share.cjs.entry.js +1 -1
  95. package/dist/cjs/salla-social.cjs.entry.js +1 -1
  96. package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
  97. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  98. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  99. package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
  100. package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
  101. package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
  102. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  103. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  104. package/dist/cjs/salla-wishlist-actions.cjs.entry.js +1 -1
  105. package/dist/cjs/salla-wishlist-summary.cjs.entry.js +1 -1
  106. package/dist/cjs/twilight.cjs.js +2 -2
  107. package/dist/cjs/{vanilla-picker-FCNrUTtN.js → vanilla-picker-DgPfWupN.js} +1 -1
  108. package/dist/collection/components/salla-bullet-delivery/location-distance-warning.js +28 -0
  109. package/dist/collection/components/salla-bullet-delivery/location-icon.svg +26 -0
  110. package/dist/collection/components/salla-bullet-delivery/location-permission-notice.js +103 -0
  111. package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.css +136 -0
  112. package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.js +133 -19
  113. package/dist/collection/components/salla-cart-coupons/salla-cart-coupons.js +69 -15
  114. package/dist/collection/components/salla-cart-summary-card/salla-cart-summary-card.js +30 -3
  115. package/dist/collection/global/app.js +2 -0
  116. package/dist/collection/global/app.spec.ts +33 -0
  117. package/dist/collection/global/app.ts +2 -0
  118. package/dist/collection/global/chunk-errors.js +14 -0
  119. package/dist/collection/global/chunk-errors.spec.ts +47 -0
  120. package/dist/collection/global/chunk-errors.ts +13 -0
  121. package/dist/components/index.js +15 -2
  122. package/dist/components/salla-bullet-delivery.js +288 -20
  123. package/dist/components/salla-cart-coupons.js +68 -14
  124. package/dist/components/salla-cart-summary-card.js +30 -3
  125. package/dist/docs.json +1 -1
  126. package/dist/esm/{filepond-DTcw03Zq.js → filepond-DF26o67L.js} +1 -1
  127. package/dist/esm/{filepond-plugin-file-poster-Csk5cMw9.js → filepond-plugin-file-poster-B4epzDDH.js} +1 -1
  128. package/dist/esm/{filepond-plugin-file-validate-size-FFrf5LrW.js → filepond-plugin-file-validate-size-DILJc03j.js} +1 -1
  129. package/dist/esm/{filepond-plugin-file-validate-type-DeZP4xXd.js → filepond-plugin-file-validate-type-Bic7dGts.js} +1 -1
  130. package/dist/esm/{filepond-plugin-image-edit-DRKyd_1I.js → filepond-plugin-image-edit-DHfCLKK0.js} +1 -1
  131. package/dist/esm/{filepond-plugin-image-exif-orientation-CxVz7OAy.js → filepond-plugin-image-exif-orientation-C7y59Hrn.js} +1 -1
  132. package/dist/esm/{filepond-plugin-image-preview-CsKN7em3.js → filepond-plugin-image-preview-C-ZqWLeC.js} +1 -1
  133. package/dist/esm/{index-0Tl_yZW8.js → index-HRJpfiBN.js} +21 -7
  134. package/dist/esm/{intlTelInput-CBN9egFg.js → intlTelInput-DOVRUqFb.js} +1 -1
  135. package/dist/esm/loader.js +3 -3
  136. package/dist/esm/salla-accordion-body_2.entry.js +1 -1
  137. package/dist/esm/salla-accordion_6.entry.js +1 -1
  138. package/dist/esm/salla-add-product-button_5.entry.js +1 -1
  139. package/dist/esm/salla-advertisement.entry.js +1 -1
  140. package/dist/esm/salla-alert_2.entry.js +1 -1
  141. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  142. package/dist/esm/salla-applied-filters.entry.js +1 -1
  143. package/dist/esm/salla-apps-icons.entry.js +1 -1
  144. package/dist/esm/salla-attachment-view_9.entry.js +10 -10
  145. package/dist/esm/salla-badge.entry.js +1 -1
  146. package/dist/esm/salla-basket-gap.entry.js +1 -1
  147. package/dist/esm/salla-bullet-delivery_3.entry.js +286 -20
  148. package/dist/esm/salla-cart-coupons.entry.js +68 -15
  149. package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
  150. package/dist/esm/salla-cart-summary-card.entry.js +29 -4
  151. package/dist/esm/salla-cashback-banner.entry.js +1 -1
  152. package/dist/esm/salla-comment-factors.entry.js +1 -1
  153. package/dist/esm/salla-comment-form_9.entry.js +1 -1
  154. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  155. package/dist/esm/salla-contacts.entry.js +1 -1
  156. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  157. package/dist/esm/salla-count-down.entry.js +1 -1
  158. package/dist/esm/salla-custom-fields.entry.js +1 -1
  159. package/dist/esm/salla-delivery-promise.entry.js +1 -1
  160. package/dist/esm/salla-edit-order-button.entry.js +1 -1
  161. package/dist/esm/salla-filters-widget.entry.js +1 -1
  162. package/dist/esm/salla-filters.entry.js +1 -1
  163. package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
  164. package/dist/esm/salla-gift-card-redeem_2.entry.js +1 -1
  165. package/dist/esm/salla-gifting.entry.js +1 -1
  166. package/dist/esm/salla-hook.entry.js +1 -1
  167. package/dist/esm/salla-infinite-scroll.entry.js +1 -1
  168. package/dist/esm/salla-installment.entry.js +1 -1
  169. package/dist/esm/salla-list-tile.entry.js +1 -1
  170. package/dist/esm/salla-localization-modal.entry.js +1 -1
  171. package/dist/esm/salla-login-modal.entry.js +1 -1
  172. package/dist/esm/salla-loyalty-banner_10.entry.js +1 -1
  173. package/dist/esm/salla-loyalty-exchange-product-card.entry.js +1 -1
  174. package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
  175. package/dist/esm/salla-loyalty-points-history.entry.js +1 -1
  176. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  177. package/dist/esm/salla-loyalty.entry.js +1 -1
  178. package/dist/esm/salla-maintenance-alert.entry.js +1 -1
  179. package/dist/esm/salla-map_3.entry.js +1 -1
  180. package/dist/esm/salla-menu.entry.js +1 -1
  181. package/dist/esm/salla-metadata.entry.js +1 -1
  182. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +1 -1
  183. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +1 -1
  184. package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
  185. package/dist/esm/salla-next-order-coupon.entry.js +1 -1
  186. package/dist/esm/salla-notification-item_2.entry.js +1 -1
  187. package/dist/esm/salla-offer-modal.entry.js +1 -1
  188. package/dist/esm/salla-offer.entry.js +1 -1
  189. package/dist/esm/salla-order-branch.entry.js +1 -1
  190. package/dist/esm/salla-order-cancel.entry.js +1 -1
  191. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  192. package/dist/esm/salla-order-details-options.entry.js +1 -1
  193. package/dist/esm/salla-order-details.entry.js +1 -1
  194. package/dist/esm/salla-order-edit-item.entry.js +1 -1
  195. package/dist/esm/salla-order-edit-product-card.entry.js +1 -1
  196. package/dist/esm/salla-order-edit.entry.js +1 -1
  197. package/dist/esm/salla-order-options-modal.entry.js +1 -1
  198. package/dist/esm/salla-order-shipments.entry.js +1 -1
  199. package/dist/esm/salla-order-summary.entry.js +1 -1
  200. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  201. package/dist/esm/salla-orders.entry.js +1 -1
  202. package/dist/esm/salla-payments.entry.js +1 -1
  203. package/dist/esm/salla-placeholder.entry.js +1 -1
  204. package/dist/esm/salla-price-range.entry.js +1 -1
  205. package/dist/esm/salla-product-card-embed.entry.js +1 -1
  206. package/dist/esm/salla-product-card.entry.js +1 -1
  207. package/dist/esm/salla-product-size-guide.entry.js +1 -1
  208. package/dist/esm/salla-products-list.entry.js +1 -1
  209. package/dist/esm/salla-products-slider.entry.js +1 -1
  210. package/dist/esm/salla-quick-order.entry.js +1 -1
  211. package/dist/esm/salla-rating-modal-v2.entry.js +1 -1
  212. package/dist/esm/salla-rating-modal.entry.js +1 -1
  213. package/dist/esm/salla-review-factors-tags.entry.js +1 -1
  214. package/dist/esm/salla-review-order-item.entry.js +1 -1
  215. package/dist/esm/salla-scopes.entry.js +1 -1
  216. package/dist/esm/salla-search-product-card.entry.js +1 -1
  217. package/dist/esm/salla-search.entry.js +1 -1
  218. package/dist/esm/salla-skeleton.entry.js +1 -1
  219. package/dist/esm/salla-social-share.entry.js +1 -1
  220. package/dist/esm/salla-social.entry.js +1 -1
  221. package/dist/esm/salla-tab-content_3.entry.js +1 -1
  222. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  223. package/dist/esm/salla-trust-badges.entry.js +1 -1
  224. package/dist/esm/salla-user-menu.entry.js +1 -1
  225. package/dist/esm/salla-user-profile.entry.js +1 -1
  226. package/dist/esm/salla-user-settings.entry.js +1 -1
  227. package/dist/esm/salla-verify.entry.js +1 -1
  228. package/dist/esm/salla-wallet.entry.js +1 -1
  229. package/dist/esm/salla-wishlist-actions.entry.js +1 -1
  230. package/dist/esm/salla-wishlist-summary.entry.js +1 -1
  231. package/dist/esm/twilight.js +3 -3
  232. package/dist/esm/{vanilla-picker-CiLp9ysz.js → vanilla-picker-DQKehCLa.js} +1 -1
  233. package/dist/twilight/global/app.spec.ts +33 -0
  234. package/dist/twilight/global/app.ts +2 -0
  235. package/dist/twilight/global/chunk-errors.spec.ts +47 -0
  236. package/dist/twilight/global/chunk-errors.ts +13 -0
  237. package/dist/twilight/{p-b566bc10.entry.js → p-02d79968.entry.js} +1 -1
  238. package/dist/twilight/{p-f445e7a3.entry.js → p-078e5ef8.entry.js} +1 -1
  239. package/dist/twilight/{p-40be8baa.entry.js → p-07e1822a.entry.js} +1 -1
  240. package/dist/twilight/{p-d744234e.entry.js → p-0e430b25.entry.js} +1 -1
  241. package/dist/twilight/{p-9a818822.entry.js → p-100260a2.entry.js} +1 -1
  242. package/dist/twilight/{p-1892ea42.entry.js → p-117c8823.entry.js} +1 -1
  243. package/dist/twilight/{p-449eae1d.entry.js → p-119aa7c1.entry.js} +1 -1
  244. package/dist/twilight/{p-e8cb4cd9.entry.js → p-14b78c6e.entry.js} +1 -1
  245. package/dist/twilight/{p-bc3ad6d2.entry.js → p-155f1fed.entry.js} +1 -1
  246. package/dist/twilight/{p-1abcc81d.entry.js → p-16b45c19.entry.js} +1 -1
  247. package/dist/twilight/{p-7c06ad6a.entry.js → p-1a684490.entry.js} +1 -1
  248. package/dist/twilight/{p-b0d66765.entry.js → p-1b0da3b9.entry.js} +1 -1
  249. package/dist/twilight/{p-fe27963f.entry.js → p-20d5665b.entry.js} +1 -1
  250. package/dist/twilight/{p-2cbed601.entry.js → p-231d4bf2.entry.js} +1 -1
  251. package/dist/twilight/{p-5cc28510.entry.js → p-235f40b0.entry.js} +1 -1
  252. package/dist/twilight/{p-7bee2390.entry.js → p-2413d450.entry.js} +1 -1
  253. package/dist/twilight/{p-6561d5d3.entry.js → p-25ea21a6.entry.js} +1 -1
  254. package/dist/twilight/{p-fea37c8c.entry.js → p-2c13b5e8.entry.js} +1 -1
  255. package/dist/twilight/{p-e8fa4bd0.entry.js → p-2f96a72f.entry.js} +1 -1
  256. package/dist/twilight/{p-fb527b4d.entry.js → p-312d231b.entry.js} +1 -1
  257. package/dist/twilight/{p-52e7b4f6.entry.js → p-313dbe67.entry.js} +1 -1
  258. package/dist/twilight/{p-636ffc46.entry.js → p-334fc442.entry.js} +1 -1
  259. package/dist/twilight/{p-c394f30a.entry.js → p-33a64882.entry.js} +1 -1
  260. package/dist/twilight/{p-fef5c118.entry.js → p-3c0be6b1.entry.js} +1 -1
  261. package/dist/twilight/{p-14c9ed90.entry.js → p-3e232b09.entry.js} +1 -1
  262. package/dist/twilight/{p-933807d7.entry.js → p-3f376a9d.entry.js} +1 -1
  263. package/dist/twilight/{p-7f59893d.entry.js → p-46ad2b0e.entry.js} +1 -1
  264. package/dist/twilight/{p-a764bfe7.entry.js → p-49d6d82e.entry.js} +1 -1
  265. package/dist/twilight/{p-cc7c4469.entry.js → p-49e2f73d.entry.js} +1 -1
  266. package/dist/twilight/{p-75fc9b99.entry.js → p-4cee6b43.entry.js} +1 -1
  267. package/dist/twilight/{p-e9372ca0.entry.js → p-4e0dcb5c.entry.js} +1 -1
  268. package/dist/twilight/{p-4701a008.entry.js → p-4e3a3c55.entry.js} +1 -1
  269. package/dist/twilight/{p-42426756.entry.js → p-4e74c79f.entry.js} +1 -1
  270. package/dist/twilight/{p-2ac1eac9.entry.js → p-4f9da81b.entry.js} +1 -1
  271. package/dist/twilight/{p-0fe961e0.entry.js → p-5134faef.entry.js} +1 -1
  272. package/dist/twilight/p-5b617110.entry.js +4 -0
  273. package/dist/twilight/{p-01b4b05f.entry.js → p-5bc3f956.entry.js} +1 -1
  274. package/dist/twilight/{p-299e7413.entry.js → p-5f0eca54.entry.js} +1 -1
  275. package/dist/twilight/{p-918fa44a.entry.js → p-5fae444a.entry.js} +1 -1
  276. package/dist/twilight/{p-65665ee3.entry.js → p-61c8e3c6.entry.js} +1 -1
  277. package/dist/twilight/{p-2d2db627.entry.js → p-6e8cb8fb.entry.js} +1 -1
  278. package/dist/twilight/{p-99e615a1.entry.js → p-6feb378a.entry.js} +1 -1
  279. package/dist/twilight/{p-1bf7cce7.entry.js → p-70c45a90.entry.js} +1 -1
  280. package/dist/twilight/{p-deb1139c.entry.js → p-73b8ed51.entry.js} +1 -1
  281. package/dist/twilight/p-75ed7d4e.entry.js +4 -0
  282. package/dist/twilight/{p-ddc61bff.entry.js → p-761e273c.entry.js} +1 -1
  283. package/dist/twilight/{p-253a352c.entry.js → p-768f5c26.entry.js} +1 -1
  284. package/dist/twilight/{p-288627a2.entry.js → p-76f49fd8.entry.js} +1 -1
  285. package/dist/twilight/{p-775f9b02.entry.js → p-7960e489.entry.js} +1 -1
  286. package/dist/twilight/{p-aec2d723.entry.js → p-7f38cf0c.entry.js} +1 -1
  287. package/dist/twilight/{p-179595d9.entry.js → p-7f58cf36.entry.js} +1 -1
  288. package/dist/twilight/{p-44afcd79.entry.js → p-83edd1a1.entry.js} +1 -1
  289. package/dist/twilight/{p-dc129d7a.entry.js → p-845e4790.entry.js} +1 -1
  290. package/dist/twilight/{p-31253c2d.entry.js → p-84c56f4d.entry.js} +1 -1
  291. package/dist/twilight/{p-4432411c.entry.js → p-8688c21f.entry.js} +1 -1
  292. package/dist/twilight/{p-821e9049.entry.js → p-87d34b7c.entry.js} +1 -1
  293. package/dist/twilight/{p-b01764d0.entry.js → p-8be3fa1c.entry.js} +1 -1
  294. package/dist/twilight/{p-f92d1971.entry.js → p-8dc7ae26.entry.js} +1 -1
  295. package/dist/twilight/{p-4d879cd3.entry.js → p-8e0a33dd.entry.js} +1 -1
  296. package/dist/twilight/{p-183e02ac.entry.js → p-8eabd62f.entry.js} +1 -1
  297. package/dist/twilight/{p-85ab4182.entry.js → p-8f0b6a64.entry.js} +1 -1
  298. package/dist/twilight/{p-d05e1bfd.entry.js → p-8fc42a50.entry.js} +1 -1
  299. package/dist/twilight/{p-ce9b6ac6.entry.js → p-943f3e5a.entry.js} +1 -1
  300. package/dist/twilight/{p-f176c43e.entry.js → p-96317fc8.entry.js} +1 -1
  301. package/dist/twilight/{p-0cc42e36.entry.js → p-96560ca2.entry.js} +1 -1
  302. package/dist/twilight/{p-3d533d87.entry.js → p-97b51153.entry.js} +1 -1
  303. package/dist/twilight/p-9a4a84b8.entry.js +4 -0
  304. package/dist/twilight/{p-e429b1e5.entry.js → p-9a723216.entry.js} +1 -1
  305. package/dist/twilight/{p-7c038d9d.entry.js → p-9c1bf3fb.entry.js} +1 -1
  306. package/dist/twilight/{p-Cbnu3aaI.js → p-BCFB-lfz.js} +1 -1
  307. package/dist/twilight/{p-CZkK9lyS.js → p-BFMu9w68.js} +1 -1
  308. package/dist/twilight/{p-YTWgVZ0u.js → p-BGUXYEQf.js} +2 -2
  309. package/dist/twilight/{p-BABHygiN.js → p-BdaR2plD.js} +1 -1
  310. package/dist/twilight/{p-CxpHph5p.js → p-CSRWBUvd.js} +1 -1
  311. package/dist/twilight/{p-BDO2BBmv.js → p-CliIfO7G.js} +1 -1
  312. package/dist/twilight/{p-BZHrTB2v.js → p-D1oXS6KY.js} +1 -1
  313. package/dist/twilight/{p-fP9RBas5.js → p-DlxVucku.js} +1 -1
  314. package/dist/twilight/{p-0Tl_yZW8.js → p-HRJpfiBN.js} +2 -2
  315. package/dist/twilight/{p-MugjBhYh.js → p-O5jKs1Zb.js} +1 -1
  316. package/dist/twilight/{p-0c26bedf.entry.js → p-a2cbbc56.entry.js} +1 -1
  317. package/dist/twilight/{p-ad9dcb47.entry.js → p-a3009d00.entry.js} +1 -1
  318. package/dist/twilight/{p-ae22bfeb.entry.js → p-b202c2d3.entry.js} +1 -1
  319. package/dist/twilight/{p-95b89c32.entry.js → p-b2b896d1.entry.js} +1 -1
  320. package/dist/twilight/{p-35d5e339.entry.js → p-b66c664b.entry.js} +1 -1
  321. package/dist/twilight/{p-9434c23f.entry.js → p-c327bc95.entry.js} +1 -1
  322. package/dist/twilight/{p-8e013db1.entry.js → p-c3afee2f.entry.js} +1 -1
  323. package/dist/twilight/{p-8d369871.entry.js → p-c699207a.entry.js} +1 -1
  324. package/dist/twilight/{p-aee17b8b.entry.js → p-c89d7291.entry.js} +1 -1
  325. package/dist/twilight/{p-eb590773.entry.js → p-c8d4b211.entry.js} +1 -1
  326. package/dist/twilight/{p-f828fefc.entry.js → p-c919171b.entry.js} +1 -1
  327. package/dist/twilight/{p-f4cff5cf.entry.js → p-d565b168.entry.js} +1 -1
  328. package/dist/twilight/{p-0433773a.entry.js → p-d7a70a29.entry.js} +1 -1
  329. package/dist/twilight/{p-af12fce1.entry.js → p-d8181149.entry.js} +1 -1
  330. package/dist/twilight/{p-a263bdbb.entry.js → p-d8a5198b.entry.js} +1 -1
  331. package/dist/twilight/{p-26adf02d.entry.js → p-db27df13.entry.js} +1 -1
  332. package/dist/twilight/{p-80f27669.entry.js → p-df8c51c2.entry.js} +1 -1
  333. package/dist/twilight/{p-220338b4.entry.js → p-e4d76bce.entry.js} +1 -1
  334. package/dist/twilight/{p-2da1eb61.entry.js → p-eb6f86fb.entry.js} +1 -1
  335. package/dist/twilight/{p-b9d2ae8a.entry.js → p-ee23fbba.entry.js} +1 -1
  336. package/dist/twilight/{p-6db61be2.entry.js → p-ee8d13fd.entry.js} +1 -1
  337. package/dist/twilight/{p-a735c70e.entry.js → p-ef09a761.entry.js} +1 -1
  338. package/dist/twilight/{p-e955b287.entry.js → p-f5e46494.entry.js} +1 -1
  339. package/dist/twilight/{p-bf3fdf6d.entry.js → p-f9abcf4f.entry.js} +1 -1
  340. package/dist/twilight/{p-3b5fe2ef.entry.js → p-fd0d136d.entry.js} +1 -1
  341. package/dist/twilight/{p-4d852a57.entry.js → p-fe72290f.entry.js} +1 -1
  342. package/dist/twilight/twilight.esm.js +1 -1
  343. package/dist/types/components/salla-bullet-delivery/location-distance-warning.d.ts +12 -0
  344. package/dist/types/components/salla-bullet-delivery/location-permission-notice.d.ts +39 -0
  345. package/dist/types/components/salla-bullet-delivery/salla-bullet-delivery.d.ts +31 -0
  346. package/dist/types/components/salla-cart-coupons/salla-cart-coupons.d.ts +14 -0
  347. package/dist/types/components/salla-cart-summary-card/salla-cart-summary-card.d.ts +3 -0
  348. package/dist/types/global/chunk-errors.d.ts +2 -0
  349. package/package.json +5 -5
  350. package/dist/twilight/p-17f2114f.entry.js +0 -4
  351. package/dist/twilight/p-b81474c4.entry.js +0 -4
  352. package/dist/twilight/p-d851751c.entry.js +0 -4
@@ -0,0 +1,28 @@
1
+ /*!
2
+ * Crafted with ❤ by Salla
3
+ */
4
+ import { h } from "@stencil/core";
5
+ import LocationIcon from "./location-icon.svg";
6
+ const EARTH_RADIUS_KM = 6371;
7
+ const WARNING_KEY = 'pages.checkout.location_distance_warning';
8
+ const WARNING_FALLBACK = 'تبعد عن موقعك {distance} كم، وقد تكون اخترت عنوان توصيل غير صحيح.';
9
+ const toRadians = (degrees) => degrees * (Math.PI / 180);
10
+ /** Haversine distance between two coordinates in kilometres. */
11
+ export function calculateLocationDistanceKm(from, to) {
12
+ const latitudeDelta = toRadians(to.lat - from.lat);
13
+ const longitudeDelta = toRadians(to.lng - from.lng);
14
+ const fromLatitude = toRadians(from.lat);
15
+ const toLatitude = toRadians(to.lat);
16
+ const haversine = Math.sin(latitudeDelta / 2) ** 2 +
17
+ Math.cos(fromLatitude) *
18
+ Math.cos(toLatitude) *
19
+ Math.sin(longitudeDelta / 2) ** 2;
20
+ return EARTH_RADIUS_KM * 2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine));
21
+ }
22
+ export const LocationDistanceWarning = ({ distanceKm, isRTL = false, }) => {
23
+ const distance = distanceKm.toFixed(1);
24
+ const message = Salla.lang
25
+ .getWithDefault(WARNING_KEY, WARNING_FALLBACK)
26
+ ?.replace('{distance}', distance);
27
+ return (h("div", { class: "s-bullet-delivery-location-distance-warning", role: "alert" }, h("span", { class: "s-bullet-delivery-location-distance-warning-icon", innerHTML: LocationIcon, "aria-hidden": "true" }), h("span", { class: "s-bullet-delivery-location-distance-warning-text", style: { textAlign: isRTL ? 'right' : 'left' }, "data-testid": "salla-bullet-delivery-location-distance-warning-text" }, message)));
28
+ };
@@ -0,0 +1,26 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 172 172" width="172" height="172">
2
+ <!-- White rounded background -->
3
+ <rect width="172" height="172" rx="64" fill="#FFFFFF"/>
4
+
5
+ <!-- Location / navigation icon -->
6
+ <path
7
+ d="M113.5 52.5
8
+ C108.5 52.5 101.5 54.5 93.5 57
9
+ L57.5 68.5
10
+ C53.5 69.8 51.8 72.2 53 75
11
+ C53.8 77 55.5 78.2 58 79
12
+ L79.5 86.5
13
+ C81.8 87.3 83.2 88.8 84 91.2
14
+ L90.5 113
15
+ C91.7 117 94 119.2 97 119.2
16
+ C100.8 119.2 103 116.5 104.2 112.8
17
+ L119 70.5
18
+ C121 64.5 121.8 58.5 119.2 55.2
19
+ C117.8 53.3 116 52.5 113.5 52.5 Z"
20
+ fill="#FFFFFF"
21
+ stroke="#000000"
22
+ stroke-width="5.5"
23
+ stroke-linecap="round"
24
+ stroke-linejoin="round"
25
+ />
26
+ </svg>
@@ -0,0 +1,103 @@
1
+ /*!
2
+ * Crafted with ❤ by Salla
3
+ */
4
+ import { h } from "@stencil/core";
5
+ import LocationIcon from "./location-icon.svg";
6
+ const GEOLOCATION_TIMEOUT = 10000;
7
+ /** GeolocationPositionError.PERMISSION_DENIED — inlined; the class is absent in some test envs. */
8
+ const PERMISSION_DENIED = 1;
9
+ /** Action the Salla app listens for to open its own location-permission settings screen. */
10
+ const NATIVE_LOCATION_SETTINGS_ACTION = 'location.settings.open';
11
+ const NOTICE_KEY = 'pages.checkout.allow_location_permission';
12
+ const NOTICE_FALLBACK = 'اسمح بمشاركة موقعك لتحديد عنوانك تلقائيًا وبشكل أدق.';
13
+ /** Whether the notice should be rendered — only for a state we know is missing the permission. */
14
+ export const isLocationPermissionMissing = (state) => state === 'prompt' || state === 'denied';
15
+ /** `PermissionStatus` for geolocation, or null when the browser can't report it. */
16
+ async function queryLocationPermission() {
17
+ try {
18
+ if (!navigator?.permissions?.query || !navigator.geolocation)
19
+ return null;
20
+ return await navigator.permissions.query({ name: 'geolocation' });
21
+ }
22
+ catch {
23
+ // Browsers that don't know the 'geolocation' descriptor throw instead of resolving.
24
+ return null;
25
+ }
26
+ }
27
+ export async function getLocationPermissionState() {
28
+ const status = await queryLocationPermission();
29
+ return status?.state ?? 'unknown';
30
+ }
31
+ /**
32
+ * Reads the permission state and keeps reporting it while it changes, so the notice disappears the
33
+ * moment the customer grants access elsewhere (browser bar, OS settings) without a manual refresh.
34
+ *
35
+ * @returns an unsubscribe function — call it on disconnect.
36
+ */
37
+ export function watchLocationPermission(onChange) {
38
+ let stopped = false;
39
+ let status = null;
40
+ const handleChange = () => {
41
+ if (!stopped && status)
42
+ onChange(status.state);
43
+ };
44
+ queryLocationPermission().then(result => {
45
+ if (stopped)
46
+ return;
47
+ status = result;
48
+ if (!status) {
49
+ onChange('unknown');
50
+ return;
51
+ }
52
+ onChange(status.state);
53
+ status.addEventListener?.('change', handleChange);
54
+ });
55
+ return () => {
56
+ stopped = true;
57
+ status?.removeEventListener?.('change', handleChange);
58
+ status = null;
59
+ };
60
+ }
61
+ /** Hands the request to the Salla app inside a native webview; it opens its permission settings. */
62
+ function openNativeLocationSettings() {
63
+ const mobile = typeof Salla !== 'undefined' ? Salla.mobile : null;
64
+ if (!mobile?.isSpaWebview?.())
65
+ return false;
66
+ mobile.action?.(NATIVE_LOCATION_SETTINGS_ACTION);
67
+ return true;
68
+ }
69
+ /**
70
+ * Acts on a tap of the notice: native apps deep-link into their settings, the web always calls
71
+ * `getCurrentPosition` so the browser can re-show its permission dialog when the state is still
72
+ * `prompt`. If the site is permanently blocked, browsers stay silent and fail with
73
+ * `PERMISSION_DENIED`.
74
+ */
75
+ export async function requestLocationPermission() {
76
+ const current = await getLocationPermissionState();
77
+ if (openNativeLocationSettings()) {
78
+ return { state: current, handledByApp: true };
79
+ }
80
+ if (!navigator?.geolocation) {
81
+ return { state: 'denied', handledByApp: false };
82
+ }
83
+ try {
84
+ const { coords } = await new Promise((resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject, {
85
+ enableHighAccuracy: true,
86
+ timeout: GEOLOCATION_TIMEOUT,
87
+ maximumAge: 0,
88
+ }));
89
+ return {
90
+ state: 'granted',
91
+ handledByApp: false,
92
+ position: { lat: coords.latitude, lng: coords.longitude },
93
+ };
94
+ }
95
+ catch (error) {
96
+ // PERMISSION_DENIED means the browser will not (or did not) grant access — including the
97
+ // permanently-blocked case where no dialog appears. Timeouts / unavailable positions are not
98
+ // a refusal, so the previous state is kept.
99
+ const denied = error?.code === PERMISSION_DENIED;
100
+ return { state: denied ? 'denied' : current, handledByApp: false };
101
+ }
102
+ }
103
+ export const LocationPermissionNotice = ({ isRTL = false, onActivate, }) => (h("div", { class: "s-bullet-delivery-location-permission" }, h("button", { type: "button", class: "s-bullet-delivery-location-permission-btn", onClick: onActivate }, h("span", { class: "s-bullet-delivery-location-permission-icon", innerHTML: LocationIcon, "aria-hidden": "true" }), h("span", { class: "s-bullet-delivery-location-permission-text", style: { textAlign: isRTL ? 'right' : 'left' }, "data-testid": "salla-bullet-delivery-location-permission-text" }, Salla.lang.getWithDefault(NOTICE_KEY, NOTICE_FALLBACK)), h("i", { class: `s-bullet-delivery-location-permission-arrow ${isRTL ? 'sicon-keyboard_arrow_left' : 'sicon-keyboard_arrow_right'}`, "aria-hidden": "true" }))));
@@ -53,6 +53,75 @@
53
53
  text-transform: uppercase;
54
54
  }
55
55
 
56
+ .s-bullet-delivery-location-permission-btn {
57
+ display: flex;
58
+ align-items: center;
59
+ gap: 10px;
60
+ width: 100%;
61
+ padding: 12px;
62
+ border: none;
63
+ border-radius: 8px;
64
+ background: #fdf2f2;
65
+ cursor: pointer;
66
+ text-align: start;
67
+ }
68
+
69
+ /* The asset is a 172x172 white badge with its own colors baked in, so it only needs sizing. */
70
+ .s-bullet-delivery-location-permission-icon {
71
+ display: inline-flex;
72
+ flex-shrink: 0;
73
+ width: 34px;
74
+ height: 34px;
75
+ }
76
+ .s-bullet-delivery-location-permission-icon svg {
77
+ width: 100%;
78
+ height: 100%;
79
+ }
80
+
81
+ .s-bullet-delivery-location-permission-text {
82
+ flex: 1;
83
+ min-width: 0;
84
+ font-size: 12px;
85
+ line-height: 18px;
86
+ color: #444;
87
+ }
88
+
89
+ .s-bullet-delivery-location-permission-arrow {
90
+ flex-shrink: 0;
91
+ font-size: 16px;
92
+ color: #666;
93
+ }
94
+
95
+ .s-bullet-delivery-location-distance-warning {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 10px;
99
+ width: 100%;
100
+ padding: 12px;
101
+ border-radius: 8px;
102
+ background: #fff8e1;
103
+ animation: s-bullet-delivery-fade-in 200ms ease;
104
+ }
105
+
106
+ .s-bullet-delivery-location-distance-warning-icon {
107
+ display: inline-flex;
108
+ flex-shrink: 0;
109
+ width: 34px;
110
+ height: 34px;
111
+ }
112
+ .s-bullet-delivery-location-distance-warning-icon svg {
113
+ width: 100%;
114
+ height: 100%;
115
+ }
116
+
117
+ .s-bullet-delivery-location-distance-warning-text {
118
+ flex: 1;
119
+ min-width: 0;
120
+ font-size: 12px;
121
+ line-height: 18px;
122
+ color: #444;
123
+ }
124
+
56
125
  .s-bullet-delivery-map-container {
57
126
  width: 100%;
58
127
  height: 320px;
@@ -1339,3 +1408,70 @@
1339
1408
  flex-shrink: 0;
1340
1409
  align-self: center;
1341
1410
  }
1411
+ .s-bullet-delivery-location-permission-btn{
1412
+ display: flex;
1413
+ width: 100%;
1414
+ cursor: pointer;
1415
+ align-items: center;
1416
+ gap: 0.625rem;
1417
+ border-radius: 0.5rem;
1418
+ border-width: 0px;
1419
+ padding: 0.75rem;
1420
+ text-align: start;
1421
+ background: #fdf2f2;
1422
+ }
1423
+ .s-bullet-delivery-location-permission-icon{
1424
+ display: inline-flex;
1425
+ height: 34px;
1426
+ width: 34px;
1427
+ flex-shrink: 0;
1428
+ }
1429
+ .s-bullet-delivery-location-permission-icon svg{
1430
+ height: 100%;
1431
+ width: 100%;
1432
+ }
1433
+ .s-bullet-delivery-location-permission-text{
1434
+ min-width: 0px;
1435
+ flex: 1 1 0%;
1436
+ font-size: 0.75rem;
1437
+ line-height: 1rem;
1438
+ line-height: 18px;
1439
+ --tw-text-opacity: 1;
1440
+ color: rgb(68 68 68 / var(--tw-text-opacity, 1));
1441
+ }
1442
+ .s-bullet-delivery-location-permission-arrow{
1443
+ flex-shrink: 0;
1444
+ font-size: 1rem;
1445
+ line-height: 1.5rem;
1446
+ --tw-text-opacity: 1;
1447
+ color: rgb(102 102 102 / var(--tw-text-opacity, 1));
1448
+ }
1449
+ .s-bullet-delivery-location-distance-warning{
1450
+ display: flex;
1451
+ width: 100%;
1452
+ animation: s-bullet-delivery-fade-in 200ms ease;
1453
+ align-items: center;
1454
+ gap: 0.625rem;
1455
+ border-radius: 0.5rem;
1456
+ padding: 0.75rem;
1457
+ background: #fff8e1;
1458
+ }
1459
+ .s-bullet-delivery-location-distance-warning-icon{
1460
+ display: inline-flex;
1461
+ height: 34px;
1462
+ width: 34px;
1463
+ flex-shrink: 0;
1464
+ }
1465
+ .s-bullet-delivery-location-distance-warning-icon svg{
1466
+ height: 100%;
1467
+ width: 100%;
1468
+ }
1469
+ .s-bullet-delivery-location-distance-warning-text{
1470
+ min-width: 0px;
1471
+ flex: 1 1 0%;
1472
+ font-size: 0.75rem;
1473
+ line-height: 1rem;
1474
+ line-height: 18px;
1475
+ --tw-text-opacity: 1;
1476
+ color: rgb(68 68 68 / var(--tw-text-opacity, 1));
1477
+ }
@@ -3,7 +3,10 @@
3
3
  */
4
4
  import { h, Host, } from "@stencil/core";
5
5
  import { bulletDeliveryAPI, clearApiCache, isSaudiArabia } from "./api-service";
6
- import { filterBranches, findNearestBranch, getGeolocationErrorMessage, getIntentBranchId, getIntentCityId, getIntentCountryCode, getIntentCountryId, getIntentDistrictId, getIntentLatitude, getIntentLongitude, getIntentRegionId, getIntentSubtitle, hasSessionAddressIntent, isMapOriginIntent, isBranchSelectable, requireRegionAndDistrictForSA, } from "./helpers";
6
+ import { filterBranches, findNearestBranch, getGeolocationErrorMessage, getIntentBranchId, getIntentCityId, getIntentCountryCode, getIntentCountryId, getIntentDistrictId, getIntentLatitude, getIntentLongitude, getIntentRegionId, getIntentSubtitle, hasSessionAddressIntent, isBranchSelectable, isMapOriginIntent, requireRegionAndDistrictForSA, } from "./helpers";
7
+ /* Location permission notice */
8
+ import { isLocationPermissionMissing, LocationPermissionNotice, requestLocationPermission, watchLocationPermission, } from "./location-permission-notice";
9
+ import { calculateLocationDistanceKm, LocationDistanceWarning, } from "./location-distance-warning";
7
10
  const BRANCH_SEARCH_DEBOUNCE_MS = 1000;
8
11
  const GEOLOCATION_TIMEOUT = 10000;
9
12
  /** Final fallback center used only if `user.default_geo_location` is absent (Riyadh — matches checkout map-page). */
@@ -127,6 +130,14 @@ export class SallaBulletDelivery {
127
130
  /** True while reverse-geocoding a map-click/geolocation pick (no place from the map component itself). */
128
131
  this.reverseGeocoding = false;
129
132
  this.confirming = false;
133
+ /** Location-sharing permission, watched so the map-view notice follows it live (SHPD-10429). */
134
+ this.locationPermission = 'unknown';
135
+ this.stopWatchingLocationPermission = null;
136
+ /** False until the Permissions API watch reports at least once — gates auto-locate so we don't
137
+ * consume the browser prompt before we know whether the notice should own it. */
138
+ this.locationPermissionResolved = false;
139
+ /** Customer's live position, kept separate from the selected delivery pin. */
140
+ this.liveLocation = null;
130
141
  this.newAddressForm = {
131
142
  ...SallaBulletDelivery.INITIAL_ADDRESS_FORM,
132
143
  };
@@ -236,23 +247,46 @@ export class SallaBulletDelivery {
236
247
  this.gmapRef.resize();
237
248
  }
238
249
  this.updateLocationBias();
239
- // Auto-locate the customer so the map never opens "empty" — matches checkout map-page
240
- // (getCurrentLocation(true) pans to the resolved position). Skip if a location is already set
241
- // (e.g. returning from the confirm step). Falls back silently to mapInitialCenter if denied.
242
- if (!this.autoGeolocationTriggered && !this.hasMapLocation() && this.gmapRef) {
243
- const getCurrentLocation = this.gmapRef.getCurrentLocation;
244
- if (typeof getCurrentLocation === 'function') {
245
- this.autoGeolocationTriggered = true;
246
- try {
247
- const result = getCurrentLocation.call(this.gmapRef, true);
248
- if (result && typeof result.catch === 'function') {
249
- result.catch((err) => log('Auto geolocation failed', err));
250
- }
251
- }
252
- catch (err) {
253
- log('Auto geolocation threw', err);
254
- }
255
- }
250
+ this.locateOnMap();
251
+ if (this.locationPermission === 'granted' && !this.liveLocation) {
252
+ void this.handleLocationPermissionChanged('granted');
253
+ }
254
+ };
255
+ /** Tap on the location-permission notice: prompt (or deep-link into the app's settings). */
256
+ this.handleLocationPermissionRequest = async () => {
257
+ const outcome = await requestLocationPermission();
258
+ if (outcome.handledByApp)
259
+ return; // native app owns the screen from here
260
+ await this.handleLocationPermissionChanged(outcome.state, outcome.position);
261
+ if (outcome.state === 'granted')
262
+ this.locateOnMap(true);
263
+ };
264
+ this.handleLocationPermissionChanged = async (state, knownPosition) => {
265
+ this.locationPermission = state;
266
+ if (state !== 'granted') {
267
+ this.liveLocation = null;
268
+ return;
269
+ }
270
+ if (knownPosition) {
271
+ this.liveLocation = knownPosition;
272
+ return;
273
+ }
274
+ // Only the map view reads liveLocation — skip the GPS fix until it opens (handleMapReady catches up).
275
+ if (!navigator.geolocation || !this.mapReady)
276
+ return;
277
+ try {
278
+ const position = await new Promise((resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject, {
279
+ enableHighAccuracy: true,
280
+ timeout: GEOLOCATION_TIMEOUT,
281
+ maximumAge: 0,
282
+ }));
283
+ this.liveLocation = {
284
+ lat: position.coords.latitude,
285
+ lng: position.coords.longitude,
286
+ };
287
+ }
288
+ catch (error) {
289
+ log('Live location capture failed', error);
256
290
  }
257
291
  };
258
292
  // ─── End Map methods ───
@@ -1354,6 +1388,45 @@ export class SallaBulletDelivery {
1354
1388
  : this.mapInitialCenter;
1355
1389
  this.gmapRef.autocompleteLocationBias = { center, radius: 500000 };
1356
1390
  }
1391
+ /**
1392
+ * Auto-locate the customer so the map never opens "empty" — matches checkout map-page
1393
+ * (getCurrentLocation(true) pans to the resolved position). Skipped when a location is already
1394
+ * set (e.g. returning from the confirm step). Falls back silently to mapInitialCenter if denied.
1395
+ *
1396
+ * When location permission is still missing (`prompt` / `denied`), we deliberately do NOT call
1397
+ * into geolocation here — that would consume the browser's one-shot permission dialog before the
1398
+ * notice tap can re-trigger it (SHPD-10429). Auto-locate runs once permission is granted
1399
+ * (via the watch or a successful notice tap), or when the Permissions API is unavailable
1400
+ * (`unknown`) because that surface never shows the notice.
1401
+ *
1402
+ * @param force re-locates even after the one-per-flow auto attempt — used once the customer
1403
+ * grants the permission from the notice, so the map catches up without a manual refresh.
1404
+ */
1405
+ locateOnMap(force = false) {
1406
+ if (!this.gmapRef)
1407
+ return;
1408
+ if (!force) {
1409
+ if (this.autoGeolocationTriggered || this.hasMapLocation())
1410
+ return;
1411
+ // Wait until we know the permission state, then leave prompt/denied for the notice tap.
1412
+ if (!this.locationPermissionResolved || isLocationPermissionMissing(this.locationPermission)) {
1413
+ return;
1414
+ }
1415
+ }
1416
+ const getCurrentLocation = this.gmapRef.getCurrentLocation;
1417
+ if (typeof getCurrentLocation !== 'function')
1418
+ return;
1419
+ this.autoGeolocationTriggered = true;
1420
+ try {
1421
+ const result = getCurrentLocation.call(this.gmapRef, true);
1422
+ if (result && typeof result.catch === 'function') {
1423
+ result.catch((err) => log('Auto geolocation failed', err));
1424
+ }
1425
+ }
1426
+ catch (err) {
1427
+ log('Auto geolocation threw', err);
1428
+ }
1429
+ }
1357
1430
  hasMapLocation() {
1358
1431
  return this.mapLocationData?.lat != null && this.mapLocationData?.lng != null;
1359
1432
  }
@@ -2338,10 +2411,34 @@ export class SallaBulletDelivery {
2338
2411
  const address = this.mapLocationData?.formattedAddress ?? '';
2339
2412
  return (h("div", { class: "s-bullet-delivery-address-confirm" }, h("div", { class: "s-bullet-delivery-address-confirm-card" }, h("span", { class: "s-bullet-delivery-address-map-icon", innerHTML: MiniMap, "aria-hidden": "true" }), h("div", { class: "s-bullet-delivery-address-confirm-details" }, h("span", { class: "s-bullet-delivery-address-confirm-label" }, Salla.lang.get('pages.checkout.selected_address')), h("p", { class: "s-bullet-delivery-address-confirm-text" }, address))), h("div", { class: "s-bullet-delivery-address-confirm-description" }, h("label", { class: "s-bullet-delivery-address-confirm-description-label" }, Salla.lang.get('pages.checkout.address_description'), h("span", { class: "s-bullet-delivery-address-confirm-description-optional" }, Salla.lang.get('common.elements.optional'))), h("input", { type: "text", class: "s-bullet-delivery-address-confirm-description-input form-input", placeholder: Salla.lang.get('pages.checkout.address_description_placeholder'), value: this.addressDescription, onInput: (e) => { this.addressDescription = e.target.value; } }))));
2340
2413
  }
2414
+ /** Notice prompting the customer to allow location sharing; only while it isn't granted. */
2415
+ renderLocationPermissionNotice() {
2416
+ if (!isLocationPermissionMissing(this.locationPermission))
2417
+ return null;
2418
+ return (h(LocationPermissionNotice, { isRTL: this.isRTL, onActivate: this.handleLocationPermissionRequest }));
2419
+ }
2420
+ renderLocationDistanceWarning() {
2421
+ const selectedLocation = this.mapLocationData;
2422
+ if (this.locationPermission !== 'granted' ||
2423
+ !this.liveLocation ||
2424
+ selectedLocation?.lat == null ||
2425
+ selectedLocation?.lng == null) {
2426
+ return null;
2427
+ }
2428
+ const distanceKm = calculateLocationDistanceKm(this.liveLocation, {
2429
+ lat: selectedLocation.lat,
2430
+ lng: selectedLocation.lng,
2431
+ });
2432
+ if (distanceKm <= 0.5)
2433
+ return null;
2434
+ return h(LocationDistanceWarning, { distanceKm: distanceKm, isRTL: this.isRTL });
2435
+ }
2341
2436
  renderGuestDeliveryForm() {
2342
2437
  if (this.isMapModeAvailable) {
2343
2438
  return [
2344
2439
  this.renderMapSection(),
2440
+ this.renderLocationPermissionNotice(),
2441
+ this.renderLocationDistanceWarning(),
2345
2442
  this.hasMapLocation() ? this.renderAddressConfirmation() : null,
2346
2443
  ];
2347
2444
  }
@@ -2602,6 +2699,17 @@ export class SallaBulletDelivery {
2602
2699
  this.closeHandler = this.close.bind(this);
2603
2700
  Salla.event.on("salla::bullet-delivery.modal.close.requested", this.closeHandler);
2604
2701
  this.isRTL = Salla.config.get("theme.is_rtl");
2702
+ // Reading the permission never prompts, so it's safe to watch from here — the map view then
2703
+ // renders the notice (or not) on its first paint instead of a frame later.
2704
+ this.stopWatchingLocationPermission = watchLocationPermission(state => {
2705
+ this.locationPermissionResolved = true;
2706
+ void this.handleLocationPermissionChanged(state).then(() => {
2707
+ // Permission often resolves after the map is ready — catch up for granted / unknown
2708
+ // so we still auto-pan without having consumed the prompt for prompt/denied.
2709
+ if (this.mapReady && !isLocationPermissionMissing(state))
2710
+ this.locateOnMap();
2711
+ });
2712
+ });
2605
2713
  this.authLoggedInHandler = async () => {
2606
2714
  if (this.cartSubmitConfirmationPending) {
2607
2715
  await this.handlePendingSubmitAfterLogin();
@@ -2646,7 +2754,7 @@ export class SallaBulletDelivery {
2646
2754
  return null; // no-op when disabled
2647
2755
  return (h(Host, { class: "s-bullet-delivery" }, h("salla-modal", { ref: modal => {
2648
2756
  this.modal = modal;
2649
- }, isClosable: !this.isRequired && !this.shouldForceNonClosable(), class: "s-bullet-delivery-modal", width: "sm" }, h("div", { class: "s-bullet-delivery-inner" }, h("div", { class: "s-bullet-delivery-header" }, h("h2", { class: "s-bullet-delivery-title" }, this.activeTab === 'address'
2757
+ }, isClosable: !this.isRequired && !this.shouldForceNonClosable(), class: "s-bullet-delivery-modal", width: "sm", "data-testid": "salla-bullet-delivery-modal" }, h("div", { class: "s-bullet-delivery-inner" }, h("div", { class: "s-bullet-delivery-header" }, h("h2", { class: "s-bullet-delivery-title" }, this.activeTab === 'address'
2650
2758
  ? Salla.lang.get('blocks.home.add_address_for_order_delivery')
2651
2759
  : Salla.lang.get('blocks.home.choose_branch_for_order_pickup')), h("p", { class: "s-bullet-delivery-subtitle" }, this.activeTab === 'address'
2652
2760
  ? Salla.lang.get('blocks.home.products_available_for_delivery_shown_while_shopping')
@@ -2726,6 +2834,10 @@ export class SallaBulletDelivery {
2726
2834
  }
2727
2835
  disconnectedCallback() {
2728
2836
  this.componentReady = false;
2837
+ if (this.stopWatchingLocationPermission) {
2838
+ this.stopWatchingLocationPermission();
2839
+ this.stopWatchingLocationPermission = null;
2840
+ }
2729
2841
  Salla.event.off("salla::bullet-delivery.modal.open.requested", this.bulletDeliveryOpenHandler);
2730
2842
  if (this.closeHandler) {
2731
2843
  Salla.event.off("salla::bullet-delivery.modal.close.requested", this.closeHandler);
@@ -2833,6 +2945,8 @@ export class SallaBulletDelivery {
2833
2945
  "addressDescription": {},
2834
2946
  "reverseGeocoding": {},
2835
2947
  "confirming": {},
2948
+ "locationPermission": {},
2949
+ "liveLocation": {},
2836
2950
  "newAddressForm": {}
2837
2951
  };
2838
2952
  }