@asante-org/leybold-design-system 1.3.1 → 1.3.2
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.
- package/README.md +163 -163
- package/dist/.storybook/algoliaProvider.d.ts +3 -0
- package/dist/assets/.gitkeep +2 -2
- package/dist/assets/desktop-layout-alt.svg +27 -27
- package/dist/assets/desktop-layout.svg +29 -29
- package/dist/assets/globe.svg +7 -7
- package/dist/assets/leybold-footer-logo.svg +19 -19
- package/dist/assets/leybold-white.svg +18 -18
- package/dist/assets/list-product-overlay-tip-active.svg +3 -3
- package/dist/assets/list-product-overlay-tip.svg +3 -3
- package/dist/assets/logo-example.svg +9 -9
- package/dist/assets/logo.svg +19 -19
- package/dist/assets/phone-layout.svg +14 -14
- package/dist/assets/red-tip.svg +10 -10
- package/dist/assets/tablet-layout.svg +28 -28
- package/dist/index.esm.js +818 -402
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.scss +701 -184
- package/dist/index.js +892 -470
- package/dist/index.js.map +1 -1
- package/dist/index.scss +701 -184
- package/dist/src/components/Button/Button.d.ts +2 -2
- package/dist/src/components/CarouselCard/CarouselCard.d.ts +18 -0
- package/dist/src/components/CarouselCard/CarouselCard.stories.d.ts +6 -0
- package/dist/src/components/CarouselCard/index.d.ts +2 -0
- package/dist/src/components/ContentCardBase/ContentCardBase.d.ts +3 -0
- package/dist/src/components/ContentCardBase/index.d.ts +2 -0
- package/dist/src/components/ContentCardHorizontal/ContentCardHorizontal.d.ts +2 -2
- package/dist/src/components/ContentCardHorizontal/ContentCardHorizontal.stories.d.ts +1 -0
- package/dist/src/components/ContentCardVertical/ContentCardVertical.d.ts +3 -0
- package/dist/src/components/ContentCardVertical/ContentCardVertical.stories.d.ts +9 -0
- package/dist/src/components/ProductCardVertical/ProductCardVertical.d.ts +2 -2
- package/dist/src/components/SearchBar/SearchBar.d.ts +2 -2
- package/dist/src/components/SearchBar/SearchSubmitButton.d.ts +2 -2
- package/dist/src/components/SearchModal/SearchModal.d.ts +2 -2
- package/dist/src/experience/Carousel/Carousel.d.ts +1 -1
- package/dist/src/experience/algolia-dynamic-search/AlgoliaDynamicSearch.stories.d.ts +2 -0
- package/dist/src/experience/federated-search/FederatedSearchWithAlgolia.stories.d.ts +1 -0
- package/dist/src/experience/federated-search/components/FilterDrawer/FilterDrawer.d.ts +2 -2
- package/dist/src/index.d.ts +4 -1
- package/dist/src/stories/foundation/_components/StoryAccordion.d.ts +13 -0
- package/dist/src/types/cards.d.ts +32 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +115 -115
- package/dist/app/layout.d.ts +0 -9
- package/dist/app/page.d.ts +0 -2
- package/dist/index.css +0 -88
- package/dist/index.d.ts +0 -3
- package/dist/index.esm.css +0 -88
- package/dist/stories/components/Algolia-dynamic-search/algolia-dynamic-search.d.ts +0 -4
- package/dist/stories/components/Algolia-dynamic-search/algolia-dynamic-search.stories.d.ts +0 -7
- package/dist/stories/components/Button/Button.d.ts +0 -35
- package/dist/stories/components/Button/Button.stories.d.ts +0 -15
- package/dist/stories/components/Button/index.d.ts +0 -2
- package/dist/stories/components/QRFormJourney/Qr-form/Qr-form.d.ts +0 -2
- package/dist/stories/components/QRFormJourney/Qr-form/Qr-form.stories.d.ts +0 -7
- package/dist/utils/styles/index.d.ts +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import 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$
|
|
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;
|
|
@@ -92,20 +92,20 @@ function requireClassnames() {
|
|
|
92
92
|
var classnamesExports = requireClassnames();
|
|
93
93
|
var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports);
|
|
94
94
|
|
|
95
|
-
/**
|
|
96
|
-
* Button variant types
|
|
95
|
+
/**
|
|
96
|
+
* Button variant types
|
|
97
97
|
*/
|
|
98
98
|
|
|
99
|
-
/**
|
|
100
|
-
* Icon types for button
|
|
99
|
+
/**
|
|
100
|
+
* Icon types for button
|
|
101
101
|
*/
|
|
102
102
|
|
|
103
|
-
/**
|
|
104
|
-
* Icon position
|
|
103
|
+
/**
|
|
104
|
+
* Icon position
|
|
105
105
|
*/
|
|
106
106
|
|
|
107
|
-
/**
|
|
108
|
-
* Get the icon component based on icon type
|
|
107
|
+
/**
|
|
108
|
+
* Get the icon component based on icon type
|
|
109
109
|
*/
|
|
110
110
|
const getIcon = icon => {
|
|
111
111
|
switch (icon) {
|
|
@@ -130,8 +130,8 @@ const getIcon = icon => {
|
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
-
/**
|
|
134
|
-
* Get default icon for certain variants
|
|
133
|
+
/**
|
|
134
|
+
* Get default icon for certain variants
|
|
135
135
|
*/
|
|
136
136
|
const getDefaultIcon = variant => {
|
|
137
137
|
switch (variant) {
|
|
@@ -151,8 +151,8 @@ const getDefaultIcon = variant => {
|
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
-
/**
|
|
155
|
-
* Map alias variants to their actual CSS class variants
|
|
154
|
+
/**
|
|
155
|
+
* Map alias variants to their actual CSS class variants
|
|
156
156
|
*/
|
|
157
157
|
const mapVariantToClass = variant => {
|
|
158
158
|
switch (variant) {
|
|
@@ -163,8 +163,8 @@ const mapVariantToClass = variant => {
|
|
|
163
163
|
}
|
|
164
164
|
};
|
|
165
165
|
|
|
166
|
-
/**
|
|
167
|
-
* Primary UI component for user interaction
|
|
166
|
+
/**
|
|
167
|
+
* Primary UI component for user interaction
|
|
168
168
|
*/
|
|
169
169
|
const Button = ({
|
|
170
170
|
children,
|
|
@@ -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$
|
|
195
|
-
[styles$
|
|
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$
|
|
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,32 +204,194 @@ const Button = ({
|
|
|
204
204
|
disabled: disabled,
|
|
205
205
|
onClick: onClick,
|
|
206
206
|
"aria-label": accessibleLabel,
|
|
207
|
-
"data-force-state": props[
|
|
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$
|
|
212
|
+
className: styles$m.button__icon__default
|
|
213
213
|
}), /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
214
214
|
icon: faArrowLeftLong,
|
|
215
|
-
className: styles$
|
|
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$
|
|
220
|
+
className: styles$m.button__icon__default
|
|
221
221
|
}), /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
222
222
|
icon: faArrowRightLong,
|
|
223
|
-
className: styles$
|
|
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
|
-
/**
|
|
232
|
-
* External link icon (↗) for footer links that open in new tabs
|
|
393
|
+
/**
|
|
394
|
+
* External link icon (↗) for footer links that open in new tabs
|
|
233
395
|
*/
|
|
234
396
|
const ExternalLinkIcon = ({
|
|
235
397
|
className,
|
|
@@ -250,8 +412,8 @@ const ExternalLinkIcon = ({
|
|
|
250
412
|
strokeLinejoin: "round"
|
|
251
413
|
}));
|
|
252
414
|
|
|
253
|
-
/**
|
|
254
|
-
* Atlas Copco Group badge icon (square)
|
|
415
|
+
/**
|
|
416
|
+
* Atlas Copco Group badge icon (square)
|
|
255
417
|
*/
|
|
256
418
|
const AtlasCopcoIcon = ({
|
|
257
419
|
className,
|
|
@@ -427,11 +589,11 @@ const FooterBottom = ({
|
|
|
427
589
|
// MAIN FOOTER COMPONENT
|
|
428
590
|
// =============================================================================
|
|
429
591
|
|
|
430
|
-
/**
|
|
431
|
-
* Footer component with brand identity, navigation links, social icons, and legal information.
|
|
432
|
-
* Supports two layout variants:
|
|
433
|
-
* - desktop: Logo at top, 3-column main content
|
|
434
|
-
* - mobile: Logo at bottom, stacked layout with CTA button
|
|
592
|
+
/**
|
|
593
|
+
* Footer component with brand identity, navigation links, social icons, and legal information.
|
|
594
|
+
* Supports two layout variants:
|
|
595
|
+
* - desktop: Logo at top, 3-column main content
|
|
596
|
+
* - mobile: Logo at bottom, stacked layout with CTA button
|
|
435
597
|
*/
|
|
436
598
|
const Footer = ({
|
|
437
599
|
variant = 'desktop',
|
|
@@ -631,8 +793,8 @@ const PaginationEllipsis = ({
|
|
|
631
793
|
}, "..."));
|
|
632
794
|
};
|
|
633
795
|
|
|
634
|
-
/**
|
|
635
|
-
* Generate page numbers to display with ellipsis logic
|
|
796
|
+
/**
|
|
797
|
+
* Generate page numbers to display with ellipsis logic
|
|
636
798
|
*/
|
|
637
799
|
const generatePageNumbers = (currentPage, totalPages, maxVisiblePages) => {
|
|
638
800
|
if (totalPages <= maxVisiblePages) {
|
|
@@ -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} ${
|
|
901
|
-
|
|
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:
|
|
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
|
|
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$
|
|
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$
|
|
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
|
|
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$
|
|
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
|
-
|
|
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
|
-
|
|
1064
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
}, [
|
|
1522
|
+
}, [shouldRender]);
|
|
1197
1523
|
useEffect(() => {
|
|
1198
1524
|
const handleEscape = event => {
|
|
1199
|
-
if (event.key ===
|
|
1525
|
+
if (event.key === "Escape" && isOpen) {
|
|
1200
1526
|
onClose();
|
|
1201
1527
|
}
|
|
1202
1528
|
};
|
|
1203
|
-
document.addEventListener(
|
|
1204
|
-
return () => document.removeEventListener(
|
|
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 !==
|
|
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(
|
|
1231
|
-
return () => modal.removeEventListener(
|
|
1556
|
+
modal.addEventListener("keydown", handleTab);
|
|
1557
|
+
return () => modal.removeEventListener("keydown", handleTab);
|
|
1232
1558
|
}, [isOpen]);
|
|
1233
|
-
if (!
|
|
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.
|
|
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 =
|
|
1314
|
-
label =
|
|
1315
|
-
variant =
|
|
1316
|
-
className =
|
|
1643
|
+
ariaLabel = "Search",
|
|
1644
|
+
label = "Search",
|
|
1645
|
+
variant = "instant",
|
|
1646
|
+
className = ""
|
|
1317
1647
|
}) => {
|
|
1318
|
-
|
|
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 =
|
|
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 ===
|
|
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:
|
|
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(
|
|
1391
|
-
|
|
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
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
}
|
|
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,
|
|
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
|
|
@@ -1601,8 +1939,8 @@ const faXmark = {
|
|
|
1601
1939
|
icon: [384, 512, [128473, 10005, 10006, 10060, 215, "close", "multiply", "remove", "times"], "f00d", "M324.5 411.1c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L214.6 256 347.1 123.5c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L192 233.4 59.6 100.9c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L169.4 256 36.9 388.5c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L192 278.6 324.5 411.1z"]
|
|
1602
1940
|
};
|
|
1603
1941
|
|
|
1604
|
-
/**
|
|
1605
|
-
* FilterSearch - Search input for filtering facet values
|
|
1942
|
+
/**
|
|
1943
|
+
* FilterSearch - Search input for filtering facet values
|
|
1606
1944
|
*/
|
|
1607
1945
|
const FilterSearch = ({
|
|
1608
1946
|
value,
|
|
@@ -1650,8 +1988,8 @@ const CheckIcon = () => /*#__PURE__*/React.createElement("svg", {
|
|
|
1650
1988
|
fill: "#E2001A"
|
|
1651
1989
|
}));
|
|
1652
1990
|
|
|
1653
|
-
/**
|
|
1654
|
-
* FilterItem - Individual facet item with checkbox and count
|
|
1991
|
+
/**
|
|
1992
|
+
* FilterItem - Individual facet item with checkbox and count
|
|
1655
1993
|
*/
|
|
1656
1994
|
const FilterItem = ({
|
|
1657
1995
|
value,
|
|
@@ -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", {
|
|
@@ -1719,8 +2064,8 @@ const FilterItem = ({
|
|
|
1719
2064
|
}, "(", value.count, ")"));
|
|
1720
2065
|
};
|
|
1721
2066
|
|
|
1722
|
-
/**
|
|
1723
|
-
* FilterAccordion - Collapsible facet section with optional search
|
|
2067
|
+
/**
|
|
2068
|
+
* FilterAccordion - Collapsible facet section with optional search
|
|
1724
2069
|
*/
|
|
1725
2070
|
const FilterAccordion = ({
|
|
1726
2071
|
facet,
|
|
@@ -1728,7 +2073,7 @@ const FilterAccordion = ({
|
|
|
1728
2073
|
onToggle,
|
|
1729
2074
|
onValueToggle,
|
|
1730
2075
|
className,
|
|
1731
|
-
variant =
|
|
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
|
-
},
|
|
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,
|
|
@@ -1804,8 +2149,8 @@ const FilterAccordion = ({
|
|
|
1804
2149
|
}, "No results found"))));
|
|
1805
2150
|
};
|
|
1806
2151
|
|
|
1807
|
-
/**
|
|
1808
|
-
* AppliedFilterTag - Individual removable filter tag/chip
|
|
2152
|
+
/**
|
|
2153
|
+
* AppliedFilterTag - Individual removable filter tag/chip
|
|
1809
2154
|
*/
|
|
1810
2155
|
const AppliedFilterTag = ({
|
|
1811
2156
|
attribute,
|
|
@@ -1849,8 +2194,8 @@ const AppliedFilterTag = ({
|
|
|
1849
2194
|
}))));
|
|
1850
2195
|
};
|
|
1851
2196
|
|
|
1852
|
-
/**
|
|
1853
|
-
* AppliedFilters - Shows all active filters as removable tags
|
|
2197
|
+
/**
|
|
2198
|
+
* AppliedFilters - Shows all active filters as removable tags
|
|
1854
2199
|
*/
|
|
1855
2200
|
const AppliedFilters = ({
|
|
1856
2201
|
facets,
|
|
@@ -1895,12 +2240,12 @@ const AppliedFilters = ({
|
|
|
1895
2240
|
}))));
|
|
1896
2241
|
};
|
|
1897
2242
|
|
|
1898
|
-
/**
|
|
1899
|
-
* FiltersPanel - Main container for all filters
|
|
1900
|
-
*
|
|
1901
|
-
* Fully controlled component - renders based on facets prop.
|
|
1902
|
-
* When facets change (e.g., after API refetch), component re-renders with new data.
|
|
1903
|
-
* Accordion expansion state persists across refetches, with new facets respecting defaultExpanded.
|
|
2243
|
+
/**
|
|
2244
|
+
* FiltersPanel - Main container for all filters
|
|
2245
|
+
*
|
|
2246
|
+
* Fully controlled component - renders based on facets prop.
|
|
2247
|
+
* When facets change (e.g., after API refetch), component re-renders with new data.
|
|
2248
|
+
* Accordion expansion state persists across refetches, with new facets respecting defaultExpanded.
|
|
1904
2249
|
*/
|
|
1905
2250
|
const FiltersPanel = ({
|
|
1906
2251
|
facets,
|
|
@@ -2000,25 +2345,32 @@ 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"};
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
*
|
|
2014
|
-
*
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2018
|
-
*
|
|
2019
|
-
*
|
|
2020
|
-
*
|
|
2021
|
-
*
|
|
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
|
+
};
|
|
2356
|
+
|
|
2357
|
+
/**
|
|
2358
|
+
* ProductCardVertical - Vertical product card for grid layouts
|
|
2359
|
+
*
|
|
2360
|
+
* Used in full results view with 4-column grid (desktop) or 2-column grid (mobile).
|
|
2361
|
+
* Figma spec: Default (no shadow) → Hover (shadow + grey button) → Focus (border + shadow)
|
|
2362
|
+
*
|
|
2363
|
+
* @example
|
|
2364
|
+
* ```tsx
|
|
2365
|
+
* <ProductCardVertical
|
|
2366
|
+
* title="TURBOVAC i - High vacuum turbopump"
|
|
2367
|
+
* url="/products/turbovac-i"
|
|
2368
|
+
* imageUrl="/assets/search-product.png"
|
|
2369
|
+
* productId="21312VISH"
|
|
2370
|
+
* description="Premium high-performance turbomolecular pump"
|
|
2371
|
+
* buttonLabel="BUY ONLINE"
|
|
2372
|
+
* />
|
|
2373
|
+
* ```
|
|
2022
2374
|
*/
|
|
2023
2375
|
const ProductCardVertical = ({
|
|
2024
2376
|
id,
|
|
@@ -2027,35 +2379,38 @@ const ProductCardVertical = ({
|
|
|
2027
2379
|
imageUrl,
|
|
2028
2380
|
productId,
|
|
2029
2381
|
description,
|
|
2030
|
-
buttonLabel =
|
|
2382
|
+
buttonLabel = "BUY ONLINE",
|
|
2031
2383
|
onButtonClick,
|
|
2032
2384
|
className,
|
|
2033
|
-
variant =
|
|
2034
|
-
|
|
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[
|
|
2043
|
-
[styles$6[
|
|
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
|
-
},
|
|
2404
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2051
2405
|
className: styles$6.productCardVertical__imageWrapper
|
|
2052
2406
|
}, /*#__PURE__*/React.createElement(Image, {
|
|
2053
|
-
src:
|
|
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","
|
|
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,
|
|
@@ -2173,32 +2528,32 @@ const ResultsList = ({
|
|
|
2173
2528
|
|
|
2174
2529
|
var styles$4 = {"tabButton":"TabButton-module__tabButton___cMU45","tabButton__count":"TabButton-module__tabButton__count___nlS1p","tabButton__label":"TabButton-module__tabButton__label___YGpiC","tabButton__results":"TabButton-module__tabButton__results___Nr6gr","tabButton--desktop":"TabButton-module__tabButton--desktop___fbAaC","tabButton--active":"TabButton-module__tabButton--active___gj6Jp","tabButton--mobile":"TabButton-module__tabButton--mobile___AnLwy"};
|
|
2175
2530
|
|
|
2176
|
-
/**
|
|
2177
|
-
* TabButton - Tab navigation component with result counts
|
|
2178
|
-
*
|
|
2179
|
-
* Supports two layout variants:
|
|
2180
|
-
* - Desktop: Background colours, top red underline when active, rounded corners
|
|
2181
|
-
* - Mobile: Text-only with bottom border underline when active
|
|
2182
|
-
*
|
|
2183
|
-
* @example
|
|
2184
|
-
* ```tsx
|
|
2185
|
-
* // Desktop variant
|
|
2186
|
-
* <TabButton
|
|
2187
|
-
* label="WEB SHOP RESULTS"
|
|
2188
|
-
* count={542}
|
|
2189
|
-
* isActive={true}
|
|
2190
|
-
* onClick={() => setActiveTab('products')}
|
|
2191
|
-
* variant="desktop"
|
|
2192
|
-
* />
|
|
2193
|
-
*
|
|
2194
|
-
* // Mobile variant
|
|
2195
|
-
* <TabButton
|
|
2196
|
-
* label="WEB SHOP"
|
|
2197
|
-
* isActive={false}
|
|
2198
|
-
* onClick={() => setActiveTab('content')}
|
|
2199
|
-
* variant="mobile"
|
|
2200
|
-
* />
|
|
2201
|
-
* ```
|
|
2531
|
+
/**
|
|
2532
|
+
* TabButton - Tab navigation component with result counts
|
|
2533
|
+
*
|
|
2534
|
+
* Supports two layout variants:
|
|
2535
|
+
* - Desktop: Background colours, top red underline when active, rounded corners
|
|
2536
|
+
* - Mobile: Text-only with bottom border underline when active
|
|
2537
|
+
*
|
|
2538
|
+
* @example
|
|
2539
|
+
* ```tsx
|
|
2540
|
+
* // Desktop variant
|
|
2541
|
+
* <TabButton
|
|
2542
|
+
* label="WEB SHOP RESULTS"
|
|
2543
|
+
* count={542}
|
|
2544
|
+
* isActive={true}
|
|
2545
|
+
* onClick={() => setActiveTab('products')}
|
|
2546
|
+
* variant="desktop"
|
|
2547
|
+
* />
|
|
2548
|
+
*
|
|
2549
|
+
* // Mobile variant
|
|
2550
|
+
* <TabButton
|
|
2551
|
+
* label="WEB SHOP"
|
|
2552
|
+
* isActive={false}
|
|
2553
|
+
* onClick={() => setActiveTab('content')}
|
|
2554
|
+
* variant="mobile"
|
|
2555
|
+
* />
|
|
2556
|
+
* ```
|
|
2202
2557
|
*/
|
|
2203
2558
|
const TabButton = ({
|
|
2204
2559
|
label,
|
|
@@ -2247,23 +2602,23 @@ const AssistanceIcon = props => {
|
|
|
2247
2602
|
|
|
2248
2603
|
var styles$3 = {"assistanceBanner":"AssistanceBanner-module__assistanceBanner___b97es","assistanceBanner__icon":"AssistanceBanner-module__assistanceBanner__icon___8NzJj","assistanceBanner__title":"AssistanceBanner-module__assistanceBanner__title___Wtkkt","assistanceBanner__description":"AssistanceBanner-module__assistanceBanner__description___AjoOr","assistanceBanner__link":"AssistanceBanner-module__assistanceBanner__link___5L45N","assistanceBanner__chevron":"AssistanceBanner-module__assistanceBanner__chevron___4km-f"};
|
|
2249
2604
|
|
|
2250
|
-
/**
|
|
2251
|
-
* AssistanceBanner - Help widget for search sidebar
|
|
2252
|
-
*
|
|
2253
|
-
* Displays a call-to-action for users who need assistance finding products.
|
|
2254
|
-
* Features chat icon, heading, description, and contact link with chevron.
|
|
2255
|
-
*
|
|
2256
|
-
* Desktop only - hidden on mobile to save space.
|
|
2257
|
-
*
|
|
2258
|
-
* @example
|
|
2259
|
-
* ```tsx
|
|
2260
|
-
* <AssistanceBanner
|
|
2261
|
-
* title="Need Assistance?"
|
|
2262
|
-
* description="Can't find what you're looking for? Our team is ready to help."
|
|
2263
|
-
* linkText="Contact support"
|
|
2264
|
-
* linkUrl="/contact"
|
|
2265
|
-
* />
|
|
2266
|
-
* ```
|
|
2605
|
+
/**
|
|
2606
|
+
* AssistanceBanner - Help widget for search sidebar
|
|
2607
|
+
*
|
|
2608
|
+
* Displays a call-to-action for users who need assistance finding products.
|
|
2609
|
+
* Features chat icon, heading, description, and contact link with chevron.
|
|
2610
|
+
*
|
|
2611
|
+
* Desktop only - hidden on mobile to save space.
|
|
2612
|
+
*
|
|
2613
|
+
* @example
|
|
2614
|
+
* ```tsx
|
|
2615
|
+
* <AssistanceBanner
|
|
2616
|
+
* title="Need Assistance?"
|
|
2617
|
+
* description="Can't find what you're looking for? Our team is ready to help."
|
|
2618
|
+
* linkText="Contact support"
|
|
2619
|
+
* linkUrl="/contact"
|
|
2620
|
+
* />
|
|
2621
|
+
* ```
|
|
2267
2622
|
*/
|
|
2268
2623
|
const AssistanceBanner = ({
|
|
2269
2624
|
title = 'Need Assistance?',
|
|
@@ -2310,27 +2665,31 @@ 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"};
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
*
|
|
2321
|
-
*
|
|
2322
|
-
*
|
|
2323
|
-
*
|
|
2324
|
-
*
|
|
2325
|
-
*
|
|
2326
|
-
*
|
|
2327
|
-
*
|
|
2328
|
-
*
|
|
2329
|
-
*
|
|
2330
|
-
*
|
|
2331
|
-
*
|
|
2332
|
-
*
|
|
2333
|
-
*
|
|
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;
|
|
2673
|
+
|
|
2674
|
+
/**
|
|
2675
|
+
* FilterDrawer - Mobile slide-in filter panel
|
|
2676
|
+
*
|
|
2677
|
+
* Slides in from the right with a dark overlay. Used on mobile to show filters
|
|
2678
|
+
* when screen space is limited. Includes focus trap, escape key handling, and
|
|
2679
|
+
* body scroll prevention.
|
|
2680
|
+
*
|
|
2681
|
+
* Desktop: Hidden (filters shown in sidebar)
|
|
2682
|
+
* Mobile: Slide-in drawer overlay
|
|
2683
|
+
*
|
|
2684
|
+
* @example
|
|
2685
|
+
* ```tsx
|
|
2686
|
+
* <FilterDrawer
|
|
2687
|
+
* isOpen={isFilterDrawerOpen}
|
|
2688
|
+
* onClose={() => setIsFilterDrawerOpen(false)}
|
|
2689
|
+
* >
|
|
2690
|
+
* <FiltersPanel facets={facets} onFacetToggle={handleToggle} />
|
|
2691
|
+
* </FilterDrawer>
|
|
2692
|
+
* ```
|
|
2334
2693
|
*/
|
|
2335
2694
|
const FilterDrawer = ({
|
|
2336
2695
|
isOpen,
|
|
@@ -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
|
-
//
|
|
2704
|
+
// Mount/unmount sequencing for transitions.
|
|
2345
2705
|
useEffect(() => {
|
|
2706
|
+
let closeTimer;
|
|
2707
|
+
let raf1;
|
|
2708
|
+
let raf2;
|
|
2346
2709
|
if (isOpen) {
|
|
2347
|
-
//
|
|
2348
|
-
|
|
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
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
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
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
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
|
-
|
|
2766
|
+
// In case the component unmounts unexpectedly.
|
|
2767
|
+
document.body.style.overflow = "";
|
|
2368
2768
|
};
|
|
2369
|
-
}, [
|
|
2769
|
+
}, [renderState]);
|
|
2370
2770
|
|
|
2371
2771
|
// Escape key handler
|
|
2372
2772
|
useEffect(() => {
|
|
2373
2773
|
const handleEscape = event => {
|
|
2374
|
-
if (event.key ===
|
|
2774
|
+
if (event.key === "Escape" && renderState !== "closed") {
|
|
2375
2775
|
onClose();
|
|
2376
2776
|
}
|
|
2377
2777
|
};
|
|
2378
|
-
document.addEventListener(
|
|
2379
|
-
return () => document.removeEventListener(
|
|
2380
|
-
}, [
|
|
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 (
|
|
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 !==
|
|
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(
|
|
2406
|
-
return () => drawer.removeEventListener(
|
|
2407
|
-
}, [
|
|
2408
|
-
if (
|
|
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[
|
|
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[
|
|
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, {
|
|
@@ -2590,41 +3006,41 @@ const FederatedResultsView = ({
|
|
|
2590
3006
|
|
|
2591
3007
|
var styles$1 = {"searchExperience":"FederatedSearchExperience-module__searchExperience___gug9X","searchBarSection":"FederatedSearchExperience-module__searchBarSection___f0Ykq","searchBarDesktopOnly":"FederatedSearchExperience-module__searchBarDesktopOnly___CetKZ","searchBarMobileOnly":"FederatedSearchExperience-module__searchBarMobileOnly___Ityxp","resultsHeaderMobileOnly":"FederatedSearchExperience-module__resultsHeaderMobileOnly___09ef-","tabsContainerSticky":"FederatedSearchExperience-module__tabsContainerSticky___-HdY5","tabs":"FederatedSearchExperience-module__tabs___Vatv8","tabSeparator":"FederatedSearchExperience-module__tabSeparator___AUjhW","mobileFilterButtonWrapper":"FederatedSearchExperience-module__mobileFilterButtonWrapper___JkRtk","mobileFilterButton":"FederatedSearchExperience-module__mobileFilterButton___sRc-w","filterIndicatorDot":"FederatedSearchExperience-module__filterIndicatorDot___vqVi2","instantResultsSection":"FederatedSearchExperience-module__instantResultsSection___AG3qn","fullResultsSection":"FederatedSearchExperience-module__fullResultsSection___NH16U"};
|
|
2592
3008
|
|
|
2593
|
-
/**
|
|
2594
|
-
* FederatedSearchExperience - Top-level search experience component
|
|
2595
|
-
*
|
|
2596
|
-
* This component orchestrates the entire federated search experience, including:
|
|
2597
|
-
* - Modal container
|
|
2598
|
-
* - Search input
|
|
2599
|
-
* - Instant results (2-column layout)
|
|
2600
|
-
* - Full results view with tabs and filters
|
|
2601
|
-
*
|
|
2602
|
-
* The component is fully controlled and does not contain any data fetching logic.
|
|
2603
|
-
* All data and callbacks are passed in via props, making it suitable for use in AEM
|
|
2604
|
-
* where a controller layer will handle Algolia integration.
|
|
2605
|
-
*
|
|
2606
|
-
* @example
|
|
2607
|
-
* ```tsx
|
|
2608
|
-
* <FederatedSearchExperience
|
|
2609
|
-
* isOpen={isOpen}
|
|
2610
|
-
* onOpen={handleOpen}
|
|
2611
|
-
* onClose={handleClose}
|
|
2612
|
-
* query={query}
|
|
2613
|
-
* onQueryChange={setQuery}
|
|
2614
|
-
* onSearchSubmit={handleSubmit}
|
|
2615
|
-
* products={products}
|
|
2616
|
-
* contents={contents}
|
|
2617
|
-
* isLoadingProducts={isLoadingProducts}
|
|
2618
|
-
* isLoadingContents={isLoadingContents}
|
|
2619
|
-
* onSeeAllProducts={handleSeeAllProducts}
|
|
2620
|
-
* onSeeAllContents={handleSeeAllContents}
|
|
2621
|
-
* onSeeAllCombined={handleSeeAllCombined}
|
|
2622
|
-
* activeView={activeView}
|
|
2623
|
-
* onChangeView={setActiveView}
|
|
2624
|
-
* activeTab={activeTab}
|
|
2625
|
-
* onTabChange={setActiveTab}
|
|
2626
|
-
* />
|
|
2627
|
-
* ```
|
|
3009
|
+
/**
|
|
3010
|
+
* FederatedSearchExperience - Top-level search experience component
|
|
3011
|
+
*
|
|
3012
|
+
* This component orchestrates the entire federated search experience, including:
|
|
3013
|
+
* - Modal container
|
|
3014
|
+
* - Search input
|
|
3015
|
+
* - Instant results (2-column layout)
|
|
3016
|
+
* - Full results view with tabs and filters
|
|
3017
|
+
*
|
|
3018
|
+
* The component is fully controlled and does not contain any data fetching logic.
|
|
3019
|
+
* All data and callbacks are passed in via props, making it suitable for use in AEM
|
|
3020
|
+
* where a controller layer will handle Algolia integration.
|
|
3021
|
+
*
|
|
3022
|
+
* @example
|
|
3023
|
+
* ```tsx
|
|
3024
|
+
* <FederatedSearchExperience
|
|
3025
|
+
* isOpen={isOpen}
|
|
3026
|
+
* onOpen={handleOpen}
|
|
3027
|
+
* onClose={handleClose}
|
|
3028
|
+
* query={query}
|
|
3029
|
+
* onQueryChange={setQuery}
|
|
3030
|
+
* onSearchSubmit={handleSubmit}
|
|
3031
|
+
* products={products}
|
|
3032
|
+
* contents={contents}
|
|
3033
|
+
* isLoadingProducts={isLoadingProducts}
|
|
3034
|
+
* isLoadingContents={isLoadingContents}
|
|
3035
|
+
* onSeeAllProducts={handleSeeAllProducts}
|
|
3036
|
+
* onSeeAllContents={handleSeeAllContents}
|
|
3037
|
+
* onSeeAllCombined={handleSeeAllCombined}
|
|
3038
|
+
* activeView={activeView}
|
|
3039
|
+
* onChangeView={setActiveView}
|
|
3040
|
+
* activeTab={activeTab}
|
|
3041
|
+
* onTabChange={setActiveTab}
|
|
3042
|
+
* />
|
|
3043
|
+
* ```
|
|
2628
3044
|
*/
|
|
2629
3045
|
const FederatedSearchExperience = ({
|
|
2630
3046
|
isOpen,
|
|
@@ -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
|