Fix features open and close + rework animation to be more pog

This commit is contained in:
ferrreo 2023-06-28 20:34:05 +01:00
parent 5eb78d7a66
commit 6908ae5bb5

View File

@ -6,12 +6,18 @@ type Props = {
const { title, description } = Astro.props; const { title, description } = Astro.props;
--- ---
<accordion-widget class="w-full rounded-lg border block overflow-hidden closed transition-height duration-200 relative px-2 py-2 dark:bg-slate-800"> <accordion-widget
<button class="w-full text-center md:text-start accordion flex flex-row gap-x-1 py-1 justify-between items-center"> class="w-full rounded-lg border block overflow-hidden transition-height duration-200 relative px-2 py-2 dark:bg-slate-800"
>
<button
class="w-full text-center md:text-start accordion flex flex-row gap-x-1 py-1 justify-between items-center"
>
<h3 class="hed w-full font-bold pointer-events-none"> <h3 class="hed w-full font-bold pointer-events-none">
{title} {title}
</h3> </h3>
<div class="chev pointer-events-none transition-transform duration-200 shrink-0 h-4 w-4"> <div
class="chev pointer-events-none transition-transform duration-200 shrink-0 h-4 w-4"
>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="shrink md:h-4 fill-slate-800 dark:fill-white transition-transform duration-500 ease-in-out pointer-events-none" class="shrink md:h-4 fill-slate-800 dark:fill-white transition-transform duration-500 ease-in-out pointer-events-none"
@ -23,32 +29,56 @@ const { title, description } = Astro.props;
> >
</div> </div>
</button> </button>
<p style="top: 50px" class="text-center md:text-start absolute pointer-events-none"> <p class="text-center md:text-start absolute pointer-events-none">
{description} {description}
</p> </p>
</accordion-widget> </accordion-widget>
<script> <script>
class AccordionWidget extends HTMLElement { class AccordionWidget extends HTMLElement {
top: HTMLElement;
bottom: HTMLElement;
chev: HTMLElement;
padding = 22;
topPadding = 15;
constructor() { constructor() {
super(); super();
this.addEventListener("click", (event) => { this.top = this.querySelector(".accordion") || new HTMLElement();
const target = event.target as HTMLElement; this.bottom = this.querySelector("p") || new HTMLElement();
const parent = target.parentNode as HTMLElement; this.chev = this.top.querySelector(".chev") || new HTMLElement();
const next = target.nextElementSibling as HTMLElement; this.addEventListener("click", () => {
const nextHeight = next.getBoundingClientRect().height; this.toggleOpen();
parent.style.height = parent.style.height ? "" : 58 + nextHeight + "px"; });
parent.classList.toggle("closed"); window.addEventListener("resize", () => {
target.querySelector(".chev")?.classList.toggle("rotate-180"); this.setInitialHeight();
this.chev.classList.remove("rotate-180");
});
this.setInitialHeight();
}
toggleOpen() {
requestAnimationFrame(() => {
const nextHeight = this.bottom.clientHeight;
const targetHeight = this.top.clientHeight;
const parentHeight = this.clientHeight;
this.style.height =
parentHeight >= targetHeight + nextHeight
? targetHeight + this.padding + "px"
: targetHeight + nextHeight + this.padding +"px";
this.bottom.style.top = targetHeight + this.topPadding + "px";
this.chev.classList.toggle("rotate-180");
});
}
setInitialHeight() {
requestAnimationFrame(() => {
console.log(this.padding);
this.style.height = this.top.clientHeight + this.padding + "px"
this.bottom.style.top = this.top.clientHeight + this.topPadding + "px";
}); });
} }
} }
customElements.define("accordion-widget", AccordionWidget); customElements.define("accordion-widget", AccordionWidget);
</script> </script>
<style>
.closed {
height: 58px;
}
</style>