@yatoday/astro-ui 0.18.2 → 0.18.4

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 (47) hide show
  1. package/components/Analytics/AnalyticsGTM.astro +3 -3
  2. package/components/Analytics/AnalyticsGTMBody.astro +16 -12
  3. package/components/Analytics/AnalyticsGoogle.astro +3 -1
  4. package/components/BreadcrumbsItem/BreadcrumbsItem.astro +8 -1
  5. package/components/Button/types.ts +2 -1
  6. package/components/CallToAction/CallToAction.astro +1 -1
  7. package/components/Card0/Card0.astro +20 -32
  8. package/components/Card1/Card1.astro +11 -19
  9. package/components/Card2/Card2.astro +10 -14
  10. package/components/Card3/Card3.astro +15 -20
  11. package/components/Card4/Card4.astro +6 -2
  12. package/components/Card5/Card5.astro +8 -1
  13. package/components/Card6/Card6.astro +76 -59
  14. package/components/Card7/Card7.astro +27 -18
  15. package/components/CookieConsent/CookieConsent.astro +323 -308
  16. package/components/CopyToClipboard/CopyToClipboard.astro +6 -14
  17. package/components/CopyToClipboard/copy.ts +1 -1
  18. package/components/DarkMode/__tests__/DarkMode.test.ts +8 -8
  19. package/components/Headline/Headline.astro +4 -1
  20. package/components/HeroSection/HeroSection.astro +13 -16
  21. package/components/Image/Image.astro +1 -7
  22. package/components/ImageGallery/ImageGallery.astro +85 -90
  23. package/components/ImageGalleryIkea/ImageGalleryIkea.astro +3 -2
  24. package/components/ImagePreload/ImagePreload.astro +22 -20
  25. package/components/ItemGrid1/ItemGrid1.astro +34 -24
  26. package/components/Metadata/Metadata.astro +1 -5
  27. package/components/PointMap/PointMap.astro +62 -48
  28. package/components/PointMap/types.ts +3 -3
  29. package/components/SEO/SEO.astro +34 -33
  30. package/components/WidgetBrands/WidgetBrands.astro +8 -1
  31. package/components/WidgetContent/WidgetContent.astro +22 -9
  32. package/components/WidgetContent/types.ts +1 -1
  33. package/components/WidgetFeaturesCard/WidgetFeaturesCard.astro +10 -2
  34. package/components/WidgetHeroSlider/WidgetHeroSlider.astro +6 -1
  35. package/components/WidgetNavbarFlyout/WidgetNavbarFlyout.astro +16 -7
  36. package/components/WidgetSwiperPhotoSlider/WidgetSwiperPhotoSlider.astro +18 -7
  37. package/components/WidgetTestimonials/WidgetTestimonials.astro +8 -1
  38. package/components/WidgetWrapper/WidgetWrapper.astro +11 -2
  39. package/index.d.ts +20 -20
  40. package/package.json +11 -9
  41. package/styles/styles.css +303 -160
  42. package/utils/i18n.ts +2 -2
  43. package/utils/images.ts +0 -1
  44. package/utils/slugify.ts +3 -0
  45. package/vendor-config/config.example.yaml +0 -1
  46. package/vendor-config/index.ts +1 -1
  47. package/vendor-config/utils/loadConfig.ts +15 -18
@@ -1,56 +1,60 @@
1
1
  ---
2
- import type {PointMapProps as Props} from './types';
3
- import {cn, id} from "../../utils";
2
+ import type { PointMapProps as Props } from './types';
3
+ import { cn, id } from '../../utils';
4
4
  import Card7 from '../Card7/Card7.astro';
5
5
 
6
6
  const {
7
7
  via = Card7,
8
8
  items = [],
9
9
  pointsDisplayMode = 'always', // default to always visible
10
- classes = {}
10
+ classes = {},
11
11
  } = Astro.props;
12
12
 
13
13
  const mapId = `map-${id()}`;
14
14
 
15
- const {
16
- container: containerClass = '',
17
- popup: popupClass = '',
18
- } = classes;
15
+ const { container: containerClass = '', popup: popupClass = '' } = classes;
19
16
 
20
17
  const Component = via;
