Installation
Usage
import { FAQAutoAccordion } from "@/components/ruixen/faq-auto-accordion";
import type { FAQItem } from "@/components/ruixen/faq-auto-accordion";
const items: FAQItem[] = [
{
question: "What is Ruixen UI?",
answer: "A curated collection of production-ready components.",
},
{
question: "Is it open-source?",
answer: "Yes, fully open-source under the MIT license.",
},
];
export default function MyFAQ() {
return <FAQAutoAccordion items={items} />;
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | "Have questions?" | Section heading |
subtitle | string | "Everything you need to know." | Subtitle below heading |
items | FAQItem[] | Built-in 6 defaults | Flat array of FAQ items |
autoInterval | number | 6 | Seconds per item auto-advance. 0 to disable |
className | string | — | Additional classes on root section |
FAQItem
interface FAQItem {
question: string;
answer: string;
}Traveling Accent Bar
A 3px rounded bar sits to the left of the active question. When the active item changes, the bar physically springs to the new position using layoutId — framer-motion measures the before/after positions and interpolates with spring(500, 30). The bar slightly overshoots and settles, creating a physical feeling that CSS transitions cannot replicate.
Spring Height Animation
Answers expand and collapse with true spring physics via AnimatePresence:
- Open:
height: 0 → "auto"withspring(300, 30)— gentle, slightly underdamped - Close:
height: "auto" → 0withspring(400, 35)— stiffer, snappier
The differential stiffness creates an asymmetry: opening feels leisurely, closing feels decisive.
Blur-Deblur Text Reveal
Answer text enters with three simultaneous properties:
- Opacity:
0 → 1over 250ms with 40ms delay - Y position:
6px → 0withspring(380, 26)— slight upward drift - Blur:
blur(3px) → blur(0px)over 300ms — text sharpens into focus
On exit, text blurs back to 2px and fades in 120ms. The blur transition is the signature — content resolves like a camera pulling focus.
Layout FLIP Repositioning
Each FAQ item uses layout="position" — when any item expands or collapses, all siblings smoothly slide to their new positions with spring(400, 35). No CSS transitions, no top calculations — framer-motion measures the DOM diff and applies FLIP interpolation.
Progress Bar
A 1px bar below the answer fills left-to-right over autoInterval seconds. Track: bg-foreground/[0.06]. Fill: bg-foreground/15. Uses CSS @keyframes for linear fill — spring physics would look wrong for a progress indicator.
Auto-Advance
The active item auto-advances every autoInterval seconds (default 6s).
- Pauses on hover — progress bar stops, timer pauses
- Resets on resume — both restart from scratch when mouse leaves
- Resets on click — clicking any item restarts the timer
- Stops when closed — if all items are closed, auto-advance pauses
- Can be disabled by setting
autoInterval={0}
Features
- Spring physics via motion — real overshoot and settle
- Traveling accent bar with layoutId FLIP animation
- Layout repositioning — siblings slide smoothly
- Blur-deblur text reveal on answers
- Auto-advance with progress bar countdown
- Differential spring stiffness (open vs close)
- Theme-aware via CSS custom properties
- Accessible — semantic buttons, ARIA expanded, keyboard navigable

