wickes-css2 2.107.0-ripple.2 → 2.107.0-ripple.21

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 (307) hide show
  1. package/build/css/category-main.css +1 -1
  2. package/build/css/components/card-product-banner.css +1 -1
  3. package/build/css/components/checkout-chip.css +1 -1
  4. package/build/css/components/checkout-payment-details-v2.css +1 -1
  5. package/build/css/components/price-block-v2-critical.css +1 -1
  6. package/build/css/components/price-block-v2.css +1 -1
  7. package/build/css/components/special-opening-schedule-v2.css +1 -1
  8. package/build/css/components/special-opening-schedule.css +1 -1
  9. package/build/css/emulation.css +1 -1
  10. package/build/css/homepage-main.css +1 -1
  11. package/build/css/kitchen-plp-main.css +1 -1
  12. package/build/css/main.css +1 -1
  13. package/build/css/my-account-main-v2.css +1 -1
  14. package/build/css/my-account-main.css +1 -1
  15. package/build/css/pages/checkout-new.css +1 -1
  16. package/build/css/pages/my-account-v2.css +1 -1
  17. package/build/css/pages/page_checkout_delivery-new.css +1 -1
  18. package/build/css/pages/page_merged-basket.css +1 -1
  19. package/build/css/pages/page_personal-details.css +1 -1
  20. package/build/css/pages/page_product-details-v2-critical.css +1 -1
  21. package/build/css/pages/page_product-details-v2.css +1 -1
  22. package/build/css/pages/page_product-details.css +1 -1
  23. package/build/css/pages/page_products-list-combined.css +1 -1
  24. package/build/css/pages/page_products-list.css +1 -1
  25. package/build/css/pages/page_shopping-cart-v2.css +1 -1
  26. package/build/css/pages/page_store-locator-details.css +1 -1
  27. package/build/css/pages/page_store-locator.css +1 -1
  28. package/build/css/pdp-main-before-combine.css +1 -1
  29. package/build/css/pdp-main-critical.css +1 -1
  30. package/build/css/pdp-main-non-critical.css +1 -1
  31. package/build/css/pdp-main.css +1 -1
  32. package/build/css/plp-main.css +1 -1
  33. package/build/css/store-locator-main.css +1 -1
  34. package/build/js/account-hub.min.js +1 -1
  35. package/build/js/basket.min.js +2 -2
  36. package/build/js/bloomreach-widget.min.js +1 -0
  37. package/build/js/bundle.min.js +1 -1
  38. package/build/js/checkout.min.js +2 -2
  39. package/build/js/components/general/accordion.js +69 -0
  40. package/build/js/components/general/back-to-top.js +45 -0
  41. package/build/js/components/general/backdrop.js +23 -0
  42. package/build/js/components/general/cart-slider.js +36 -0
  43. package/build/js/components/general/clamp-content.js +95 -0
  44. package/build/js/components/general/clamp.js +216 -0
  45. package/build/js/components/general/clear-input.js +33 -0
  46. package/build/js/components/general/cookie-chat-back.js +51 -0
  47. package/build/js/components/general/cookies-policy.js +9 -0
  48. package/build/js/components/general/create-popup-slider.js +194 -0
  49. package/build/js/components/general/device-type.js +6 -0
  50. package/build/js/components/general/footer.js +67 -0
  51. package/build/js/components/general/handleAccordion.js +35 -0
  52. package/build/js/components/general/image-accordion.js +54 -0
  53. package/build/js/components/general/is-trade-pro.js +38 -0
  54. package/build/js/components/general/main-nav.js +16 -0
  55. package/build/js/components/general/main-navigation.js +275 -0
  56. package/build/js/components/general/notification.js +70 -0
  57. package/build/js/components/general/offer-banner.js +74 -0
  58. package/build/js/components/general/scroll-disable.js +54 -0
  59. package/build/js/components/general/search.js +43 -0
  60. package/build/js/components/general/snack-bar.js +160 -0
  61. package/build/js/components/general/sticky_header.js +62 -0
  62. package/build/js/components/general/switchVat.js +161 -0
  63. package/build/js/components/general/text-clamp.js +102 -0
  64. package/build/js/components/general/tooltips.js +8 -0
  65. package/build/js/components/general/validation.js +48 -0
  66. package/build/js/emulation.min.js +3377 -164
  67. package/build/js/general.bundle.min.js +1 -1
  68. package/build/js/gift-cards.min.js +1 -1
  69. package/build/js/kitchen/kitchen-plp.min.js +1 -1
  70. package/build/js/merged-checkout.min.js +2 -2
  71. package/build/js/mini-basket-slider.min.js +1 -1
  72. package/build/js/package-bulk-add.min.js +1 -0
  73. package/build/js/page/basket/mini-basket-total.js +17 -2
  74. package/build/js/page/bloomreach-widget.js +1148 -0
  75. package/build/js/page/checkout-payment-details.js +12 -1
  76. package/build/js/page/checkout.js +1 -1
  77. package/build/js/page/components/notify-me.js +99 -0
  78. package/build/js/page/components/order-summary.js +35 -0
  79. package/build/js/page/plp-load-more.js +81 -66
  80. package/build/js/page/ripple/bulk-add.js +63 -0
  81. package/build/js/page/ripple/package-bulk-add.js +43 -0
  82. package/build/js/page/ripple/postcode-checker.js +83 -0
  83. package/build/js/page/ripple/thumb-gallery.js +168 -0
  84. package/build/js/page/utils/create-count-stepper.js +30 -9
  85. package/build/js/page/utils/create-loading-button.js +37 -0
  86. package/build/js/page/utils/create-toast.js +79 -0
  87. package/build/js/page/utils/custom-dropdown.js +80 -0
  88. package/build/js/pdp-count-stepper.min.js +1 -1
  89. package/build/js/pdp.bundle.min.js +2 -1
  90. package/build/js/plp.bundle.min.js +1 -1
  91. package/build/js/postcode-checker.min.js +1 -0
  92. package/build/js/project-list.min.js +1 -1
  93. package/build/js/saving-shopping-list.min.js +1 -1
  94. package/build/js/wickes-dc.js +1 -0
  95. package/package.json +1 -4
  96. package/src/badges-ripple.html +120 -0
  97. package/src/badges.html +9 -18
  98. package/src/components/base/button.hbs +23 -5
  99. package/src/components/bloomreach/complete-card-dropdown.hbs +47 -0
  100. package/src/components/bloomreach/complete-card-skeleton.hbs +19 -0
  101. package/src/components/bloomreach/complete-card.hbs +138 -0
  102. package/src/components/bloomreach/complete-divider.hbs +3 -0
  103. package/src/components/bloomreach/complete-summary-skeleton.hbs +12 -0
  104. package/src/components/bloomreach/complete-summary.hbs +43 -0
  105. package/src/components/bloomreach/complete-wrapper.hbs +1 -0
  106. package/src/components/bloomreach/complete-your-project.hbs +21 -0
  107. package/src/components/card-store-locator.hbs +70 -33
  108. package/src/components/card_bloomreach_media_banner.hbs +10 -0
  109. package/src/components/card_product_banner_v2.hbs +4 -1
  110. package/src/components/card_sponsor_banner.hbs +4 -1
  111. package/src/components/cart-voucher.hbs +10 -1
  112. package/src/components/checkout_order-summary-new.hbs +11 -2
  113. package/src/components/click-and-collect-modal.hbs +0 -14
  114. package/src/components/date-selection.hbs +1 -1
  115. package/src/components/delivery-types.hbs +11 -3
  116. package/src/components/fulfilment-accordions.hbs +1 -1
  117. package/src/components/gift-cards.hbs +1 -1
  118. package/src/components/injected-content.hbs +6 -1
  119. package/src/components/kitchen/price.hbs +49 -29
  120. package/src/components/kitchen/strip-stickers.hbs +9 -3
  121. package/src/components/modal.hbs +1 -1
  122. package/src/components/modals/notify-me-modal.hbs +76 -0
  123. package/src/components/order-item.hbs +18 -5
  124. package/src/components/order-summary.hbs +2 -2
  125. package/src/components/package-card.hbs +30 -0
  126. package/src/components/pdp-price-actions.hbs +17 -0
  127. package/src/components/postcode-checker.hbs +24 -0
  128. package/src/components/potential-promotion.hbs +12 -3
  129. package/src/components/price-badges.hbs +14 -0
  130. package/src/components/price-block-v2.hbs +91 -31
  131. package/src/components/product-main-info-v2.hbs +2 -0
  132. package/src/components/sponsor-top-banner.hbs +10 -0
  133. package/src/components/suite-includes.hbs +43 -12
  134. package/src/components/suite-product-card.hbs +37 -15
  135. package/src/components/thumb-gallery.hbs +23 -0
  136. package/src/data/data_badges.json +143 -0
  137. package/src/data/data_bathroom-plp.json +814 -0
  138. package/src/data/data_delivery-address-v2.json +1 -1
  139. package/src/data/data_locators.json +441 -135
  140. package/src/data/data_search-results_v2.json +20 -2
  141. package/src/data/data_shopping-cart-v2.json +23 -5
  142. package/src/data/data_spr_injected_content.json +4 -0
  143. package/src/data/data_suite-includes-products.json +73 -2
  144. package/src/elements/checkbox.hbs +8 -1
  145. package/src/js/components/banner-placement-manager.js +25 -9
  146. package/src/js/components/general/accordion.js +25 -2
  147. package/src/js/components/general/cart-slider.js +19 -6
  148. package/src/js/components/package-card.js +69 -0
  149. package/src/js/components/store-locator-cards.js +76 -0
  150. package/src/js/emulation/banner-placement-manager.js +285 -53
  151. package/src/js/emulation/bloomreach-widget-calculations.js +132 -0
  152. package/src/js/emulation/bloomreach-widget-loading.js +11 -0
  153. package/src/js/emulation/checkout-delivery-details.js +28 -25
  154. package/src/js/emulation/custom-slider-emulation.js +1 -1
  155. package/src/js/emulation/date-selection.js +136 -24
  156. package/src/js/emulation/forms.js +12 -0
  157. package/src/js/emulation/gift-cards.js +1 -1
  158. package/src/js/emulation/mini-basket-data.js +3 -3
  159. package/src/js/emulation/mock.js +3112 -4
  160. package/src/js/emulation/notify-me.js +9 -0
  161. package/src/js/emulation/plp-load-more.js +13 -4
  162. package/src/js/emulation/postcode-checker.js +11 -0
  163. package/src/js/emulation/store-locator-load-more.js +69 -0
  164. package/src/js/emulation/switchCalendar.js +12 -8
  165. package/src/js/page/basket/mini-basket-total.js +17 -2
  166. package/src/js/page/bloomreach-widget.js +1148 -0
  167. package/src/js/page/checkout-payment-details.js +12 -1
  168. package/src/js/page/checkout.js +1 -1
  169. package/src/js/page/components/notify-me.js +99 -0
  170. package/src/js/page/components/order-summary.js +35 -0
  171. package/src/js/page/plp-load-more.js +81 -66
  172. package/src/js/page/ripple/bulk-add.js +63 -0
  173. package/src/js/page/ripple/package-bulk-add.js +43 -0
  174. package/src/js/page/ripple/postcode-checker.js +83 -0
  175. package/src/js/page/ripple/thumb-gallery.js +168 -0
  176. package/src/js/page/utils/create-count-stepper.js +30 -9
  177. package/src/js/page/utils/create-loading-button.js +37 -0
  178. package/src/js/page/utils/create-toast.js +79 -0
  179. package/src/js/page/utils/custom-dropdown.js +80 -0
  180. package/src/page_bathroom-plp-vat.html +81 -0
  181. package/src/page_bathroom-plp-without-load-more.html +83 -0
  182. package/src/page_bathroom-plp.html +98 -0
  183. package/src/page_checkout_next-day-delivery-details.html +2 -2
  184. package/src/page_checkout_payment-details-v2-asm.html +1 -1
  185. package/src/page_checkout_payment-details-v2.html +1 -1
  186. package/src/page_checkout_payment-details_with-card-loader.html +1 -1
  187. package/src/page_checkout_payment-details_with-klarna-loader.html +1 -1
  188. package/src/page_checkout_payment-details_with-loader-v2.html +1 -1
  189. package/src/page_checkout_rapid-delivery-details.html +7 -5
  190. package/src/page_klarna_payment-details_with-klarna.html +1 -1
  191. package/src/page_my-account-installer-carousel.html +131 -0
  192. package/src/page_payment-details-with-billie.html +1 -1
  193. package/src/page_payment-details-with-clearpay.html +1 -1
  194. package/src/page_payment-details-with-gift-card.html +1 -1
  195. package/src/page_payment-details_with_apple-pay.html +1 -1
  196. package/src/page_payment-details_with_google-pay.html +1 -1
  197. package/src/page_plp_bloomreach.html +81 -0
  198. package/src/page_plp_v2.html +6 -0
  199. package/src/page_product-details-banner.html +1 -4
  200. package/src/page_product-details-big-wins-disabled-delivery.html +1 -4
  201. package/src/page_product-details-big-wins-non-registered.html +1 -4
  202. package/src/page_product-details-big-wins-out-nearest.html +1 -4
  203. package/src/page_product-details-big-wins-unhappy.html +1 -4
  204. package/src/page_product-details-big-wins.html +1 -4
  205. package/src/page_product-details-billie.html +1 -4
  206. package/src/page_product-details-bloomreach.html +130 -0
  207. package/src/page_product-details-calculator.html +1 -4
  208. package/src/page_product-details-cashback-v2.html +1 -4
  209. package/src/page_product-details-clearpay.html +1 -4
  210. package/src/page_product-details-cnc-error-notification.html +1 -4
  211. package/src/page_product-details-cnc-success-notification-vat.html +1 -5
  212. package/src/page_product-details-cnc-success-notification.html +1 -4
  213. package/src/page_product-details-default-store.html +1 -4
  214. package/src/page_product-details-energy-efficiency.html +1 -4
  215. package/src/page_product-details-flooring-with-pr-placeholder.html +1 -4
  216. package/src/page_product-details-flooring.html +1 -4
  217. package/src/page_product-details-gallery-actual.html +1 -4
  218. package/src/page_product-details-mfe-calculator.html +10 -7
  219. package/src/page_product-details-minimum-v2.html +0 -1
  220. package/src/page_product-details-mtm-doors.html +1 -4
  221. package/src/page_product-details-only-clearpay.html +1 -4
  222. package/src/page_product-details-paint-mixing.html +1 -4
  223. package/src/page_product-details-ripple-gallery.html +119 -0
  224. package/src/page_product-details-saved-pl.html +1 -4
  225. package/src/page_product-details-suite-includes-banners.html +139 -0
  226. package/src/page_product-details-suite-includes-vat.html +126 -0
  227. package/src/page_product-details-suite-includes.html +32 -20
  228. package/src/page_product-details-tile-steps-klarna-widget-with-method-ids.html +1 -4
  229. package/src/page_product-details-tile-steps-logout.html +1 -4
  230. package/src/page_product-details-tile-steps-no-new-project-list.html +1 -4
  231. package/src/page_product-details-tile-steps-with-klarna.html +1 -4
  232. package/src/page_product-details-tile-steps.html +1 -4
  233. package/src/page_product-details-v2.html +1 -4
  234. package/src/page_product-details-vat.html +1 -4
  235. package/src/page_product-details-wisdom-mcfc-registered.html +1 -4
  236. package/src/page_product-details-wisdom-mcfc.html +1 -4
  237. package/src/page_product-details-wisdom-oos-registered.html +1 -4
  238. package/src/page_product-details-wisdom-oos.html +1 -4
  239. package/src/page_product-details-wisdom-registered.html +1 -4
  240. package/src/page_product-details-wisdom.html +1 -4
  241. package/src/page_product-details-with-favourite.html +1 -4
  242. package/src/page_product-details-with-global-search-v2.html +8 -4
  243. package/src/page_product-details_no-previous-default.html +1 -4
  244. package/src/page_shopping-cart-v2-vat.html +2 -1
  245. package/src/page_store-locator-list.html +17 -28
  246. package/src/page_track-my-order-result.html +1 -0
  247. package/src/partials/scripts.hbs +1 -0
  248. package/src/scss/common/_CTAs.scss +7 -3
  249. package/src/scss/common/_common.scss +1 -0
  250. package/src/scss/common/_elements.scss +13 -1
  251. package/src/scss/common/_loading-button.scss +49 -0
  252. package/src/scss/components/_card-store-locator.scss +139 -32
  253. package/src/scss/components/_custom-slider.scss +18 -0
  254. package/src/scss/components/_date-selection-add-new-styles.scss +43 -1
  255. package/src/scss/components/_image-accordion.scss +5 -2
  256. package/src/scss/components/_kitchen-card.scss +5 -4
  257. package/src/scss/components/_notifications.scss +86 -5
  258. package/src/scss/components/_notify-me-modal.scss +139 -0
  259. package/src/scss/components/_order-summary.scss +25 -12
  260. package/src/scss/components/_package-card.scss +63 -0
  261. package/src/scss/components/_package-plp.scss +88 -0
  262. package/src/scss/components/_pdp-action-v2-critical.scss +12 -0
  263. package/src/scss/components/_pdp-action-v2.scss +12 -0
  264. package/src/scss/components/_postcode-checker.scss +115 -0
  265. package/src/scss/components/_price-badges-critical.scss +10 -1
  266. package/src/scss/components/_price-badges.scss +10 -2
  267. package/src/scss/components/_price-block-critical.scss +11 -3
  268. package/src/scss/components/_price-block.scss +15 -4
  269. package/src/scss/components/_suite-includes.scss +29 -26
  270. package/src/scss/components/_suite-product-card.scss +33 -23
  271. package/src/scss/components/_thumb-gallery-critical.scss +34 -0
  272. package/src/scss/components/_thumb-gallery.scss +192 -0
  273. package/src/scss/components/bloomreach/_bloomreach.scss +3 -0
  274. package/src/scss/components/bloomreach/_complete-card-dropdown.scss +174 -0
  275. package/src/scss/components/bloomreach/_complete-card.scss +402 -0
  276. package/src/scss/components/bloomreach/_complete-your-project.scss +207 -0
  277. package/src/scss/components/card-product-banner.scss +35 -27
  278. package/src/scss/components/checkout-chip.scss +1 -0
  279. package/src/scss/components/checkout-payment-details-v2.scss +12 -0
  280. package/src/scss/components/kitchen/_price.scss +10 -0
  281. package/src/scss/components/kitchen/_strip-stickers.scss +46 -0
  282. package/src/scss/components/my-account/_clipboard-code.scss +4 -0
  283. package/src/scss/components/price-block-v2-critical.scss +54 -1
  284. package/src/scss/components/price-block-v2.scss +54 -3
  285. package/src/scss/components/special-opening-schedule-v2.scss +2 -6
  286. package/src/scss/components/special-opening-schedule.scss +17 -4
  287. package/src/scss/emulation.scss +0 -6
  288. package/src/scss/helpers/_CTAs.scss +15 -5
  289. package/src/scss/helpers/_variables.scss +1 -0
  290. package/src/scss/pages/page_checkout_delivery-new.scss +36 -0
  291. package/src/scss/pages/page_product-details-v2-critical.scss +217 -111
  292. package/src/scss/pages/page_product-details-v2.scss +200 -109
  293. package/src/scss/pages/page_product-details.scss +0 -2
  294. package/src/scss/pages/page_products-list-combined.scss +8 -1
  295. package/src/scss/pages/page_products-list.scss +8 -1
  296. package/src/scss/pages/page_shopping-cart-v2.scss +34 -10
  297. package/src/scss/pages/page_store-locator.scss +48 -26
  298. package/src/scss/pdp-main-critical.scss +1 -1
  299. package/src/scss/pdp-main.scss +5 -1
  300. package/src/scss/plp-main.scss +5 -0
  301. package/src/scss/store-locator-main.scss +15 -1
  302. package/src/sitemap.html +15 -0
  303. package/build/css/components/kitchen/strip-stickers.css +0 -1
  304. package/build/css/components/strip-stickers.css +0 -1
  305. package/src/js/emulation/store-locator-list.js +0 -19
  306. package/src/scss/components/kitchen/strip-stickers.scss +0 -18
  307. package/src/scss/components/strip-stickers.scss +0 -18
