Docs
FAQ Categorized

FAQ Categorized

A categorized FAQ section with color-coded topics. Features organized categories, smooth accordions, and customizable color themes for each section.

Frequently Asked Questions

Browse questions by category to find what you're looking for

General

Basic information about our product

Pricing & Billing

Information about plans and payments

Technical

Technical details and integrations

Support & Training

Help and learning resources

Still have questions?

Can't find the answer you're looking for? Our support team is here to help.

Contact Support

Installation

Copy and paste the following code into your project.

import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
 
interface FAQItem {
  id: string;
  question: string;
  answer: string;
}
 
interface FAQCategory {
  id: string;
  title: string;
  description?: string;
  color: "orange" | "blue" | "green" | "purple" | "pink" | "yellow";
  faqs: FAQItem[];
}
 
interface FAQCategorizedProps {
  title?: string;
  description?: string;
  categories: FAQCategory[];
  className?: string;
}
 
const colorClasses = {
  orange: {
    border: "border-orange-500/20",
    borderHover: "hover:border-orange-500/40",
    borderOpen: "data-[state=open]:border-orange-500/50",
    text: "text-orange-500",
    bg: "bg-orange-500/10",
    icon: "bg-orange-600",
  },
  blue: {
    border: "border-blue-500/20",
    borderHover: "hover:border-blue-500/40",
    borderOpen: "data-[state=open]:border-blue-500/50",
    text: "text-blue-500",
    bg: "bg-blue-500/10",
    icon: "bg-blue-600",
  },
  green: {
    border: "border-green-500/20",
    borderHover: "hover:border-green-500/40",
    borderOpen: "data-[state=open]:border-green-500/50",
    text: "text-green-500",
    bg: "bg-green-500/10",
    icon: "bg-green-600",
  },
  purple: {
    border: "border-purple-500/20",
    borderHover: "hover:border-purple-500/40",
    borderOpen: "data-[state=open]:border-purple-500/50",
    text: "text-purple-500",
    bg: "bg-purple-500/10",
    icon: "bg-purple-600",
  },
  pink: {
    border: "border-pink-500/20",
    borderHover: "hover:border-pink-500/40",
    borderOpen: "data-[state=open]:border-pink-500/50",
    text: "text-pink-500",
    bg: "bg-pink-500/10",
    icon: "bg-pink-600",
  },
  yellow: {
    border: "border-yellow-500/20",
    borderHover: "hover:border-yellow-500/40",
    borderOpen: "data-[state=open]:border-yellow-500/50",
    text: "text-yellow-500",
    bg: "bg-yellow-500/10",
    icon: "bg-yellow-600",
  },
};
 
export function FAQCategorized({
  title = "Frequently Asked Questions",
  description = "Browse questions by category to find what you're looking for",
  categories,
  className = "",
}: FAQCategorizedProps) {
  return (
    <section className={`w-full bg-black py-20 ${className}`}>
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        {/* Header */}
        <div className="mx-auto mb-16 max-w-3xl text-center">
          <h2 className="mb-4 text-4xl font-bold text-white sm:text-5xl">
            {title}
          </h2>
          <p className="text-lg text-zinc-400">{description}</p>
        </div>
 
        {/* Categories */}
        <div className="space-y-12">
          {categories.map((category) => {
            const colors = colorClasses[category.color];
            return (
              <div key={category.id}>
                {/* Category Header */}
                <div className="mb-6 flex items-center gap-4">
                  <div className={`h-12 w-12 rounded-lg ${colors.icon}`} />
                  <div>
                    <h3 className="text-2xl font-bold text-white">
                      {category.title}
                    </h3>
                    {category.description && (
                      <p className="text-sm text-zinc-500">
                        {category.description}
                      </p>
                    )}
                  </div>
                </div>
 
                {/* FAQs */}
                <Accordion type="single" collapsible className="space-y-3">
                  {category.faqs.map((faq) => (
                    <AccordionItem
                      key={faq.id}
                      value={faq.id}
                      className={`rounded-xl border ${colors.border} ${colors.borderOpen} bg-zinc-950 px-6 transition-colors ${colors.borderHover}`}
                    >
                      <AccordionTrigger
                        className={`text-left text-base font-semibold text-white hover:no-underline hover:${colors.text}`}
                      >
                        {faq.question}
                      </AccordionTrigger>
                      <AccordionContent className="text-zinc-400">
                        {faq.answer}
                      </AccordionContent>
                    </AccordionItem>
                  ))}
                </Accordion>
              </div>
            );
          })}
        </div>
 
        {/* CTA */}
        <div className="mt-16 rounded-2xl border border-zinc-800 bg-zinc-950 p-8 text-center">
          <h3 className="mb-2 text-2xl font-bold text-white">
            Still have questions?
          </h3>
          <p className="mb-6 text-zinc-400">
            Can't find the answer you're looking for? Our support team is here
            to help.
          </p>
          <a
            href="#contact"
            className="inline-flex items-center gap-2 rounded-lg bg-orange-600 px-6 py-3 font-semibold text-white transition-all hover:bg-orange-700"
          >
            Contact Support
          </a>
        </div>
      </div>
    </section>
  );
}

install dependencies.

npx shadcn@latest add accordion
or 
pnpm dlx shadcn@latest add accordion

