@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.
- package/components/Analytics/AnalyticsGTM.astro +3 -3
- package/components/Analytics/AnalyticsGTMBody.astro +16 -12
- package/components/Analytics/AnalyticsGoogle.astro +3 -1
- package/components/BreadcrumbsItem/BreadcrumbsItem.astro +8 -1
- package/components/Button/types.ts +2 -1
- package/components/CallToAction/CallToAction.astro +1 -1
- package/components/Card0/Card0.astro +20 -32
- package/components/Card1/Card1.astro +11 -19
- package/components/Card2/Card2.astro +10 -14
- package/components/Card3/Card3.astro +15 -20
- package/components/Card4/Card4.astro +6 -2
- package/components/Card5/Card5.astro +8 -1
- package/components/Card6/Card6.astro +76 -59
- package/components/Card7/Card7.astro +27 -18
- package/components/CookieConsent/CookieConsent.astro +323 -308
- package/components/CopyToClipboard/CopyToClipboard.astro +6 -14
- package/components/CopyToClipboard/copy.ts +1 -1
- package/components/DarkMode/__tests__/DarkMode.test.ts +8 -8
- package/components/Headline/Headline.astro +4 -1
- package/components/HeroSection/HeroSection.astro +13 -16
- package/components/Image/Image.astro +1 -7
- package/components/ImageGallery/ImageGallery.astro +85 -90
- package/components/ImageGalleryIkea/ImageGalleryIkea.astro +3 -2
- package/components/ImagePreload/ImagePreload.astro +22 -20
- package/components/ItemGrid1/ItemGrid1.astro +34 -24
- package/components/Metadata/Metadata.astro +1 -5
- package/components/PointMap/PointMap.astro +62 -48
- package/components/PointMap/types.ts +3 -3
- package/components/SEO/SEO.astro +34 -33
- package/components/WidgetBrands/WidgetBrands.astro +8 -1
- package/components/WidgetContent/WidgetContent.astro +22 -9
- package/components/WidgetContent/types.ts +1 -1
- package/components/WidgetFeaturesCard/WidgetFeaturesCard.astro +10 -2
- package/components/WidgetHeroSlider/WidgetHeroSlider.astro +6 -1
- package/components/WidgetNavbarFlyout/WidgetNavbarFlyout.astro +16 -7
- package/components/WidgetSwiperPhotoSlider/WidgetSwiperPhotoSlider.astro +18 -7
- package/components/WidgetTestimonials/WidgetTestimonials.astro +8 -1
- package/components/WidgetWrapper/WidgetWrapper.astro +11 -2
- package/index.d.ts +20 -20
- package/package.json +11 -9
- package/styles/styles.css +303 -160
- package/utils/i18n.ts +2 -2
- package/utils/images.ts +0 -1
- package/utils/slugify.ts +3 -0
- package/vendor-config/config.example.yaml +0 -1
- package/vendor-config/index.ts +1 -1
- package/vendor-config/utils/loadConfig.ts +15 -18
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { CopyToClipboardProps as Props } from './types';
|
|
3
|
-
import Button from
|
|
3
|
+
import Button from '../Button/Button.astro';
|
|
4
4
|
import { Icon } from 'astro-icon/components';
|
|
5
5
|
|
|
6
|
-
const {
|
|
7
|
-
variant = 'outline',
|
|
8
|
-
size = 'icon',
|
|
9
|
-
text = '',
|
|
10
|
-
class: className = '',
|
|
11
|
-
type = 'button',
|
|
12
|
-
...rest
|
|
13
|
-
} = Astro.props;
|
|
6
|
+
const { variant = 'outline', size = 'icon', text = '', class: className = '', type = 'button', ...rest } = Astro.props;
|
|
14
7
|
---
|
|
15
8
|
|
|
16
9
|
<Button
|
|
@@ -19,7 +12,7 @@ const {
|
|
|
19
12
|
class={className}
|
|
20
13
|
variant={variant}
|
|
21
14
|
size={size}
|
|
22
|
-
{...
|
|
15
|
+
{...rest as any}
|
|
23
16
|
>
|
|
24
17
|
<span class="copy-icon">
|
|
25
18
|
<Icon name="tabler:copy" />
|
|
@@ -31,7 +24,7 @@ const {
|
|
|
31
24
|
|
|
32
25
|
<script>
|
|
33
26
|
import { on, get } from '../../utils';
|
|
34
|
-
import copyToClipboard from
|
|
27
|
+
import copyToClipboard from './copy';
|
|
35
28
|
|
|
36
29
|
declare global {
|
|
37
30
|
interface Window {
|
|
@@ -54,8 +47,8 @@ const {
|
|
|
54
47
|
const addCopyListeners = (btn: HTMLElement) => {
|
|
55
48
|
btn.addEventListener('click', (e) => {
|
|
56
49
|
e.preventDefault();
|
|
57
|
-
|
|
58
|
-
if(btn.dataset.ytCopyToClipboard) {
|
|
50
|
+
|
|
51
|
+
if (btn.dataset.ytCopyToClipboard) {
|
|
59
52
|
copyToClipboard(btn.dataset.ytCopyToClipboard);
|
|
60
53
|
|
|
61
54
|
// Show check icon
|
|
@@ -72,7 +65,6 @@ const {
|
|
|
72
65
|
checkIcon.style.display = 'none';
|
|
73
66
|
}, 3000);
|
|
74
67
|
}
|
|
75
|
-
|
|
76
68
|
}
|
|
77
69
|
});
|
|
78
70
|
};
|
|
@@ -17,7 +17,7 @@ function unsecuredCopyToClipboard(text: string) {
|
|
|
17
17
|
* Check if using HTTPS and navigator.clipboard is available
|
|
18
18
|
* Then uses standard clipboard API, otherwise uses fallback
|
|
19
19
|
*/
|
|
20
|
-
export default async function copyToClipboard
|
|
20
|
+
export default async function copyToClipboard(value: string) {
|
|
21
21
|
if (window.isSecureContext && navigator.clipboard) {
|
|
22
22
|
await navigator.clipboard.writeText(value);
|
|
23
23
|
} else {
|
|
@@ -14,10 +14,10 @@ describe('DarkMode Component', () => {
|
|
|
14
14
|
add: vi.fn(),
|
|
15
15
|
remove: vi.fn(),
|
|
16
16
|
toggle: vi.fn(),
|
|
17
|
-
contains: vi.fn().mockReturnValue(true)
|
|
18
|
-
}
|
|
17
|
+
contains: vi.fn().mockReturnValue(true),
|
|
18
|
+
},
|
|
19
19
|
},
|
|
20
|
-
writable: true
|
|
20
|
+
writable: true,
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
// Mock localStorage
|
|
@@ -25,14 +25,14 @@ describe('DarkMode Component', () => {
|
|
|
25
25
|
value: {
|
|
26
26
|
theme: null,
|
|
27
27
|
getItem: vi.fn(),
|
|
28
|
-
setItem: vi.fn()
|
|
28
|
+
setItem: vi.fn(),
|
|
29
29
|
},
|
|
30
|
-
writable: true
|
|
30
|
+
writable: true,
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
// Mock matchMedia
|
|
34
34
|
Object.defineProperty(window, 'matchMedia', {
|
|
35
|
-
value: vi.fn().mockImplementation(query => ({
|
|
35
|
+
value: vi.fn().mockImplementation((query) => ({
|
|
36
36
|
matches: false,
|
|
37
37
|
media: query,
|
|
38
38
|
onchange: null,
|
|
@@ -42,7 +42,7 @@ describe('DarkMode Component', () => {
|
|
|
42
42
|
removeEventListener: vi.fn(),
|
|
43
43
|
dispatchEvent: vi.fn(),
|
|
44
44
|
})),
|
|
45
|
-
writable: true
|
|
45
|
+
writable: true,
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// Reset darkModeInitialized
|
|
@@ -52,7 +52,7 @@ describe('DarkMode Component', () => {
|
|
|
52
52
|
// Test toggle functionality
|
|
53
53
|
it('toggles dark mode correctly', () => {
|
|
54
54
|
const root = document.documentElement;
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
// Simulate toggle
|
|
57
57
|
root.classList.toggle('dark');
|
|
58
58
|
localStorage.theme = root.classList.contains('dark') ? 'dark' : 'light';
|
|
@@ -51,7 +51,10 @@ const SubtitleTag = asSubtitle;
|
|
|
51
51
|
)}
|
|
52
52
|
|
|
53
53
|
{subtitle && (
|
|
54
|
-
<SubtitleTag
|
|
54
|
+
<SubtitleTag
|
|
55
|
+
class={cn('mt-1 md:mt-4 text-muted-foreground text-lg/6 md:text-xl', subtitleClass)}
|
|
56
|
+
set:html={subtitle}
|
|
57
|
+
/>
|
|
55
58
|
)}
|
|
56
59
|
</div>
|
|
57
60
|
)
|
|
@@ -39,14 +39,9 @@ const WrapperHeaderTag = asHeader;
|
|
|
39
39
|
const WrapperDescriptionTag = asDescription;
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
<div
|
|
43
|
-
class={cn(
|
|
44
|
-
'overflow-hidden bg-zinc-700 text-zinc-200 dark:bg-card dark:text-card-foreground',
|
|
45
|
-
containerClass
|
|
46
|
-
)}
|
|
47
|
-
>
|
|
42
|
+
<div class={cn('overflow-hidden bg-zinc-700 text-zinc-200 dark:bg-card dark:text-card-foreground', containerClass)}>
|
|
48
43
|
<div class="flex flex-col-reverse justify-between md:flex-row h-full">
|
|
49
|
-
<div class={cn(
|
|
44
|
+
<div class={cn('flex items-center justify-center', startClass)}>
|
|
50
45
|
<div class={cn('p-6 w-full h-full md:h-auto', contentClass)}>
|
|
51
46
|
{
|
|
52
47
|
title && description && (
|
|
@@ -57,7 +52,9 @@ const WrapperDescriptionTag = asDescription;
|
|
|
57
52
|
>
|
|
58
53
|
{title}
|
|
59
54
|
</WrapperHeaderTag>
|
|
60
|
-
<WrapperDescriptionTag class={cn('text-sm md:text-base xl:text-lg', descriptionClass)}>
|
|
55
|
+
<WrapperDescriptionTag class={cn('text-sm md:text-base xl:text-lg', descriptionClass)}>
|
|
56
|
+
{description}
|
|
57
|
+
</WrapperDescriptionTag>
|
|
61
58
|
</div>
|
|
62
59
|
|
|
63
60
|
{callToAction && (
|
|
@@ -77,7 +74,7 @@ const WrapperDescriptionTag = asDescription;
|
|
|
77
74
|
{typeof callToAction === 'string' ? (
|
|
78
75
|
<Fragment set:html={callToAction} />
|
|
79
76
|
) : (
|
|
80
|
-
<Button {...(callToAction as
|
|
77
|
+
<Button {...(callToAction as object)} class="w-full sm:mb-0" />
|
|
81
78
|
)}
|
|
82
79
|
</Fragment>
|
|
83
80
|
)}
|
|
@@ -90,7 +87,7 @@ const WrapperDescriptionTag = asDescription;
|
|
|
90
87
|
<slot />
|
|
91
88
|
</div>
|
|
92
89
|
</div>
|
|
93
|
-
<div class={cn(
|
|
90
|
+
<div class={cn('md:h-auto', endClass)}>
|
|
94
91
|
{
|
|
95
92
|
image && (
|
|
96
93
|
<Fragment>
|
|
@@ -106,9 +103,9 @@ const WrapperDescriptionTag = asDescription;
|
|
|
106
103
|
height={1080}
|
|
107
104
|
sizes="(max-width: 768px) 100vw, 60vw"
|
|
108
105
|
layout="cover"
|
|
109
|
-
loading={isFirstSlide ?
|
|
110
|
-
fetchpriority={isFirstSlide ?
|
|
111
|
-
decoding={isFirstSlide ?
|
|
106
|
+
loading={isFirstSlide ? 'eager' : 'lazy'}
|
|
107
|
+
fetchpriority={isFirstSlide ? 'high' : undefined}
|
|
108
|
+
decoding={isFirstSlide ? 'sync' : 'async'}
|
|
112
109
|
{...image}
|
|
113
110
|
/>
|
|
114
111
|
)}
|
|
@@ -125,9 +122,9 @@ const WrapperDescriptionTag = asDescription;
|
|
|
125
122
|
height={1080}
|
|
126
123
|
sizes="(max-width: 768px) 100vw, 60vw"
|
|
127
124
|
layout="cover"
|
|
128
|
-
loading={isFirstSlide ?
|
|
129
|
-
fetchpriority={isFirstSlide ?
|
|
130
|
-
decoding={isFirstSlide ?
|
|
125
|
+
loading={isFirstSlide ? 'eager' : 'lazy'}
|
|
126
|
+
fetchpriority={isFirstSlide ? 'high' : undefined}
|
|
127
|
+
decoding={isFirstSlide ? 'sync' : 'async'}
|
|
131
128
|
{...image}
|
|
132
129
|
/>
|
|
133
130
|
)}
|
|
@@ -22,104 +22,99 @@ const hasBadgeBottomRight = Astro.slots.has('badgeBottomRight');
|
|
|
22
22
|
const hasBadgeBottomLeft = Astro.slots.has('badgeBottomLeft');
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
{
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
{hasBadgeBottomLeft && (
|
|
35
|
-
<div class="absolute z-30 bottom-2 left-2">
|
|
36
|
-
<slot name="badgeBottomLeft" />
|
|
37
|
-
</div>
|
|
38
|
-
)}
|
|
39
|
-
|
|
40
|
-
{hasMultipleImages ? (
|
|
41
|
-
/* Multi-image gallery with hover zones */
|
|
42
|
-
<div class="image-gallery-multi relative w-full h-full" data-image-count={images.length}>
|
|
43
|
-
{/* All images stacked, first visible by default */}
|
|
44
|
-
{images.map((img, index) => (
|
|
45
|
-
<div
|
|
46
|
-
class={cn(
|
|
47
|
-
'image-gallery-item absolute inset-0 transition-opacity duration-200',
|
|
48
|
-
index === 0 ? 'opacity-100' : 'opacity-0'
|
|
49
|
-
)}
|
|
50
|
-
data-index={index}
|
|
51
|
-
>
|
|
52
|
-
{typeof img === 'string' ? (
|
|
53
|
-
<Fragment set:html={img} />
|
|
54
|
-
) : (
|
|
55
|
-
<Image
|
|
56
|
-
class={cn(
|
|
57
|
-
'w-full h-full',
|
|
58
|
-
imageClass,
|
|
59
|
-
hoverEffect && 'group-hover:scale-105 transition duration-300'
|
|
60
|
-
)}
|
|
61
|
-
widths={widths}
|
|
62
|
-
width={width}
|
|
63
|
-
height={height}
|
|
64
|
-
sizes={sizes}
|
|
65
|
-
layout={imageLayout}
|
|
66
|
-
loading={index === 0 ? 'eager' : 'lazy'}
|
|
67
|
-
decoding="async"
|
|
68
|
-
{...img}
|
|
69
|
-
/>
|
|
70
|
-
)}
|
|
71
|
-
</div>
|
|
72
|
-
))}
|
|
25
|
+
{
|
|
26
|
+
images.length > 0 && (
|
|
27
|
+
<div class={cn('image-gallery relative w-full h-full', className)}>
|
|
28
|
+
{/* Badge slots */}
|
|
29
|
+
{hasBadgeBottomRight && (
|
|
30
|
+
<div class="absolute z-30 bottom-2 right-2">
|
|
31
|
+
<slot name="badgeBottomRight" />
|
|
32
|
+
</div>
|
|
33
|
+
)}
|
|
73
34
|
|
|
74
|
-
|
|
75
|
-
<div class="absolute
|
|
76
|
-
|
|
77
|
-
<div
|
|
78
|
-
class="image-gallery-zone flex-1 h-full cursor-pointer"
|
|
79
|
-
data-zone={index}
|
|
80
|
-
/>
|
|
81
|
-
))}
|
|
35
|
+
{hasBadgeBottomLeft && (
|
|
36
|
+
<div class="absolute z-30 bottom-2 left-2">
|
|
37
|
+
<slot name="badgeBottomLeft" />
|
|
82
38
|
</div>
|
|
39
|
+
)}
|
|
83
40
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
41
|
+
{hasMultipleImages ? (
|
|
42
|
+
/* Multi-image gallery with hover zones */
|
|
43
|
+
<div class="image-gallery-multi relative w-full h-full" data-image-count={images.length}>
|
|
44
|
+
{/* All images stacked, first visible by default */}
|
|
45
|
+
{images.map((img, index) => (
|
|
87
46
|
<div
|
|
88
47
|
class={cn(
|
|
89
|
-
'image-gallery-
|
|
90
|
-
index === 0 ? '
|
|
48
|
+
'image-gallery-item absolute inset-0 transition-opacity duration-200',
|
|
49
|
+
index === 0 ? 'opacity-100' : 'opacity-0'
|
|
91
50
|
)}
|
|
92
|
-
data-
|
|
93
|
-
|
|
51
|
+
data-index={index}
|
|
52
|
+
>
|
|
53
|
+
{typeof img === 'string' ? (
|
|
54
|
+
<Fragment set:html={img} />
|
|
55
|
+
) : (
|
|
56
|
+
<Image
|
|
57
|
+
class={cn(
|
|
58
|
+
'w-full h-full',
|
|
59
|
+
imageClass,
|
|
60
|
+
hoverEffect && 'group-hover:scale-105 transition duration-300'
|
|
61
|
+
)}
|
|
62
|
+
widths={widths}
|
|
63
|
+
width={width}
|
|
64
|
+
height={height}
|
|
65
|
+
sizes={sizes}
|
|
66
|
+
layout={imageLayout}
|
|
67
|
+
loading={index === 0 ? 'eager' : 'lazy'}
|
|
68
|
+
decoding="async"
|
|
69
|
+
{...img}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
</div>
|
|
94
73
|
))}
|
|
74
|
+
|
|
75
|
+
{/* Invisible hover zones */}
|
|
76
|
+
<div class="absolute inset-0 flex z-20">
|
|
77
|
+
{images.map((_, index) => (
|
|
78
|
+
<div class="image-gallery-zone flex-1 h-full cursor-pointer" data-zone={index} />
|
|
79
|
+
))}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
{/* Indicator dots */}
|
|
83
|
+
<div class="absolute bottom-2 left-1/2 -translate-x-1/2 flex gap-1 z-10">
|
|
84
|
+
{images.map((_, index) => (
|
|
85
|
+
<div
|
|
86
|
+
class={cn(
|
|
87
|
+
'image-gallery-indicator w-1.5 h-1.5 rounded-full transition-all duration-200',
|
|
88
|
+
index === 0 ? 'bg-white' : 'bg-white/50'
|
|
89
|
+
)}
|
|
90
|
+
data-indicator={index}
|
|
91
|
+
/>
|
|
92
|
+
))}
|
|
93
|
+
</div>
|
|
95
94
|
</div>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
</Fragment>
|
|
120
|
-
)}
|
|
121
|
-
</div>
|
|
122
|
-
)}
|
|
95
|
+
) : (
|
|
96
|
+
/* Single image */
|
|
97
|
+
<Fragment>
|
|
98
|
+
{typeof images[0] === 'string' ? (
|
|
99
|
+
<Fragment set:html={images[0]} />
|
|
100
|
+
) : (
|
|
101
|
+
<Image
|
|
102
|
+
class={cn('w-full h-full', imageClass, hoverEffect && 'group-hover:scale-105 transition duration-300')}
|
|
103
|
+
widths={widths}
|
|
104
|
+
width={width}
|
|
105
|
+
height={height}
|
|
106
|
+
sizes={sizes}
|
|
107
|
+
layout={imageLayout}
|
|
108
|
+
loading="lazy"
|
|
109
|
+
decoding="async"
|
|
110
|
+
{...images[0]}
|
|
111
|
+
/>
|
|
112
|
+
)}
|
|
113
|
+
</Fragment>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
123
118
|
|
|
124
119
|
<script>
|
|
125
120
|
function initImageGalleries() {
|
|
@@ -38,7 +38,9 @@ const { container: containerClass = '', swiper: swiperClass = '', swiperThumb: s
|
|
|
38
38
|
|
|
39
39
|
/* Loading spinner animation */
|
|
40
40
|
@keyframes gallery-spin {
|
|
41
|
-
to {
|
|
41
|
+
to {
|
|
42
|
+
transform: rotate(360deg);
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
45
|
.gallery-spinner {
|
|
44
46
|
animation: gallery-spin 1s linear infinite;
|
|
@@ -83,7 +85,6 @@ const { container: containerClass = '', swiper: swiperClass = '', swiperThumb: s
|
|
|
83
85
|
prevEl: `#btn-prev-${id}`,
|
|
84
86
|
})
|
|
85
87
|
: false}
|
|
86
|
-
})}
|
|
87
88
|
>
|
|
88
89
|
{
|
|
89
90
|
images &&
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
* />
|
|
14
14
|
*/
|
|
15
15
|
import { findImage } from '../../utils/images';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
astroAsseetsOptimizer,
|
|
18
|
+
getImagesOptimized,
|
|
19
|
+
isUnpicCompatible,
|
|
20
|
+
unpicOptimizer,
|
|
21
|
+
} from '../../utils/images-optimization';
|
|
17
22
|
import type { ImageProps } from '../../utils/images-optimization';
|
|
18
23
|
|
|
19
24
|
interface Props {
|
|
@@ -31,7 +36,7 @@ const {
|
|
|
31
36
|
widths = [400, 600],
|
|
32
37
|
width = 600,
|
|
33
38
|
height = 400,
|
|
34
|
-
fetchpriority = 'high'
|
|
39
|
+
fetchpriority = 'high',
|
|
35
40
|
} = Astro.props;
|
|
36
41
|
|
|
37
42
|
const _image = await findImage(src);
|
|
@@ -62,25 +67,22 @@ if (_image) {
|
|
|
62
67
|
|
|
63
68
|
if (image) {
|
|
64
69
|
imageSrc = image.src;
|
|
65
|
-
imageSrcset = image.attributes.srcset as string || '';
|
|
70
|
+
imageSrcset = (image.attributes.srcset as string) || '';
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
73
|
---
|
|
69
74
|
|
|
70
|
-
{
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
rel="preload"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
fetchpriority={fetchpriority}
|
|
85
|
-
/>
|
|
86
|
-
) : null}
|
|
75
|
+
{
|
|
76
|
+
imageSrcset ? (
|
|
77
|
+
<link
|
|
78
|
+
rel="preload"
|
|
79
|
+
as="image"
|
|
80
|
+
href={imageSrc}
|
|
81
|
+
imagesrcset={imageSrcset}
|
|
82
|
+
imagesizes={sizes}
|
|
83
|
+
fetchpriority={fetchpriority}
|
|
84
|
+
/>
|
|
85
|
+
) : imageSrc ? (
|
|
86
|
+
<link rel="preload" as="image" href={imageSrc} fetchpriority={fetchpriority} />
|
|
87
|
+
) : null
|
|
88
|
+
}
|
|
@@ -1,64 +1,74 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { ItemGrid1Props as Props } from './types';
|
|
3
3
|
|
|
4
|
-
import {cn} from
|
|
4
|
+
import { cn } from '../../utils';
|
|
5
5
|
|
|
6
6
|
const { class: classNames } = Astro.props;
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
<style is:global>
|
|
10
|
-
.item-grid > :nth-child(1) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.item-grid > :nth-child(
|
|
14
|
-
|
|
10
|
+
.item-grid > :nth-child(1) {
|
|
11
|
+
grid-area: a;
|
|
12
|
+
}
|
|
13
|
+
.item-grid > :nth-child(2) {
|
|
14
|
+
grid-area: b;
|
|
15
|
+
}
|
|
16
|
+
.item-grid > :nth-child(3) {
|
|
17
|
+
grid-area: c;
|
|
18
|
+
}
|
|
19
|
+
.item-grid > :nth-child(4) {
|
|
20
|
+
grid-area: d;
|
|
21
|
+
}
|
|
22
|
+
.item-grid > :nth-child(5) {
|
|
23
|
+
grid-area: e;
|
|
24
|
+
}
|
|
15
25
|
|
|
16
26
|
/* Dynamic grid layouts based on number of children */
|
|
17
|
-
.item-grid:has(
|
|
18
|
-
grid-template-areas:
|
|
27
|
+
.item-grid:has(> :nth-child(4):last-child) {
|
|
28
|
+
grid-template-areas: 'a a' 'b c' 'd d';
|
|
19
29
|
}
|
|
20
30
|
|
|
21
31
|
@media screen and (min-width: 56.25em) {
|
|
22
|
-
.item-grid:has(
|
|
23
|
-
grid-template-areas:
|
|
32
|
+
.item-grid:has(> :nth-child(4):last-child) {
|
|
33
|
+
grid-template-areas: 'a a b c' 'a a d d';
|
|
24
34
|
}
|
|
25
35
|
}
|
|
26
36
|
/* 5 items */
|
|
27
|
-
.item-grid:has(
|
|
28
|
-
grid-template-areas:
|
|
37
|
+
.item-grid:has(> :nth-child(5):last-child) {
|
|
38
|
+
grid-template-areas: 'a a' 'b c' 'd c' 'd e';
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
@media screen and (min-width: 56.25em) {
|
|
32
|
-
.item-grid:has(
|
|
33
|
-
grid-template-areas:
|
|
42
|
+
.item-grid:has(> :nth-child(5):last-child) {
|
|
43
|
+
grid-template-areas: 'a a b c' 'a a d c' 'a a d e';
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
|
37
47
|
/* 3 items */
|
|
38
|
-
.item-grid:has(
|
|
39
|
-
grid-template-areas:
|
|
48
|
+
.item-grid:has(> :nth-child(3):last-child) {
|
|
49
|
+
grid-template-areas: 'a a' 'b c';
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
@media screen and (min-width: 56.25em) {
|
|
43
|
-
.item-grid:has(
|
|
44
|
-
grid-template-areas:
|
|
53
|
+
.item-grid:has(> :nth-child(3):last-child) {
|
|
54
|
+
grid-template-areas: 'a a b b' 'a a c c';
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
57
|
|
|
48
58
|
/* 2 items */
|
|
49
|
-
.item-grid:has(
|
|
50
|
-
grid-template-areas:
|
|
59
|
+
.item-grid:has(> :nth-child(2):last-child) {
|
|
60
|
+
grid-template-areas: 'a' 'b';
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
@media screen and (min-width: 56.25em) {
|
|
54
|
-
.item-grid:has(
|
|
55
|
-
grid-template-areas:
|
|
64
|
+
.item-grid:has(> :nth-child(2):last-child) {
|
|
65
|
+
grid-template-areas: 'a b';
|
|
56
66
|
}
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
/* 1 item */
|
|
60
|
-
.item-grid:has(
|
|
61
|
-
grid-template-areas:
|
|
70
|
+
.item-grid:has(> :nth-child(1):last-child) {
|
|
71
|
+
grid-template-areas: 'a';
|
|
62
72
|
}
|
|
63
73
|
</style>
|
|
64
74
|
|
|
@@ -47,11 +47,7 @@ const alternateLocales = alternateUrls
|
|
|
47
47
|
locale: lang,
|
|
48
48
|
url: alternateUrls[lang],
|
|
49
49
|
}))
|
|
50
|
-
.concat(
|
|
51
|
-
alternateUrls[defaultLocale]
|
|
52
|
-
? [{ locale: 'x-default', url: alternateUrls[defaultLocale] }]
|
|
53
|
-
: []
|
|
54
|
-
)
|
|
50
|
+
.concat(alternateUrls[defaultLocale] ? [{ locale: 'x-default', url: alternateUrls[defaultLocale] }] : [])
|
|
55
51
|
: supportedLocales
|
|
56
52
|
.map((lang) => {
|
|
57
53
|
// Replace current locale with target locale and ensure trailing slash
|