@asante-org/leybold-design-system 1.3.1 → 1.3.3

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 (31) hide show
  1. package/dist/.storybook/algoliaProvider.d.ts +3 -0
  2. package/dist/index.esm.js +661 -245
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.esm.scss +701 -184
  5. package/dist/index.js +661 -281
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.scss +701 -184
  8. package/dist/src/components/Button/Button.d.ts +2 -2
  9. package/dist/src/components/CarouselCard/CarouselCard.d.ts +18 -0
  10. package/dist/src/components/CarouselCard/CarouselCard.stories.d.ts +6 -0
  11. package/dist/src/components/CarouselCard/index.d.ts +2 -0
  12. package/dist/src/components/ContentCardBase/ContentCardBase.d.ts +3 -0
  13. package/dist/src/components/ContentCardBase/index.d.ts +2 -0
  14. package/dist/src/components/ContentCardHorizontal/ContentCardHorizontal.d.ts +2 -2
  15. package/dist/src/components/ContentCardHorizontal/ContentCardHorizontal.stories.d.ts +1 -0
  16. package/dist/src/components/ContentCardVertical/ContentCardVertical.d.ts +3 -0
  17. package/dist/src/components/ContentCardVertical/ContentCardVertical.stories.d.ts +9 -0
  18. package/dist/src/components/ProductCardVertical/ProductCardVertical.d.ts +2 -2
  19. package/dist/src/components/SearchBar/SearchBar.d.ts +2 -2
  20. package/dist/src/components/SearchBar/SearchSubmitButton.d.ts +2 -2
  21. package/dist/src/components/SearchModal/SearchModal.d.ts +2 -2
  22. package/dist/src/experience/Carousel/Carousel.d.ts +1 -1
  23. package/dist/src/experience/algolia-dynamic-search/AlgoliaDynamicSearch.stories.d.ts +2 -0
  24. package/dist/src/experience/federated-search/FederatedSearchWithAlgolia.stories.d.ts +1 -0
  25. package/dist/src/experience/federated-search/components/FilterDrawer/FilterDrawer.d.ts +2 -2
  26. package/dist/src/experience/qr-form-journey/QrFormJourney.d.ts +1 -0
  27. package/dist/src/index.d.ts +4 -1
  28. package/dist/src/stories/foundation/_components/StoryAccordion.d.ts +13 -0
  29. package/dist/src/types/cards.d.ts +32 -2
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useState, useCallback, useRef, useEffect } from 'react';
1
+ import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
2
2
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
3
  import { faArrowLeft, faArrowLeftLong, faArrowRight, faArrowRightLong, faChevronRight, faChevronLeft, faArrowUpRightFromSquare, faGlobe, faXmark as faXmark$1 } from '@fortawesome/free-solid-svg-icons';
4
4
  import { faInstagram, faYoutube, faLinkedinIn, faXTwitter, faFacebookF } from '@fortawesome/free-brands-svg-icons';
@@ -15,7 +15,7 @@ function _extends() {
15
15
  }, _extends.apply(null, arguments);
16
16
  }
17
17
 
18
- var styles$k = {"button":"Button-module__button___18Bed","button--primary":"Button-module__button--primary___VuF-P","button--disabled":"Button-module__button--disabled___IuOY8","button--secondary":"Button-module__button--secondary___lD5E3","button--solid-grey":"Button-module__button--solid-grey___oRbEy","button--solid-black":"Button-module__button--solid-black___1Ma5K","button--solid-white":"Button-module__button--solid-white___bE-Z0","button--outlined-grey":"Button-module__button--outlined-grey___xWGbB","button--outlined-black":"Button-module__button--outlined-black___qfX5o","button--outlined-white":"Button-module__button--outlined-white___QLXNP","button--link-text":"Button-module__button--link-text___R2kun","button__icon":"Button-module__button__icon___hlcHo","button--link-text-alt":"Button-module__button--link-text-alt___1p7wH","button--external-link":"Button-module__button--external-link___Mhxuk","button--carousel-arrow-left":"Button-module__button--carousel-arrow-left___Wx-Jo","button--carousel-arrow-right":"Button-module__button--carousel-arrow-right___3ZtgT","button__icon__default":"Button-module__button__icon__default___0qlF1","button__icon__hover":"Button-module__button__icon__hover___3xPGT","button--extra-small":"Button-module__button--extra-small___R0QTM","button--small":"Button-module__button--small___ADJQe","button--medium":"Button-module__button--medium___ZuR4Z","button--large":"Button-module__button--large___-FaV5","button__icon--left":"Button-module__button__icon--left___wMCeH","button__icon--right":"Button-module__button__icon--right___-pGHl"};
18
+ var styles$m = {"button":"Button-module__button___18Bed","button--primary":"Button-module__button--primary___VuF-P","button--disabled":"Button-module__button--disabled___IuOY8","button--secondary":"Button-module__button--secondary___lD5E3","button--solid-grey":"Button-module__button--solid-grey___oRbEy","button--solid-black":"Button-module__button--solid-black___1Ma5K","button--solid-white":"Button-module__button--solid-white___bE-Z0","button--outlined-grey":"Button-module__button--outlined-grey___xWGbB","button--outlined-black":"Button-module__button--outlined-black___qfX5o","button--outlined-white":"Button-module__button--outlined-white___QLXNP","button--link-text":"Button-module__button--link-text___R2kun","button__icon":"Button-module__button__icon___hlcHo","button--link-text-alt":"Button-module__button--link-text-alt___1p7wH","button--external-link":"Button-module__button--external-link___Mhxuk","button--carousel-arrow-left":"Button-module__button--carousel-arrow-left___Wx-Jo","button--carousel-arrow-right":"Button-module__button--carousel-arrow-right___3ZtgT","button__icon__default":"Button-module__button__icon__default___0qlF1","button__icon__hover":"Button-module__button__icon__hover___3xPGT","button--extra-small":"Button-module__button--extra-small___R0QTM","button--small":"Button-module__button--small___ADJQe","button--medium":"Button-module__button--medium___ZuR4Z","button--large":"Button-module__button--large___-FaV5","button__icon--left":"Button-module__button__icon--left___wMCeH","button__icon--right":"Button-module__button__icon--right___-pGHl"};
19
19
 
20
20
  function getDefaultExportFromCjs (x) {
21
21
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -191,10 +191,10 @@ const Button = ({
191
191
  const isIconOnly = variant === "carousel-arrow-left" || variant === "carousel-arrow-right";
192
192
  const isCarouselLeft = variant === "carousel-arrow-left";
193
193
  const isCarouselRight = variant === "carousel-arrow-right";
194
- const buttonClasses = classNames(styles$k.button, styles$k[`button--${cssVariant}`], styles$k[`button--${size}`], {
195
- [styles$k["button--disabled"]]: disabled
194
+ const buttonClasses = classNames(styles$m.button, styles$m[`button--${cssVariant}`], styles$m[`button--${size}`], {
195
+ [styles$m["button--disabled"]]: disabled
196
196
  }, className);
197
- const iconClasses = classNames(styles$k.button__icon, styles$k[`button__icon--${iconPosition}`]);
197
+ const iconClasses = classNames(styles$m.button__icon, styles$m[`button__icon--${iconPosition}`]);
198
198
 
199
199
  // Generate accessible label for icon-only buttons
200
200
  const accessibleLabel = ariaLabel || (isIconOnly ? variant === "carousel-arrow-left" ? "Previous" : "Next" : undefined);
@@ -204,28 +204,190 @@ const Button = ({
204
204
  disabled: disabled,
205
205
  onClick: onClick,
206
206
  "aria-label": accessibleLabel,
207
- "data-force-state": props['data-force-state']
207
+ "data-force-state": props["data-force-state"]
208
208
  }, props), !isIconOnly && children, isCarouselLeft && /*#__PURE__*/React.createElement("span", {
209
209
  className: iconClasses
210
210
  }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
211
211
  icon: faArrowLeft,
212
- className: styles$k.button__icon__default
212
+ className: styles$m.button__icon__default
213
213
  }), /*#__PURE__*/React.createElement(FontAwesomeIcon, {
214
214
  icon: faArrowLeftLong,
215
- className: styles$k.button__icon__hover
215
+ className: styles$m.button__icon__hover
216
216
  })), isCarouselRight && /*#__PURE__*/React.createElement("span", {
217
217
  className: iconClasses
218
218
  }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
219
219
  icon: faArrowRight,
220
- className: styles$k.button__icon__default
220
+ className: styles$m.button__icon__default
221
221
  }), /*#__PURE__*/React.createElement(FontAwesomeIcon, {
222
222
  icon: faArrowRightLong,
223
- className: styles$k.button__icon__hover
223
+ className: styles$m.button__icon__hover
224
224
  })), !isIconOnly && iconElement && /*#__PURE__*/React.createElement("span", {
225
225
  className: iconClasses
226
226
  }, iconElement));
227
227
  };
228
228
 
