Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/components/Carousel.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
const { items, class: className } = Astro.props;
---

<div class:list={["carousel", "slide", className]}>
<ol class="carousel-indicators">
{items.map((_, i) => <li class={i === 0 ? "active" : undefined}></li>)}
</ol>
<div class="carousel-inner">
{
items.map((item, i) => (
<div class:list={["carousel-item", { active: i === 0 }]}>
<img
class="d-block w-100"
src={item.src}
alt={item.header}
loading="lazy"
/>
<div class="carousel-caption d-none d-md-block mb-4">
<h3>{item.header}</h3>
</div>
</div>
))
}
</div>
<button
type="button"
class="carousel-control-prev border-0 bg-transparent"
data-slide="prev"
>
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</button>
<button
type="button"
class="carousel-control-next border-0 bg-transparent"
data-slide="next"
>
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</button>
</div>

<script>
// Bootstrap's carousel JS needs jQuery, which the site does not load. Its CSS
// has all the styling and transitions, so this script only swaps the classes.
function setupCarousel(carousel: Element) {
const items = Array.from(carousel.querySelectorAll(".carousel-item"));
const indicators = Array.from(
carousel.querySelectorAll(".carousel-indicators li"),
);
let current = items.findIndex((item) => item.classList.contains("active"));
let sliding = false;

function goTo(index: number, direction: "prev" | "next") {
const target = (index + items.length) % items.length;
if (sliding || target === current) return;
sliding = true;

const active = items[current];
const incoming = items[target];
const orderClass =
direction === "next" ? "carousel-item-next" : "carousel-item-prev";
const moveClass =
direction === "next" ? "carousel-item-left" : "carousel-item-right";

incoming.classList.add(orderClass);
void (incoming as HTMLElement).offsetHeight; // reflow so the transition animates
active.classList.add(moveClass);
incoming.classList.add(moveClass);
indicators[current].classList.remove("active");
indicators[target].classList.add("active");

let finished = false;
const finish = () => {
if (finished) return;
finished = true;
incoming.classList.remove(orderClass, moveClass);
incoming.classList.add("active");
active.classList.remove("active", moveClass);
current = target;
sliding = false;
};
active.addEventListener("transitionend", finish, { once: true });
setTimeout(finish, 700); // transitionend never fires under prefers-reduced-motion
}

carousel
.querySelector('[data-slide="prev"]')
?.addEventListener("click", () => goTo(current - 1, "prev"));
carousel
.querySelector('[data-slide="next"]')
?.addEventListener("click", () => goTo(current + 1, "next"));
indicators.forEach((indicator, i) =>
indicator.addEventListener("click", () =>
goTo(i, i > current ? "next" : "prev"),
),
);
}

document.querySelectorAll(".carousel").forEach(setupCarousel);
</script>
19 changes: 9 additions & 10 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import Layout from "../layouts/Layout.astro";
import InlineEditor from "../components/InlineEditor.astro";
import Carousel from "../components/Carousel.astro";
import {
httpExample,
adtExample,
Expand All @@ -22,6 +23,13 @@ import {
datalogExample,
latticeExample,
} from "../lib/indexExamples.js";

const vscodeSlides = [
{ src: "/images/vscode1.png", header: "Semantic Highlighting" },
{ src: "/images/vscode2.png", header: "Hover to Inspect" },
{ src: "/images/vscode3.png", header: "Highlight References" },
{ src: "/images/vscode4.png", header: "Inline Errors" },
];
---

<Layout title="The Flix Programming Language">
Expand Down Expand Up @@ -798,16 +806,7 @@ import {
</ul>
</div>

<!-- TODO add the rest of images (we need to find a good carousel replacement for Astro) -->
<div class="mt-3 ml-4 mr-4 carousel slide">
<div class="carousel-inner">
<div class="carousel-item active"><img class="d-block w-100" src="/images/vscode1.png" loading="lazy">
<div class="carousel-caption d-none d-md-block mb-4">
<h3>Semantic Highlighting</h3>
</div>
</div>
</div>
</div>
<Carousel items={vscodeSlides} class="mt-3 ml-4 mr-4" />
</div>

<hr class="mb-4" />
Expand Down
Loading