Merge pull request #17 from mcgill-ecsess/melissa
FAQ accordion component
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
--color-ecsess-600: #3B6A3A;
|
--color-ecsess-600: #3B6A3A;
|
||||||
--color-ecsess-800: #0A3D2A;
|
--color-ecsess-800: #0A3D2A;
|
||||||
--color-ecsess-black: #1F1F1F;
|
--color-ecsess-black: #1F1F1F;
|
||||||
|
--color-ecsess-black-hover:#2c2c2c;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
<script>
|
||||||
|
// import { slide } from 'svelte/transition';
|
||||||
|
import { Accordion } from '@skeletonlabs/skeleton-svelte';
|
||||||
|
|
||||||
|
// FAQ closed by default
|
||||||
|
let isOpen = $state(false);
|
||||||
|
// const toggle = () => (isOpen = !isOpen);
|
||||||
|
|
||||||
|
// Variable to be included into the component
|
||||||
|
let { /** @type {String} */ entries } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Accordion classes="w-[500px] max-w-[500px] transition-all ease-in-out" multiple>
|
||||||
|
{#snippet iconClosed()}
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
><path d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet iconOpen()}
|
||||||
|
<svg
|
||||||
|
class="rotate-90"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
><path d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
{#each entries as entry, index}
|
||||||
|
<Accordion.Item
|
||||||
|
value={index.toString()}
|
||||||
|
classes="border-ecsess-200 mb-4 overflow-hidden rounded-xl border-2"
|
||||||
|
leadClasses="text-xl font-bold"
|
||||||
|
controlClasses="hover:bg-ecsess-black-hover
|
||||||
|
flex w-inherit cursor-pointer items-center justify-between
|
||||||
|
py-4 transition-colors ease-in-out"
|
||||||
|
panelClasses=" border-t-ecsess-200 max-h-fit border-t-2 bg-transparent p-4 bg-ecsess-400"
|
||||||
|
>
|
||||||
|
<!-- Control -->
|
||||||
|
{#snippet lead()}
|
||||||
|
{entry.question}
|
||||||
|
{/snippet}
|
||||||
|
{#snippet control()}{/snippet}
|
||||||
|
|
||||||
|
<!-- Panel -->
|
||||||
|
{#snippet panel()}{entry.answer}{/snippet}
|
||||||
|
</Accordion.Item>
|
||||||
|
{/each}
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="accordion-wrapper w-full max-w-[500px]">
|
||||||
|
<div
|
||||||
|
class="accordion-item
|
||||||
|
border-ecsess-200 mb-4 overflow-hidden rounded-xl border-2
|
||||||
|
{isOpen ? '' : 'open'}"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="accordion-header hover:bg-ecsess-black-hover
|
||||||
|
flex h-16 w-full cursor-pointer items-center justify-between
|
||||||
|
px-4 transition-colors ease-in-out"
|
||||||
|
onclick={toggle}
|
||||||
|
aria-expanded={isOpen}
|
||||||
|
>
|
||||||
|
<span class="text-xl font-bold">{question}</span>
|
||||||
|
<svg
|
||||||
|
class="accordion-icon transform-cpu transition-all ease-in-out"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if isOpen}
|
||||||
|
<div
|
||||||
|
class="accordion-content border-t-ecsess-200 max-h-fit border-t-2 bg-transparent p-4 transition-all ease-in"
|
||||||
|
transition:slide={{ duration: 300 }}
|
||||||
|
>
|
||||||
|
<p>{answer}</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- <style>
|
||||||
|
[aria-expanded='true'] .accordion-icon {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-item.open .accordion-header,
|
||||||
|
.accordion-item.open .accordion-content {
|
||||||
|
background-color: var(--color-ecsess-black-hover);
|
||||||
|
}
|
||||||
|
</style> -->
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { getFromCMS } from 'utils/utils.js';
|
|||||||
|
|
||||||
const homepageQuery = `*[_type == "homepage"]{
|
const homepageQuery = `*[_type == "homepage"]{
|
||||||
"description": description[],
|
"description": description[],
|
||||||
"councilPhoto": councilPhoto.asset->url
|
"councilPhoto": councilPhoto.asset->url,
|
||||||
|
"faqs": faqs[]{ question, answer },
|
||||||
}[0]`;
|
}[0]`;
|
||||||
|
|
||||||
const ohQuery = `*[_type=="oh"].schedule[]{
|
const ohQuery = `*[_type=="oh"].schedule[]{
|
||||||
@@ -13,12 +14,26 @@ const ohQuery = `*[_type=="oh"].schedule[]{
|
|||||||
}`;
|
}`;
|
||||||
|
|
||||||
export const load = async () => {
|
export const load = async () => {
|
||||||
|
/**
|
||||||
|
* @description Response data type based on the `homepageQuery` above.
|
||||||
|
* Note that `description` is a rich/portable text type
|
||||||
|
*
|
||||||
|
* @type {{
|
||||||
|
* description: import('@portabletext/svelte').InputValue,
|
||||||
|
* councilPhoto: string,
|
||||||
|
* faqs: [{
|
||||||
|
* question: string,
|
||||||
|
* answer: string
|
||||||
|
* }],
|
||||||
|
* }}
|
||||||
|
*
|
||||||
|
*/
|
||||||
let CMSresponse = await getFromCMS(homepageQuery);
|
let CMSresponse = await getFromCMS(homepageQuery);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: CMSresponse.description,
|
description: CMSresponse.description,
|
||||||
councilPhoto: CMSresponse.councilPhoto
|
councilPhoto: CMSresponse.councilPhoto,
|
||||||
|
faqs: CMSresponse.faqs
|
||||||
// ohs: await getFromCMS(ohQuery),
|
// ohs: await getFromCMS(ohQuery),
|
||||||
// FAQs: "",
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import FaqAccordion from 'components/FAQAccordion.svelte';
|
||||||
import Section from 'components/Section.svelte';
|
import Section from 'components/Section.svelte';
|
||||||
import { PortableText } from '@portabletext/svelte';
|
import { PortableText } from '@portabletext/svelte';
|
||||||
|
|
||||||
/** loading things from the server side */
|
/** loading things from the server side */
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
</script>
|
</script>
|
||||||
@@ -19,20 +21,17 @@
|
|||||||
|
|
||||||
<!-- Picture, FAQ -->
|
<!-- Picture, FAQ -->
|
||||||
<Section black>
|
<Section black>
|
||||||
<h1>Our student council</h1>
|
<div>
|
||||||
<div class="flex justify-around gap-12">
|
<h1>Our Student Council</h1>
|
||||||
<div>
|
<img src={data.councilPhoto} alt="ECSESS Council" />
|
||||||
<img src={data.councilPhoto} alt="ECSESS Council" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
|
||||||
|
|
||||||
<!-- Office Hours Calendar -->
|
|
||||||
<Section>
|
|
||||||
<div>
|
<div>
|
||||||
<h1>FAQ</h1>
|
<h1>FAQ</h1>
|
||||||
<p>Under development</p>
|
<FaqAccordion entries={data.faqs} />
|
||||||
</div>
|
</div>
|
||||||
|
</Section>
|
||||||
|
<!-- Office Hours Calendar -->
|
||||||
|
<Section>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-2xl">Office Hours</h1>
|
<h1 class="text-2xl">Office Hours</h1>
|
||||||
<p>Under development</p>
|
<p>Under development</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user