21
18
  ---
22
19
 
23
20
  <div id={mapId} class={cn(`map-picker relative h-full w-full points-${pointsDisplayMode}`, containerClass)}>
24
- {items.map((point, i) => (
25
- <>
26
- <!-- Hotspot point -->
27
- <button
28
- class="hotspot-point cursor-pointer"
29
- style={`left: ${point.x}%; top: ${point.y}%; width: 24px; height: 24px; transform: translate(-50%, -50%);`}
30
- data-index={i}
31
- data-map-id={mapId}
32
- aria-label={point.title}
33
- {...(point.isPopupOpen ? { 'data-initially-open': '' } : {})}
34
- >
35
- </button>
36
-
37
- <!-- Popup content (hidden by default) -->
38
- <div
39
- class={cn("popup-content absolute rounded-md shadow-lg z-10 max-w-xs hidden", popupClass)}
40
- style={`left: ${point.x}%; top: ${point.y}%; transform: translate(${point.x > 50 ? '-100%' : '0'}, ${point.y > 50 ? '-100%' : '0'});`}
41
- data-popup={i}
42
- data-map-id={mapId}
43
- >
44
- <Component
45
- {...point}
46
- classes={Object.assign({container: 'border-transparent dark:border-input'}, classes?.card || {}, point?.classes || {}) as Record<string, string>}
21
+ {
22
+ items.map((point, i) => (
23
+ <>
24
+ {/* Hotspot point */}
25
+ <button
26
+ class="hotspot-point cursor-pointer"
27
+ style={`left: ${point.x}%; top: ${point.y}%; width: 24px; height: 24px; transform: translate(-50%, -50%);`}
28
+ data-index={i}
29
+ data-map-id={mapId}
30
+ aria-label={point.title}
31
+ {...(point.isPopupOpen ? { 'data-initially-open': '' } : {})}
47
32
  />
48
- </div>
49
- </>
50
- ))}
33
+
34
+ {/* Popup content (hidden by default) */}
35
+ <div
36
+ class={cn('popup-content absolute rounded-md shadow-lg z-10 max-w-xs hidden', popupClass)}
37
+ style={`left: ${point.x}%; top: ${point.y}%; transform: translate(${point.x > 50 ? '-100%' : '0'}, ${point.y > 50 ? '-100%' : '0'});`}
38
+ data-popup={i}
39
+ data-map-id={mapId}
40
+ >
41
+ <Component
42
+ {...point}
43
+ classes={
44
+ Object.assign(
45
+ { container: 'border-transparent dark:border-input' },
46
+ classes?.card || {},
47
+ point?.classes || {}
48
+ ) as Record<string, string>
49
+ }
50
+ />
51
+ </div>
52
+ </>
53
+ ))
54
+ }
51
55
 
52
56
  <div class="w-full h-full">
53
- <slot/>
57
+ <slot />
54
58
  </div>
55
59
  </div>
56
60
 
@@ -70,7 +74,9 @@ const Component = via;
70
74
  .points-hover .hotspot-point {
71
75
  opacity: 0;
72
76
  visibility: hidden;
73
- transition: opacity 250ms ease-in-out, visibility 250ms ease-in-out;
77
+ transition:
78
+ opacity 250ms ease-in-out,
79
+ visibility 250ms ease-in-out;
74
80
  }
75
81
 
76
82
  .points-hover:hover .hotspot-point,
@@ -81,7 +87,10 @@ const Component = via;
81
87
 
82
88
  .hotspot-point {
83
89
  box-sizing: border-box;
84
- transition: border-color 250ms ease-in-out, opacity 250ms ease-in-out, visibility 250ms ease-in-out;
90
+ transition:
91
+ border-color 250ms ease-in-out,
92
+ opacity 250ms ease-in-out,
93
+ visibility 250ms ease-in-out;
85
94
  transform: translateX(-1rem) translateY(-1rem) scale(0.999);
86
95
  padding: 0;
87
96
  width: 2rem;
@@ -91,14 +100,14 @@ const Component = via;
91
100
  position: absolute;
92
101
  background-color: rgba(17, 17, 17, 0.75);
93
102
  border-radius: 64px;
94
- line-height: .5;
103
+ line-height: 0.5;
95
104
  display: flex;
96
105
  align-items: center;
97
106
  justify-content: center;
98
107
  }