@@ -0,0 +1,168 @@
1
+ var Wick = window.Wick || {};
2
+
3
+ Wick.ThumbGallery = (function () {
4
+ const BASE_URL = 'https://media.wickes.co.uk/image/upload/';
5
+ const productName = window.pdpProduct && window.pdpProduct.name ? window.pdpProduct.name : '';
6
+
7
+ const IMG_BREAKPOINTS = [
8
+ { media: '(max-width: 576px)', w: 576, h: 324 },
9
+ { media: '(max-width: 768px)', w: 510, h: 287 },
10
+ { media: '(max-width: 992px)', w: 310, h: 174 },
11
+ ];
12
+
13
+ const MAIN_DEFAULT = { w: 710, h: 399 };
14
+ const THUMB = { w: 100, h: 56 };
15
+
16
+ function buildCloudinaryUrl(publicId, w, h) {
17
+ const transforms = `b_rgb:FFFFFF,c_pad,dpr_1.0,f_jpg,h_${h},q_auto:good,w_${w}`;
18
+ return `${BASE_URL}${transforms}/c_pad,h_${h},w_${w}/v1/${publicId}?pgw=1`;
19
+ }
20
+
21
+ function parseIdentifiers(hybrisString) {
22
+ return hybrisString
23
+ .trim()
24
+ .slice(1, hybrisString.length - 1)
25
+ .split(',')
26
+ .map((s) => s.trim())
27
+ .filter(Boolean);
28
+ }
29
+
30
+ function generateMainSlideHtml(publicId) {
31
+ const sources = IMG_BREAKPOINTS.map(
32
+ (bp) =>
33
+ `<source srcset="${buildCloudinaryUrl(publicId, bp.w, bp.h)}" media="${bp.media}">`
34
+ ).join('\n ');
35
+
36
+ return `<div class="thumb-gallery__slide-wrapper swiper-slide">
37
+ <picture>
38
+ ${sources}
39
+ <img class="swiper-slide-main" src="${buildCloudinaryUrl(publicId, MAIN_DEFAULT.w, MAIN_DEFAULT.h)}" alt="${productName}">
40
+ </picture>
41
+ </div>`;
42
+ }
43
+
44
+ function generateThumbSlideHtml(publicId) {
45
+ return `<div class="thumb-gallery__slide-wrapper swiper-slide">
46
+ <img class="swiper-slide-thumbs" src="${buildCloudinaryUrl(publicId, THUMB.w, THUMB.h)}" alt="${productName}">
47
+ </div>`;
48
+ }
49
+
50
+ const SELECTORS = {
51
+ galleryCarousel: '.thumb-gallery',
52
+ swiperContainerMain: '.swiper-container-main',
53
+ swiperContainerThumbs: '.swiper-container-thumbs',
54
+ swiperMainWrapper: '.swiper-container-main .swiper-wrapper',
55
+ swiperThumbsWrapper: '.swiper-container-thumbs .swiper-wrapper',
56
+ nextBtn: '.thumb-gallery__next-btn',
57
+ prevBtn: '.thumb-gallery__prev-btn',
58
+ thumbNextBtn: '.swiper-container-thumbs__next-btn',
59
+ thumbPrevBtn: '.swiper-container-thumbs__prev-btn',
60
+ swiperSlide: '.swiper-slide',
61
+ activeThumbClass: 'swiper-true-active',
62
+ };
63
+
64
+ const THUMBS_SWIPER_CONFIG = {
65
+ spaceBetween: 8,
66
+ slidesPerView: 8,
67
+ watchSlidesVisibility: true,
68
+ watchSlidesProgress: true,
69
+ watchOverflow: true,
70
+ observer: true,
71
+ observeParents: true,
72
+ simulateTouch: false,
73
+ };
74
+
75
+ const THUMBS_BREAKPOINTS = {
76
+ 991: { slidesPerView: 5 },
77
+ 767: { allowTouchMove: true, slidesPerView: 5 },
78
+ };
79
+
80
+ const MAIN_SWIPER_CONFIG = {
81
+ speed: 400,
82
+ slidesPerView: 1,
83
+ loop: true,
84
+ observer: true,
85
+ observeParents: true,
86
+ simulateTouch: false,
87
+ };
88
+
89
+ function handleThumbClick(swiper) {
90
+ return function () {
91
+ const clickedIndex = $(this).index();
92
+ swiper.slideToLoop(clickedIndex);
93
+ };
94
+ }
95
+
96
+ function updateActiveThumbnail(swiper, thumbsSwiper) {
97
+ const activeIndex = swiper.realIndex;
98
+ thumbsSwiper.slides.removeClass(SELECTORS.activeThumbClass);
99
+ thumbsSwiper.slides.eq(activeIndex).addClass(SELECTORS.activeThumbClass);
100
+ }
101
+
102
+ function getThumbsConfig($thumbNextBtn, $thumbPrevBtn) {
103
+ return {
104
+ ...THUMBS_SWIPER_CONFIG,
105
+ navigation: {
106
+ nextEl: $thumbNextBtn[0],
107
+ prevEl: $thumbPrevBtn[0],
108
+ },
109
+ breakpoints: { ...THUMBS_BREAKPOINTS },
110
+ };
111
+ }
112
+
113
+ function getMainSwiperConfig($nextBtn, $prevBtn, thumbsSwiper, onSlideChange) {
114
+ return {
115
+ ...MAIN_SWIPER_CONFIG,
116
+ navigation: {
117
+ nextEl: $nextBtn[0],
118
+ prevEl: $prevBtn[0],
119
+ },
120
+ thumbs: { swiper: thumbsSwiper },
121
+ on: { slideChange: onSlideChange },
122
+ };
123
+ }
124
+
125
+ function initializeCarousel($slider, ids) {
126
+ $slider.find(SELECTORS.swiperMainWrapper).html(ids.map(generateMainSlideHtml).join('\n'));
127
+ $slider
128
+ .find(SELECTORS.swiperThumbsWrapper)
129
+ .html(ids.map(generateThumbSlideHtml).join('\n'));
130
+
131
+ const $container = $slider.find(SELECTORS.swiperContainerMain);
132
+ const $nextBtn = $slider.find(SELECTORS.nextBtn);
133
+ const $prevBtn = $slider.find(SELECTORS.prevBtn);
134
+
135
+ const $thumbContainer = $slider.find(SELECTORS.swiperContainerThumbs);
136
+ const $thumbNextBtn = $slider.find(SELECTORS.thumbNextBtn);
137
+ const $thumbPrevBtn = $slider.find(SELECTORS.thumbPrevBtn);
138
+
139
+ const thumbsSwiper = new Swiper(
140
+ $thumbContainer[0],
141
+ getThumbsConfig($thumbNextBtn, $thumbPrevBtn)
142
+ );
143
+
144
+ const swiper = new Swiper(
145
+ $container[0],
146
+ getMainSwiperConfig($nextBtn, $prevBtn, thumbsSwiper, () => {
147
+ updateActiveThumbnail(swiper, thumbsSwiper);
148
+ })
149
+ );
150
+
151
+ $thumbContainer.on('click', SELECTORS.swiperSlide, handleThumbClick(swiper));
152
+ updateActiveThumbnail(swiper, thumbsSwiper);
153
+ }
154
+
155
+ function init(hybrisString) {
156
+ const ids = parseIdentifiers(hybrisString);
157
+
158
+ if (ids.length < 2) {
159
+ return;
160
+ }
161
+
162
+ $(SELECTORS.galleryCarousel).each(function (_, slider) {
163
+ initializeCarousel($(slider), ids);
164
+ });
165
+ }
166
+
167
+ return { init };
168
+ })();
@@ -18,7 +18,8 @@ function normalizeOptions(options) {
18
18
  }
