@asantemedia-org/leybold-design-system 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/assets/ai-banner-desktop.png +0 -0
  2. package/dist/assets/ai-banner-mobile.png +0 -0
  3. package/dist/assets/carousel-card.png +0 -0
  4. package/dist/assets/desktop-layout-alt.svg +27 -0
  5. package/dist/assets/desktop-layout.svg +29 -0
  6. package/dist/assets/globe.svg +7 -0
  7. package/dist/assets/language-selector-bg.png +0 -0
  8. package/dist/assets/leybold-footer-logo.svg +19 -0
  9. package/dist/assets/leybold-white.svg +19 -0
  10. package/dist/assets/list-card-alt.png +0 -0
  11. package/dist/assets/list-card.png +0 -0
  12. package/dist/assets/list-link-a.png +0 -0
  13. package/dist/assets/list-link-b.png +0 -0
  14. package/dist/assets/list-link-c.png +0 -0
  15. package/dist/assets/list-product-overlay-tip-active.svg +3 -0
  16. package/dist/assets/list-product-overlay-tip.svg +3 -0
  17. package/dist/assets/list-product.png +0 -0
  18. package/dist/assets/logo-example.svg +9 -0
  19. package/dist/assets/logo.svg +19 -0
  20. package/dist/assets/phone-layout.svg +14 -0
  21. package/dist/assets/red-tip.svg +10 -0
  22. package/dist/assets/tablet-layout.svg +28 -0
  23. package/dist/index.esm.js +560 -7
  24. package/dist/index.esm.js.map +1 -1
  25. package/dist/index.esm.scss +1805 -84
  26. package/dist/index.js +565 -5
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.scss +1805 -84
  29. package/dist/src/app/layout.d.ts +1 -0
  30. package/dist/src/app/page.d.ts +1 -0
  31. package/dist/src/components/AIBanner/AIBanner.d.ts +15 -0
  32. package/dist/src/components/AIBanner/AIBanner.stories.d.ts +7 -0
  33. package/dist/src/components/AIBanner/index.d.ts +2 -0
  34. package/dist/src/components/Button/Button.d.ts +50 -5
  35. package/dist/src/components/Button/Button.stories.d.ts +16 -3
  36. package/dist/src/components/LanguageSelector/LanguageSelector.d.ts +7 -0
  37. package/dist/src/components/LanguageSelector/LanguageSelector.stories.d.ts +32 -0
  38. package/dist/src/components/LanguageSelector/LanguageSelector.types.d.ts +64 -0
  39. package/dist/src/components/LanguageSelector/LanguageSelectorLink.d.ts +20 -0
  40. package/dist/src/components/LanguageSelector/LocationDropdown.d.ts +6 -0
  41. package/dist/src/components/LanguageSelector/LocationSelectorLink.d.ts +20 -0
  42. package/dist/src/components/LanguageSelector/index.d.ts +7 -0
  43. package/dist/src/experience/Carousel/Carousel.d.ts +36 -0
  44. package/dist/src/experience/Carousel/Carousel.stories.d.ts +7 -0
  45. package/dist/src/experience/Carousel/index.d.ts +2 -0
  46. package/dist/src/experience/Footer/Footer.d.ts +201 -0
  47. package/dist/src/experience/Footer/Footer.stories.d.ts +28 -0
  48. package/dist/src/experience/Footer/icons/AtlasCopcoIcon.d.ts +10 -0
  49. package/dist/src/experience/Footer/icons/ExternalLinkIcon.d.ts +10 -0
  50. package/dist/src/experience/Footer/icons/index.d.ts +2 -0
  51. package/dist/src/experience/Footer/index.d.ts +2 -0
  52. package/dist/src/experience/GeneratedList/GeneratedList.d.ts +40 -0
  53. package/dist/src/experience/GeneratedList/GeneratedList.stories.d.ts +7 -0
  54. package/dist/src/experience/GeneratedList/GeneratedList.types.d.ts +131 -0
  55. package/dist/src/experience/GeneratedList/GeneratedListExternalLink.stories.d.ts +7 -0
  56. package/dist/src/experience/GeneratedList/GeneratedListList.stories.d.ts +9 -0
  57. package/dist/src/experience/GeneratedList/GeneratedListProduct.stories.d.ts +7 -0
  58. package/dist/src/experience/GeneratedList/_Card.d.ts +8 -0
  59. package/dist/src/experience/GeneratedList/_CardMobile.d.ts +8 -0
  60. package/dist/src/experience/GeneratedList/_ExternalLink.d.ts +8 -0
  61. package/dist/src/experience/GeneratedList/_List.d.ts +8 -0
  62. package/dist/src/experience/GeneratedList/_Product.d.ts +9 -0
  63. package/dist/src/experience/GeneratedList/index.d.ts +2 -0
  64. package/dist/src/experience/Header/Header.d.ts +20 -0
  65. package/dist/src/experience/Header/Header.stories.d.ts +9 -0
  66. package/dist/src/experience/Header/HeaderNavButton.d.ts +9 -0
  67. package/dist/src/experience/Header/MegaMenu.d.ts +10 -0
  68. package/dist/src/experience/Header/MenuLink.d.ts +8 -0
  69. package/dist/src/experience/Header/MobileHeader.stories.d.ts +6 -0
  70. package/dist/src/experience/Header/MobileMenu.d.ts +9 -0
  71. package/dist/src/experience/Header/MobileNavBar.d.ts +13 -0
  72. package/dist/src/experience/Header/index.d.ts +6 -0
  73. package/dist/src/experience/algolia-dynamic-search/AlgoliaDynamicSearch.d.ts +1 -0
  74. package/dist/src/experience/qr-form-journey/QrFormJourney.d.ts +1 -0
  75. package/dist/src/index.d.ts +4 -0
  76. package/dist/src/stories/foundation/Buttons/ButtonComponents.d.ts +56 -0
  77. package/dist/src/stories/foundation/Typography/TypographyComponents.d.ts +45 -0
  78. package/dist/src/stories/foundation/_components/StoryLayout.d.ts +11 -0
  79. package/dist/src/types/cards.d.ts +1 -0
  80. package/dist/src/types/search.d.ts +5 -2
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +5 -2
package/dist/index.esm.js CHANGED
@@ -1,4 +1,8 @@
1
- import React, { useMemo, useState, useCallback, useRef, useEffect } from 'react';
1
+ import React, { useRef, useState, useEffect, useMemo, useCallback } from 'react';
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
+ import { faArrowLeft, faArrowLeftLong, faArrowRight, faArrowRightLong, faChevronRight, faChevronLeft, faArrowUpRightFromSquare, faGlobe } from '@fortawesome/free-solid-svg-icons';
4
+ import Slider from 'react-slick';
5
+ import { faInstagram, faYoutube, faLinkedinIn, faXTwitter, faFacebookF } from '@fortawesome/free-brands-svg-icons';
2
6
  import { ProductDetailsCard, AlgoliaDynamicSearchRaw, QrForm } from '@asantemedia-org/edwardsvacuum-design-system';