229
+ var styles$l = {"imageContainer":"Image-module__imageContainer___iD5Kd","loading":"Image-module__loading___Sh1zO","image":"Image-module__image___1pa50","error":"Image-module__error___0LGZ2","skeleton":"Image-module__skeleton___0bGS6","shimmer":"Image-module__shimmer___aanrl","errorState":"Image-module__errorState___TjV-8","errorIcon":"Image-module__errorIcon___QCKvj","errorText":"Image-module__errorText___Q8pnb"};
230
+
231
+ const Image = ({
232
+ src,
233
+ alt,
234
+ width,
235
+ height,
236
+ loading = "lazy",
237
+ decoding = "async",
238
+ objectFit = "cover",
239
+ objectPosition = "center",
240
+ aspectRatio,
241
+ isDecorative = false,
242
+ fallbackSrc,
243
+ onLoad,
244
+ onError,
245
+ className = "",
246
+ srcSet,
247
+ sizes
248
+ }) => {
249
+ const [isLoading, setIsLoading] = useState(true);
250
+ const [hasError, setHasError] = useState(false);
251
+ const [currentSrc, setCurrentSrc] = useState(src);
252
+
253
+ // Keep internal state in sync when parent updates `src` (e.g. async data).
254
+ useEffect(() => {
255
+ setCurrentSrc(src);
256
+ setIsLoading(true);
257
+ setHasError(false);
258
+ }, [src]);
259
+ const handleLoad = useCallback(() => {
260
+ setIsLoading(false);
261
+ setHasError(false);
262
+ onLoad?.();
263
+ }, [onLoad]);
264
+ const handleError = useCallback(() => {
265
+ setIsLoading(false);
266
+ setHasError(true);
267
+
268
+ // Try fallback if available and not already using it
269
+ if (fallbackSrc && currentSrc !== fallbackSrc) {
270
+ setCurrentSrc(fallbackSrc);
271
+ setHasError(false);
272
+ setIsLoading(true);
273
+ } else {
274
+ onError?.();
275
+ }
276
+ }, [fallbackSrc, currentSrc, onError]);
277
+
278
+ // Accessibility: decorative images should have empty alt and be hidden from screen readers
279
+ const accessibilityProps = isDecorative ? {
280
+ alt: "",
281
+ "aria-hidden": true,
282
+ role: "presentation"
283
+ } : {
284
+ alt
285
+ };
286
+ const containerStyle = {
287
+ ...(aspectRatio && {
288
+ aspectRatio
289
+ }),
290
+ ...(width && {
291
+ width: typeof width === "number" ? `${width}px` : width
292
+ }),
293
+ ...(height && {
294
+ height: typeof height === "number" ? `${height}px` : height
295
+ })
296
+ };
297
+ const imageStyle = {
298
+ objectFit,
299
+ objectPosition
300
+ };
301
+ return /*#__PURE__*/React.createElement("div", {
302
+ className: `${styles$l.imageContainer} ${className} ${isLoading ? styles$l.loading : ""} ${hasError ? styles$l.error : ""}`,
303
+ style: containerStyle
304
+ }, isLoading && /*#__PURE__*/React.createElement("div", {
305
+ className: styles$l.skeleton,
306
+ "aria-hidden": "true"
307
+ }, /*#__PURE__*/React.createElement("div", {
308
+ className: styles$l.shimmer
309
+ })), hasError && !fallbackSrc ? /*#__PURE__*/React.createElement("div", {
310
+ className: styles$l.errorState,
311
+ role: "img",
312
+ "aria-label": alt || "Image failed to load"
313
+ }, /*#__PURE__*/React.createElement("svg", {
314
+ xmlns: "http://www.w3.org/2000/svg",
315
+ viewBox: "0 0 24 24",
316
+ fill: "none",
317
+ stroke: "currentColor",
318
+ strokeWidth: "1.5",
319
+ strokeLinecap: "round",
320
+ strokeLinejoin: "round",
321
+ className: styles$l.errorIcon,
322
+ "aria-hidden": "true"
323
+ }, /*#__PURE__*/React.createElement("rect", {
324
+ x: "3",
325
+ y: "3",
326
+ width: "18",
327
+ height: "18",
328
+ rx: "2",
329
+ ry: "2"
330
+ }), /*#__PURE__*/React.createElement("circle", {
331
+ cx: "8.5",
332
+ cy: "8.5",
333
+ r: "1.5"
334
+ }), /*#__PURE__*/React.createElement("polyline", {
335
+ points: "21 15 16 10 5 21"
336
+ })), /*#__PURE__*/React.createElement("span", {
337
+ className: styles$l.errorText
338
+ }, "Image unavailable")) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("img", _extends({
339
+ src: currentSrc
340
+ }, accessibilityProps, {
341
+ width: width,
342
+ height: height,
343
+ loading: loading,
344
+ decoding: decoding,
345
+ onLoad: handleLoad,
346
+ onError: handleError,
347
+ className: styles$l.image,
348
+ style: imageStyle,
349
+ srcSet: srcSet,
350
+ sizes: sizes
351
+ }))));
352
+ };
353
+
354
+ var styles$k = {"carouselCard":"CarouselCard-module__carouselCard___7SltX","carouselCard__content":"CarouselCard-module__carouselCard__content___SEDzm","carouselCard__linkText":"CarouselCard-module__carouselCard__linkText___fe3NV","carouselCard__icon":"CarouselCard-module__carouselCard__icon___sQ26Z","carouselCard__imageWrapper":"CarouselCard-module__carouselCard__imageWrapper___i-uYe","carouselCard__title":"CarouselCard-module__carouselCard__title___PN7o3"};
355
+
356
+ const CarouselCard = ({
357
+ imageUrl,
358
+ imageAlt,
359
+ title,
360
+ linkText,
361
+ linkUrl,
362
+ className,
363
+ ariaLabel
364
+ }) => {
365
+ return /*#__PURE__*/React.createElement("a", {
366
+ href: linkUrl,
367
+ className: classNames(styles$k.carouselCard, className),
368
+ "aria-label": ariaLabel
369
+ }, /*#__PURE__*/React.createElement(Image, {
370
+ src: imageUrl,
371
+ alt: imageAlt,
372
+ className: styles$k.carouselCard__imageWrapper,
373
+ width: "100%",
374
+ height: "100%",
375
+ objectFit: "cover",
376
+ objectPosition: "center"
377
+ }), /*#__PURE__*/React.createElement("div", {
378
+ className: styles$k.carouselCard__content
379
+ }, /*#__PURE__*/React.createElement("h3", {
380
+ className: styles$k.carouselCard__title
381
+ }, title), /*#__PURE__*/React.createElement("span", {
382
+ className: styles$k.carouselCard__linkText
383
+ }, linkText, /*#__PURE__*/React.createElement("span", {
384
+ className: styles$k.carouselCard__icon,
385
+ "aria-hidden": "true"
386
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
387
+ icon: faArrowRight
388
+ })))));
389
+ };
390
+
229
391
  var styles$j = {"footer":"Footer-module__footer___Oavyx","footer--mobile":"Footer-module__footer--mobile___9HQC-","footer__container":"Footer-module__footer__container___ohvnm","footer__links":"Footer-module__footer__links___DdVK8","footer__linkGroup":"Footer-module__footer__linkGroup___1B7JA","footer__linkList":"Footer-module__footer__linkList___j-DWF","footer__linkHeading":"Footer-module__footer__linkHeading___LtE6X","footer__link":"Footer-module__footer__link___G5HPW","footer__cta":"Footer-module__footer__cta___MRJLr","footer__socialIcons":"Footer-module__footer__socialIcons___j0aRp","footer__socialIcon":"Footer-module__footer__socialIcon___1uVTm","footer__countrySelector":"Footer-module__footer__countrySelector___pVtN5","footer__bottom":"Footer-module__footer__bottom___77bPL","footer__bottomLeft":"Footer-module__footer__bottomLeft___tlst1","footer__bottomLinks":"Footer-module__footer__bottomLinks___s22h7","footer__bottomLink":"Footer-module__footer__bottomLink___SLzwY","footer__copyright":"Footer-module__footer__copyright___4bZOF","footer__brandSection":"Footer-module__footer__brandSection___BBr5f","footer__logo":"Footer-module__footer__logo___mv-9M","footer__leftCol":"Footer-module__footer__leftCol___vmKNN","footer__motto":"Footer-module__footer__motto___QtB2m","footer__main":"Footer-module__footer__main___NSU9d","footer__badge":"Footer-module__footer__badge___faejb","footer__badgeIcon":"Footer-module__footer__badgeIcon___xJ519","footer__badgeText":"Footer-module__footer__badgeText___imXgG","footer__linkText":"Footer-module__footer__linkText___Gc18Z","footer__linkIcon":"Footer-module__footer__linkIcon___IZzJM","footer__countrySelectorIcon":"Footer-module__footer__countrySelectorIcon___hhEd4"};
230
392
 
231
393
  /**
@@ -745,125 +907,7 @@ const Pagination = ({
745
907
  })));
746
908
  };
747
909
 
748
- var styles$h = {"productCard":"ProductCardHorizontal-module__productCard___Nl4jK","productWrapper":"ProductCardHorizontal-module__productWrapper___gs8fn","withImage":"ProductCardHorizontal-module__withImage___pPFw2","productTitle":"ProductCardHorizontal-module__productTitle___xBuu7","productPrice":"ProductCardHorizontal-module__productPrice___lf32A","productImage":"ProductCardHorizontal-module__productImage___sQsUO","productId":"ProductCardHorizontal-module__productId___3oOQV","productTitleDescriptionWrapper":"ProductCardHorizontal-module__productTitleDescriptionWrapper___Obv-j","productPriceCtaWrapper":"ProductCardHorizontal-module__productPriceCtaWrapper___Npkfl","productArrowIcon":"ProductCardHorizontal-module__productArrowIcon___1-A76"};
749
-
750
- var styles$g = {"imageContainer":"Image-module__imageContainer___iD5Kd","loading":"Image-module__loading___Sh1zO","image":"Image-module__image___1pa50","error":"Image-module__error___0LGZ2","skeleton":"Image-module__skeleton___0bGS6","shimmer":"Image-module__shimmer___aanrl","errorState":"Image-module__errorState___TjV-8","errorIcon":"Image-module__errorIcon___QCKvj","errorText":"Image-module__errorText___Q8pnb"};
751
-
752
- const Image = ({
753
- src,
754
- alt,
755
- width,
756
- height,
757
- loading = "lazy",
758
- decoding = "async",
759
- objectFit = "cover",
760
- objectPosition = "center",
761
- aspectRatio,
762
- isDecorative = false,
763
- fallbackSrc,
764
- onLoad,
765
- onError,
766
- className = "",
767
- srcSet,
768
- sizes
769
- }) => {
770
- const [isLoading, setIsLoading] = useState(true);
771
- const [hasError, setHasError] = useState(false);
772
- const [currentSrc, setCurrentSrc] = useState(src);
773
- const handleLoad = useCallback(() => {
774
- setIsLoading(false);
775
- setHasError(false);
776
- onLoad?.();
777
- }, [onLoad]);
778
- const handleError = useCallback(() => {
779
- setIsLoading(false);
780
- setHasError(true);
781
-
782
- // Try fallback if available and not already using it
783
- if (fallbackSrc && currentSrc !== fallbackSrc) {
784
- setCurrentSrc(fallbackSrc);
785
- setHasError(false);
786
- setIsLoading(true);
787
- } else {
788
- onError?.();
789
- }
790
- }, [fallbackSrc, currentSrc, onError]);
791
-
792
- // Accessibility: decorative images should have empty alt and be hidden from screen readers
793
- const accessibilityProps = isDecorative ? {
794
- alt: "",
795
- "aria-hidden": true,
796
- role: "presentation"
797
- } : {
798
- alt
799
- };
800
- const containerStyle = {
801
- ...(aspectRatio && {
802
- aspectRatio
803
- }),
804
- ...(width && {
805
- width: typeof width === "number" ? `${width}px` : width
806
- }),
807
- ...(height && {
808
- height: typeof height === "number" ? `${height}px` : height
809
- })
810
- };
811
- const imageStyle = {
812
- objectFit,
813
- objectPosition
814
- };
815
- return /*#__PURE__*/React.createElement("div", {
816
- className: `${styles$g.imageContainer} ${className} ${isLoading ? styles$g.loading : ""} ${hasError ? styles$g.error : ""}`,
817
- style: containerStyle
818
- }, isLoading && /*#__PURE__*/React.createElement("div", {
819
- className: styles$g.skeleton,
820
- "aria-hidden": "true"
821
- }, /*#__PURE__*/React.createElement("div", {
822
- className: styles$g.shimmer
823
- })), hasError && !fallbackSrc ? /*#__PURE__*/React.createElement("div", {
824
- className: styles$g.errorState,
825
- role: "img",
826
- "aria-label": alt || "Image failed to load"
827
- }, /*#__PURE__*/React.createElement("svg", {
828
- xmlns: "http://www.w3.org/2000/svg",
829
- viewBox: "0 0 24 24",
830
- fill: "none",
831
- stroke: "currentColor",
832
- strokeWidth: "1.5",
833
- strokeLinecap: "round",
834
- strokeLinejoin: "round",
835
- className: styles$g.errorIcon,
836
- "aria-hidden": "true"
837
- }, /*#__PURE__*/React.createElement("rect", {
838
- x: "3",
839
- y: "3",
840
- width: "18",
841
- height: "18",
842
- rx: "2",
843
- ry: "2"
844
- }), /*#__PURE__*/React.createElement("circle", {
845
- cx: "8.5",
846
- cy: "8.5",
847
- r: "1.5"
848
- }), /*#__PURE__*/React.createElement("polyline", {
849
- points: "21 15 16 10 5 21"
850
- })), /*#__PURE__*/React.createElement("span", {
851
- className: styles$g.errorText
852
- }, "Image unavailable")) : /*#__PURE__*/React.createElement("img", _extends({
853
- src: currentSrc
854
- }, accessibilityProps, {
855
- width: width,
856
- height: height,
857
- loading: loading,
858
- decoding: decoding,
859
- onLoad: handleLoad,
860
- onError: handleError,
861
- className: styles$g.image,
862
- style: imageStyle,
863
- srcSet: srcSet,
864
- sizes: sizes
865
- })));
866
- };
910
+ var styles$h = {"productCard":"ProductCardHorizontal-module__productCard___Nl4jK","productWrapper":"ProductCardHorizontal-module__productWrapper___gs8fn","withImage":"ProductCardHorizontal-module__withImage___pPFw2","withPlaceholder":"ProductCardHorizontal-module__withPlaceholder___x8IUh","productTitle":"ProductCardHorizontal-module__productTitle___xBuu7","productPrice":"ProductCardHorizontal-module__productPrice___lf32A","productImage":"ProductCardHorizontal-module__productImage___sQsUO","placeholderImage":"ProductCardHorizontal-module__placeholderImage___kT1sp","productId":"ProductCardHorizontal-module__productId___3oOQV","productTitleDescriptionWrapper":"ProductCardHorizontal-module__productTitleDescriptionWrapper___Obv-j","productPriceCtaWrapper":"ProductCardHorizontal-module__productPriceCtaWrapper___Npkfl","productArrowIcon":"ProductCardHorizontal-module__productArrowIcon___1-A76"};
867
911
 
