84 lines
2.1 KiB
Plaintext
84 lines
2.1 KiB
Plaintext
---
|
|
import { slugify } from "../utils";
|
|
interface Props {
|
|
title: string;
|
|
hasBorder?: boolean;
|
|
}
|
|
|
|
const { title, hasBorder } = Astro.props;
|
|
---
|
|
|
|
<astro-section id={slugify(title)} class="group">
|
|
<abbr title="Press to open">
|
|
<h2
|
|
class="text-lg md:text-xl text-white lowercase transition-colors opacity-60 hover:text-secondary hover:cursor-pointer hover:opacity-80 group-[.open]:text-secondary group-[.open]:underline group-[.open]:opacity-100"
|
|
>
|
|
{title}
|
|
</h2>
|
|
</abbr>
|
|
|
|
<div
|
|
class={`text-white h-full max-h-0 overflow-hidden transition-max-height duration-300 ease-in-out ${
|
|
hasBorder ? "md:border-l-4 md:pl-4" : ""
|
|
}`}
|
|
>
|
|
<slot />
|
|
</div>
|
|
</astro-section>
|
|
|
|
<script>
|
|
class Section extends HTMLElement {
|
|
container: HTMLElement;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
const container = this.querySelector("div");
|
|
if (!container) {
|
|
throw new Error("No container found");
|
|
}
|
|
|
|
this.container = container;
|
|
|
|
const trigger = this.querySelector("h2");
|
|
|
|
if (!trigger) {
|
|
throw new Error("No trigger found");
|
|
}
|
|
|
|
trigger.addEventListener("click", () => {
|
|
// Close all other sections
|
|
document
|
|
.querySelectorAll(`astro-section:not(#${this.id})`)
|
|
.forEach((section) => {
|
|
const container = section.querySelector("div");
|
|
if (!container) {
|
|
throw new Error("No container found");
|
|
}
|
|
|
|
this.collapse(section, container);
|
|
});
|
|
|
|
// Check if the section is open
|
|
if (this.classList.contains("open")) {
|
|
this.collapse(this, this.container);
|
|
} else {
|
|
this.extend(this, this.container);
|
|
}
|
|
});
|
|
}
|
|
|
|
extend(section: Element, container: HTMLElement) {
|
|
container.style.maxHeight = "1000vh";
|
|
section.classList.add("open");
|
|
}
|
|
|
|
collapse(section: Element, container: HTMLElement) {
|
|
container.style.maxHeight = "0";
|
|
section.classList.remove("open");
|
|
}
|
|
}
|
|
|
|
customElements.define("astro-section", Section);
|
|
</script>
|