3
7
 
4
8
  function _extends() {
@@ -11,7 +15,7 @@ function _extends() {
11
15
  }, _extends.apply(null, arguments);
12
16
  }
13
17
 
14
- var styles$f = {"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--outline":"Button-module__button--outline___wB6-g","button--text":"Button-module__button--text___iZIMo","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"};
18
+ var styles$h = {"button":"Button-module__button___18Bed","button--primary":"Button-module__button--primary___VuF-P","button--default":"Button-module__button--default___MDa35","button--disabled":"Button-module__button--disabled___IuOY8","button--secondary":"Button-module__button--secondary___lD5E3","button--solid-red":"Button-module__button--solid-red___YPpnL","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-red":"Button-module__button--outlined-red___cgZXa","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"};
15
19
 
16
20
  function getDefaultExportFromCjs (x) {
17
21
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -88,6 +92,79 @@ function requireClassnames() {
88
92
  var classnamesExports = requireClassnames();
89
93
  var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports);
90
94
 
95
+ /**
96
+ * Button variant types
97
+ */
98
+
99
+ /**
100
+ * Icon types for button
101
+ */
102
+
103
+ /**
104
+ * Icon position
105
+ */
106
+
107
+ /**
108
+ * Get the icon component based on icon type
109
+ */
110
+ const getIcon = icon => {
111
+ switch (icon) {
112
+ case "arrow-right":
113
+ return /*#__PURE__*/React.createElement(FontAwesomeIcon, {
114
+ icon: faArrowRight
115
+ });
116
+ case "external":
117
+ return /*#__PURE__*/React.createElement(FontAwesomeIcon, {
118
+ icon: faArrowUpRightFromSquare
119
+ });
120
+ case "chevron-left":
121
+ return /*#__PURE__*/React.createElement(FontAwesomeIcon, {
122
+ icon: faChevronLeft
123
+ });
124
+ case "chevron-right":
125
+ return /*#__PURE__*/React.createElement(FontAwesomeIcon, {
126
+ icon: faChevronRight
127
+ });
128
+ default:
129
+ return null;
130
+ }
131
+ };
132
+
133
+ /**
134
+ * Get default icon for certain variants
135
+ */
136
+ const getDefaultIcon = variant => {
137
+ switch (variant) {
138
+ case "link-text":
139
+ case "link-text-alt":
140
+ case "text":
141
+ // Alias
142
+ return "arrow-right";
143
+ case "external-link":
144
+ return "external";
145
+ case "carousel-arrow-left":
146
+ return "chevron-left";
147
+ case "carousel-arrow-right":
148
+ return "chevron-right";
149
+ default:
150
+ return "none";
151
+ }
152
+ };
153
+
154
+ /**
155
+ * Map alias variants to their actual CSS class variants
156
+ */
157
+ const mapVariantToClass = variant => {
158
+ switch (variant) {
159
+ case "outline":
160
+ return "outlined-red";
161
+ case "text":
162
+ return "link-text";
163
+ default:
164
+ return variant;
165
+ }
166
+ };
167
+
91
168
  /**
92
169
  * Primary UI component for user interaction
93
170
  */
@@ -99,17 +176,493 @@ const Button = ({
99
176
  onClick,
100
177
  type = "button",
101
178
  className,
179
+ icon,
180
+ iconPosition = "right",
181
+ ariaLabel,
182
+ opensInNewTab,
102
183
  ...props
103
184
  }) => {
104
- const buttonClasses = classNames(styles$f.button, styles$f[`button--${variant}`], styles$f[`button--${size}`], {
105
- [styles$f["button--disabled"]]: disabled
185
+ // Map alias variants to actual class names
186
+ const cssVariant = mapVariantToClass(variant);
187
+
188
+ // Determine the icon to display
189
+ const displayIcon = icon ?? getDefaultIcon(variant);
190
+ const iconElement = getIcon(displayIcon);
191
+
192
+ // Check if this is an icon-only button (carousel arrows)
193
+ const isIconOnly = variant === "carousel-arrow-left" || variant === "carousel-arrow-right";
194
+ const isCarouselLeft = variant === "carousel-arrow-left";
195
+ const isCarouselRight = variant === "carousel-arrow-right";
196
+ const buttonClasses = classNames(styles$h.button, styles$h[`button--${cssVariant}`], styles$h[`button--${size}`], {
197
+ [styles$h["button--disabled"]]: disabled
106
198
  }, className);
199
+ const iconClasses = classNames(styles$h.button__icon, styles$h[`button__icon--${iconPosition}`]);
200
+
201
+ // Generate accessible label for icon-only buttons
202
+ const accessibleLabel = ariaLabel || (isIconOnly ? variant === "carousel-arrow-left" ? "Previous" : "Next" : undefined);
107
203
  return /*#__PURE__*/React.createElement("button", _extends({
108
204
  type: type,
109
205
  className: buttonClasses,
110
206
  disabled: disabled,
111
- onClick: onClick
112
- }, props), children);
207
+ onClick: onClick,
208
+ "aria-label": accessibleLabel,
209
+ "data-force-state": props['data-force-state']
210
+ }, props), !isIconOnly && children, isCarouselLeft && /*#__PURE__*/React.createElement("span", {
211
+ className: iconClasses
212
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
213
+ icon: faArrowLeft,
214
+ className: styles$h.button__icon__default
215
+ }), /*#__PURE__*/React.createElement(FontAwesomeIcon, {
216
+ icon: faArrowLeftLong,
217
+ className: styles$h.button__icon__hover
218
+ })), isCarouselRight && /*#__PURE__*/React.createElement("span", {
219
+ className: iconClasses
220
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
221
+ icon: faArrowRight,
222
+ className: styles$h.button__icon__default
223
+ }), /*#__PURE__*/React.createElement(FontAwesomeIcon, {
224
+ icon: faArrowRightLong,
225
+ className: styles$h.button__icon__hover
226
+ })), !isIconOnly && iconElement && /*#__PURE__*/React.createElement("span", {
227
+ className: iconClasses
228
+ }, iconElement));
229
+ };
230
+
231
+ var styles$g = {"carousel":"Carousel-module__carousel___hkXkF","carousel__header":"Carousel-module__carousel__header___IMcN5","carousel__headerContent":"Carousel-module__carousel__headerContent___9uU-H","carousel__title":"Carousel-module__carousel__title___CCgcY","carousel__subtitle":"Carousel-module__carousel__subtitle___aj4q1","carousel__slider":"Carousel-module__carousel__slider___b27-P","carousel__slideWrapper":"Carousel-module__carousel__slideWrapper___PjXgD","carousel__card":"Carousel-module__carousel__card___lga-D","carousel__cardContent":"Carousel-module__carousel__cardContent___v0jc-","carousel__cardImageWrapper":"Carousel-module__carousel__cardImageWrapper___aFqXD","carousel__cardImage":"Carousel-module__carousel__cardImage___4MrRU","carousel__cardTitle":"Carousel-module__carousel__cardTitle___z-mMo","carousel__navigation":"Carousel-module__carousel__navigation___dMbcP","carousel__arrows":"Carousel-module__carousel__arrows___uj5nF","carousel__dotsList":"Carousel-module__carousel__dotsList___upZ7L","carousel__dot":"Carousel-module__carousel__dot___HwZc0","carousel__dot--active":"Carousel-module__carousel__dot--active___NxRvq"};
232
+
233
+ /**
234
+ * Carousel component for displaying multiple content cards in a sliding format.
235
+ * Supports responsive layouts with 3 cards on desktop and 1 card on mobile.
236
+ */
237
+ const Carousel = ({
238
+ title,
239
+ subtitle,
240
+ buttonText,
241
+ buttonUrl,
242
+ cards,
243
+ showDots = true,
244
+ showArrows = true,
245
+ className
246
+ }) => {
247
+ const sliderRef = useRef(null);
248
+ const [currentSlide, setCurrentSlide] = useState(0);
249
+
250
+ // Uses document.documentElement.clientWidth to work correctly in iframes (Storybook)
251
+ const [isMobile, setIsMobile] = useState(() => {
252
+ if (typeof window !== 'undefined') {
253
+ return document.documentElement.clientWidth < 768;
254
+ }
255
+ return false;
256
+ });
257
+ useEffect(() => {
258
+ const handleResize = () => {
259
+ setIsMobile(document.documentElement.clientWidth < 768);
260
+ };
261
+ window.addEventListener('resize', handleResize);
262
+ return () => window.removeEventListener('resize', handleResize);
263
+ }, []);
264
+ const handlePrev = () => sliderRef.current?.slickPrev();
265
+ const handleNext = () => sliderRef.current?.slickNext();
266
+ const goToSlide = index => sliderRef.current?.slickGoTo(index);
267
+ const settings = {
268
+ dots: false,
269
+ infinite: true,
270
+ speed: 500,
271
+ slidesToShow: isMobile ? 1 : 3,
272
+ slidesToScroll: 1,
273
+ arrows: false,
274
+ beforeChange: (_, next) => setCurrentSlide(next)
275
+ };
276
+ return /*#__PURE__*/React.createElement("div", {
277
+ className: classNames(styles$g.carousel, className)
278
+ }, /*#__PURE__*/React.createElement("div", {
279
+ className: styles$g.carousel__header
280
+ }, /*#__PURE__*/React.createElement("div", {
281
+ className: styles$g.carousel__headerContent
282
+ }, /*#__PURE__*/React.createElement("h2", {
283
+ className: styles$g.carousel__title
284
+ }, title), subtitle && /*#__PURE__*/React.createElement("p", {
285
+ className: styles$g.carousel__subtitle
286
+ }, subtitle)), buttonText && buttonUrl && /*#__PURE__*/React.createElement(Button, {
287
+ variant: "outlined-black",
288
+ onClick: () => window.location.href = buttonUrl,
289
+ style: {
290
+ minWidth: '215px',
291
+ minHeight: '56px'
292
+ }
293
+ }, buttonText)), /*#__PURE__*/React.createElement(Slider, _extends({
294
+ ref: sliderRef
295
+ }, settings, {
296
+ className: styles$g.carousel__slider
297
+ }), cards.map((card, index) => /*#__PURE__*/React.createElement("div", {
298
+ key: index,
299
+ className: styles$g.carousel__slideWrapper
300
+ }, /*#__PURE__*/React.createElement("a", {
301
+ href: card.linkUrl,
302
+ className: styles$g.carousel__card,
303
+ "aria-label": `${card.title} - ${card.linkText}`
304
+ }, /*#__PURE__*/React.createElement("div", {
305
+ className: styles$g.carousel__cardImageWrapper
306
+ }, /*#__PURE__*/React.createElement("img", {
307
+ src: card.imageUrl,
308
+ alt: card.imageAlt,
309
+ className: styles$g.carousel__cardImage
310
+ })), /*#__PURE__*/React.createElement("div", {
311
+ className: styles$g.carousel__cardContent
312
+ }, /*#__PURE__*/React.createElement("h3", {
313
+ className: styles$g.carousel__cardTitle
314
+ }, card.title), /*#__PURE__*/React.createElement(Button, {
315
+ variant: "link-text-alt",
316
+ icon: "arrow-right"
317
+ }, card.linkText)))))), /*#__PURE__*/React.createElement("div", {
318
+ className: styles$g.carousel__navigation
319
+ }, !isMobile && showDots && /*#__PURE__*/React.createElement("div", {
320
+ className: styles$g.carousel__dotsList
321
+ }, cards.map((_, index) => /*#__PURE__*/React.createElement("button", {
322
+ key: index,
323
+ type: "button",
324
+ className: classNames(styles$g.carousel__dot, currentSlide === index && styles$g['carousel__dot--active']),
325
+ onClick: () => goToSlide(index),
326
+ "aria-label": `Go to slide ${index + 1}`
327
+ }))), showArrows && /*#__PURE__*/React.createElement("div", {
328
+ className: styles$g.carousel__arrows
329
+ }, /*#__PURE__*/React.createElement(Button, {
330
+ variant: "carousel-arrow-left",
331
+ onClick: handlePrev,
332
+ ariaLabel: "Previous"
333
+ }), /*#__PURE__*/React.createElement(Button, {
334
+ variant: "carousel-arrow-right",
335
+ onClick: handleNext,
336
+ ariaLabel: "Next"
337
+ }))));
338
+ };
339
+
340
+ var styles$f = {"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"};
341
+
342
+ /**
343
+ * External link icon (↗) for footer links that open in new tabs
344
+ */
345
+ const ExternalLinkIcon = ({
346
+ className,
347
+ size = 15
348
+ }) => /*#__PURE__*/React.createElement("svg", {
349
+ width: size,
350
+ height: size,
351
+ viewBox: "0 0 15 15",
352
+ fill: "none",
353
+ xmlns: "http://www.w3.org/2000/svg",
354
+ className: className,
355
+ "aria-hidden": "true"
356
+ }, /*#__PURE__*/React.createElement("path", {
357
+ d: "M11.25 8.125V11.875C11.25 12.2065 11.1183 12.5245 10.8839 12.7589C10.6495 12.9933 10.3315 13.125 10 13.125H3.125C2.79348 13.125 2.47554 12.9933 2.24112 12.7589C2.0067 12.5245 1.875 12.2065 1.875 11.875V5C1.875 4.66848 2.0067 4.35054 2.24112 4.11612C2.47554 3.8817 2.79348 3.75 3.125 3.75H6.875M9.375 1.875H13.125M13.125 1.875V5.625M13.125 1.875L6.25 8.75",
358
+ stroke: "currentColor",
359
+ strokeWidth: "1.5",
360
+ strokeLinecap: "round",
361
+ strokeLinejoin: "round"
362
+ }));
363
+
364
+ /**
365
+ * Atlas Copco Group badge icon (square)
366
+ */
367
+ const AtlasCopcoIcon = ({
368
+ className,
369
+ size = 14
370
+ }) => /*#__PURE__*/React.createElement("svg", {
371
+ width: size,
372
+ height: size,
373
+ viewBox: "0 0 14 14",
374
+ fill: "none",
375
+ xmlns: "http://www.w3.org/2000/svg",
376
+ className: className,
377
+ "aria-hidden": "true"
378
+ }, /*#__PURE__*/React.createElement("rect", {
379
+ x: "0.5",
380
+ y: "0.5",
381
+ width: "13",
382
+ height: "13",
383
+ rx: "1.5",
384
+ fill: "#D9D9D9",
385
+ stroke: "#D9D9D9"
386
+ }));
387
+
388
+ // =============================================================================
389
+ // TYPE DEFINITIONS
390
+ // =============================================================================
391
+
392
+ // =============================================================================
393
+ // SOCIAL ICON COMPONENT
394
+ // =============================================================================
395
+
396
+ const SocialIconComponent = ({
397
+ platform
398
+ }) => {
399
+ const iconMap = {
400
+ facebook: faFacebookF,
401
+ x: faXTwitter,
402
+ linkedin: faLinkedinIn,
403
+ youtube: faYoutube,
404
+ instagram: faInstagram
405
+ };
406
+ return /*#__PURE__*/React.createElement(FontAwesomeIcon, {
407
+ icon: iconMap[platform]
408
+ });
409
+ };
410
+
411
+ // =============================================================================
412
+ // FOOTER LINK COMPONENT
413
+ // =============================================================================
414
+
415
+ const FooterLink = ({
416
+ item,
417
+ className,
418
+ variant = 'default'
419
+ }) => {
420
+ const baseClass = variant === 'bottom' ? styles$f.footer__bottomLink : styles$f.footer__link;
421
+ const linkClasses = classNames(baseClass, className);
422
+ const handleClick = e => {
423
+ if (item.onClick) {
424
+ e.preventDefault();
425
+ item.onClick();
426
+ }
427
+ };
428
+ return /*#__PURE__*/React.createElement("a", _extends({
429
+ href: item.href,
430
+ className: linkClasses,
431
+ onClick: item.onClick ? handleClick : undefined
432
+ }, item.external && {
433
+ target: '_blank',
434
+ rel: 'noopener noreferrer'
435
+ }), /*#__PURE__*/React.createElement("span", {
436
+ className: styles$f.footer__linkText
437
+ }, item.label), item.external && /*#__PURE__*/React.createElement("span", {
438
+ className: styles$f.footer__linkIcon
439
+ }, /*#__PURE__*/React.createElement(ExternalLinkIcon, {
440
+ size: 15
441
+ })));
442
+ };
443
+
444
+ // =============================================================================
445
+ // FOOTER LINK GROUP COMPONENT
446
+ // =============================================================================
447
+
448
+ const FooterLinkGroup = ({
449
+ heading,
450
+ links,
451
+ className,
452
+ children
453
+ }) => {
454
+ return /*#__PURE__*/React.createElement("div", {
455
+ className: classNames(styles$f.footer__linkGroup, className)
456
+ }, /*#__PURE__*/React.createElement("h3", {
457
+ className: styles$f.footer__linkHeading
458
+ }, heading), /*#__PURE__*/React.createElement("ul", {
459
+ className: styles$f.footer__linkList
460
+ }, links.map((link, index) => /*#__PURE__*/React.createElement("li", {
461
+ key: index
462
+ }, /*#__PURE__*/React.createElement(FooterLink, {
463
+ item: link
464
+ })))), children);
465
+ };
466
+
467
+ // =============================================================================
468
+ // FOOTER SOCIAL ICONS COMPONENT
469
+ // =============================================================================
470
+
471
+ const FooterSocialIcons = ({
472
+ links,
473
+ className
474
+ }) => {
475
+ return /*#__PURE__*/React.createElement("div", {
476
+ className: classNames(styles$f.footer__socialIcons, className)
477
+ }, links.map((link, index) => /*#__PURE__*/React.createElement("a", {
478
+ key: index,
479
+ href: link.href,
480
+ className: styles$f.footer__socialIcon,
481
+ "aria-label": link.ariaLabel,
482
+ target: "_blank",
483
+ rel: "noopener noreferrer"
484
+ }, /*#__PURE__*/React.createElement(SocialIconComponent, {
485
+ platform: link.platform
486
+ }))));
487
+ };
488
+
489
+ // =============================================================================
490
+ // FOOTER SOCIAL ICON (STANDALONE) COMPONENT
491
+ // =============================================================================
492
+
493
+ const FooterSocialIcon = ({
494
+ platform,
495
+ className
496
+ }) => {
497
+ const iconClasses = classNames(styles$f.footer__socialIcon, className);
498
+ return /*#__PURE__*/React.createElement("span", {
499
+ className: iconClasses
500
+ }, /*#__PURE__*/React.createElement(SocialIconComponent, {
501
+ platform: platform
502
+ }));
503
+ };
504
+
505
+ // =============================================================================
506
+ // FOOTER BOTTOM COMPONENT
507
+ // =============================================================================
508
+
509
+ const FooterBottom = ({
510
+ links,
511
+ copyright,
512
+ countrySelector,
513
+ className
514
+ }) => {
515
+ return /*#__PURE__*/React.createElement("div", {
516
+ className: classNames(styles$f.footer__bottom, className)
517
+ }, /*#__PURE__*/React.createElement("div", {
518
+ className: styles$f.footer__bottomLeft
519
+ }, /*#__PURE__*/React.createElement("div", {
520
+ className: styles$f.footer__bottomLinks
521
+ }, links.map((link, index) => /*#__PURE__*/React.createElement(FooterLink, {
522
+ key: index,
523
+ item: link,
524
+ variant: "bottom"
525
+ }))), /*#__PURE__*/React.createElement("p", {
526
+ className: styles$f.footer__copyright
527
+ }, copyright)), countrySelector && /*#__PURE__*/React.createElement("a", {
528
+ href: countrySelector.href || '#',
529
+ className: styles$f.footer__countrySelector
530
+ }, countrySelector.showIcon !== false && /*#__PURE__*/React.createElement("span", {
531
+ className: styles$f.footer__countrySelectorIcon
532
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
533
+ icon: faGlobe
534
+ })), countrySelector.label));
535
+ };
536
+
537
+ // =============================================================================
538
+ // MAIN FOOTER COMPONENT
539
+ // =============================================================================
540
+
541
+ /**
542
+ * Footer component with brand identity, navigation links, social icons, and legal information.
543
+ * Supports two layout variants:
544
+ * - desktop: Logo at top, 3-column main content
545
+ * - mobile: Logo at bottom, stacked layout with CTA button
546
+ */
547
+ const Footer = ({
548
+ variant = 'desktop',
549
+ logo,
550
+ motto,
551
+ atlasCopcoBadge,
552
+ quickLinks,
553
+ quickLinksHeading = 'Quick links',
554
+ contactLinks,
555
+ contactHeading = 'Contact us',
556
+ socialLinks,
557
+ contactFormButton,
558
+ bottomLinks,
559
+ copyright,
560
+ countrySelector,
561
+ className
562
+ }) => {
563
+ const isMobile = variant === 'mobile';
564
+ const footerClasses = classNames(styles$f.footer, isMobile && styles$f['footer--mobile'], className);
565
+ const LogoWrapper = logo.href ? 'a' : 'div';
566
+ const logoProps = logo.href ? {
567
+ href: logo.href,
568
+ className: styles$f.footer__logo
569
+ } : {
570
+ className: styles$f.footer__logo
571
+ };
572
+
573
+ // Logo + Motto + Badge component (used in both layouts)
574
+ const LogoSection = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LogoWrapper, logoProps, /*#__PURE__*/React.createElement("img", {
575
+ src: logo.src,
576
+ alt: logo.alt
577
+ })), /*#__PURE__*/React.createElement("div", {
578
+ className: styles$f.footer__leftCol
579
+ }, /*#__PURE__*/React.createElement("h2", {
580
+ className: styles$f.footer__motto
581
+ }, motto), atlasCopcoBadge && /*#__PURE__*/React.createElement("div", {
582
+ className: styles$f.footer__badge
583
+ }, atlasCopcoBadge.showIcon !== false && /*#__PURE__*/React.createElement("span", {
584
+ className: styles$f.footer__badgeIcon
585
+ }, /*#__PURE__*/React.createElement(AtlasCopcoIcon, {
586
+ size: 14
587
+ })), /*#__PURE__*/React.createElement("span", {
588
+ className: styles$f.footer__badgeText
589
+ }, atlasCopcoBadge.text))));
590
+
591
+ // Mobile layout: Links at top, logo/motto at bottom
592
+ if (isMobile) {
593
+ return /*#__PURE__*/React.createElement("footer", {
594
+ className: footerClasses
595
+ }, /*#__PURE__*/React.createElement("div", {
596
+ className: styles$f.footer__container
597
+ }, /*#__PURE__*/React.createElement("div", {
598
+ className: styles$f.footer__links
599
+ }, /*#__PURE__*/React.createElement(FooterLinkGroup, {
600
+ heading: quickLinksHeading,
601
+ links: quickLinks
602
+ }), /*#__PURE__*/React.createElement(FooterLinkGroup, {
603
+ heading: contactHeading,
604
+ links: contactLinks
605
+ })), contactFormButton && /*#__PURE__*/React.createElement("div", {
606
+ className: styles$f.footer__cta
607
+ }, /*#__PURE__*/React.createElement("a", {
608
+ href: contactFormButton.href,
609
+ style: {
610
+ textDecoration: 'none',
611
+ width: '100%'
612
+ }
613
+ }, /*#__PURE__*/React.createElement(Button, {
614
+ variant: "solid-red",
615
+ style: {
616
+ width: '100%'
617
+ }
618
+ }, contactFormButton.label))), socialLinks.length > 0 && /*#__PURE__*/React.createElement(FooterSocialIcons, {
619
+ links: socialLinks
620
+ }), /*#__PURE__*/React.createElement(FooterBottom, {
621
+ links: bottomLinks,
622
+ copyright: copyright,
623
+ countrySelector: countrySelector
624
+ }), /*#__PURE__*/React.createElement("div", {
625
+ className: styles$f.footer__brandSection
626
+ }, /*#__PURE__*/React.createElement(LogoSection, null))));
627
+ }
628
+
629
+ // Desktop layout: Logo at top, 3-column main content
630
+ return /*#__PURE__*/React.createElement("footer", {
631
+ className: footerClasses
632
+ }, /*#__PURE__*/React.createElement("div", {
633
+ className: styles$f.footer__container
634
+ }, /*#__PURE__*/React.createElement(LogoWrapper, logoProps, /*#__PURE__*/React.createElement("img", {
635
+ src: logo.src,
636
+ alt: logo.alt
637
+ })), /*#__PURE__*/React.createElement("div", {
638
+ className: styles$f.footer__main
639
+ }, /*#__PURE__*/React.createElement("div", {
640
+ className: styles$f.footer__leftCol
641
+ }, /*#__PURE__*/React.createElement("h2", {
642
+ className: styles$f.footer__motto
643
+ }, motto), atlasCopcoBadge && /*#__PURE__*/React.createElement("div", {
644
+ className: styles$f.footer__badge
645
+ }, atlasCopcoBadge.showIcon !== false && /*#__PURE__*/React.createElement("span", {
646
+ className: styles$f.footer__badgeIcon
647
+ }, /*#__PURE__*/React.createElement(AtlasCopcoIcon, {
648
+ size: 14
649
+ })), /*#__PURE__*/React.createElement("span", {
650
+ className: styles$f.footer__badgeText
651
+ }, atlasCopcoBadge.text))), /*#__PURE__*/React.createElement("div", {
652
+ className: styles$f.footer__links
653
+ }, /*#__PURE__*/React.createElement(FooterLinkGroup, {
654
+ heading: quickLinksHeading,
655
+ links: quickLinks
656
+ }), /*#__PURE__*/React.createElement(FooterLinkGroup, {
657
+ heading: contactHeading,
658
+ links: contactLinks
659
+ }, socialLinks.length > 0 && /*#__PURE__*/React.createElement(FooterSocialIcons, {
660
+ links: socialLinks
661
+ })))), /*#__PURE__*/React.createElement(FooterBottom, {
662
+ links: bottomLinks,
663
+ copyright: copyright,
664
+ countrySelector: countrySelector
665
+ })));
113
666
  };
