Sunflower UI
Search
Copy Code
Light Mode
accordion-demo.tsx
accordion.tsx
prompt.md
Collapse
Reset
Copy Code
Download
Run
1
"use client"
2
3
import * as React from "react"
4
import { Accordion, AccordionItem } from "@/components/ui/accordion"
5
import { motion, AnimatePresence } from "framer-motion"
6
import { ArrowRight, Loader2 } from "lucide-react"
7
import { cn } from "@/lib/utils"
8
9
const initialFaqs = [
10
{
11
id: "1",
12
title: "What is this?",
13
content: "The greatest component library known to man.",
14
},
15
{
16
id: "2",
17
title: "How do I theme it?",
18
content: "Change the CSS variables at the top of app.css. There is no provider to wrap, no config to learn, and nothing that needs a rebuild to see.",
19
},
20
{
21
id: "3",
22
title: "What is the typeface?",
23
content: "Inter, a beautiful geometric sans-serif typeface.",
24
},
25
{
26
id: "4",
27
title: "Where do icons come from?",
28
content: "Lucide icons, a community-driven fork of Feather icons.",
29
}
30
]
31
32
export default function AccordionDemo() {
33
const [faqs, setFaqs] = React.useState(initialFaqs)
34
const [inputValue, setInputValue] = React.useState("")
35
const [isSubmitting, setIsSubmitting] = React.useState(false)
36
37
// Ref for accordion to trigger expanded item from demo component
38
// Actually we'll let the user manage it, but to auto-expand the new one,
39
// we can use a controlled accordion value.
40
const [expandedValue, setExpandedValue] = React.useState<string | null>(null)
41
42
const handleSubmit = (e: React.FormEvent) => {
43
e.preventDefault()
44
if (!inputValue.trim() || isSubmitting) return
45
46
const newId = Date.now().toString()
47
const question = inputValue.trim()
48
49
setIsSubmitting(true)
50
51
// Simulate API delay
52
setTimeout(() => {
53
setFaqs([...faqs, {
54
id: newId,
55
title: question,
56
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
57
}])
58
setInputValue("")
59
setIsSubmitting(false)
60
setExpandedValue(newId)
61
}, 1500)
62
}
63
64
return (
65
<div className="w-full h-full min-h-[600px] flex items-center justify-center p-10 bg-white dark:bg-[#1C1C1C]">
66
<div className="w-full max-w-xl">
67
<Accordion
68
className="w-full"
69
value={expandedValue}
70
onValueChange={setExpandedValue}
71
>
72
{faqs.map((faq) => (
73
<AccordionItem
74
key={faq.id}
75
value={faq.id}
76
title={faq.title}
77
>
78
{faq.content}
79
</AccordionItem>
80
))}
81
</Accordion>
82
83
{/* Input Area acting as the last pseudo-item */}
84
<div className="relative border-b border-black/10 dark:border-white/10 group">
85
<form onSubmit={handleSubmit} className="flex items-center w-full py-4">
86
<input
87
type="text"
88
value={inputValue}
89
onChange={(e) => setInputValue(e.target.value)}
90
disabled={isSubmitting}
91
placeholder="Ask anything else"
92
className={cn(
93
"w-full bg-transparent outline-none text-[14px] font-semibold text-zinc-900 dark:text-[#E2E2E2] placeholder:font-normal placeholder:text-zinc-500",
94
isSubmitting && "opacity-50"
95
)}
96
/>
97
98
<AnimatePresence mode="wait">
99
{isSubmitting ? (
100
<motion.div
101
key="loading"
102
initial={{ opacity: 0, scale: 0.5 }}
103
animate={{ opacity: 1, scale: 1 }}
104
exit={{ opacity: 0, scale: 0.5 }}
105
className="w-6 h-6 rounded-full bg-zinc-100 dark:bg-white/10 flex items-center justify-center flex-shrink-0"
106
>
107
<motion.div
108
className="w-1.5 h-1.5 rounded-full bg-zinc-500 dark:bg-zinc-400"
109
animate={{ scale: [1, 1.5, 1], opacity: [0.5, 1, 0.5] }}
110
transition={{ duration: 1, repeat: Infinity }}
111
/>
112
</motion.div>
113
) : (
114
<motion.button
115
key="submit"
116
initial={{ opacity: 0, scale: 0.5 }}
117
animate={{ opacity: 1, scale: 1 }}
118
exit={{ opacity: 0, scale: 0.5 }}
119
type="submit"
120
disabled={!inputValue.trim()}
121
className={cn(
122
"w-6 h-6 rounded-full flex items-center justify-center flex-shrink-0 transition-colors",
123
inputValue.trim()
124
? "bg-zinc-900 dark:bg-white/10 text-white dark:text-zinc-400 hover:text-white"
125
: "text-zinc-400 dark:text-zinc-600"
126
)}
127
>
128
<ArrowRight className="w-3 h-3" />
129
</motion.button>
130
)}
131
</AnimatePresence>
132
</form>
133
</div>
134
</div>
135
</div>
136
)
137
}
138