19
19
 
20
20
  function toInt(value) {
21
- const n = parseInt(String(value || '').trim(), 10);
21
+ const n = parseInt(`${value || ''}`.trim(), 10);
22
+
22
23
  return Number.isFinite(n) ? n : NaN;
23
24
  }
24
25
 
@@ -28,6 +29,7 @@ function clampMin(n, min) {
28
29
 
29
30
  function ensureQty(value, fallback) {
30
31
  const n = toInt(value);
32
+
31
33
  return Number.isFinite(n) ? n : fallback;
32
34
  }
33
35
 
@@ -58,12 +60,15 @@ function updateButtons($input, opt) {
58
60
 
59
61
  const $minus = getMinusBtn($wrap);
60
62
 
61
- if ($minus.length) $minus.prop('disabled', qty <= opt.min);
63
+ if ($minus.length) {
64
+ $minus.prop('disabled', qty <= opt.min);
65
+ }
62
66
  }
63
67
 
64
68
  function setQty($input, opt, qty) {
65
69
  const next = clampMin(qty, opt.min);
66
- $input.val(String(next));
70
+
71
+ $input.val(`${next}`);
67
72
  updateButtons($input, opt);
68
73
 
69
74
  if (typeof opt.onChange === 'function') {
@@ -83,11 +88,13 @@ function ensureButtons($input, opt) {
83
88
  if (!hasMinus) {
84
89
  $input.before(buildBtn('minus', true));
85
90
  }
91
+
86
92
  if (!hasPlus) {
87
93
  $input.after(buildBtn('plus', false));
88
94
  }
89
95
 
90
96
  const initial = ensureQty($input.val(), opt.min);
97
+
91
98
  setQty($input, opt, initial);
92
99
  }
93
100
 
@@ -95,16 +102,24 @@ function getInputs($root, inputSel) {
95
102
  const $scope = $root && $root.length ? $root : $(document);
96
103
  const $self = $scope.is(inputSel) ? $scope : $();
97
104
  const $found = $scope.find(inputSel);
105
+
98
106
  return $self.add($found);
99
107
  }
100
108
 
109
+ function getNamespace(inputSel) {
110
+ return `.countStepper_${inputSel.replace(/[^a-zA-Z0-9_-]/g, '')}`;
111
+ }
112
+
101
113
  // ===== FACTORY =====
102
114
 
103
115
  export function createCountStepper(options = {}) {
104
116
  const OPT = normalizeOptions(options);
105
- if (!OPT.inputSel) throw new Error('[createCountStepper] Missing inputSel');
106
117
 
107
- const NS = `.cnt_${Math.random().toString(16).slice(2)}`;
118
+ if (!OPT.inputSel) {
119
+ throw new Error('[createCountStepper] Missing inputSel');
120
+ }
121
+
122
+ const NS = getNamespace(OPT.inputSel);
108
123
 
109
124
  function init($root) {
110
125
  getInputs($root, OPT.inputSel).each(function () {
@@ -112,7 +127,6 @@ export function createCountStepper(options = {}) {
112
127
  });
113
128
  }
114
129
 
115
- // +/- click
116
130
  $(document)
117
131
  .off(`click${NS}`, '[data-count-btn]')
118
132
  .on(`click${NS}`, '[data-count-btn]', function (e) {
@@ -120,15 +134,22 @@ export function createCountStepper(options = {}) {
120
134
  const $parent = $btn.parent();
121
135
  const $input = $parent.find(OPT.inputSel).first();
122
136
 
123
- if (!$input.length) return;
137
+ if (!$input.length) {
138
+ return;
139
+ }
124
140
 
125
141
  e.preventDefault();
126
142
 
127
143
  const type = ($btn.attr('data-count-type') || '').toLowerCase();
128
144
  const current = ensureQty($input.val(), OPT.min);
129
145
 
130
- if (type === 'plus') setQty($input, OPT, current + 1);
131
- if (type === 'minus') setQty($input, OPT, current - 1);
146
+ if (type === 'plus') {
147
+ setQty($input, OPT, current + 1);
148
+ }
149
+
150
+ if (type === 'minus') {
151
+ setQty($input, OPT, current - 1);
152
+ }
132
153
  });
133
154
 
134
155
  $(document)
@@ -0,0 +1,37 @@
1
+ export function createLoadingButton(config = {}) {
2
+ const settings = {
3
+ text: '.loading-button__text',
4
+ loader: '.loading-button__loader',
5
+ loadingClass: 'loading-button--loading',
6
+ ...config,
7
+ };
8
+
9
+ function setLoading($button, isLoading) {
10
+ if (!$button.length) {
11
+ return;
12
+ }
13
+
14
+ $button.toggleClass(settings.loadingClass, isLoading);
15
+ $button.find(settings.text).toggleClass('d-none', isLoading);
16
+ $button.find(settings.loader).toggleClass('d-none', !isLoading);
17
+ }
18
+
19
+ function start($button) {
20
+ setLoading($button, true);
21
+ }
22
+
23
+ function stop($button) {
24
+ setLoading($button, false);
25
+ }
26
+
27
+ function isLoading($button) {
28
+ return $button.hasClass(settings.loadingClass);
29
+ }
30
+
31
+ return {
32
+ setLoading,
33
+ start,
34
+ stop,
35
+ isLoading,
36
+ };
37
+ }
@@ -0,0 +1,79 @@
1
+ export function createToast(config = {}) {
2
+ const settings = {
3
+ containerClass: 'toast-container',
4
+ toastClass: 'toast',
5
+ closeSelector: '.notification__close',
6
+ backdropClass: 'modal-backdrop--toast',
7
+ duration: 3000,
8
+ template: null,
9
+ getData(type, text) {
10
+ return {
11
+ text,
12
+ classModifier: `${settings.toastClass} notification_${type}`,
13
+ success: type === 'success',
14
+ warning: type === 'warning',
15
+ error: type === 'error',
16
+ };
17
+ },
18
+ ...config,
19
+ };
20
+
21
+ let closeTimer = null;
22
+
23
+ function clearCloseTimer() {
24
+ if (closeTimer) {
25
+ window.clearTimeout(closeTimer);
26
+ closeTimer = null;
27
+ }
28
+ }
29
+
30
+ function hide() {
31
+ clearCloseTimer();
32
+
33
+ $(`.${settings.containerClass}`).remove();
34
+ $(`.${settings.backdropClass}`).removeClass(settings.backdropClass);
35
+
36
+ if (window.Wick && Wick.Backdrop) {
37
+ Wick.Backdrop.hide();
38
+ }
39
+
40
+ $(document).off('click.toast');
41
+ }
42
+
43
+ function show({ type = 'success', text = '' }) {
44
+ if (!settings.template) {
45
+ return;
46
+ }
47
+
48
+ hide();
49
+
50
+ const toastHtml = settings.template(settings.getData(type, text));
51
+
52
+ if (window.Wick && Wick.Backdrop) {
53
+ Wick.Backdrop.show();
54
+ $('.modal-backdrop').addClass(settings.backdropClass);
55
+ }
56
+
57
+ $('body').append(`<div class="${settings.containerClass}">${toastHtml}</div>`);
58
+
59
+ $(`.${settings.containerClass}`)
60
+ .off('click.toastClose', settings.closeSelector)
61
+ .on('click.toastClose', settings.closeSelector, function (event) {
62
+ event.preventDefault();
63
+ hide();
64
+ });
65
+
66
+ $(document)
67
+ .off('click.toast')
68
+ .on('click.toast', `.${settings.backdropClass}`, function () {
69
+ hide();
70
+ });
71
+
72
+ closeTimer = window.setTimeout(hide, settings.duration);
73
+ }
74
+
75
+ return {
76
+ show,
77
+ hide,
78
+ };
79
+ }
@@ -0,0 +1,80 @@
1
+ export function createDropdown(config) {
2
+ const settings = {
3
+ root: '[data-dropdown]',
4
+ toggle: '[data-dropdown-toggle]',
5
+ value: '[data-dropdown-value]',
6
+ option: '[data-dropdown-option]',
7
+ openClass: 'dropdown--open',
8
+ selectedClass: 'dropdown__option--selected',
9
+ selectedValueData: 'selected-value',
10
+ ariaExpandedAttr: 'aria-expanded',
11
+ ariaSelectedAttr: 'aria-selected',
12
+ namespace: 'customDropdown',
13
+ onSelect: function () {},
14
+ ...config,
15
+ };
16
+
17
+ function closeAll() {
18
+ $(settings.root).each(function () {
19
+ const $dropdown = $(this);
20
+ const $toggle = $dropdown.find(settings.toggle);
21
+
22
+ $dropdown.removeClass(settings.openClass);
23
+ $toggle.attr(settings.ariaExpandedAttr, 'false');
24
+ });
25
+ }
26
+
27
+ function selectOption($dropdown, $option) {
28
+ const $value = $dropdown.find(settings.value);
29
+ const $options = $dropdown.find(settings.option);
30
+ const selectedValue = $option.attr('data-value') || '';
31
+
32
+ $options.removeClass(settings.selectedClass).attr(settings.ariaSelectedAttr, 'false');
33
+ $option.addClass(settings.selectedClass).attr(settings.ariaSelectedAttr, 'true');
34
+
35
+ if ($value.length) {
36
+ $value.text($option.text().trim());
37
+ }
38
+
39
+ $dropdown.data(settings.selectedValueData, selectedValue);
40
+
41
+ settings.onSelect($dropdown, $option, selectedValue);
42
+ }
43
+
44
+ function bind() {
45
+ $(document).off(`click.${settings.namespace}`);
46
+ $(document).on(`click.${settings.namespace}`, function (event) {
47
+ const $target = $(event.target);
48
+ const $toggle = $target.closest(settings.toggle);
49
+ const $option = $target.closest(settings.option);
50
+ const $dropdown = $target.closest(settings.root);
51
+
52
+ if (!$dropdown.length) {
53
+ closeAll();
54
+ return;
55
+ }
56
+
57
+ if ($toggle.length) {
58
+ const isOpen = $dropdown.hasClass(settings.openClass);
59
+
60
+ closeAll();
61
+
62
+ $dropdown.toggleClass(settings.openClass, !isOpen);
63
+ $toggle.attr(settings.ariaExpandedAttr, String(!isOpen));
64
+
65
+ return;
66
+ }
67
+
68
+ if ($option.length) {
69
+ selectOption($dropdown, $option);
70
+ closeAll();
71
+ }
72
+ });
73
+ }
74
+
75
+ return {
76
+ bind,
77
+ closeAll,
78
+ selectOption,
79
+ };
80
+ }
@@ -0,0 +1,81 @@
1
+ {{#extend "base" hybrisClass="hybris-class" pageClass="products-list-page" title="Bathroom PLP" globalSearchV2="true" pagePlp=true bundle="plp" switch-vat=true}}
2
+ {{#content "head" mode="append"}}
3
+ <link type="text/css" rel="stylesheet" href="./css/components/global-search.css">
4
+ {{/content}}
5
+ {{#content "body"}}
6
+ <main>
7
+ <div class="package-plp container">
8
+ <div class="page-header page-header_border-all">
9
+ <h1 class="page-header__title">
10
+ Bathroom Suite Packages
11
+ </h1>
12
+ {{> srp-injected}}
13
+ </div>
14
+
15
+ {{> quick-filter filterData=quickFilter.iconAndText_5}}
16
+
17
+ <div class="package-plp__container">
18
+ <aside class="package-plp__search-filter">
19
+ {{> search-filter collapsed="accordion_collapsed" hidden="hidden-state"}}
20
+ </aside>
21
+
22
+ <div class="package-plp__content">
23
+ <div class="plp-filters" data-component="plp-filters" aria-label="Product filters">
24
+ <div class="plp-filters__bar plp-filters__bar-mobile" role="tablist" aria-label="Filters">
25
+ {{> kitchen/mobile-nav-item
26
+ icon="fas fa-filter"
27
+ title="Filter by"
28
+ info="24 results"
29
+ modalId="filterModal"
30
+ mod="filter-modal-cta"
31
+ }}
32
+ {{> kitchen/mobile-nav-item
33
+ icon="fas fa-sort-alt"
34
+ title="Sort by"
35
+ info="Relevance"
36
+ dropdown=true
37
+ }}
38
+ </div>
39
+ </div>
40
+
41
+ <input id="numberOfPagesPLP" value="2" type="hidden">
42
+ <div class="sort-products-list">
43
+ {{> kitchen/sort-by }}
44
+ </div>
45
+
46
+ <div class="package-plp__cards">
47
+ {{> package-card cards=ripple-plp.cards}}
48
+ {{#if search-result_v2.product-banner}}
49
+ {{#each search-result_v2.product-banner}}
50
+ {{>card_product_banner_v2}}
51
+ {{/each}}
52
+ {{/if}}
53
+ {{#if search-result_v2.bloomreach-media-banner}}
54
+ {{#each search-result_v2.bloomreach-media-banner}}
55
+ {{>card_bloomreach_media_banner}}
56
+ {{/each}}
57
+ {{/if}}
58
+ {{#if search-result_v2.sponsor-banner}}
59
+ {{#each search-result_v2.sponsor-banner}}
60
+ {{>card_sponsor_banner}}
61
+ {{/each}}
62
+ {{/if}}
63
+ </div>
64
+
65
+ <div class="load-more-wrap">
66
+ <button class="btn btn-primary btn_full btn-load-more">
67
+ Load more
68
+ </button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </main>
74
+ {{/content}}
75
+ {{#content "foot" mode="append"}}
76
+ {{> kitchen/filter-modal isKitchenMode=false modalTitle="Filter by" }}
77
+ <script defer src="./js/search-filter.min.js"></script>
78
+ <script defer src="./js/plp-filters.min.js"></script>
79
+ <script defer src="./js/page/quick-filter.js"></script>
80
+ {{/content}}
81
+ {{/extend}}
@@ -0,0 +1,83 @@
1
+ {{#extend "base" hybrisClass="hybris-class" pageClass="products-list-page" title="Bathroom PLP" globalSearchV2="true" pagePlp=true bundle="plp"}}
2
+ {{#content "head" mode="append"}}
3
+ <link type="text/css" rel="stylesheet" href="./css/components/global-search.css">
4
+ <link type="text/css" rel="stylesheet" href="https://static-content-develop.dev.wickes.co.uk/whisk/kitchen-static/css/kitchen-content.css">
5
+ {{/content}}
6
+ {{#content "body"}}
7
+ <main>
8
+ <div class="package-plp container">
9
+ <div class="page-header page-header_border-all">
10
+ <h1 class="page-header__title">
11
+ Bathroom Suite Packages
12
+ </h1>
13
+ {{> srp-injected}}
14
+ {{> sponsor-top-banner }}
15
+ </div>
16
+
17
+ {{> quick-filter filterData=quickFilter.iconAndText_5}}
18
+
19
+ <div class="hybris-slot">
20
+ <div style="min-height: 120px; background-color: gray;"></div>
21
+ <div style="min-height: 120px; background-color: gray;"></div>
22
+ </div>
23
+
24
+ <div class="package-plp__container">
25
+ <aside class="package-plp__search-filter">
26
+ {{> search-filter collapsed="accordion_collapsed" hidden="hidden-state"}}
27
+ </aside>
28
+
29
+ <div class="package-plp__content">
30
+ <div class="plp-filters" data-component="plp-filters" aria-label="Product filters">
31
+ <div class="plp-filters__bar plp-filters__bar-mobile" role="tablist" aria-label="Filters">
32
+ {{> kitchen/mobile-nav-item
33
+ icon="fas fa-filter"
34
+ title="Filter by"
35
+ info="24 results"
36
+ modalId="filterModal"
37
+ mod="filter-modal-cta"
38
+ }}
39
+ {{> kitchen/mobile-nav-item
40
+ icon="fas fa-sort-alt"
41
+ title="Sort by"
42
+ info="Relevance"
43
+ dropdown=true
44
+ }}
45
+ </div>
46
+ </div>
47
+
48
+ <input id="numberOfPagesPLP" value="1" type="hidden">
49
+ <div class="sort-products-list">
50
+ {{> kitchen/sort-by }}
51
+ </div>
52
+
53
+ <div class="package-plp__cards">
54
+ {{> package-card cards=(limitArray ripple-plp.cards 7)}}
55
+ </div>
56
+
57
+ <div class="load-more-wrap">
58
+ <button class="btn btn-primary btn_full btn-load-more">
59
+ Load more
60
+ </button>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="container">
67
+ <div class="hybris-slot">
68
+ <div class="banner-emulation" style="height: 398px; min-height: 120px; background-color: gray;"></div>
69
+ <div style="min-height: 120px; background-color: gray;"></div>
70
+ <div style="min-height: 120px; background-color: gray;"></div>
71
+ </div>
72
+ </div>
73
+
74
+ {{> legal-info}}
75
+ </main>
76
+ {{/content}}
77
+ {{#content "foot" mode="append"}}
78
+ {{> kitchen/filter-modal isKitchenMode=false modalTitle="Filter by" }}
79
+ <script defer src="./js/search-filter.min.js"></script>
80
+ <script defer src="./js/plp-filters.min.js"></script>
81
+ <script defer src="./js/page/quick-filter.js"></script>
82
+ {{/content}}
83
+ {{/extend}}