1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- ---
- interface Props {
- title: string;
- }
- const { title } = Astro.props as Props;
- ---
- <div class="accordion group relative rounded-md border border-neutral-200 my-3">
- <button
- class="accordion__button flex w-full flex-1 items-center justify-between gap-2 p-3 text-left font-medium transition sm:px-4 text-xl"
- type="button"
- id={`${title} accordion menu button`}
- aria-expanded="false"
- aria-controls={`${title} accordion menu content`}
- >
- {title}
- <svg
- class="accordion__chevron h-7 w-7 shrink-0 transition-transform text-lime-900"
- aria-hidden="true"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- ><path
- fill="none"
- stroke="currentColor"
- stroke-linecap="round"
- stroke-linejoin="round"
- stroke-width="2"
- d="m6 9l6 6l6-6"></path></svg
- >
- </button>
- <div
- id={`${title} accordion menu content`}
- aria-labelledby={`${title} accordion menu button`}
- class="accordion__content hidden max-h-0 overflow-hidden transition-all duration-300 ease-in-out sm:px-4"
- >
- <slot />
- </div>
- </div>
- <script>
- function accordionSetup() {
- const accordionMenus = document.querySelectorAll(
- ".accordion"
- ) as NodeListOf<HTMLElement>;
- accordionMenus.forEach((accordionMenu) => {
- const accordionButton = accordionMenu.querySelector(
- ".accordion__button"
- ) as HTMLElement;
- const accordionChevron = accordionMenu.querySelector(
- ".accordion__chevron"
- ) as HTMLElement;
- const accordionContent = accordionMenu.querySelector(
- ".accordion__content"
- ) as HTMLElement;
- if (accordionButton && accordionContent && accordionChevron) {
- accordionButton.addEventListener("click", (event) => {
- if (!accordionMenu.classList.contains("active")) {
- // if accordion is currently closed, so open it
- accordionMenu.classList.add("active");
- accordionButton.setAttribute("aria-expanded", "true");
- // set max-height to the height of the accordion content
- // this makes it animate properly
- accordionContent.classList.remove("hidden");
- accordionContent.style.maxHeight =
- accordionContent.scrollHeight + "px";
- accordionChevron.classList.add("rotate-180");
- } else {
- // accordion is currently open, so close it
- accordionMenu.classList.remove("active");
- accordionButton.setAttribute("aria-expanded", "false");
- // set max-height to the height of the accordion content
- // this makes it animate properly
- accordionContent.style.maxHeight = "0px";
- accordionChevron.classList.remove("rotate-180");
- // delay to allow close animation
- setTimeout(() => {
- accordionContent.classList.add("hidden");
- }, 300);
- }
- event.preventDefault();
- return false;
- });
- }
- });
- }
- // runs on initial page load
- accordionSetup();
- // runs on view transitions navigation
- document.addEventListener("astro:after-swap", accordionSetup);
- </script>
|