FAQ Accordion

FAQs

Here are some frequently asked questions about our project.

Overview

The FAQ Accordion Component is designed to display frequently asked questions (FAQs) in a compact and interactive format. It enhances user experience by allowing visitors to expand and collapse questions to reveal answers, making it easier to navigate through information. This component is ideal for informational sections, help centers, or product support pages where clarity and accessibility are paramount.

Features

  • Interactive Accordion Behavior: Questions can be expanded or collapsed to show or hide their answers, improving the readability of FAQs.
  • Dynamic Content Support: Easily customizable for any set of questions and answers.
  • Reactive State Management: Utilizes Vue's reactive state to ensure UI updates are efficient and reflect user interactions.
  • Accessibility: Designed with accessibility in mind, allowing users to interact with the component via click actions.

Data Structure

The component's data structure is defined within a reactive faqContent object, which contains an array of content. Each item in the content array represents an FAQ entry with the following properties:

  • title (String): The question being asked.
  • description (Array of Strings): The answer(s) to the question. Supports multiple paragraphs.
  • isOpen (Boolean): Indicates whether the accordion item is expanded or collapsed.

Methods

  • toggleAccordion(index: number): A method to toggle the isOpen state of an FAQ item, identified by its index within the content array. This controls the accordion behavior.

Example Usage

<FAQAccordion />

Customization

  • Content: Adjust the title, description, and faqContent array to match the FAQs specific to your project or product.
  • Styling: Utilizes Tailwind CSS for styling. Tailor the classes to match your design preferences and ensure consistency with your brand's aesthetic.

Integration

To integrate the FAQ Accordion Component into your Vue 3 application:

  1. Ensure you have Vue 3 and Tailwind CSS set up in your project.
  2. Copy the component code into a new .vue file within your project's components directory.
  3. Import and use the component on your pages or within other components where FAQs are needed.

Component Code

<script setup lang="ts">
const title = 'FAQs';
const description =
  'Here are some frequently asked questions about our project.';
const content = [
  {
    title: 'What is this project?',
    description: [
      'This project is a cool project that does cool things and is cool to use and look at and stuff like that and things and stuff.',
    ],
    isOpen: false,
  },
  {
    title: 'How do I use this project?',
    description: [
      'You can use this project by doing cool things and stuff like that and things and stuff.',
    ],
    isOpen: false,
  },
];

const faqContent = reactive({ content });

const toggleAccordion = (index: number) => {
  faqContent.content[index].isOpen = !faqContent.content[index].isOpen;
};
</script>

<template>
  <div class="m-lg">
    <div class="mx-auto w-full max-w-7xl text-black dark:text-primary">
      <h2
        class="mx-auto text-4xl font-bold text-black dark:text-primary sm:text-6xl"
      >
        {{ title }}
      </h2>
      <p
        class="mt-xs border-b border-black pb-xs text-xl dark:border-primary sm:pb-sm md:pb-md"
      >
        {{ description }}
      </p>
      <div class="">
        <div
          v-for="(items, index) in faqContent.content"
          :key="index"
          class="border-b border-black text-base dark:border-primary"
        >
          <button
            class="w-full py-4 text-left"
            @click="toggleAccordion(index)"
          >
            {{ items.title }}
            <div v-if="faqContent.content[index].isOpen">
              <p
                v-for="item in items.description"
                :key="item"
                class="mt-xs sm:mt-sm"
              >
                {{ item }}
              </p>
            </div>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>