PageSourceSearch

https://www.lidl.com.mt/s/storesearch-frontend/26_19_4/store-search-pop-up.js

js lidl.com.mt collected 2026-09-24 23:11:45 UTC 10,056 bytes, 313 lines download raw bytes

1import {
2  prepareStoreSearchAndOpen,
3  selectAppLocale,
4} from "./store-search-utils.js";
5
6const template = document.createElement("template");
7template.innerHTML = `
8<style>
9    .store-search-pop-up {       
10      position: fixed;
11      top: 0;
12      left: 0;
13      z-index: 10000;
14      display: flex;
15      align-items: flex-end;
16      justify-content: center;
17      width: calc(100% - 2rem);
18      height: calc(100% - 2rem);
19      pointer-events: none;
20      padding: 1rem;
21      opacity: 0;
22      transition: opacity 0.4s ease;
23    }
24    .store-search-pop-up.visible {
25      opacity: 1;
26    }
27    .store-search-pop-up.hidden {
28      opacity: 0;
29    }
30    .store-search-pop-up__item {
31      width: 100%;
32      border-radius: 0.5rem;
33      background: #1e2124;
34      padding: 1rem;
35      pointer-events: auto;
36      display: flex;
37      flex-direction: column;
38      align-items: flex-end;
39      gap: 0.75rem;
40      transform: translateY(-6.25rem);
41      transition: transform 0.4s ease, opacity 0.4s ease;
42    }
43    .store-search-pop-up.visible .store-search-pop-up__item {
44      transform: translateY(0); 
45    }
46    .store-search-pop-up.hidden .store-search-pop-up__item {
47      transform: translateY(-6.25rem);
48      transition: transform 0.2s ease, opacity 0.2s ease;
49    }
50    .store-search-pop-up__container {
51      display: flex;
52      align-items: flex-start;
53      gap: 1rem;
54    }
55    .store-search-pop-up__success-icon {
56      order: 1;
57      display: flex;
58      align-items: center;
59      justify-content: center;
60    }
61    .store-search-pop-up__text {       
62      order: 2;
63      font-family: 'LidlFontPro', Arial, Helvetica, sans-serif;
64      font-weight: 500;
65      font-size: 0.875rem;
66      line-height: 1.25rem;
67      color: #ffffff;
68      margin-top: 0;
69      margin-bottom: 0;
70      padding-right: 0.5rem;
71    }
72    .store-search-pop-up__close-button {
73      all: unset;
74      order: 3;
75      display: flex;
76      align-items: center;
77      justify-content: center;
78      min-width: 1.5rem;
79      width: 1.5rem;
80      height: 1.5rem;
81      border-radius: 0.75rem;
82      fill: #ffffff;
83      pointer-events: auto;
84      cursor: pointer;
85    }
86    .store-search-pop-up__close-button:hover {
87      background-color: #ffffff;
88      fill: #636d79;
89    }
90    .store-search-pop-up__close-button:focus {
91      border-radius: 0;
92      outline: 0.125rem solid #ffffff;
93    }
94    .store-search-pop-up__store-search-button {
95      all: unset;
96      white-space: nowrap;
97      font-family: 'LidlFontPro', Arial, Helvetica, sans-serif;
98      font-weight: 600;
99      font-size: 1rem;
100      line-height: 1.25rem;
101      color: #fff000;
102      pointer-events: auto;
103      cursor: pointer;
104    }
105    .store-search-pop-up__store-search-button:hover {
106      color: #ffc400;
107    }
108    .store-search-pop-up__store-search-button:focus {
109      color: #ffc400;
110      outline: 0.125rem solid #ffffff;
111      outline-offset: 0.125rem;
112    }
113    @media (min-width: 568px) {
114      .store-search-pop-up__item {
115        flex-direction: row;
116        align-items: center;
117        justify-content: space-between;
118        width: fit-content;
119        max-width: 1320px;
120      }
121      .store-search-pop-up__container {
122        display: contents;
123      }
124      .store-search-pop-up__success-icon {
125        order: 1;
126      }
127      .store-search-pop-up__text {       
128        order: 2;
129        padding-right: 1rem;
130      }
131      .store-search-pop-up__store-search-button {
132        order: 3;
133      }
134      .store-search-pop-up__close-button {
135        order: 4;
136      }
137    }
138    @media (min-width: 1440px) {
139      .store-search-pop-up__text {  
140        font-size: 1rem;
141        line-height: 1.25rem;
142        padding-right: 1.5rem;
143      }
144      .store-search-pop-up__store-search-button {
145        font-size: 1.125rem;
146        line-height: 1.5rem;
147      }
148    }
149}
150</style>
151<div class="store-search-pop-up">
152    <div class="store-search-pop-up__item">
153        <div class="store-search-pop-up__container">
154          <span class="store-search-pop-up__success-icon">
155            <svg width="24" height="24" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
156              <path fill="#00e09d" d="M30 1.5C14.29 1.5 1.5 14.29 1.5 30C1.5 45.71 14.29 58.5 30 58.5C45.71 58.5 58.5 45.71 58.5 30C58.5 14.29 45.71 1.5 30 1.5ZM30 55.5C15.94 55.5 4.5 44.06 4.5 30C4.5 15.94 15.94 4.5 30 4.5C44.06 4.5 55.5 15.94 55.5 30C55.5 44.06 44.06 55.5 30 55.5Z" />
157              <path fill="#00e09d" d="M42.17 19.71L25 36.88L16.41 28.29C16.21 28.09 15.9 28.09 15.7 28.29L14.29 29.7C14.09 29.9 14.09 30.21 14.29 30.41L23.58 39.7C24.36 40.48 25.63 40.48 26.41 39.7L45.7 20.41C45.9 20.21 45.9 19.9 45.7 19.7C44.73 18.73 43.15 18.73 42.17 19.71Z" />
158            </svg>
159          </span>
160          <p class="store-search-pop-up__text" part="text" role="alert"></p>
161          <button class="store-search-pop-up__close-button">
162            <svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
163              <path d="M8.56522 8L15.3892 1.176C15.4426 1.12267 15.4426 1.04 15.3892 0.986667L15.0132 0.610667C14.9599 0.557334 14.8772 0.557334 14.8239 0.610667L7.99989 7.43467L1.17589 0.610667C1.12256 0.557334 1.03989 0.557334 0.986557 0.610667L0.610557 0.989334C0.557223 1.04267 0.557223 1.12533 0.610557 1.17867L7.43456 8L0.610557 14.824C0.557223 14.8773 0.557223 14.96 0.610557 15.0133C0.87189 15.2747 1.29322 15.2747 1.55456 15.0133L7.99989 8.56533L14.4452 15.0107C14.7066 15.272 15.1279 15.272 15.3892 15.0107C15.4426 14.9573 15.4426 14.8747 15.3892 14.8213L8.56522 8Z" />
164            </svg>
165          </button>
166        </div>
167        <button class="store-search-pop-up__store-search-button">
168          <span class="store-search-pop-up__store-search-button-label" part="text"></span>
169        </button>
170    </div>
171</div>
172`;
173
174// web component
175class StoreSearchPopUp extends HTMLElement {
176  constructor() {
177    super();
178
179    this.locale = selectAppLocale(
180      window.mindShiftNav && window.mindShiftNav.locale,
181    );
182    this.shadow = this.attachShadow({ mode: "closed" });
183    this.shadow.appendChild(template.content.cloneNode(true));
184  }
185
186  connectedCallback() {
187    const timestamp = window.storeSearchDeployTimestamp || "0000000000000";
188    this._queryTranslations(timestamp).then((translations) => {
189      const wrapper = this.shadow.querySelector(".store-search-pop-up");
190      const popUpText = this.shadow.querySelector(".store-search-pop-up__text");
191      const closeButton = this.shadow.querySelector(
192        ".store-search-pop-up__close-button",
193      );
194      const storeSearchButton = this.shadow.querySelector(
195        ".store-search-pop-up__store-search-button",
196      );
197      const storeSearchButtonLabel = this.shadow.querySelector(
198        ".store-search-pop-up__store-search-button-label",
199      );
200      const successIcon = this.shadow.querySelector(
201        ".store-search-pop-up__success-icon",
202      );
203      const item = this.shadow.querySelector(".store-search-pop-up__item");
204
205      const showAltPopUp = this.getAttribute("show-alt-pop-up") === "true";
206      const detectedRegion = this.getAttribute("detected-region");
207
208      if (showAltPopUp === true) {
209        if (successIcon) {
210          successIcon.style.display = "none";
211          storeSearchButton.style.display = "none";
212          item.style.alignItems = "normal";
213          popUpText.style.marginTop = "0.125rem";
214
215          popUpText.textContent =
216            translations[
217              `storeSearch.storeSearchPopUp.regionalization.labelLocationAlt`
218            ] +
219            " " +
220            detectedRegion.trim() +
221            ". " +
222            translations[
223              `storeSearch.storeSearchPopUp.regionalization.textAlt`
224            ];
225        }
226      } else {
227        popUpText.textContent =
228          translations[
229            `storeSearch.storeSearchPopUp.regionalization.labelLocation`
230          ] +
231          ": " +
232          detectedRegion.trim() +
233          ". " +
234          translations[`storeSearch.storeSearchPopUp.regionalization.text`];
235      }
236
237      storeSearchButtonLabel.innerText =
238        translations[
239          `storeSearch.storeSearchPopUp.regionalization.searchButton`
240        ];
241
242      requestAnimationFrame(() => {
243        wrapper.classList.add("visible");
244      });
245
246      closeButton.setAttribute(
247        "aria-label",
248        translations[
249          `storeSearch.storeSearchPopUp.regionalization.closeButtonA11yLabel`
250        ],
251      );
252      closeButton.addEventListener("click", () => {
253        this.closePopUp();
254      });
255
256      storeSearchButton.addEventListener("click", () => {
257        let storeData = {
258          type: "storeSearch",
259        };
260        prepareStoreSearchAndOpen(storeData);
261        this.closePopUp();
262      });
263
264      this.autoCloseTimer = setTimeout(() => {
265        this.closePopUp();
266      }, 10000); // close pop-up after 10s
267    });
268  }
269
270  closePopUp() {
271    const wrapper = this.shadow.querySelector(".store-search-pop-up");
272    clearTimeout(this.autoCloseTimer);
273
274    const targetElement = document.querySelector("store-selector-flyer-addon");
275
276    wrapper.classList.remove("visible");
277    wrapper.classList.add("hidden");
278
279    setTimeout(() => {
280      this.remove();
281      if (targetElement) {
282        if (!targetElement.hasAttribute("tabindex")) {
283          targetElement.setAttribute("tabindex", "-1");
284        }
285        targetElement.focus();
286      }
287    }, 200);
288  }
289
290  async _queryTranslations(timestamp) {
291    const url = `/s/translation/${this.locale}.json?_=${timestamp}`;
292    try {
293      let response = await fetch(url, {
294        method: "GET",
295        headers: {
296          "Content-Type": "application/json",
297        },
298      });
299      if (response.ok) {
300        return await response.json();
301      } else {
302        console.error("unable to fetch translations");
303        return null;
304      }
305    } catch (error) {
306      console.error("unable to fetch translations", error);
307      return null;
308    }
309  }
310}
311
312// register component
313customElements.define("store-search-pop-up", StoreSearchPopUp);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.