868
912
  /*!
869
913
  * Font Awesome Pro 6.7.2 by @fontawesome - https://fontawesome.com
@@ -876,9 +920,16 @@ const faArrowUpRight = {
876
920
  icon: [384, 512, [], "e09f", "M328 96c13.3 0 24 10.7 24 24l0 240c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-182.1L73 409c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l231-231L88 144c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0z"]
877
921
  };
878
922
 
923
+ const PLACEHOLDER_INDICATOR$1 = "?placeholder-storybook";
924
+ const PLACEHOLDER_SVG$1 = `<svg xmlns="http://www.w3.org/2000/svg" width="440" height="133" viewBox="218.446 219.139 440 133" role="img" aria-label="Leybold placeholder logo"><g fill="#ffff"><path d="M290.317,313.442h37.784v12.782h-53.654v-70.62h15.87V313.442z"/><path d="M386.309,310.883c-3.912,12.593-15.135,16.722-24.761,16.722c-15.878,0-28.046-7.084-28.046-28.62c0-6.296,2.322-26.458,26.98-26.458c11.116,0,26.457,4.917,26.457,28.819v2.457h-38.626c0.428,3.935,1.274,12.785,13.232,12.785c4.125,0,8.356-1.965,9.521-5.704L386.309,310.883L386.309,310.883z M371.709,294.852c-0.85-8.456-6.666-11.017-11.434-11.017c-6.979,0-10.686,4.129-11.532,11.017H371.709z"/><path d="M423.556,325.343c-6.986,19.374-8.892,21.932-21.799,21.932c-2.014,0-4.553-0.096-6.665-0.194v-11.02c0.629,0.104,1.582,0.197,2.854,0.197c5.397,0,8.36-0.688,9.737-7.864l-20.741-54.488h16.508l12.062,38.553h0.209l11.539-38.553h15.658L423.556,325.343z"/><path d="M463.54,280.689h0.213c2.328-3.344,6.775-8.164,16.297-8.164c12.385,0,23.389,8.854,23.389,26.949c0,14.359-6.98,28.129-23.703,28.129c-6.141,0-12.701-2.067-16.299-7.968h-0.211v6.589h-14.498v-70.62h14.812V280.689z M475.604,284.427c-10.158,0-12.701,8.455-12.701,16.815c0,7.773,3.707,15.049,13.129,15.049c9.521,0,12.168-9.641,12.168-15.83C488.198,292.192,485.02,284.427,475.604,284.427z"/><path d="M538.094,327.604c-15.141,0-28.787-8.652-28.787-27.542c0-18.881,13.646-27.536,28.787-27.536c15.129,0,28.785,8.655,28.785,27.536C566.88,318.95,553.223,327.604,538.094,327.604z M538.094,284.129c-11.434,0-13.547,9.244-13.547,15.934c0,6.691,2.113,15.939,13.547,15.939c11.426,0,13.547-9.248,13.547-15.939C551.641,293.373,549.52,284.129,538.094,284.129z"/><path d="M588.811,326.225h-14.814v-70.62h14.814V326.225z"/><path d="M651.969,326.225h-14.5v-6.589h-0.213c-3.598,5.898-10.156,7.968-16.295,7.968c-16.727,0-23.703-13.77-23.703-28.129c0-18.097,11.004-26.949,23.381-26.949c9.523,0,13.975,4.82,16.295,8.164h0.221v-25.085h14.814V326.225z M624.663,316.291c9.418,0,13.121-7.273,13.121-15.05c0-8.359-2.537-16.814-12.703-16.814c-9.416,0-12.592,7.767-12.592,16.034C612.49,306.651,615.135,316.291,624.663,316.291z"/></g><g fill="#ffff"><path d="M268.323,226.771h-41.551v39.685C230.996,246.516,247.442,230.811,268.323,226.771z"/><path d="M226.771,286.726v39.688h41.551C247.442,322.371,230.996,306.67,226.771,286.726z"/><path d="M331.122,266.455V226.77h-41.552C310.449,230.811,326.892,246.516,331.122,266.455z"/></g></svg>`;
925
+ const PLACEHOLDER_IMAGE_DATA_URI$1 = `data:image/svg+xml,${encodeURIComponent(PLACEHOLDER_SVG$1)}`;
926
+ const isPlaceholderImg$1 = url => {
927
+ return !!url && url.includes(PLACEHOLDER_INDICATOR$1);
928
+ };
879
929
  const ProductCardHorizontal = ({
880
930
  id,
881
931
  imageUrl,
932
+ showProductImage = true,
882
933
  url,
883
934
  title,
884
935
  description,
@@ -886,34 +937,43 @@ const ProductCardHorizontal = ({
886
937
  productId,
887
938
  button,
888
939
  utm,
889
- className = ""
940
+ className = "",
941
+ style,
942
+ code,
943
+ showProductPrice
890
944
  }) => {
891
945
  if (!title) {
892
946
  return null;
893
947
  }
948
+ const hasPlaceholderImage = showProductImage && (!imageUrl || isPlaceholderImg$1(imageUrl));
949
+ const productImage = hasPlaceholderImage === true ? PLACEHOLDER_IMAGE_DATA_URI$1 : imageUrl;
894
950
  const href = !utm || url && url.indexOf("utm") > -1 ? url : url + `?utm_source=${utm.utmSource}&utm_medium=${utm.utmMedium}&utm_campaign=${utm.utmCampaign}`;
895
951
  return /*#__PURE__*/React.createElement("a", {
896
952
  href: href,
897
953
  className: `${styles$h.productCard} ${className}`,
898
954
  "aria-label": `View product: ${title}`
899
955
  }, /*#__PURE__*/React.createElement("div", {
900
- className: `${styles$h.productWrapper} ${imageUrl ? styles$h.withImage : ""}`
901
- }, imageUrl && /*#__PURE__*/React.createElement("div", {
956
+ className: `${styles$h.productWrapper} ${showProductImage ? hasPlaceholderImage ? styles$h.withPlaceholder : styles$h.withImage : ""}`,
957
+ style: style
958
+ }, showProductImage && /*#__PURE__*/React.createElement("div", {
902
959
  className: styles$h.productImage
903
960
  }, /*#__PURE__*/React.createElement(Image, {
904
- src: imageUrl,
905
- alt: title
961
+ src: productImage,
962
+ alt: title,
963
+ className: hasPlaceholderImage ? styles$h.placeholderImage : "",
964
+ objectFit: hasPlaceholderImage ? "contain" : "cover",
965
+ fallbackSrc: PLACEHOLDER_IMAGE_DATA_URI$1
906
966
  })), /*#__PURE__*/React.createElement("div", {
907
967
  className: styles$h.productTitleDescriptionWrapper
908
968
  }, /*#__PURE__*/React.createElement("h3", {
909
969
  className: styles$h.productTitle
910
- }, title), productId && /*#__PURE__*/React.createElement("p", {
970
+ }, title), productId || code ? /*#__PURE__*/React.createElement("p", {
911
971
  className: styles$h.productId
912
- }, productId)), /*#__PURE__*/React.createElement("div", {
972
+ }, productId || code) : null), /*#__PURE__*/React.createElement("div", {
913
973
  className: styles$h.productPriceCtaWrapper
914
974
  }, /*#__PURE__*/React.createElement("p", {
915
975
  className: styles$h.productPrice
916
- }, price || " "), button ? /*#__PURE__*/React.createElement(Button, {
976
+ }, showProductPrice ? price || "" : ""), button ? /*#__PURE__*/React.createElement(Button, {
917
977
  className: styles$h.productButton,
918
978
  onClick: button.onClick,
919
979
  size: "extra-small"
@@ -927,7 +987,7 @@ const ProductCardHorizontal = ({
927
987
  // Alias for backward compatibility
928
988
  const ProductCardHorizontalParts = ProductCardHorizontal;
929
989
 
930
- var styles$f = {"productDetails":"ProductCardDetails-module__productDetails___-sx2l","spareCard":"ProductCardDetails-module__spareCard___vC1Ju"};
990
+ var styles$g = {"productDetails":"ProductCardDetails-module__productDetails___-sx2l","spareCard":"ProductCardDetails-module__spareCard___vC1Ju"};
931
991
 
932
992
  // Adapter to map design system props to ProductCardHorizontalParts props
933
993
  const SpareCardAdapter = props => {
@@ -936,13 +996,16 @@ const SpareCardAdapter = props => {
936
996
  ...rest
937
997
  } = props;
938
998
  return /*#__PURE__*/React.createElement(ProductCardHorizontalParts, {
939
- className: styles$f.spareCard,
999
+ className: styles$g.spareCard,
940
1000
  url: spare?.url || spare?.link || "#",
941
1001
  title: spare?.name || spare?.title || "",
942
1002
  description: spare?.description || "",
943
- price: spare?.priceValue || spare?.price || "",
944
- imageUrl: spare?.["img-product"] || spare?.image || "",
1003
+ price: spare?.priceValue || spare?.price || props?.productPrice || ""
1004
+ // imageUrl={spare?.["img-product"] || spare?.image || ""}
1005
+ ,
945
1006
  utm: props.utm,
1007
+ showProductPrice: props.showProductPrice,
1008
+ showProductImage: false,
946
1009
  button: {
947
1010
  label: rest.cta || "View Product",
948
1011
  onClick: () => window.open(spare?.url || spare?.link || "#", "_blank")
@@ -963,7 +1026,9 @@ const ProductCardDetails = ({
963
1026
  utm,
964
1027
  className = "",
965
1028
  ProductCardComponent,
966
- hidespares
1029
+ hidespares,
1030
+ showProductPrice,
1031
+ showProductImage = true
967
1032
  }) => {
968
1033
  // Build the hit object expected by ProductDetailsCard
969
1034
  const hitData = hit || {
@@ -975,23 +1040,146 @@ const ProductCardDetails = ({
975
1040
  image: imageUrl
976
1041
  };
977
1042
  return /*#__PURE__*/React.createElement("div", {
978
- className: styles$f.productDetails
1043
+ className: styles$g.productDetails
979
1044
  }, /*#__PURE__*/React.createElement(ProductDetailsCard, {
980
1045
  className: `${className}`,
981
1046
  title: title,
982
- imageUrl: imageUrl,
1047
+ imageUrl: showProductImage ? imageUrl : "",
983
1048
  imageAlt: title,
984
1049
  hit: hitData,
985
1050
  utm: utm,
986
1051
  facets: facets,
987
1052
  usePlainClasses: true,
988
1053
  ProductCardComponent: ProductCardComponent || SpareCardAdapter,
989
- hidespares: hidespares
1054
+ hidespares: hidespares,
1055
+ showProductPrice: showProductPrice,
1056
+ showProductImage: showProductImage
990
1057
  }));
991
1058
  };
992
1059
 
1060
+ const ContentCardBase = ({
1061
+ title,
1062
+ variant,
1063
+ url,
1064
+ imageUrl,
1065
+ category,
1066
+ meta = "something interesting",
1067
+ excerpt,
1068
+ className = "",
1069
+ style,
1070
+ ariaLabel,
1071
+ contentMetaClassName,
1072
+ contentCategoryClassName,
1073
+ contentMetaTextClassName,
1074
+ contentTitleClassName,
1075
+ contentExcerptClassName,
1076
+ showButton
1077
+ }) => {
1078
+ console.log("variant in ContentCardBase:", variant);
1079
+ const fallbackImage = "/assets/list-card.png";
1080
+ const isCareerView = variant === "career-view";
1081
+ const seperator = category && meta ? " | " : "";
1082
+ const defaultAriaLabel = isCareerView ? `View career opportunity: ${title}` : `View content: ${title}`;
1083
+ return /*#__PURE__*/React.createElement("a", {
1084
+ href: url,
1085
+ className: className,
1086
+ style: style,
1087
+ "aria-label": ariaLabel || defaultAriaLabel
1088
+ }, imageUrl && /*#__PURE__*/React.createElement("div", {
1089
+ className: "content-card-image-wrapper"
1090
+ }, /*#__PURE__*/React.createElement(Image, {
1091
+ src: imageUrl,
1092
+ alt: title,
1093
+ className: "content-card-image",
1094
+ aspectRatio: "16 / 9",
1095
+ loading: "lazy",
1096
+ decoding: "async",
1097
+ fallbackSrc: fallbackImage
1098
+ })), isCareerView ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h3", {
1099
+ className: contentTitleClassName
1100
+ }, title), category && /*#__PURE__*/React.createElement("span", {
1101
+ className: contentCategoryClassName
1102
+ }, category), meta && /*#__PURE__*/React.createElement("span", {
1103
+ className: contentMetaTextClassName
1104
+ }, meta), /*#__PURE__*/React.createElement(Button, {
1105
+ "aria-label": ariaLabel || defaultAriaLabel,
1106
+ variant: "link-text-alt",
1107
+ className: "career-button"
1108
+ }, "See more")) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
1109
+ className: contentMetaClassName
1110
+ }, category && /*#__PURE__*/React.createElement("span", {
1111
+ className: contentCategoryClassName
1112
+ }, category), seperator && /*#__PURE__*/React.createElement("span", {
1113
+ className: `${contentCategoryClassName} separator`
1114
+ }, seperator), meta && /*#__PURE__*/React.createElement("span", {
1115
+ className: contentMetaTextClassName
1116
+ }, meta)), /*#__PURE__*/React.createElement("h3", {
1117
+ className: contentTitleClassName
1118
+ }, title), excerpt && /*#__PURE__*/React.createElement("p", {
1119
+ className: contentExcerptClassName
1120
+ }, excerpt), showButton && /*#__PURE__*/React.createElement(Button, {
1121
+ "aria-label": ariaLabel || defaultAriaLabel
1122
+ }, "Read More")));
1123
+ };
1124
+
1125
+ var styles$f = {"contentCard":"ContentCardVertical-module__contentCard___EoYej","contentCard--instant-view":"ContentCardVertical-module__contentCard--instant-view___dsIUf","contentCard--results-view":"ContentCardVertical-module__contentCard--results-view___6mSHQ","contentMeta":"ContentCardVertical-module__contentMeta___l2GtO","contentCategory":"ContentCardVertical-module__contentCategory___78vrj","contentMetaText":"ContentCardVertical-module__contentMetaText___Rl-ln","contentTitle":"ContentCardVertical-module__contentTitle___rEiHm","contentExcerpt":"ContentCardVertical-module__contentExcerpt___5Gb2G"};
1126
+
1127
+ const ContentCardVertical = ({
1128
+ id,
1129
+ title,
1130
+ url,
1131
+ imageUrl,
1132
+ category,
1133
+ meta,
1134
+ excerpt,
1135
+ className = "",
1136
+ variant
1137
+ }) => {
1138
+ const cardClasses = classNames(styles$f.contentCard, styles$f[`contentCard--${variant}`], className);
1139
+ console.log("Rendering ContentCardVertical with variant:", variant);
1140
+ return /*#__PURE__*/React.createElement(ContentCardBase, {
1141
+ id: id,
1142
+ variant: variant,
1143
+ title: title,
1144
+ url: url,
1145
+ imageUrl: imageUrl,
1146
+ category: category,
1147
+ meta: meta,
1148
+ excerpt: excerpt,
1149
+ className: cardClasses,
1150
+ contentMetaClassName: styles$f.contentMeta,
1151
+ contentCategoryClassName: styles$f.contentCategory,
1152
+ contentMetaTextClassName: styles$f.contentMetaText,
1153
+ contentTitleClassName: styles$f.contentTitle,
1154
+ contentExcerptClassName: styles$f.contentExcerpt
1155
+ });
1156
+ };
1157
+
993
1158
  // Adapter component that maps props from AlgoliaDynamicSearchRaw to ProductCardHorizontal
994
1159
  // AlgoliaDynamicSearchRaw passes: title, cardLink, productPrice, cta, hit (original data)
1160
+
1161
+ const cardAdapter = props => {
1162
+ const {
1163
+ hit,
1164
+ title,
1165
+ cardLink,
1166
+ productPrice,
1167
+ showProductPrice,
1168
+ className,
1169
+ queryType
1170
+ } = props;
1171
+ return /*#__PURE__*/React.createElement(ContentCardVertical, {
1172
+ id: hit?.id || "",
1173
+ variant: queryType && queryType === "careers" ? "career-view" : "content-view",
1174
+ title: title || hit?.title || "",
1175
+ url: cardLink || hit?.link || "#",
1176
+ imageUrl: hit?.image || "",
1177
+ category: hit?.category || "",
1178
+ meta: showProductPrice ? productPrice || hit?.price || "" : "",
1179
+ excerpt: hit?.description || "",
1180
+ className: className
1181
+ });
1182
+ };
995
1183
  const ProductCardAdapter = props => {
996
1184
  const {
997
1185
  hit,
@@ -1000,20 +1188,22 @@ const ProductCardAdapter = props => {
1000
1188
  productPrice,
1001
1189
  cta,
1002
1190
  showProductPrice,
1191
+ showProductImage,
1003
1192
  className,
1004
1193
  code,
1005
1194
  utm
1006
1195
  } = props;
1007
- console.log(props);
1196
+
1008
1197
  // Get values from direct props or fallback to hit object
1009
1198
  const url = cardLink || hit?.link || "#";
1010
- const imageUrl = "";
1199
+ const imageUrl = hit?.image || "";
1011
1200
  const price = showProductPrice ? productPrice || hit?.price || "" : "";
1012
1201
  const productTitle = title || hit?.title || "";
1013
1202
  const productCode = code || hit?.code || "";
1014
1203
  const buttonLabel = cta || "View Product";
1015
1204
  return /*#__PURE__*/React.createElement(ProductCardHorizontalParts, {
1016
1205
  imageUrl: imageUrl,
1206
+ showProductImage: showProductImage,
1017
1207
  url: url,
1018
1208
  utm: utm,
1019
1209
  title: productTitle,
@@ -1023,17 +1213,23 @@ const ProductCardAdapter = props => {
1023
1213
  label: buttonLabel,
1024
1214
  onClick: () => window.open(url, "_blank")
1025
1215
  },
1026
- className: className
1216
+ className: className,
1217
+ style: {
1218
+ ...(showProductImage ? {
1219
+ minHeight: "130px"
1220
+ } : {})
1221
+ },
1222
+ code: productCode,
1223
+ showProductPrice: showProductPrice
1027
1224
  });
1028
1225
  };
1029
1226
  const ProductCardDetailsAdapter = props => {
1030
1227
  const {
1031
1228
  hit,
1032
1229
  title,
1033
- cardLink,
1034
1230
  productPrice,
1035
- cta,
1036
1231
  showProductPrice,
1232
+ showProductImage,
1037
1233
  className,
1038
1234
  code,
1039
1235
  utm,
@@ -1055,13 +1251,44 @@ const ProductCardDetailsAdapter = props => {
1055
1251
  className: className,
1056
1252
  facets: facets,
1057
1253
  relatedProducts: hit?.related_products || related_products,
1058
- hidespares: hidespares
1254
+ hidespares: hidespares,
1255
+ showProductPrice: showProductPrice,
1256
+ showProductImage: showProductImage
1059
1257
  });
1060
1258
  };
1259
+ const ButtonAdapter = props => {
1260
+ const {
1261
+ label,
1262
+ onClick,
1263
+ className
1264
+ } = props;
1265
+ return /*#__PURE__*/React.createElement(Button, {
1266
+ className: className,
1267
+ onClick: onClick
1268
+ }, label);
1269
+ };
1061
1270
  const AlgoliaDynamicSearchLeybold = props => {
1271
+ const parentComponentProps = {
1272
+ queryType: props?.queryType,
1273
+ showProductPrice: props?.showProductPrice,
1274
+ showProductImage: props?.showProductImage,
1275
+ hitCta: props?.hitCta,
1276
+ hidespares: props?.hidespares
1277
+ };
1062
1278
  const innerComponents = {
1063
- ProductCard: ProductCardAdapter,
1064
- ProductDetailsCard: ProductCardDetailsAdapter
1279
+ Card: innerProps => cardAdapter({
1280
+ ...parentComponentProps,
1281
+ ...innerProps
1282
+ }),
1283
+ ProductCard: innerProps => ProductCardAdapter({
1284
+ ...parentComponentProps,
1285
+ ...innerProps
1286
+ }),
1287
+ ProductDetailsCard: innerProps => ProductCardDetailsAdapter({
1288
+ ...parentComponentProps,
1289
+ ...innerProps
1290
+ }),
1291
+ Button: ButtonAdapter
1065
1292
  };
1066
1293
  return /*#__PURE__*/React.createElement(AlgoliaDynamicSearchRaw, _extends({}, props, {
1067
1294
  innerComponents: innerComponents
@@ -1121,7 +1348,7 @@ const QrFormLeybold = props => {
1121
1348
  })));
1122
1349
  };
1123
1350
 
1124
- var styles$e = {"overlay":"SearchModal-module__overlay___Vbvg9","modal":"SearchModal-module__modal___1k5gO","closeButton":"SearchModal-module__closeButton___AN0zt","closeButton__icon":"SearchModal-module__closeButton__icon___vISSw","closeButton__text":"SearchModal-module__closeButton__text___-4EH1","closeButtonDesktop":"SearchModal-module__closeButtonDesktop___Lxxb0","closeButtonMobile":"SearchModal-module__closeButtonMobile___WIIMS","stickyHeader":"SearchModal-module__stickyHeader___wp-gA","scrollableContent":"SearchModal-module__scrollableContent___lrZP3"};
1351
+ var styles$e = {"overlay":"SearchModal-module__overlay___Vbvg9","overlayOpen":"SearchModal-module__overlayOpen___Ipajg","overlayClosing":"SearchModal-module__overlayClosing___yXsw3","modal":"SearchModal-module__modal___1k5gO","modalOpen":"SearchModal-module__modalOpen___t3hpr","modalClosing":"SearchModal-module__modalClosing___W3m8i","closeButton":"SearchModal-module__closeButton___AN0zt","closeButton__icon":"SearchModal-module__closeButton__icon___vISSw","closeButton__text":"SearchModal-module__closeButton__text___-4EH1","closeButtonDesktop":"SearchModal-module__closeButtonDesktop___Lxxb0","closeButtonMobile":"SearchModal-module__closeButtonMobile___WIIMS","closeButtonMobileWrapper":"SearchModal-module__closeButtonMobileWrapper___LSynI","closeButtonMobileWrapperHidden":"SearchModal-module__closeButtonMobileWrapperHidden___O9nRE","stickyHeader":"SearchModal-module__stickyHeader___wp-gA","stickyHeaderHidden":"SearchModal-module__stickyHeaderHidden___-UI7O","scrollableContent":"SearchModal-module__scrollableContent___lrZP3"};
1125
1352
 
1126
1353
  const ModalCloseButton = ({
1127
1354
  onClick,
@@ -1159,16 +1386,111 @@ const ModalCloseButton = ({
1159
1386
  }, "CLOSE X"));
1160
1387
  };
1161
1388
 
1389
+ const CLOSE_ANIMATION_MS = 600;
1390
+ const prefersReducedMotion = () => {
1391
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
1392
+ return false;
1393
+ }
1394
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1395
+ };
1162
1396
  const SearchModal = ({
1163
1397
  isOpen,
1164
1398
  onClose,
1165
- title = 'Search',
1399
+ title = "Search",
1166
1400
  children,
1167
- className = '',
1401
+ className = "",
1168
1402
  stickyHeaderContent
1169
1403
  }) => {
1170
1404
  const modalRef = useRef(null);
1405
+ const scrollableContentRef = useRef(null);
1171
1406
  const previouslyFocusedElement = useRef(null);
1407
+ const lastScrollTopRef = useRef(0);
1408
+ const scrollTickingRef = useRef(false);
1409
+ const [shouldRender, setShouldRender] = useState(isOpen);
1410
+ const [isClosing, setIsClosing] = useState(false);
1411
+ const closeTimerRef = useRef(null);
1412
+ const [isMobileCloseVisible, setIsMobileCloseVisible] = useState(true);
1413
+ const stateClassNames = useMemo(() => {
1414
+ if (isClosing) {
1415
+ return {
1416
+ overlay: styles$e.overlayClosing,
1417
+ modal: styles$e.modalClosing
1418
+ };
1419
+ }
1420
+ return {
1421
+ overlay: styles$e.overlayOpen,
1422
+ modal: styles$e.modalOpen
1423
+ };
1424
+ }, [isClosing]);
1425
+ useEffect(() => {
1426
+ return () => {
1427
+ if (closeTimerRef.current) {
1428
+ window.clearTimeout(closeTimerRef.current);
1429
+ }
1430
+ };
1431
+ }, []);
1432
+ useEffect(() => {
1433
+ if (isOpen) {
1434
+ if (closeTimerRef.current) {
1435
+ window.clearTimeout(closeTimerRef.current);
1436
+ closeTimerRef.current = null;
1437
+ }
1438
+ setShouldRender(true);
1439
+ setIsClosing(false);
1440
+ setIsMobileCloseVisible(true);
1441
+ return;
1442
+ }
1443
+ if (!shouldRender) return;
1444
+ setIsClosing(true);
1445
+ const duration = prefersReducedMotion() ? 0 : CLOSE_ANIMATION_MS;
1446
+ closeTimerRef.current = window.setTimeout(() => {
1447
+ setShouldRender(false);
1448
+ setIsClosing(false);
1449
+ closeTimerRef.current = null;
1450
+ }, duration);
1451
+ }, [isOpen, shouldRender]);
1452
+
1453
+ // Mobile-only: hide close button when scrolling down, show when scrolling up.
1454
+ useEffect(() => {
1455
+ if (!isOpen) return;
1456
+ // Important: this component renders `null` until `shouldRender` becomes true.
1457
+ // We need to wait for that render so `scrollableContentRef.current` exists.
1458
+ if (!shouldRender) return;
1459
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1460
+ const isMobile = window.matchMedia("(max-width: 768px)").matches;
1461
+ if (!isMobile) return;
1462
+ const el = scrollableContentRef.current;
1463
+ if (!el) return;
1464
+ lastScrollTopRef.current = el.scrollTop;
1465
+ setIsMobileCloseVisible(true);
1466
+ const thresholdPx = 10;
1467
+ const topRevealPx = 8;
1468
+ const update = () => {
1469
+ scrollTickingRef.current = false;
1470
+ const current = el.scrollTop;
1471
+ const prev = lastScrollTopRef.current;
1472
+ const delta = current - prev;
1473
+ if (current <= topRevealPx) {
1474
+ setIsMobileCloseVisible(true);
1475
+ } else if (delta > thresholdPx) {
1476
+ setIsMobileCloseVisible(false);
1477
+ } else if (delta < -thresholdPx) {
1478
+ setIsMobileCloseVisible(true);
1479
+ }
1480
+ lastScrollTopRef.current = current;
1481
+ };
1482
+ const onScroll = () => {
1483
+ if (scrollTickingRef.current) return;
1484
+ scrollTickingRef.current = true;
1485
+ window.requestAnimationFrame(update);
1486
+ };
1487
+ el.addEventListener("scroll", onScroll, {
1488
+ passive: true
1489
+ });
1490
+ return () => {
1491
+ el.removeEventListener("scroll", onScroll);
1492
+ };
1493
+ }, [isOpen, shouldRender]);
1172
1494
  useEffect(() => {
1173
1495
  if (isOpen) {
1174
1496
  // Store the previously focused element
@@ -1180,28 +1502,32 @@ const SearchModal = ({
1180
1502
  }
1181
1503
 
1182
1504
  // Prevent body scroll
1183
- document.body.style.overflow = 'hidden';
1505
+ document.body.style.overflow = "hidden";
1184
1506
  } else {
1185
- // Restore body scroll
1186
- document.body.style.overflow = '';
1187
-
1188
1507
  // Return focus to previously focused element
1189
1508
  if (previouslyFocusedElement.current) {
1190
1509
  previouslyFocusedElement.current.focus();
1191
1510
  }
1192
1511
  }
1512
+ }, [isOpen]);
1513
+ useEffect(() => {
1514
+ if (shouldRender) {
1515
+ document.body.style.overflow = "hidden";
1516
+ } else {
1517
+ document.body.style.overflow = "";
1518
+ }
1193
1519
  return () => {
1194
- document.body.style.overflow = '';
1520
+ document.body.style.overflow = "";
1195
1521
  };
1196
- }, [isOpen]);
1522
+ }, [shouldRender]);
1197
1523
  useEffect(() => {
1198
1524
  const handleEscape = event => {
1199
- if (event.key === 'Escape' && isOpen) {
1525
+ if (event.key === "Escape" && isOpen) {
1200
1526
  onClose();
1201
1527
  }
1202
1528
  };
1203
- document.addEventListener('keydown', handleEscape);
1204
- return () => document.removeEventListener('keydown', handleEscape);
1529
+ document.addEventListener("keydown", handleEscape);
1530
+ return () => document.removeEventListener("keydown", handleEscape);
1205
1531
  }, [isOpen, onClose]);
1206
1532
 
1207
1533
  // Focus trap implementation
@@ -1212,7 +1538,7 @@ const SearchModal = ({
1212
1538
  const firstElement = focusableElements[0];
1213
1539
  const lastElement = focusableElements[focusableElements.length - 1];
1214
1540
  const handleTab = event => {
1215
- if (event.key !== 'Tab') return;
1541
+ if (event.key !== "Tab") return;
1216
1542
  if (event.shiftKey) {
1217
1543
  // Shift + Tab
1218
1544
  if (document.activeElement === firstElement) {
@@ -1227,17 +1553,18 @@ const SearchModal = ({
1227
1553
  }
1228
1554
  }
1229
1555
  };
1230
- modal.addEventListener('keydown', handleTab);
1231
- return () => modal.removeEventListener('keydown', handleTab);
1556
+ modal.addEventListener("keydown", handleTab);
1557
+ return () => modal.removeEventListener("keydown", handleTab);
1232
1558
  }, [isOpen]);
1233
- if (!isOpen) return null;
1559
+ if (!shouldRender) return null;
1234
1560
  const handleOverlayClick = event => {
1561
+ if (isClosing) return;
1235
1562
  if (event.target === event.currentTarget) {
1236
1563
  onClose();
1237
1564
  }
1238
1565
  };
1239
1566
  return /*#__PURE__*/React.createElement("div", {
1240
- className: styles$e.overlay,
1567
+ className: `${styles$e.overlay} ${stateClassNames.overlay}`,
1241
1568
  onClick: handleOverlayClick,
1242
1569
  "aria-hidden": "true"
1243
1570
  }, /*#__PURE__*/React.createElement("div", {
@@ -1246,13 +1573,16 @@ const SearchModal = ({
1246
1573
  "aria-modal": "true",
1247
1574
  "aria-label": title,
1248
1575
  tabIndex: -1,
1249
- className: `${styles$e.modal} ${className}`
1576
+ className: `${styles$e.modal} ${stateClassNames.modal} ${className}`
1577
+ }, /*#__PURE__*/React.createElement("div", {
1578
+ className: `${styles$e.stickyHeader}` + ` ${!isMobileCloseVisible ? styles$e.stickyHeaderHidden : ""}`
1250
1579
  }, /*#__PURE__*/React.createElement("div", {
1251
- className: styles$e.stickyHeader
1580
+ className: `${styles$e.closeButtonMobileWrapper} ${isMobileCloseVisible ? "" : styles$e.closeButtonMobileWrapperHidden}`
1252
1581
  }, /*#__PURE__*/React.createElement(ModalCloseButton, {
1253
1582
  onClick: onClose,
1254
1583
  className: styles$e.closeButtonMobile
1255
- }), stickyHeaderContent), /*#__PURE__*/React.createElement("div", {
1584
+ })), stickyHeaderContent), /*#__PURE__*/React.createElement("div", {
1585
+ ref: scrollableContentRef,
1256
1586
  className: styles$e.scrollableContent
1257
1587
  }, /*#__PURE__*/React.createElement(ModalCloseButton, {
1258
1588
  onClick: onClose,
@@ -1310,17 +1640,23 @@ const SearchInput = ({
1310
1640
  const SearchSubmitButton = ({
1311
1641
  onClick,
1312
1642
  disabled = false,
1313
- ariaLabel = 'Search',
1314
- label = 'Search',
1315
- variant = 'instant',
1316
- className = ''
1643
+ ariaLabel = "Search",
1644
+ label = "Search",
1645
+ variant = "instant",
1646
+ className = ""
1317
1647
  }) => {
1318
- return /*#__PURE__*/React.createElement("button", {
1648
+ const transformVariant = variant === "instant" ? "solid-grey" : "primary";
1649
+ return /*#__PURE__*/React.createElement(Button, {
1319
1650
  type: "submit",
1651
+ size: "small",
1320
1652
  onClick: onClick,
1321
1653
  disabled: disabled,
1322
1654
  "aria-label": ariaLabel,
1323
- className: `${styles$d.submitButton} ${className}`
1655
+ className: `${styles$d.submitButton} ${className}`,
1656
+ variant: transformVariant,
1657
+ style: {
1658
+ minWidth: "unset" // Ensure button doesn't shrink too much when only showing icon
1659
+ }
1324
1660
  }, /*#__PURE__*/React.createElement("span", {
1325
1661
  className: styles$d.submitButton__text
1326
1662
  }, label), /*#__PURE__*/React.createElement("span", {
@@ -1334,21 +1670,21 @@ const SearchBar = ({
1334
1670
  onSubmit,
1335
1671
  placeholder,
1336
1672
  autoFocus = false,
1337
- className = '',
1338
- variant = 'instant'
1673
+ className = "",
1674
+ variant = "instant"
1339
1675
  }) => {
1340
1676
  const handleSubmit = event => {
1341
1677
  event.preventDefault();
1342
1678
  onSubmit();
1343
1679
  };
1344
1680
  const handleKeyDown = event => {
1345
- if (event.key === 'Enter') {
1681
+ if (event.key === "Enter") {
1346
1682
  event.preventDefault();
1347
1683
  onSubmit();
1348
1684
  }
1349
1685
  };
1350
1686
  const handleClear = () => {
1351
- onChange('');
1687
+ onChange("");
1352
1688
  };
1353
1689
  const showClearButton = value.length > 0;
1354
1690
  return /*#__PURE__*/React.createElement("form", {
@@ -1370,7 +1706,7 @@ const SearchBar = ({
1370
1706
  }, "CLEAR X")), /*#__PURE__*/React.createElement(SearchSubmitButton, {
1371
1707
  onClick: onSubmit,
1372
1708
  label: "SEE ALL RESULTS",
1373
- variant: variant
1709
+ variant: "results"
1374
1710
  }));
1375
1711
  };
1376
1712
 
@@ -1387,21 +1723,20 @@ const ContentCardHorizontal = ({
1387
1723
  variant = "instant-view"
1388
1724
  }) => {
1389
1725
  const cardClasses = classNames(styles$c.contentCard, styles$c[`contentCard--${variant}`], className);
1390
- return /*#__PURE__*/React.createElement("a", {
1391
- href: url,
1726
+ return /*#__PURE__*/React.createElement(ContentCardBase, {
1727
+ id: id,
1728
+ title: title,
1729
+ url: url,
1730
+ category: category,
1731
+ meta: meta,
1732
+ excerpt: excerpt,
1392
1733
  className: cardClasses,
1393
- "aria-label": `View content: ${title}`
1394
- }, /*#__PURE__*/React.createElement("div", {
1395
- className: styles$c.contentMeta
1396
- }, category && /*#__PURE__*/React.createElement("span", {
1397
- className: styles$c.contentCategory
1398
- }, category), meta && /*#__PURE__*/React.createElement("span", {
1399
- className: styles$c.contentMetaText
1400
- }, meta)), /*#__PURE__*/React.createElement("h3", {
1401
- className: styles$c.contentTitle
1402
- }, title), excerpt && /*#__PURE__*/React.createElement("p", {
1403
- className: styles$c.contentExcerpt
1404
- }, excerpt));
1734
+ contentMetaClassName: styles$c.contentMeta,
1735
+ contentCategoryClassName: styles$c.contentCategory,
1736
+ contentMetaTextClassName: styles$c.contentMetaText,
1737
+ contentTitleClassName: styles$c.contentTitle,
1738
+ contentExcerptClassName: styles$c.contentExcerpt
1739
+ });
1405
1740
  };
1406
1741
 
1407
1742
  var styles$b = {"instantResultsLayout":"InstantResults-module__instantResultsLayout___oy-o4","columnsGrid":"InstantResults-module__columnsGrid___bHRUM","resultsColumn":"InstantResults-module__resultsColumn___ZBSlT","columnHeader":"InstantResults-module__columnHeader___VYYhi","showingText":"InstantResults-module__showingText___lECiA","seeAllButton":"InstantResults-module__seeAllButton___xEDAX","chevronIcon":"InstantResults-module__chevronIcon___bjb3q","resultsList":"InstantResults-module__resultsList___7s3PT","divider":"InstantResults-module__divider___Ky6zK","loadingState":"InstantResults-module__loadingState___l0fMq","errorState":"InstantResults-module__errorState___hTBbE","spinner":"InstantResults-module__spinner___85jF-"};
@@ -1462,7 +1797,10 @@ const FederatedInstantResultsLayout = ({
1462
1797
  className: styles$b.resultsList
1463
1798
  }, displayProducts.map((product, index) => /*#__PURE__*/React.createElement(React.Fragment, {
1464
1799
  key: product.id
1465
- }, /*#__PURE__*/React.createElement(ProductCardHorizontal, product), index < displayProducts.length - 1 && /*#__PURE__*/React.createElement("hr", {
1800
+ }, /*#__PURE__*/React.createElement(ProductCardHorizontal, _extends({}, product, {
1801
+ showProductPrice: true,
1802
+ className: "search-result"
1803
+ })), index < displayProducts.length - 1 && /*#__PURE__*/React.createElement("hr", {
1466
1804
  className: styles$b.divider
1467
1805
  })))) : null), /*#__PURE__*/React.createElement("div", {
1468
1806
  className: styles$b.resultsColumn
@@ -1663,6 +2001,13 @@ const FilterItem = ({
1663
2001
  const handleChange = () => {
1664
2002
  onToggle(value.value);
1665
2003
  };
2004
+ const handleCheckboxKeyDown = e => {
2005
+ // Space toggles native checkboxes by default; add Enter support.
2006
+ if (e.key === "Enter") {
2007
+ e.preventDefault();
2008
+ handleChange();
2009
+ }
2010
+ };
1666
2011
  const handleKeyDown = e => {
1667
2012
  if (e.key === "Enter" || e.key === " ") {
1668
2013
  e.preventDefault();
@@ -1702,12 +2047,12 @@ const FilterItem = ({
1702
2047
 
1703
2048
  // Desktop with checkbox (Products tab): Multi-select checkboxes
1704
2049
  return /*#__PURE__*/React.createElement("label", {
1705
- className: `${styles$7.filterItem} ${className || ""}`,
1706
- onKeyDown: handleKeyDown
2050
+ className: `${styles$7.filterItem} ${className || ""}`
1707
2051
  }, /*#__PURE__*/React.createElement("input", {
1708
2052
  type: "checkbox",
1709
2053
  checked: value.isRefined,
1710
2054
  onChange: handleChange,
2055
+ onKeyDown: handleCheckboxKeyDown,
1711
2056
  className: styles$7.filterCheckboxInput,
1712
2057
  "aria-label": `${value.value} (${value.count} results)`
1713
2058
  }), /*#__PURE__*/React.createElement("div", {
@@ -1728,7 +2073,7 @@ const FilterAccordion = ({
1728
2073
  onToggle,
1729
2074
  onValueToggle,
1730
2075
  className,
1731
- variant = 'desktop',
2076
+ variant = "desktop",
1732
2077
  showCheckbox = true
1733
2078
  }) => {
1734
2079
  const [searchQuery, setSearchQuery] = useState("");
@@ -1785,7 +2130,7 @@ const FilterAccordion = ({
1785
2130
  }))), isExpanded && /*#__PURE__*/React.createElement("div", {
1786
2131
  id: `accordion-${facet.id}`,
1787
2132
  className: styles$7.accordionContent
1788
- }, variant === 'desktop' && facet.searchable && facet.values.length > 5 && /*#__PURE__*/React.createElement("div", {
2133
+ }, facet.searchable && facet.values.length > 5 && (variant === "desktop" || variant === "mobile" && showCheckbox) && /*#__PURE__*/React.createElement("div", {
1789
2134
  className: styles$7.accordionSearch
1790
2135
  }, /*#__PURE__*/React.createElement(FilterSearch, {
1791
2136
  value: searchQuery,
@@ -2000,7 +2345,14 @@ const FiltersPanel = ({
2000
2345
  }))));
2001
2346
  };
2002
2347
 
2003
- var styles$6 = {"productCardVertical":"ProductCardVertical-module__productCardVertical___kXgmt","productCardVertical--hover":"ProductCardVertical-module__productCardVertical--hover___8Nsyp","productCardVertical__button":"ProductCardVertical-module__productCardVertical__button___oQPJG","productCardVertical--focus":"ProductCardVertical-module__productCardVertical--focus___8U57I","productCardVertical__imageWrapper":"ProductCardVertical-module__productCardVertical__imageWrapper___SgKoZ","productCardVertical__image":"ProductCardVertical-module__productCardVertical__image___kg-QU","productCardVertical__content":"ProductCardVertical-module__productCardVertical__content___sZdOs","productCardVertical__title":"ProductCardVertical-module__productCardVertical__title___PPKWb","productCardVertical__description":"ProductCardVertical-module__productCardVertical__description___Ai90p","productCardVertical__footer":"ProductCardVertical-module__productCardVertical__footer___rv6BH"};
2348
+ var styles$6 = {"productCardVertical":"ProductCardVertical-module__productCardVertical___kXgmt","productCardVertical--hover":"ProductCardVertical-module__productCardVertical--hover___8Nsyp","productCardVertical__button":"ProductCardVertical-module__productCardVertical__button___oQPJG","productCardVertical--focus":"ProductCardVertical-module__productCardVertical--focus___8U57I","productCardVertical__imageWrapper":"ProductCardVertical-module__productCardVertical__imageWrapper___SgKoZ","productCardVertical__image":"ProductCardVertical-module__productCardVertical__image___kg-QU","productCardVertical__placeholderImage":"ProductCardVertical-module__productCardVertical__placeholderImage___w0sd0","productCardVertical__content":"ProductCardVertical-module__productCardVertical__content___sZdOs","productCardVertical__title":"ProductCardVertical-module__productCardVertical__title___PPKWb","productCardVertical__description":"ProductCardVertical-module__productCardVertical__description___Ai90p","productCardVertical__footer":"ProductCardVertical-module__productCardVertical__footer___rv6BH"};
2349
+
2350
+ const PLACEHOLDER_INDICATOR = "?placeholder-storybook";
2351
+ const PLACEHOLDER_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="440" height="133" viewBox="218.446 219.139 440 133" role="img" aria-label="Leybold placeholder logo"><g fill="#ffff"><path d="M290.317,313.442h37.784v12.782h-53.654v-70.62h15.87V313.442z"/><path d="M386.309,310.883c-3.912,12.593-15.135,16.722-24.761,16.722c-15.878,0-28.046-7.084-28.046-28.62c0-6.296,2.322-26.458,26.98-26.458c11.116,0,26.457,4.917,26.457,28.819v2.457h-38.626c0.428,3.935,1.274,12.785,13.232,12.785c4.125,0,8.356-1.965,9.521-5.704L386.309,310.883L386.309,310.883z M371.709,294.852c-0.85-8.456-6.666-11.017-11.434-11.017c-6.979,0-10.686,4.129-11.532,11.017H371.709z"/><path d="M423.556,325.343c-6.986,19.374-8.892,21.932-21.799,21.932c-2.014,0-4.553-0.096-6.665-0.194v-11.02c0.629,0.104,1.582,0.197,2.854,0.197c5.397,0,8.36-0.688,9.737-7.864l-20.741-54.488h16.508l12.062,38.553h0.209l11.539-38.553h15.658L423.556,325.343z"/><path d="M463.54,280.689h0.213c2.328-3.344,6.775-8.164,16.297-8.164c12.385,0,23.389,8.854,23.389,26.949c0,14.359-6.98,28.129-23.703,28.129c-6.141,0-12.701-2.067-16.299-7.968h-0.211v6.589h-14.498v-70.62h14.812V280.689z M475.604,284.427c-10.158,0-12.701,8.455-12.701,16.815c0,7.773,3.707,15.049,13.129,15.049c9.521,0,12.168-9.641,12.168-15.83C488.198,292.192,485.02,284.427,475.604,284.427z"/><path d="M538.094,327.604c-15.141,0-28.787-8.652-28.787-27.542c0-18.881,13.646-27.536,28.787-27.536c15.129,0,28.785,8.655,28.785,27.536C566.88,318.95,553.223,327.604,538.094,327.604z M538.094,284.129c-11.434,0-13.547,9.244-13.547,15.934c0,6.691,2.113,15.939,13.547,15.939c11.426,0,13.547-9.248,13.547-15.939C551.641,293.373,549.52,284.129,538.094,284.129z"/><path d="M588.811,326.225h-14.814v-70.62h14.814V326.225z"/><path d="M651.969,326.225h-14.5v-6.589h-0.213c-3.598,5.898-10.156,7.968-16.295,7.968c-16.727,0-23.703-13.77-23.703-28.129c0-18.097,11.004-26.949,23.381-26.949c9.523,0,13.975,4.82,16.295,8.164h0.221v-25.085h14.814V326.225z M624.663,316.291c9.418,0,13.121-7.273,13.121-15.05c0-8.359-2.537-16.814-12.703-16.814c-9.416,0-12.592,7.767-12.592,16.034C612.49,306.651,615.135,316.291,624.663,316.291z"/></g><g fill="#ffff"><path d="M268.323,226.771h-41.551v39.685C230.996,246.516,247.442,230.811,268.323,226.771z"/><path d="M226.771,286.726v39.688h41.551C247.442,322.371,230.996,306.67,226.771,286.726z"/><path d="M331.122,266.455V226.77h-41.552C310.449,230.811,326.892,246.516,331.122,266.455z"/></g></svg>`;
2352
+ const PLACEHOLDER_IMAGE_DATA_URI = `data:image/svg+xml,${encodeURIComponent(PLACEHOLDER_SVG)}`;
2353
+ const isPlaceholderImg = url => {
2354
+ return !!url && url.includes(PLACEHOLDER_INDICATOR);
2355
+ };
2004
2356
 
2005
2357
  /**
2006
2358
  * ProductCardVertical - Vertical product card for grid layouts
@@ -2027,35 +2379,38 @@ const ProductCardVertical = ({
2027
2379
  imageUrl,
2028
2380
  productId,
2029
2381
  description,
2030
- buttonLabel = 'BUY ONLINE',
2382
+ buttonLabel = "BUY ONLINE",
2031
2383
  onButtonClick,
2032
2384
  className,
2033
- variant = 'desktop',
2034
- 'data-force-state': forceState
2385
+ variant = "desktop",
2386
+ "data-force-state": forceState
2035
2387
  }) => {
2388
+ const hasPlaceholderImage = !imageUrl || isPlaceholderImg(imageUrl);
2389
+ const productImage = hasPlaceholderImage ? PLACEHOLDER_IMAGE_DATA_URI : imageUrl;
2036
2390
  const handleButtonClick = e => {
2037
2391
  e.preventDefault(); // Prevent card link navigation
2038
2392
  e.stopPropagation(); // Stop event bubbling
2039
2393
  onButtonClick?.();
2040
2394
  };
2041
2395
  const cardClasses = classNames(styles$6.productCardVertical, styles$6[`productCardVertical--${variant}`], {
2042
- [styles$6['productCardVertical--hover']]: forceState === 'hover',
2043
- [styles$6['productCardVertical--focus']]: forceState === 'focus'
2396
+ [styles$6["productCardVertical--hover"]]: forceState === "hover",
2397
+ [styles$6["productCardVertical--focus"]]: forceState === "focus"
2044
2398
  }, className);
2045
2399
  return /*#__PURE__*/React.createElement("a", {
2046
2400
  href: url,
2047
2401
  className: cardClasses,
2048
2402
  "aria-label": `View product: ${title}`,
2049
2403
  "data-product-id": id
2050
- }, imageUrl && /*#__PURE__*/React.createElement("div", {
2404
+ }, /*#__PURE__*/React.createElement("div", {
2051
2405
  className: styles$6.productCardVertical__imageWrapper
2052
2406
  }, /*#__PURE__*/React.createElement(Image, {
2053
- src: imageUrl,
2407
+ src: productImage,
2054
2408
  alt: title,
2055
- className: styles$6.productCardVertical__image,
2409
+ className: styles$6.productCardVertical__image + (hasPlaceholderImage ? ` ${styles$6.productCardVertical__placeholderImage}` : ""),
2056
2410
  objectFit: "contain",
2057
2411
  objectPosition: "center",
2058
- loading: "lazy"
2412
+ loading: "lazy",
2413
+ fallbackSrc: PLACEHOLDER_IMAGE_DATA_URI
2059
2414
  })), /*#__PURE__*/React.createElement("div", {
2060
2415
  className: styles$6.productCardVertical__content
2061
2416
  }, /*#__PURE__*/React.createElement("h3", {
@@ -2074,7 +2429,7 @@ const ProductCardVertical = ({
2074
2429
  })));
2075
2430
  };
2076
2431
 
2077
- var styles$5 = {"resultsView":"ResultsView-module__resultsView___S4Wh2","searchBarWrapper":"ResultsView-module__searchBarWrapper___XNtwR","tabsContainer":"ResultsView-module__tabsContainer___mB-Q2","tabs":"ResultsView-module__tabs___rOexd","tabSeparator":"ResultsView-module__tabSeparator___MSq9p","mobileFilterButton":"ResultsView-module__mobileFilterButton___ZrMQY","resultsContainer":"ResultsView-module__resultsContainer___J4URa","sidebar":"ResultsView-module__sidebar___nQq5J","assistanceBanner":"ResultsView-module__assistanceBanner___1r72a","mainContent":"ResultsView-module__mainContent___S9eIG","productsGrid":"ResultsView-module__productsGrid___gnAQ-","contentsList":"ResultsView-module__contentsList___tcfNG","contentDivider":"ResultsView-module__contentDivider___5n6sl","resultsList":"ResultsView-module__resultsList___8eYNX","resultsSection":"ResultsView-module__resultsSection___sCUaO","sectionTitle":"ResultsView-module__sectionTitle___mfvH3","loadingState":"ResultsView-module__loadingState___W5YXx","errorState":"ResultsView-module__errorState___UkkG-","emptyState":"ResultsView-module__emptyState___D0Iyn","spinner":"ResultsView-module__spinner___nk8E5","emptyIcon":"ResultsView-module__emptyIcon___fes8T","paginationWrapper":"ResultsView-module__paginationWrapper___mDTyl","searchBarDesktopOnly":"ResultsView-module__searchBarDesktopOnly___dZHUw","tabsContainerDesktopOnly":"ResultsView-module__tabsContainerDesktopOnly___-MQpa"};
2432
+ var styles$5 = {"resultsView":"ResultsView-module__resultsView___S4Wh2","searchBarWrapper":"ResultsView-module__searchBarWrapper___XNtwR","tabsContainer":"ResultsView-module__tabsContainer___mB-Q2","tabs":"ResultsView-module__tabs___rOexd","mobileFilterButton":"ResultsView-module__mobileFilterButton___ZrMQY","resultsContainer":"ResultsView-module__resultsContainer___J4URa","sidebar":"ResultsView-module__sidebar___nQq5J","assistanceBanner":"ResultsView-module__assistanceBanner___1r72a","mainContent":"ResultsView-module__mainContent___S9eIG","productsGrid":"ResultsView-module__productsGrid___gnAQ-","contentsList":"ResultsView-module__contentsList___tcfNG","contentDivider":"ResultsView-module__contentDivider___5n6sl","resultsList":"ResultsView-module__resultsList___8eYNX","resultsSection":"ResultsView-module__resultsSection___sCUaO","sectionTitle":"ResultsView-module__sectionTitle___mfvH3","loadingState":"ResultsView-module__loadingState___W5YXx","errorState":"ResultsView-module__errorState___UkkG-","emptyState":"ResultsView-module__emptyState___D0Iyn","spinner":"ResultsView-module__spinner___nk8E5","emptyIcon":"ResultsView-module__emptyIcon___fes8T","paginationWrapper":"ResultsView-module__paginationWrapper___mDTyl","searchBarDesktopOnly":"ResultsView-module__searchBarDesktopOnly___dZHUw","tabsContainerDesktopOnly":"ResultsView-module__tabsContainerDesktopOnly___-MQpa"};
2078
2433
 
2079
2434
  const ResultsList = ({
2080
2435
  type,
@@ -2310,7 +2665,11 @@ const AssistanceBanner = ({
2310
2665
  }))));
2311
2666
  };
2312
2667
 
2313
- var styles$2 = {"drawerOverlay":"FilterDrawer-module__drawerOverlay___P6M4y","drawerOverlay--open":"FilterDrawer-module__drawerOverlay--open___blJZo","drawerPanel":"FilterDrawer-module__drawerPanel___35h-U","drawerPanel--open":"FilterDrawer-module__drawerPanel--open___Fw1SY","drawerCloseButton":"FilterDrawer-module__drawerCloseButton___cfMmf","drawerContent":"FilterDrawer-module__drawerContent___KBff6"};
2668
+ var styles$2 = {"drawerOverlay":"FilterDrawer-module__drawerOverlay___P6M4y","drawerOverlay--open":"FilterDrawer-module__drawerOverlay--open___blJZo","drawerOverlay--closing":"FilterDrawer-module__drawerOverlay--closing___diQr0","drawerPanel":"FilterDrawer-module__drawerPanel___35h-U","drawerPanel--open":"FilterDrawer-module__drawerPanel--open___Fw1SY","drawerCloseButton":"FilterDrawer-module__drawerCloseButton___cfMmf","drawerContent":"FilterDrawer-module__drawerContent___KBff6"};
2669
+
2670
+ const OVERLAY_FADE_MS = 300;
2671
+ const PANEL_SLIDE_MS = 300;
2672
+ const CLOSE_ANIMATION_BUFFER_MS = 50;
2314
2673
 
2315
2674
  /**
2316
2675
  * FilterDrawer - Mobile slide-in filter panel
@@ -2340,54 +2699,95 @@ const FilterDrawer = ({
2340
2699
  }) => {
2341
2700
  const drawerRef = useRef(null);
2342
2701
  const previouslyFocusedElement = useRef(null);
2702
+ const [renderState, setRenderState] = useState(isOpen ? "opening" : "closed");
2343
2703
 
2344
- // Focus management
2704
+ // Mount/unmount sequencing for transitions.
2345
2705
  useEffect(() => {
2706
+ let closeTimer;
2707
+ let raf1;
2708
+ let raf2;
2346
2709
  if (isOpen) {
2347
- // Store previously focused element
2348
- previouslyFocusedElement.current = document.activeElement;
2710
+ // Ensure it is mounted in the "closed" styles first, then flip to "open" next frame.
2711
+ setRenderState("opening");
2712
+
2713
+ // Double rAF: guarantees at least one paint with the base styles
2714
+ // before we apply the `--open` classes.
2715
+ raf1 = window.requestAnimationFrame(() => {
2716
+ raf2 = window.requestAnimationFrame(() => {
2717
+ setRenderState("open");
2718
+ });
2719
+ });
2720
+ return () => {
2721
+ if (raf1) window.cancelAnimationFrame(raf1);
2722
+ if (raf2) window.cancelAnimationFrame(raf2);
2723
+ };
2724
+ }
2349
2725
 
2350
- // Focus the drawer
2351
- if (drawerRef.current) {
2352
- drawerRef.current.focus();
2353
- }
2726
+ // If we're currently rendered, play exit animation before unmounting.
2727
+ setRenderState(prev => prev === "closed" ? "closed" : "closing");
2728
+ closeTimer = window.setTimeout(() => {
2729
+ setRenderState("closed");
2730
+ }, PANEL_SLIDE_MS + OVERLAY_FADE_MS + CLOSE_ANIMATION_BUFFER_MS);
2731
+ return () => {
2732
+ if (closeTimer) window.clearTimeout(closeTimer);
2733
+ };
2734
+ }, [isOpen]);
2354
2735
 
2355
- // Prevent body scroll
2356
- document.body.style.overflow = 'hidden';
2357
- } else {
2736
+ // Focus management
2737
+ useEffect(() => {
2738
+ const isRendered = renderState !== "closed";
2739
+ if (!isRendered) {
2358
2740
  // Restore body scroll
2359
- document.body.style.overflow = '';
2741
+ document.body.style.overflow = "";
2360
2742
 
2361
2743
  // Return focus to previously focused element
2362
2744
  if (previouslyFocusedElement.current) {
2363
2745
  previouslyFocusedElement.current.focus();
2364
2746
  }
2747
+
2748
+ // Reset for next open cycle
2749
+ previouslyFocusedElement.current = null;
2750
+ return;
2751
+ }
2752
+
2753
+ // Store previously focused element (once per open)
2754
+ if (!previouslyFocusedElement.current) {
2755
+ previouslyFocusedElement.current = document.activeElement;
2756
+ }
2757
+
2758
+ // Prevent body scroll for the whole time the drawer is mounted (open + closing animation)
2759
+ document.body.style.overflow = "hidden";
2760
+
2761
+ // Focus the drawer once it reaches open state
2762
+ if (renderState === "open" && drawerRef.current) {
2763
+ drawerRef.current.focus();
2365
2764
  }
2366
2765
  return () => {
2367
- document.body.style.overflow = '';
2766
+ // In case the component unmounts unexpectedly.
2767
+ document.body.style.overflow = "";
2368
2768
  };
2369
- }, [isOpen]);
2769
+ }, [renderState]);
2370
2770
 
2371
2771
  // Escape key handler
2372
2772
  useEffect(() => {
2373
2773
  const handleEscape = event => {
2374
- if (event.key === 'Escape' && isOpen) {
2774
+ if (event.key === "Escape" && renderState !== "closed") {
2375
2775
  onClose();
2376
2776
  }
2377
2777
  };
2378
- document.addEventListener('keydown', handleEscape);
2379
- return () => document.removeEventListener('keydown', handleEscape);
2380
- }, [isOpen, onClose]);
2778
+ document.addEventListener("keydown", handleEscape);
2779
+ return () => document.removeEventListener("keydown", handleEscape);
2780
+ }, [renderState, onClose]);
2381
2781
 
2382
2782
  // Focus trap implementation
2383
2783
  useEffect(() => {
2384
- if (!isOpen || !drawerRef.current) return;
2784
+ if (renderState !== "open" || !drawerRef.current) return;
2385
2785
  const drawer = drawerRef.current;
2386
2786
  const focusableElements = drawer.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
2387
2787
  const firstElement = focusableElements[0];
2388
2788
  const lastElement = focusableElements[focusableElements.length - 1];
2389
2789
  const handleTab = event => {
2390
- if (event.key !== 'Tab') return;
2790
+ if (event.key !== "Tab") return;
2391
2791
  if (event.shiftKey) {
2392
2792
  // Shift + Tab
2393
2793
  if (document.activeElement === firstElement) {
@@ -2402,20 +2802,21 @@ const FilterDrawer = ({
2402
2802
  }
2403
2803
  }
2404
2804
  };
2405
- drawer.addEventListener('keydown', handleTab);
2406
- return () => drawer.removeEventListener('keydown', handleTab);
2407
- }, [isOpen]);
2408
- if (!isOpen) return null;
2805
+ drawer.addEventListener("keydown", handleTab);
2806
+ return () => drawer.removeEventListener("keydown", handleTab);
2807
+ }, [renderState]);
2808
+ if (renderState === "closed") return null;
2409
2809
  const handleOverlayClick = event => {
2410
2810
  if (event.target === event.currentTarget) {
2411
2811
  onClose();
2412
2812
  }
2413
2813
  };
2414
2814
  const overlayClasses = classNames(styles$2.drawerOverlay, {
2415
- [styles$2['drawerOverlay--open']]: isOpen
2815
+ [styles$2["drawerOverlay--open"]]: renderState === "open",
2816
+ [styles$2["drawerOverlay--closing"]]: renderState === "closing"
2416
2817
  });
2417
2818
  const panelClasses = classNames(styles$2.drawerPanel, {
2418
- [styles$2['drawerPanel--open']]: isOpen
2819
+ [styles$2["drawerPanel--open"]]: renderState === "open"
2419
2820
  }, className);
2420
2821
  return /*#__PURE__*/React.createElement("div", {
2421
2822
  className: overlayClasses,
@@ -2461,6 +2862,23 @@ const FederatedResultsView = ({
2461
2862
  onFilterDrawerToggle,
2462
2863
  onFilterDrawerClose
2463
2864
  }) => {
2865
+ const [isMobile, setIsMobile] = useState(false);
2866
+ useEffect(() => {
2867
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
2868
+ return;
2869
+ }
2870
+ const mql = window.matchMedia("(max-width: 768px)");
2871
+ const update = () => setIsMobile(mql.matches);
2872
+ update();
2873
+
2874
+ // Safari < 14 fallback
2875
+ if (typeof mql.addEventListener === "function") {
2876
+ mql.addEventListener("change", update);
2877
+ return () => mql.removeEventListener("change", update);
2878
+ }
2879
+ mql.addListener(update);
2880
+ return () => mql.removeListener(update);
2881
+ }, []);
2464
2882
  const isLoading = activeTab === "products" && isLoadingProducts || activeTab === "content" && isLoadingContents;
2465
2883
  const error = activeTab === "products" ? productsError : contentsError;
2466
2884
 
@@ -2524,8 +2942,6 @@ const FederatedResultsView = ({
2524
2942
  isActive: activeTab === "products",
2525
2943
  onClick: () => onTabChange("products"),
2526
2944
  variant: "desktop"
2527
- }), /*#__PURE__*/React.createElement("div", {
2528
- className: styles$5.tabSeparator
2529
2945
  }), /*#__PURE__*/React.createElement(TabButton, {
2530
2946
  label: "WEBSITE RESULTS",
2531
2947
  count: contents.length,
@@ -2574,7 +2990,7 @@ const FederatedResultsView = ({
2574
2990
  currentPage: currentPage,
2575
2991
  totalPages: totalPages,
2576
2992
  onPageChange: onPageChange,
2577
- maxVisiblePages: 10,
2993
+ maxVisiblePages: isMobile ? 3 : 10,
2578
2994
  showPrevious: false,
2579
2995
  ariaLabel: `${activeTab === "products" ? "Products" : "Content"} pagination`
2580
2996
  }))))), onFilterDrawerClose && /*#__PURE__*/React.createElement(FilterDrawer, {
@@ -2700,7 +3116,7 @@ const FederatedSearchExperience = ({
2700
3116
  variant: "mobile"
2701
3117
  })), /*#__PURE__*/React.createElement("div", {
2702
3118
  className: styles$1.mobileFilterButtonWrapper
2703
- }, /*#__PURE__*/React.createElement("button", {
3119
+ }, onFilterDrawerToggle && /*#__PURE__*/React.createElement("button", {
2704
3120
  type: "button",
2705
3121
  className: styles$1.mobileFilterButton,
2706
3122
  onClick: onFilterDrawerToggle
@@ -2828,5 +3244,5 @@ const SearchTriggerButton = ({
2828
3244
  }, label));
2829
3245
  };
2830
3246
 
2831
- export { AlgoliaDynamicSearchLeybold as AlgoliaDynamicSearch, AlgoliaDynamicSearchLeybold, AppliedFilterTag, AppliedFilters, Button, ContentCardHorizontal, FederatedInstantResultsLayout, FederatedResultsView, FederatedSearchExperience, FilterAccordion, FilterItem, FilterSearch, FiltersPanel, Footer, FooterBottom, FooterLink, FooterLinkGroup, FooterSocialIcon, FooterSocialIcons, ModalCloseButton, Pagination, PaginationButton, PaginationEllipsis, PaginationItem, ProductCardHorizontal, ProductCardVertical, QrFormLeybold as QrForm, QrFormLeybold, ResultsColumn, ResultsCount, ResultsList, SearchBar, SearchIcon, SearchInput, SearchModal, SearchSubmitButton, SearchTriggerButton, SeeAllLinkButton };
3247
+ export { AlgoliaDynamicSearchLeybold as AlgoliaDynamicSearch, AlgoliaDynamicSearchLeybold, AppliedFilterTag, AppliedFilters, Button, CarouselCard, ContentCardBase, ContentCardHorizontal, FederatedInstantResultsLayout, FederatedResultsView, FederatedSearchExperience, FilterAccordion, FilterItem, FilterSearch, FiltersPanel, Footer, FooterBottom, FooterLink, FooterLinkGroup, FooterSocialIcon, FooterSocialIcons, ModalCloseButton, Pagination, PaginationButton, PaginationEllipsis, PaginationItem, ProductCardHorizontal, ProductCardVertical, QrFormLeybold as QrForm, QrFormLeybold, ResultsColumn, ResultsCount, ResultsList, SearchBar, SearchIcon, SearchInput, SearchModal, SearchSubmitButton, SearchTriggerButton, SeeAllLinkButton };
2832
3248
  //# sourceMappingURL=index.esm.js.map