UIPackage
Menu

Framework

Change language

Boilerplate repo

FAQ — Categorized Tabs

blockmarketing

Question set grouped behind category tabs, each panel holding its own accordion with a count badge, for support pages where one flat list would run past thirty entries.

Also available for React ->

Installation

$npx shadcn-vue@latest add https://uipkge.dev/r/vue/faq-categorized-tabs.json
Named registry:npx shadcn-vue@latest add @uipkge/faq-categorized-tabsInstalls to:app/components/blocks/

Variants

Loading interactive previews…

Files installed (1)

  • app/components/blocks/FaqCategorizedTabs.vue3.3 kB
    <script setup lang="ts">
    import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
    import { Badge } from '@/components/ui/badge'
    import { Button } from '@/components/ui/button'
    import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
    
    const categories = [
      {
        id: 'security',
        label: 'Security',
        entries: [
          {
            q: 'Where is our data stored?',
            a: 'Definitions and query metadata sit in your chosen region. Warehouse rows are never copied out.',
          },
          {
            q: 'Are you SOC 2 audited?',
            a: 'Type II, audited annually. The report and the subprocessor list are on the trust centre.',
          },
          { q: 'Can we bring our own keys?', a: 'Yes, on the enterprise plan, with rotation handled through your KMS.' },
        ],
      },
      {
        id: 'billing',
        label: 'Billing',
        entries: [
          {
            q: 'How is usage counted?',
            a: 'By query, not by seat. Materialised reads are not billed twice within their freshness window.',
          },
          {
            q: 'Can we cap spend?',
            a: 'Per-team query budgets are enforced at run time, so a runaway dashboard cannot outspend its ceiling.',
          },
          { q: 'Do you offer annual terms?', a: 'Yes, with a discount and an invoiced option above a threshold.' },
        ],
      },
      {
        id: 'setup',
        label: 'Setup',
        entries: [
          {
            q: 'What do you need from us?',
            a: 'A read-only role, your identity provider, and an hour with whoever owns the warehouse.',
          },
          {
            q: 'How long until first value?',
            a: 'Most teams publish a first certified metric on day one and finish the rollout in five weeks.',
          },
        ],
      },
    ]
    </script>
    
    <template>
      <section data-slot="faq-categorized-tabs" class="bg-background">
        <div class="mx-auto max-w-4xl px-6 py-20 lg:py-28">
          <div class="max-w-2xl">
            <Badge variant="secondary">Support</Badge>
            <h2 class="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">Answers by topic</h2>
            <p class="text-muted-foreground mt-3 text-lg">
              Grouped rather than listed, because one flat list of thirty questions is a list nobody reads.
            </p>
          </div>
    
          <Tabs :default-value="categories[0].id" class="mt-10">
            <TabsList variant="pill" class="flex-nowrap overflow-x-auto">
              <TabsTrigger v-for="category in categories" :key="category.id" :value="category.id" variant="pill">
                {{ category.label }}
                <span class="text-muted-foreground ml-1.5 font-mono text-xs">{{ category.entries.length }}</span>
              </TabsTrigger>
            </TabsList>
    
            <TabsContent v-for="category in categories" :key="category.id" :value="category.id" class="mt-6">
              <Accordion type="single" collapsible class="w-full">
                <AccordionItem v-for="entry in category.entries" :key="entry.q" :value="entry.q">
                  <AccordionTrigger class="text-left font-medium">{{ entry.q }}</AccordionTrigger>
                  <AccordionContent class="text-muted-foreground leading-relaxed">{{ entry.a }}</AccordionContent>
                </AccordionItem>
              </Accordion>
            </TabsContent>
          </Tabs>
    
          <Button variant="ghost" class="mt-8">Browse the full help centre</Button>
        </div>
      </section>
    </template>
    

Raw manifest:https://uipkge.dev/r/vue/faq-categorized-tabs.json