Skip to content

Commit 5e6e2eb

Browse files
committed
feat: enhance carousel functionality and styling for mobile responsiveness
1 parent e0c76ca commit 5e6e2eb

File tree

3 files changed

+97
-18
lines changed

3 files changed

+97
-18
lines changed

index.html

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,29 @@ <h3>bungate</h3>
210210
<span>TypeScript</span>
211211
<button class="copy-btn" aria-label="Copy code">Copy</button>
212212
</div>
213-
<pre><code><span class="k">import</span> { Gateway } <span class="k">from</span> <span class="s">'bungate'</span>;
213+
<pre><code><span class="k">import</span> { BunGateway } <span class="k">from</span> <span class="s">'bungate'</span>;
214214

215-
<span class="k">const</span> gateway = <span class="k">new</span> <span class="f">Gateway</span>({
216-
routes: [{
217-
prefix: <span class="s">'/api'</span>,
218-
target: <span class="s">'http://localhost:3000'</span>
219-
}]
215+
<span class="k">const</span> gateway = <span class="k">new</span> <span class="f">BunGateway</span>({
216+
server: { port: <span class="n">3000</span> },
217+
metrics: { enabled: <span class="k">true</span> },
218+
});
219+
220+
gateway.<span class="f">addRoute</span>({
221+
pattern: <span class="s">'/api/*'</span>,
222+
loadBalancer: {
223+
strategy: <span class="s">'least-connections'</span>,
224+
targets: [
225+
{ url: <span class="s">'http://api1.example.com'</span> },
226+
{ url: <span class="s">'http://api2.example.com'</span> },
227+
{ url: <span class="s">'http://api3.example.com'</span> },
228+
],
229+
healthCheck: { enabled: <span class="k">true</span>, interval: <span class="n">30000</span>, path: <span class="s">'/health'</span> },
230+
},
220231
});
221232

222-
gateway.<span class="f">start</span>(<span class="n">8080</span>);</code></pre>
233+
<span class="k">await</span> gateway.<span class="f">listen</span>();
234+
<span class="k">console</span>.<span class="f">log</span>(<span class="s">'🚀 Bungate running on http://localhost:3000'</span>);
235+
</code></pre>
223236
</div>
224237
</article>
225238

script.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,18 @@ document.addEventListener("DOMContentLoaded", () => {
285285
const dynamicGap = gap;
286286
const totalSlidesDynamic = Math.ceil(cards.length / cardsPerView);
287287
const offsetPx = currentSlide * cardsPerView * (dynamicCardWidth + dynamicGap);
288-
carousel.style.transform = `translateX(-${offsetPx}px)`;
288+
// On mobile (single card view), scroll the container; on desktop use transform
289+
if (window.innerWidth <= 768) {
290+
const cardScrollPosition = currentSlide * dynamicCardWidth;
291+
try {
292+
carouselContainer.scrollTo({ left: cardScrollPosition, behavior: "smooth" });
293+
} catch (e) {
294+
carouselContainer.scrollLeft = cardScrollPosition;
295+
}
296+
carousel.style.transform = "";
297+
} else {
298+
carousel.style.transform = `translateX(-${offsetPx}px)`;
299+
}
289300

290301
// Update dots
291302
document.querySelectorAll(".carousel-dot").forEach((dot, index) => {
@@ -317,17 +328,13 @@ document.addEventListener("DOMContentLoaded", () => {
317328
}
318329

319330
prevBtn.addEventListener("click", () => {
320-
if (currentSlide > 0) {
321-
currentSlide--;
322-
updateCarousel();
323-
}
331+
currentSlide = Math.max(0, currentSlide - 1);
332+
updateCarousel();
324333
});
325334

326335
nextBtn.addEventListener("click", () => {
327-
if (currentSlide < totalSlides - 1) {
328-
currentSlide++;
329-
updateCarousel();
330-
}
336+
currentSlide = currentSlide + 1;
337+
updateCarousel();
331338
});
332339

333340
// Handle window resize
@@ -340,6 +347,25 @@ document.addEventListener("DOMContentLoaded", () => {
340347
}, 250);
341348
});
342349

350+
// Sync current slide when user scrolls the container (mobile touch scrolling)
351+
if (window.innerWidth <= 768) {
352+
let scrollTimeout;
353+
carouselContainer.addEventListener("scroll", () => {
354+
clearTimeout(scrollTimeout);
355+
scrollTimeout = setTimeout(() => {
356+
const dynamicCardWidth = cards[0] && cards[0].offsetWidth ? cards[0].offsetWidth : cardWidth;
357+
const scrolled = Math.round(carouselContainer.scrollLeft / dynamicCardWidth);
358+
if (scrolled !== currentSlide && scrolled < cards.length) {
359+
currentSlide = scrolled;
360+
// Update dots only, don't trigger updateCarousel to avoid loop
361+
document.querySelectorAll(".carousel-dot").forEach((dot, index) => {
362+
dot.classList.toggle("active", index === currentSlide);
363+
});
364+
}
365+
}, 150);
366+
});
367+
}
368+
343369
updateCarousel();
344370
console.log(`Carousel initialized. cards=${cards.length}`, { cardsPerView, totalSlides });
345371
}

styles.css

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,13 @@ ul {
296296
gap: 16px;
297297
}
298298

299+
@media (max-width: 768px) {
300+
.carousel-wrapper {
301+
position: relative;
302+
display: block;
303+
}
304+
}
305+
299306
.carousel-container {
300307
flex: 1;
301308
overflow: hidden;
@@ -752,17 +759,45 @@ ul {
752759
}
753760

754761
.carousel-btn {
755-
display: none;
762+
display: flex;
763+
position: absolute;
764+
top: 50%;
765+
transform: translateY(-50%);
766+
width: 48px;
767+
height: 48px;
768+
box-shadow: var(--shadow-lg);
769+
z-index: 20;
770+
}
771+
772+
.carousel-prev {
773+
left: 8px;
774+
}
775+
776+
.carousel-next {
777+
right: 8px;
756778
}
757779

758780
.carousel-container {
759781
overflow-x: auto;
760782
scroll-snap-type: x mandatory;
761783
-webkit-overflow-scrolling: touch;
784+
scrollbar-width: none;
785+
-ms-overflow-style: none;
786+
}
787+
788+
.carousel-container::-webkit-scrollbar {
789+
display: none;
762790
}
763791

764792
.carousel-track {
765-
scroll-snap-align: start;
793+
display: flex;
794+
gap: 16px;
795+
padding: 0 16px;
796+
}
797+
798+
.carousel-track .blog-card {
799+
flex: 0 0 calc(100% - 32px);
800+
scroll-snap-align: center;
766801
}
767802

768803
.blog-carousel {
@@ -779,4 +814,9 @@ ul {
779814
flex-direction: column;
780815
gap: 12px;
781816
}
817+
.carousel-dot {
818+
min-width: 24px;
819+
min-height: 24px;
820+
padding: 4px;
821+
}
782822
}

0 commit comments

Comments
 (0)