@codesinger0/shared-components 1.1.106 → 1.1.107
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.
|
@@ -4,7 +4,8 @@ import Autoplay from 'embla-carousel-autoplay';
|
|
|
4
4
|
|
|
5
5
|
const FullscreenCarousel = ({
|
|
6
6
|
slides = [],
|
|
7
|
-
|
|
7
|
+
desktopHeight = '100vh',
|
|
8
|
+
mobileHeight = '100vh',
|
|
8
9
|
autoplay = true,
|
|
9
10
|
scrollInterval = 5000,
|
|
10
11
|
loop = true,
|
|
@@ -17,6 +18,7 @@ const FullscreenCarousel = ({
|
|
|
17
18
|
const [prevBtnEnabled, setPrevBtnEnabled] = useState(false);
|
|
18
19
|
const [nextBtnEnabled, setNextBtnEnabled] = useState(false);
|
|
19
20
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
21
|
+
const [scrollSnaps, setScrollSnaps] = useState([]);
|
|
20
22
|
|
|
21
23
|
// Embla carousel setup
|
|
22
24
|
const autoplayOptions = {
|
|
@@ -51,13 +53,14 @@ const FullscreenCarousel = ({
|
|
|
51
53
|
useEffect(() => {
|
|
52
54
|
if (!emblaApi) return;
|
|
53
55
|
onSelect();
|
|
56
|
+
setScrollSnaps(emblaApi.scrollSnapList());
|
|
54
57
|
emblaApi.on('select', onSelect);
|
|
55
58
|
emblaApi.on('reInit', onSelect);
|
|
56
59
|
}, [emblaApi, onSelect]);
|
|
57
60
|
|
|
58
61
|
if (!slides || slides.length === 0) {
|
|
59
62
|
return (
|
|
60
|
-
<div className="w-full flex items-center justify-center bg-gray-100" style={{ height }}>
|
|
63
|
+
<div className="w-full flex items-center justify-center bg-gray-100" style={{ height: desktopHeight }}>
|
|
61
64
|
<p className="text-gray-500">No slides to display</p>
|
|
62
65
|
</div>
|
|
63
66
|
);
|
|
@@ -65,17 +68,79 @@ const FullscreenCarousel = ({
|
|
|
65
68
|
|
|
66
69
|
return (
|
|
67
70
|
<div className={`fullscreen-carousel-wrapper ${className}`} {...props}>
|
|
68
|
-
<div className="fullscreen-carousel"
|
|
71
|
+
<div className="fullscreen-carousel" dir="rtl">
|
|
69
72
|
<div className="fullscreen-carousel__viewport" ref={emblaRef}>
|
|
70
73
|
<div className="fullscreen-carousel__container">
|
|
71
|
-
{slides.map((slide, index) =>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
{slides.map((slide, index) => {
|
|
75
|
+
const isSingleSlide = !slide.leftContent && !slide.rightContent;
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div key={index} className="fullscreen-carousel__slide">
|
|
79
|
+
{isSingleSlide ? (
|
|
80
|
+
/* Single Slide Mode */
|
|
81
|
+
<>
|
|
82
|
+
<div
|
|
83
|
+
className="hidden md:block w-full h-full"
|
|
84
|
+
style={{ height: desktopHeight }}
|
|
85
|
+
>
|
|
86
|
+
{slide.content}
|
|
87
|
+
</div>
|
|
88
|
+
<div
|
|
89
|
+
className="block md:hidden w-full h-full"
|
|
90
|
+
style={{ height: mobileHeight }}
|
|
91
|
+
>
|
|
92
|
+
{slide.content}
|
|
93
|
+
</div>
|
|
94
|
+
</>
|
|
95
|
+
) : (
|
|
96
|
+
<>
|
|
97
|
+
{/* Desktop Layout - Horizontal Split */}
|
|
98
|
+
<div
|
|
99
|
+
className="hidden md:grid md:grid-cols-2 w-full h-full"
|
|
100
|
+
style={{ height: desktopHeight }}
|
|
101
|
+
>
|
|
102
|
+
<div className="w-full h-full">
|
|
103
|
+
{slide.leftContent}
|
|
104
|
+
</div>
|
|
105
|
+
<div className="w-full h-full">
|
|
106
|
+
{slide.rightContent}
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
{/* Mobile Layout - Vertical Split */}
|
|
111
|
+
<div
|
|
112
|
+
className="md:hidden grid grid-rows-2 w-full h-full"
|
|
113
|
+
style={{ height: mobileHeight }}
|
|
114
|
+
>
|
|
115
|
+
<div className="w-full h-full">
|
|
116
|
+
{slide.leftContent}
|
|
117
|
+
</div>
|
|
118
|
+
<div className="w-full h-full">
|
|
119
|
+
{slide.rightContent}
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</>
|
|
123
|
+
)}
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
})}
|
|
76
127
|
</div>
|
|
77
128
|
</div>
|
|
78
129
|
|
|
130
|
+
{/* Dots indicator */}
|
|
131
|
+
{showDots && slides.length > 1 && (
|
|
132
|
+
<div className="fullscreen-carousel__dots">
|
|
133
|
+
{scrollSnaps.map((_, index) => (
|
|
134
|
+
<button
|
|
135
|
+
key={index}
|
|
136
|
+
className={`fullscreen-carousel__dot ${index === selectedIndex ? 'fullscreen-carousel__dot--selected' : ''}`}
|
|
137
|
+
onClick={() => scrollTo(index)}
|
|
138
|
+
aria-label={`Go to slide ${index + 1}`}
|
|
139
|
+
/>
|
|
140
|
+
))}
|
|
141
|
+
</div>
|
|
142
|
+
)}
|
|
143
|
+
|
|
79
144
|
{/* Navigation buttons */}
|
|
80
145
|
{showArrows && slides.length > 1 && (
|
|
81
146
|
<>
|
|
@@ -101,20 +166,6 @@ const FullscreenCarousel = ({
|
|
|
101
166
|
</button>
|
|
102
167
|
</>
|
|
103
168
|
)}
|
|
104
|
-
|
|
105
|
-
{/* Dots indicator */}
|
|
106
|
-
{showDots && slides.length > 1 && (
|
|
107
|
-
<div className="fullscreen-carousel__dots">
|
|
108
|
-
{slides.map((_, index) => (
|
|
109
|
-
<button
|
|
110
|
-
key={index}
|
|
111
|
-
className={`fullscreen-carousel__dot ${index === selectedIndex ? 'fullscreen-carousel__dot--selected' : ''}`}
|
|
112
|
-
onClick={() => scrollTo(index)}
|
|
113
|
-
aria-label={`Go to slide ${index + 1}`}
|
|
114
|
-
/>
|
|
115
|
-
))}
|
|
116
|
-
</div>
|
|
117
|
-
)}
|
|
118
169
|
</div>
|
|
119
170
|
|
|
120
171
|
{/* Styles */}
|
|
@@ -122,6 +173,7 @@ const FullscreenCarousel = ({
|
|
|
122
173
|
.fullscreen-carousel-wrapper {
|
|
123
174
|
position: relative;
|
|
124
175
|
width: 100%;
|
|
176
|
+
overflow: hidden;
|
|
125
177
|
}
|
|
126
178
|
|
|
127
179
|
.fullscreen-carousel {
|
|
@@ -132,20 +184,17 @@ const FullscreenCarousel = ({
|
|
|
132
184
|
.fullscreen-carousel__viewport {
|
|
133
185
|
overflow: hidden;
|
|
134
186
|
width: 100%;
|
|
135
|
-
height: 100%;
|
|
136
187
|
}
|
|
137
|
-
|
|
188
|
+
|
|
138
189
|
.fullscreen-carousel__container {
|
|
139
190
|
display: flex;
|
|
140
191
|
width: 100%;
|
|
141
|
-
height: 100%;
|
|
142
192
|
}
|
|
143
193
|
|
|
144
194
|
.fullscreen-carousel__slide {
|
|
145
195
|
flex: 0 0 100%;
|
|
146
196
|
min-width: 0;
|
|
147
197
|
position: relative;
|
|
148
|
-
height: 100%;
|
|
149
198
|
}
|
|
150
199
|
|
|
151
200
|
.fullscreen-carousel__button {
|
|
@@ -217,19 +266,12 @@ const FullscreenCarousel = ({
|
|
|
217
266
|
display: flex;
|
|
218
267
|
justify-content: center;
|
|
219
268
|
gap: 0.5rem;
|
|
220
|
-
|
|
269
|
+
position: absolute;
|
|
270
|
+
bottom: 2rem;
|
|
271
|
+
left: 50%;
|
|
272
|
+
transform: translateX(-50%);
|
|
221
273
|
z-index: 10;
|
|
222
274
|
}
|
|
223
|
-
|
|
224
|
-
@media (min-width: 768px) {
|
|
225
|
-
.fullscreen-carousel__dots {
|
|
226
|
-
position: absolute;
|
|
227
|
-
bottom: 2rem;
|
|
228
|
-
left: 50%;
|
|
229
|
-
transform: translateX(-50%);
|
|
230
|
-
padding: 0;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
275
|
|
|
234
276
|
.fullscreen-carousel__dot {
|
|
235
277
|
background-color: ${dotsColor};
|