114
667
 
115
668
  var styles$e = {"pagination":"Pagination-module__pagination___Kih79","paginationList":"Pagination-module__paginationList___-lZpm","paginationItem":"Pagination-module__paginationItem___VsGFa","pageButton":"Pagination-module__pageButton___b6UNF","pageButtonActive":"Pagination-module__pageButtonActive___D9m18","navButton":"Pagination-module__navButton___ZCIai","navIcon":"Pagination-module__navIcon___-BVJ3","navButton--previous":"Pagination-module__navButton--previous___Cy5TE","navButton--next":"Pagination-module__navButton--next___kTmgK","navButtonDisabled":"Pagination-module__navButtonDisabled___IZK8H","ellipsis":"Pagination-module__ellipsis___iAsGN","ellipsisText":"Pagination-module__ellipsisText___fd6u1"};
@@ -1773,5 +2326,5 @@ const SearchTriggerButton = ({
1773
2326
  }, label));
1774
2327
  };
1775
2328
 
1776
- export { AlgoliaDynamicSearchLeybold as AlgoliaDynamicSearch, AlgoliaDynamicSearchLeybold, AppliedFilterTag, AppliedFilters, Button, ContentCardHorizontal, FederatedInstantResultsLayout, FederatedResultsView, FederatedSearchExperience, FilterAccordion, FilterItem, FilterSearch, FiltersPanel, ModalCloseButton, Pagination, PaginationButton, PaginationEllipsis, PaginationItem, ProductCardHorizontal, QrFormLeybold as QrForm, QrFormLeybold, ResultsColumn, ResultsCount, ResultsList, SearchBar, SearchIcon, SearchInput, SearchModal, SearchSubmitButton, SearchTriggerButton, SeeAllLinkButton };
2329
+ export { AlgoliaDynamicSearchLeybold as AlgoliaDynamicSearch, AlgoliaDynamicSearchLeybold, AppliedFilterTag, AppliedFilters, Button, Carousel, ContentCardHorizontal, FederatedInstantResultsLayout, FederatedResultsView, FederatedSearchExperience, FilterAccordion, FilterItem, FilterSearch, FiltersPanel, Footer, FooterBottom, FooterLink, FooterLinkGroup, FooterSocialIcon, FooterSocialIcons, ModalCloseButton, Pagination, PaginationButton, PaginationEllipsis, PaginationItem, ProductCardHorizontal, QrFormLeybold as QrForm, QrFormLeybold, ResultsColumn, ResultsCount, ResultsList, SearchBar, SearchIcon, SearchInput, SearchModal, SearchSubmitButton, SearchTriggerButton, SeeAllLinkButton };
1777
2330
  //# sourceMappingURL=index.esm.js.map