99
108
 
100
109
  .hotspot-point::before {
101
- content: "";
110
+ content: '';
102
111
  position: absolute;
103
112
  top: -0.5rem;
104
113
  left: -0.5rem;
@@ -108,18 +117,19 @@ const Component = via;
108
117
  }
109
118
 
110
119
  .hotspot-point::after {
111
- content: "";
120
+ content: '';
112
121
  position: relative;
113
122
  display: block;
114
123
  background: rgb(255, 255, 255);
115
124
  box-shadow: 0 1px 4px rgba(17, 17, 17, 0.55);
116
- width: .75rem;
117
- height: .75rem;
125
+ width: 0.75rem;
126
+ height: 0.75rem;
118
127
  border-radius: 64px;
119
128
  transition: transform 250ms ease-in-out;
120
129
  }
121
130
 
122
- .hotspot-point:active, .hotspot-point:hover {
131
+ .hotspot-point:active,
132
+ .hotspot-point:hover {
123
133
  background-color: rgba(17, 17, 17, 0.9);
124
134
  }
125
135
 
@@ -139,13 +149,15 @@ const Component = via;
139
149
  const MAP_ID_ATTRIBUTE = 'data-map-id';
140
150
 
141
151
  // Initialize each map component separately
142
- document.querySelectorAll('.map-picker').forEach(mapContainer => {
152
+ document.querySelectorAll('.map-picker').forEach((mapContainer) => {
143
153
  const mapId = mapContainer.id;
144
154
  if (!mapId) return;
145
155
 
146
156
  // Get all hotspot points and popups for this specific map
147
157
  const hotspotPoints = document.querySelectorAll(`.hotspot-point[${MAP_ID_ATTRIBUTE}="${mapId}"]`);
148
- const popups = document.querySelectorAll(`.popup-content[${MAP_ID_ATTRIBUTE}="${mapId}"]`) as NodeListOf<HTMLElement>;
158
+ const popups = document.querySelectorAll(
159
+ `.popup-content[${MAP_ID_ATTRIBUTE}="${mapId}"]`
160
+ ) as NodeListOf<HTMLElement>;
149
161
 
150
162
  if (!hotspotPoints.length || !popups.length) return;
151
163
 
@@ -196,7 +208,9 @@ const Component = via;
196
208
  return;
197
209
  }
198
210
 
199
- const point = document.querySelector(`.hotspot-point[data-index="${popupIndex}"][${MAP_ID_ATTRIBUTE}="${mapId}"]`) as HTMLElement;
211
+ const point = document.querySelector(
212
+ `.hotspot-point[data-index="${popupIndex}"][${MAP_ID_ATTRIBUTE}="${mapId}"]`
213
+ ) as HTMLElement;
200
214
  if (!point) return;
201
215
  const coordinates = getPointCoordinates(point);
202
216
  const translateX = coordinates.x > 50 ? '-100%' : '0';
@@ -214,7 +228,7 @@ const Component = via;
214
228
  function getPointCoordinates(pointElement: HTMLElement): PointCoordinates {
215
229
  return {
216
230
  x: parseFloat(pointElement.style.left) || 0,
217
- y: parseFloat(pointElement.style.top) || 0
231
+ y: parseFloat(pointElement.style.top) || 0,
218
232
  };
219
233
  }
220
234
 
@@ -258,13 +272,13 @@ const Component = via;
258
272
 
259
273
  // Hide all popups (including initially open ones)
260
274
  function hideAllPopups() {
261
- popups.forEach(popup => {
275
+ popups.forEach((popup) => {
262
276
  popup.classList.add('hidden');
263
277
  });
264
278
  }
265
279
 
266
280
  // Add event listeners to hotspot points
267
- hotspotPoints.forEach(point => {
281
+ hotspotPoints.forEach((point) => {
268
282
  const index = getPointIndex(point);
269
283
  if (index === null) return;
270
284
 
@@ -1,4 +1,4 @@
1
- import type {HotspotPoint} from "../../types";
1
+ import type { HotspotPoint } from '../../types';
2
2
  import type { Snippet } from 'svelte';
3
3
 
4
4
  export type PointMapProps = {
@@ -6,7 +6,7 @@ export type PointMapProps = {
6
6
  items: HotspotPoint[];
7
7
  pointsDisplayMode?: 'always' | 'hover' | undefined; // controls visibility of hotspot points
8
8
  classes?: Record<string, string>;
9
- }
9
+ };
10
10
 
11
11
  export type SveltePointMapProps = {
12
12
  via?: any;
@@ -14,4 +14,4 @@ export type SveltePointMapProps = {
14
14
  pointsDisplayMode?: 'always' | 'hover' | undefined;
15
15
  classes?: Record<string, string>;
16
16
  children?: Snippet;
17
- }
17
+ };
@@ -65,45 +65,46 @@ const getOGLocale = (loc: string): string => {
65
65
  };
66
66
  ---
67
67
 
68
- <!-- Primary Meta Tags -->
69
- {title && <title>{title}</title>}
68
+ <!-- Primary Meta Tags -->{title && <title>{title}</title>}
70
69
  {description && <meta name="description" content={description} />}
71
70
  {canonical && <link rel="canonical" href={canonical} />}
72
71
  <meta name="robots" content={robotsContent} />
73
72
 
74
73
  <!-- Open Graph / Facebook -->
75
- {openGraph && (
76
- <>
77
- {openGraph.title && <meta property="og:title" content={openGraph.title} />}
78
- {openGraph.description && <meta property="og:description" content={openGraph.description} />}
79
- {openGraph.url && <meta property="og:url" content={openGraph.url} />}
80
- {openGraph.type && <meta property="og:type" content={openGraph.type} />}
81
- {openGraph.image && (
82
- <>
83
- <meta property="og:image" content={openGraph.image.url} />
84
- {openGraph.image.width && <meta property="og:image:width" content={openGraph.image.width.toString()} />}
85
- {openGraph.image.height && <meta property="og:image:height" content={openGraph.image.height.toString()} />}
86
- {openGraph.image.alt && <meta property="og:image:alt" content={openGraph.image.alt} />}
87
- </>
88
- )}
89
- <meta property="og:locale" content={getOGLocale(locale)} />
90
- {openGraph.siteName && <meta property="og:site_name" content={openGraph.siteName} />}
91
- </>
92
- )}
74
+ {
75
+ openGraph && (
76
+ <>
77
+ {openGraph.title && <meta property="og:title" content={openGraph.title} />}
78
+ {openGraph.description && <meta property="og:description" content={openGraph.description} />}
79
+ {openGraph.url && <meta property="og:url" content={openGraph.url} />}
80
+ {openGraph.type && <meta property="og:type" content={openGraph.type} />}
81
+ {openGraph.image && (
82
+ <>
83
+ <meta property="og:image" content={openGraph.image.url} />
84
+ {openGraph.image.width && <meta property="og:image:width" content={openGraph.image.width.toString()} />}
85
+ {openGraph.image.height && <meta property="og:image:height" content={openGraph.image.height.toString()} />}
86
+ {openGraph.image.alt && <meta property="og:image:alt" content={openGraph.image.alt} />}
87
+ </>
88
+ )}
89
+ <meta property="og:locale" content={getOGLocale(locale)} />
90
+ {openGraph.siteName && <meta property="og:site_name" content={openGraph.siteName} />}
91
+ </>
92
+ )
93
+ }
93
94
 
94
95
  <!-- Alternate Language Links (hreflang) -->
95
- {alternateLocales.map(({ locale: altLocale, url }) => (
96
- <link rel="alternate" hreflang={altLocale} href={url} />
97
- ))}
96
+ {alternateLocales.map(({ locale: altLocale, url }) => <link rel="alternate" hreflang={altLocale} href={url} />)}
98
97
 
99
98
  <!-- Twitter Card -->
100
- {twitter && (
101
- <>
102
- <meta name="twitter:card" content={twitter.card || 'summary_large_image'} />
103
- {twitter.site && <meta name="twitter:site" content={twitter.site} />}
104
- {twitter.creator && <meta name="twitter:creator" content={twitter.creator} />}
105
- {twitter.title && <meta name="twitter:title" content={twitter.title} />}
106
- {twitter.description && <meta name="twitter:description" content={twitter.description} />}
107
- {twitter.image && <meta name="twitter:image" content={twitter.image} />}
108
- </>
109
- )}
99
+ {
100
+ twitter && (
101
+ <>
102
+ <meta name="twitter:card" content={twitter.card || 'summary_large_image'} />
103
+ {twitter.site && <meta name="twitter:site" content={twitter.site} />}
104
+ {twitter.creator && <meta name="twitter:creator" content={twitter.creator} />}
105
+ {twitter.title && <meta name="twitter:title" content={twitter.title} />}
106
+ {twitter.description && <meta name="twitter:description" content={twitter.description} />}
107
+ {twitter.image && <meta name="twitter:image" content={twitter.image} />}
108
+ </>
109
+ )
110
+ }
@@ -29,7 +29,14 @@ const {
29
29
  containerClass={`${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : ''} ${classes?.container ?? ''}`}
30
30
  bg={bg}
31
31
  >
32
- <Headline title={title} subtitle={subtitle} tagline={tagline} position={position} as={asHeader} asSubtitle={asSubtitle} />
32
+ <Headline
33
+ title={title}
34
+ subtitle={subtitle}
35
+ tagline={tagline}
36
+ position={position}
37
+ as={asHeader}
38
+ asSubtitle={asSubtitle}
39
+ />
33
40
 
34
41
  <div class="flex flex-wrap justify-center gap-x-6 sm:gap-x-12 lg:gap-x-24">
35
42
  {
@@ -50,7 +50,7 @@ const {
50
50
  />
51
51
 
52
52
  <div class={`md:flex ${isReversed ? 'md:flex-row-reverse' : ''} md:gap-16`}>
53
- <div class={cn("md:basis-1/2 self-center", classes?.start ?? '')}>
53
+ <div class={cn('md:basis-1/2 self-center', classes?.start ?? '')}>
54
54
  <slot />
55
55
  {content && <div class={cn('mb-12 text-lg', classes?.content ?? '')} set:html={content} />}
56
56
 
@@ -70,21 +70,34 @@ const {
70
70
  icon={defaultIcon}
71
71
  {...item}
72
72
  classes={{
73
- container: cn('gap-0 border-0 py-0 justify-start', (classes?.items as Record<string, string>)?.container),
74
- title: cn('text-lg font-medium leading-6 dark:text-white ml-2 rtl:ml-0 rtl:mr-2', (classes?.items as Record<string, string>)?.title),
73
+ container: cn(
74
+ 'gap-0 border-0 py-0 justify-start',
75
+ (classes?.items as Record<string, string>)?.container
76
+ ),
77
+ title: cn(
78
+ 'text-lg font-medium leading-6 dark:text-white ml-2 rtl:ml-0 rtl:mr-2',
79
+ (classes?.items as Record<string, string>)?.title
80
+ ),
75
81
  description: cn('ml-2 rtl:ml-0 rtl:mr-2', (classes?.items as Record<string, string>)?.description),
76
- icon: cn('flex h-7 w-7 items-center justify-center rounded-full bg-green-600 dark:bg-green-700 text-gray-50 p-1', (classes?.items as Record<string, string>)?.icon),
82
+ icon: cn(
83
+ 'flex h-7 w-7 items-center justify-center rounded-full bg-green-600 dark:bg-green-700 text-gray-50 p-1',
84
+ (classes?.items as Record<string, string>)?.icon
85
+ ),
77
86
  }}
78
87
  />
79
88
  ))
80
89
  }
81
90
  </ItemGrid0>
82
91
  </div>
83
- <div aria-hidden="true" class={cn("mt-10 md:mt-0 md:basis-1/2", classes?.end ?? '')}>
92
+ <div aria-hidden="true" class={cn('mt-10 md:mt-0 md:basis-1/2', classes?.end ?? '')}>
84
93
  {
85
94
  image && (
86
- <div class={cn('relative m-auto max-w-4xl', classes?.image ?? '')}>
87
- <PointMap items={points} pointsDisplayMode={pointsDisplayMode} classes={{...((classes?.points as object) ?? {})}}>
95
+ <div class={cn('relative m-auto max-w-4xl', classes?.image ?? '')}>
96
+ <PointMap
97
+ items={points}
98
+ pointsDisplayMode={pointsDisplayMode}
99
+ classes={{ ...((classes?.points as object) ?? {}) }}
100
+ >
88
101
  {typeof image === 'string' ? (
89
102
  <Fragment set:html={image} />
90
103
  ) : (
@@ -97,8 +110,8 @@ const {
97
110
  {...image}
98
111
  />
99
112
  )}
100
- </PointMap>
101
- </div>
113
+ </PointMap>
114
+ </div>
102
115
  )
103
116
  }
104
117
  </div>
@@ -1,4 +1,4 @@
1
- import type {Item, HotspotPoint, ToAction} from '../../types';
1
+ import type { Item, HotspotPoint, ToAction } from '../../types';
2
2
  import type { WidgetWrapperProps, SvelteWidgetWrapperProps } from '../WidgetWrapper/types';
3
3
  import type { HeadlineProps } from '../Headline/types.ts';
4
4
  import type { Snippet } from 'svelte';
@@ -49,7 +49,7 @@ const ComponentGrid = viaGrid;
49
49
  as={asHeader}
50
50
  asSubtitle={asSubtitle}
51
51
  />
52
-
52
+
53
53
  {
54
54
  image && (
55
55
  <div aria-hidden="true" class={cn('aspect-w-16 aspect-h-7 mb-6')}>
@@ -79,6 +79,14 @@ const ComponentGrid = viaGrid;
79
79
  <slot />
80
80
 
81
81
  <ComponentGrid columns={columns} class={classes?.grid && ''}>
82
- {items && items.map((item) => <Component {...item} classes={Object.assign({}, classes?.card || {}, item?.classes || {}) as Record<string, string>}/>)}
82
+ {
83
+ items &&
84
+ items.map((item) => (
85
+ <Component
86
+ {...item}
87
+ classes={Object.assign({}, classes?.card || {}, item?.classes || {}) as Record<string, string>}
88
+ />
89
+ ))
90
+ }
83
91
  </ComponentGrid>
84
92
  </WidgetWrapper>
@@ -197,7 +197,12 @@ const {
197
197
  }
198
198
 
199
199
  <!-- Loading indicator -->
200
- <div class={cn('absolute top-0 left-0 w-full h-full flex items-center justify-center pointer-events-none', `${classes?.loading}`)}>
200
+ <div
201
+ class={cn(
202
+ 'absolute top-0 left-0 w-full h-full flex items-center justify-center pointer-events-none',
203
+ `${classes?.loading}`
204
+ )}
205
+ >
201
206
  <svg class="animate-spin h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
202
207
  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
203
208
  <path
@@ -118,8 +118,7 @@ const panelItems = links.map((link, index) => ({ link, index })).filter(({ link
118
118
  aria-expanded="false"
119
119
  class={cn('hidden md:flex px-4 py-3 items-center whitespace-nowrap cursor-pointer', linksClass)}
120
120
  >
121
- {item.text}{' '}
122
- <Icon name="tabler:chevron-down" class="w-3.5 h-3.5 ml-0.5 rtl:ml-0 rtl:mr-0.5" />
121
+ {item.text} <Icon name="tabler:chevron-down" class="w-3.5 h-3.5 ml-0.5 rtl:ml-0 rtl:mr-0.5" />
123
122
  </button>
124
123
  ) : (
125
124
  <a
@@ -140,7 +139,9 @@ const panelItems = links.map((link, index) => ({ link, index })).filter(({ link
140
139
  <div class="md:hidden">
141
140
  {hasPanel ? (
142
141
  <>
143
- <span class={cn('block px-4 py-3 text-base font-semibold uppercase tracking-wider', megaHeadingClass)}>
142
+ <span
143
+ class={cn('block px-4 py-3 text-base font-semibold uppercase tracking-wider', megaHeadingClass)}
144
+ >
144
145
  {item.text}
145
146
  </span>
146
147
  <ul class="flex flex-col pb-2">
@@ -202,7 +203,10 @@ const panelItems = links.map((link, index) => ({ link, index })).filter(({ link
202
203
  role="region"
203
204
  aria-label="Menu details"
204
205
  >
205
- <div class={cn('flyout-bg relative overflow-hidden rounded-xl border border-border', megaMenuClass)} data-flyout-bg>
206
+ <div
207
+ class={cn('flyout-bg relative overflow-hidden rounded-xl border border-border', megaMenuClass)}
208
+ data-flyout-bg
209
+ >
206
210
  {panelItems.map(({ link, index }) => (
207
211
  <div class="flyout-panel absolute top-0 left-0" data-flyout-panel data-flyout-key={index}>
208
212
  {link.mega ? (
@@ -297,9 +301,14 @@ const panelItems = links.map((link, index) => ({ link, index })).filter(({ link
297
301
  >
298
302
  <div class="items-center flex justify-between w-full md:w-auto">
299
303
  <div class="flex">
300
- {showToggleTheme && (
301
- <DarkMode initialMode={initialMode} iconClass={cn('w-6 h-6 md:w-5 md:h-5 md:inline-block', darkModeIconClass)} />
302
- )}
304
+ {
305
+ showToggleTheme && (
306
+ <DarkMode
307
+ initialMode={initialMode}
308
+ iconClass={cn('w-6 h-6 md:w-5 md:h-5 md:inline-block', darkModeIconClass)}
309
+ />
310
+ )
311
+ }
303
312
  </div>
304
313
 
305
314
  <!-- Actions Buttons -->
@@ -6,7 +6,7 @@ import SwiperSlider from '../SwiperSlider/SwiperSlider.astro';
6
6
  import { Image as AstroImage, getImage } from 'astro:assets';
7
7
  import { fetchLocalImages } from '../../utils/images';
8
8
  import { cn } from '../../utils';
9
- import Button from "../Button/Button.astro";
9
+ import Button from '../Button/Button.astro';
10
10
 
11
11
  const {
12
12
  title = await Astro.slots.render('title'),
@@ -28,7 +28,7 @@ const {
28
28
  ...rest
29
29
  } = Astro.props;
30
30
 
31
- const images = await fetchLocalImages() as Record<string, () => any>;
31
+ const images = (await fetchLocalImages()) as Record<string, () => any>;
32
32
  const imagePaths = Object.keys(images).filter((imagePath) => {
33
33
  return imagePath.startsWith(`/src/assets/images/${imagesFolder}/`);
34
34
  });
@@ -62,11 +62,19 @@ const imagePaths = Object.keys(images).filter((imagePath) => {
62
62
 
63
63
  // Generate alt text: alt prop > title-based > numbered fallback
64
64
  // Detect UUID filenames (8-4-4-4-12 hex pattern) and treat as meaningless
65
- const filename = imagePath.split('/').pop()?.replace(/\.[^/.]+$/, '') || '';
65
+ const filename =
66
+ imagePath
67
+ .split('/')
68
+ .pop()
69
+ ?.replace(/\.[^/.]+$/, '') || '';
66
70
  const isUuidFilename = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(filename);
67
71
  const imageNumber = index + 1;
68
- const imageName = (filename && !isUuidFilename) ? filename : String(imageNumber);
69
- const baseTitle = title ? String(title).replace(/<[^>]*>/g, '').trim() : '';
72
+ const imageName = filename && !isUuidFilename ? filename : String(imageNumber);
73
+ const baseTitle = title
74
+ ? String(title)
75
+ .replace(/<[^>]*>/g, '')
76
+ .trim()
77
+ : '';
70
78
  const altText = alt
71
79
  ? alt + ' - ' + imageName
72
80
  : baseTitle
@@ -90,7 +98,10 @@ const imagePaths = Object.keys(images).filter((imagePath) => {
90
98
  widths={[400, 900]}
91
99
  width={400}
92
100
  sizes="(max-width: 900px) 400px, 900px"
93
- class={cn("object-cover object-top w-full md:h-full group-hover:scale-105 transition duration-300", classes?.image)}
101
+ class={cn(
102
+ 'object-cover object-top w-full md:h-full group-hover:scale-105 transition duration-300',
103
+ classes?.image
104
+ )}
94
105
  />
95
106
  </a>
96
107
  </swiper-slide>
@@ -107,7 +118,7 @@ const imagePaths = Object.keys(images).filter((imagePath) => {
107
118
  </div>
108
119
  )
109
120
  }
110
-
121
+
111
122
  <slot />
112
123
  </WidgetWrapper>
113
124
 
@@ -30,7 +30,14 @@ const {
30
30
  containerClass={`max-w-6xl mx-auto ${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : ''} ${classes?.container ?? ''}`}
31
31
  bg={bg}
32
32
  >
33
- <Headline title={title} subtitle={subtitle} tagline={tagline} position={position} as={asHeader} asSubtitle={asSubtitle} />
33
+ <Headline
34
+ title={title}
35
+ subtitle={subtitle}
36
+ tagline={tagline}
37
+ position={position}
38
+ as={asHeader}
39
+ asSubtitle={asSubtitle}
40
+ />
34
41
 
35
42
  <ItemGrid0 columns={columns}>
36
43
  {
@@ -1,9 +1,18 @@
1
1
  ---
2
2
  import type { WidgetWrapperProps as Props } from './types';
3
3
  import Background from '../Background/Background.astro';
4
- import {cn} from "../../utils";
4
+ import { cn } from '../../utils';
5
5
 
6
- const { id, isDark = false, class: className = '', containerClass = '', bg, as = 'section', isAfterContent = false, ...rest } = Astro.props;
6
+ const {
7
+ id,
8
+ isDark = false,
9
+ class: className = '',
10
+ containerClass = '',
11
+ bg,
12
+ as = 'section',
13
+ isAfterContent = false,
14
+ ...rest
15
+ } = Astro.props;
7
16
 
8
17
  const WrapperTag = as;
9
18
  ---
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Utility Types
2
- import type {HTMLAttributes} from "astro/types";
3
- import type {ImageMetadata} from "astro";
2
+ import type { HTMLAttributes } from 'astro/types';
3
+ import type { ImageMetadata } from 'astro';
4
4
 
5
5
  export type ClassValue = ClassArray | ClassDictionary | string | number | bigint | null | boolean | undefined;
6
6
  export type ClassDictionary = Record<string, any>;
@@ -33,7 +33,7 @@ export type HotspotPoint = {
33
33
  isPopupOpen?: boolean; // whether the popup is open on initialization
34
34
  classes?: Record<string, string>;
35
35
  callToAction?: CallToAction;
36
- }
36
+ };
37
37
 
38
38
  export type Item = {
39
39
  title?: string;
@@ -51,23 +51,23 @@ export type Image = {
51
51
  aspectRatio?: string;
52
52
  class?: string;
53
53
  } & Omit<HTMLAttributes<'img'>, 'src'> & {
54
- src?: string | ImageMetadata | null;
55
- width?: string | number | null;
56
- height?: string | number | null;
57
- alt?: string | null;
58
- loading?: 'eager' | 'lazy' | null;
59
- decoding?: 'sync' | 'async' | 'auto' | null;
60
- class?: string;
61
- style?: string;
62
- srcset?: string | null;
63
- sizes?: string | null;
64
- fetchpriority?: 'high' | 'low' | 'auto' | null;
65
- layout?: Layout;
66
- widths?: number[] | null;
67
- aspectRatio?: string | number | null;
68
- objectPosition?: string;
69
- format?: string;
70
- };
54
+ src?: string | ImageMetadata | null;
55
+ width?: string | number | null;
56
+ height?: string | number | null;
57
+ alt?: string | null;
58
+ loading?: 'eager' | 'lazy' | null;
59
+ decoding?: 'sync' | 'async' | 'auto' | null;
60
+ class?: string;
61
+ style?: string;
62
+ srcset?: string | null;
63
+ sizes?: string | null;
64
+ fetchpriority?: 'high' | 'low' | 'auto' | null;
65
+ layout?: Layout;
66
+ widths?: number[] | null;
67
+ aspectRatio?: string | number | null;
68
+ objectPosition?: string;
69
+ format?: string;
70
+ };
71
71
 
72
72
  export type Testimonial = {
73
73
  title?: string;