Features

  • Category organization - Group FAQs by topic
  • Color-coded - 6 solid color themes per category
  • Category icons - Visual indicators for each section
  • Accordion functionality - Expand/collapse answers
  • Hover effects - Interactive color transitions
  • Open state indicator - Border highlight when expanded
  • Category descriptions - Optional subtitle for each category
  • CTA section - Built-in contact support card
  • Smooth animations - Radix UI powered transitions
  • TypeScript support - Full type safety

Usage

Basic Usage

import FAQCategorized from "@/components/ui/faq-categorized";
 
const categories = [
  {
    id: "general",
    title: "General",
    description: "Basic information",
    color: "orange",
    faqs: [
      {
        id: "1",
        question: "What is your product?",
        answer: "Our product is...",
      },
    ],
  },
  {
    id: "pricing",
    title: "Pricing",
    color: "blue",
    faqs: [
      {
        id: "2",
        question: "How much does it cost?",
        answer: "Our pricing starts at...",
      },
    ],
  },
];
 
export default function Page() {
  return <FAQCategorized categories={categories} />;
}

Custom Title and Description

<FAQCategorized
  title="Help Center"
  description="Find answers organized by topic"
  categories={categories}
/>

All Color Options

const categories = [
  { id: "1", title: "General", color: "orange", faqs: [...] },
  { id: "2", title: "Pricing", color: "blue", faqs: [...] },
  { id: "3", title: "Technical", color: "green", faqs: [...] },
  { id: "4", title: "Support", color: "purple", faqs: [...] },
  { id: "5", title: "Account", color: "pink", faqs: [...] },
  { id: "6", title: "Security", color: "yellow", faqs: [...] },
];

Without Category Description

const categories = [
  {
    id: "general",
    title: "General Questions",
    color: "orange",
    // No description field
    faqs: [...],
  },
];

Props

FAQCategorizedProps

PropTypeDefaultDescription
categoriesFAQCategory[]RequiredArray of category objects
titlestring"Frequently Asked Questions"Section title
descriptionstring"Browse questions by category..."Section description
classNamestring""Additional CSS classes

FAQCategory

PropTypeRequiredDescription
idstringYesUnique identifier
titlestringYesCategory title
descriptionstringNoCategory subtitle
color"orange" | "blue" | "green" | "purple" | "pink" | "yellow"YesColor theme
faqsFAQItem[]YesArray of FAQ items

FAQItem

PropTypeRequiredDescription
idstringYesUnique identifier
questionstringYesFAQ question
answerstringYesFAQ answer

TypeScript Interface

interface FAQItem {
  id: string;
  question: string;
  answer: string;
}
 
interface FAQCategory {
  id: string;
  title: string;
  description?: string;
  color: "orange" | "blue" | "green" | "purple" | "pink" | "yellow";
  faqs: FAQItem[];
}
 
interface FAQCategorizedProps {
  title?: string;
  description?: string;
  categories: FAQCategory[];
  className?: string;
}

Color Themes

Each category can use one of 6 solid color themes:

  • Orange - General, Getting Started
  • Blue - Pricing, Billing, Plans
  • Green - Technical, Integrations, API
  • Purple - Support, Training, Help
  • Pink - Account, Profile, Settings
  • Yellow - Security, Privacy, Compliance

Each color includes:

  • Border color (20% opacity default, 40% hover, 50% open)
  • Text color for hover states
  • Background color for icon (solid 600 shade)
  • Background color for highlights (10% opacity)

Styling

  • Background - Black section with zinc-950 cards
  • Borders - Color-coded per category with opacity
  • Text - White questions, zinc-400 answers
  • Icons - Solid color squares (12x12) per category
  • Hover - Color-matched text and border effects
  • CTA Card - Zinc-950 with orange button
  • Animations - Smooth accordion transitions

Layout

  • Single column - Stacked categories
  • Category spacing - 12 units between categories
  • FAQ spacing - 3 units between items
  • Icon size - 48px square with rounded corners
  • Responsive - Full width on all devices

Accordion Behavior

  • Single open - Only one item can be open at a time per category
  • Collapsible - Click to toggle open/closed
  • Independent - Each category has its own accordion state
  • Smooth animations - Radix UI powered expand/collapse

Use Cases

Perfect for:

  • Knowledge bases
  • Help centers
  • Documentation sites
  • Support pages
  • Product FAQs
  • Service pages
  • SaaS websites
  • Customer portals

Best Practices

  1. Categories - Use 3-6 categories for optimal organization
  2. FAQs per category - Keep 3-5 questions per category
  3. Color assignment - Use consistent colors for similar topics
  4. Order - Place most important categories first
  5. Descriptions - Add category descriptions for clarity
  6. Questions - Keep questions concise and specific
  7. Answers - Provide detailed but scannable answers
  8. Updates - Keep content current and accurate

Customization

Add Custom Icons

import { HelpCircle, DollarSign, Code } from "lucide-react";
 
// Replace the colored square with an icon
<div className={`flex h-12 w-12 items-center justify-center rounded-lg ${colors.icon}`}>
  <HelpCircle className="h-6 w-6 text-white" />
</div>

Add Category Count

<h3 className="text-2xl font-bold text-white">
  {category.title}
  <span className="ml-2 text-sm text-zinc-500">
    ({category.faqs.length} questions)
  </span>
</h3>

Rich Content Answers

<AccordionContent>
  <div className="space-y-3 text-zinc-400">
    <p>{faq.answer}</p>
    <ul className="list-disc pl-5 space-y-1">
      <li>Feature 1</li>
      <li>Feature 2</li>
    </ul>
  </div>
</AccordionContent>