Skip to content

Commit c3850db

Browse files
fix: layout issue
1 parent b1b941c commit c3850db

File tree

1 file changed

+131
-57
lines changed

1 file changed

+131
-57
lines changed

src/components/faqs/faqs.tsx

Lines changed: 131 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ const FAQs: React.FC = () => {
5050
setActiveIndex(activeIndex === index ? null : index);
5151
};
5252

53+
// Split FAQs into two columns manually to prevent shifting
54+
const midPoint = Math.ceil(faqData.length / 2);
55+
const leftColumnFAQs = faqData.slice(0, midPoint);
56+
const rightColumnFAQs = faqData.slice(midPoint);
57+
5358
return (
5459
<section
5560
className={`py-8 transition-colors duration-300 ${
@@ -79,67 +84,136 @@ const FAQs: React.FC = () => {
7984
</p>
8085
</div>
8186

82-
{/* Accordion Masonry Columns to prevent sibling expansion */}
83-
<div className="columns-1 md:columns-2 md:gap-x-6">
84-
{faqData.map((faq, index) => (
85-
<motion.div
86-
key={index}
87-
className="accordion h-fit border-gray-200 dark:border-gray-700 pb-4 mb-4 break-inside-avoid"
88-
initial={{ opacity: 0, y: 10 }}
89-
animate={{ opacity: 1, y: 0 }}
90-
transition={{ duration: 0.3 }}
91-
>
92-
<button
93-
className={`accordion-toggle group flex justify-between items-center text-lg font-semibold w-full transition-all duration-300
94-
${
95-
isDark
96-
? "text-gray-100 bg-gray-800 hover:bg-gray-700 hover:text-white border border-gray-700 hover:border-gray-600"
97-
: "text-gray-900 bg-white hover:bg-gray-50 hover:text-gray-900 border border-gray-200 hover:border-gray-300 shadow-sm"
98-
}
99-
p-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`}
100-
onClick={() => toggleAccordion(index)}
101-
>
102-
<span className="text-left pr-4">{faq.question}</span>
103-
<motion.span
104-
className={`transform transition-transform duration-300 flex-shrink-0 ${
105-
isDark ? "text-gray-300" : "text-gray-600"
106-
}`}
107-
animate={{ rotate: activeIndex === index ? 180 : 0 }}
108-
>
109-
<FiChevronDown size={22} />
110-
</motion.span>
111-
</button>
87+
{/* FAQ Manual Column Layout - Prevents vertical shifting */}
88+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
89+
{/* Left Column */}
90+
<div className="space-y-4">
91+
{leftColumnFAQs.map((faq, index) => (
11292
<motion.div
113-
className="accordion-content overflow-hidden"
114-
initial={{ height: 0, opacity: 0 }}
115-
animate={{
116-
height: activeIndex === index ? "auto" : 0,
117-
opacity: activeIndex === index ? 1 : 0,
118-
}}
119-
transition={{ duration: 0.3, ease: "easeInOut" }}
93+
key={index}
94+
className="accordion border-gray-200 dark:border-gray-700"
95+
initial={{ opacity: 0, y: 10 }}
96+
animate={{ opacity: 1, y: 0 }}
97+
transition={{ duration: 0.3 }}
12098
>
121-
<div
122-
className={`mt-3 p-5 text-base leading-relaxed transition-colors duration-200 rounded-lg border-l-4 ${
123-
isDark
124-
? "text-gray-100 bg-gradient-to-r from-gray-800/80 to-gray-900/60 border-l-indigo-400 shadow-lg"
125-
: "text-gray-900 bg-gradient-to-r from-white to-gray-50 border-l-indigo-500 shadow-md"
126-
}`}
127-
dangerouslySetInnerHTML={{
128-
__html: faq.answer.replace(
129-
/<strong>/g,
130-
`<strong style="color: ${isDark ? '#ffffff' : '#000000'}; font-weight: 700; background: ${isDark ? 'rgba(99, 102, 241, 0.2)' : 'rgba(199, 210, 254, 0.4)'}; padding: 2px 6px; border-radius: 4px;">`
131-
).replace(
132-
/<a /g,
133-
`<a style="color: ${isDark ? '#c4b5fd' : '#3730a3'}; text-decoration: underline; font-weight: 600; transition: all 0.2s ease;" `
134-
).replace(
135-
/ /g,
136-
`<span style="color: ${isDark ? '#818cf8' : '#4f46e5'}; font-weight: bold;">•</span> `
137-
)
99+
<button
100+
className={`accordion-toggle group flex justify-between items-center text-lg font-semibold w-full transition-all duration-300
101+
${
102+
isDark
103+
? "text-gray-100 bg-gray-800 hover:bg-gray-700 hover:text-white border border-gray-700 hover:border-gray-600"
104+
: "text-gray-900 bg-white hover:bg-gray-50 hover:text-gray-900 border border-gray-200 hover:border-gray-300 shadow-sm"
105+
}
106+
p-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`}
107+
onClick={() => toggleAccordion(index)}
108+
>
109+
<span className="text-left pr-4">{faq.question}</span>
110+
<motion.span
111+
className={`transform transition-transform duration-300 flex-shrink-0 ${
112+
isDark ? "text-gray-300" : "text-gray-600"
113+
}`}
114+
animate={{ rotate: activeIndex === index ? 180 : 0 }}
115+
>
116+
<FiChevronDown size={22} />
117+
</motion.span>
118+
</button>
119+
<motion.div
120+
className="accordion-content overflow-hidden"
121+
initial={{ height: 0, opacity: 0 }}
122+
animate={{
123+
height: activeIndex === index ? "auto" : 0,
124+
opacity: activeIndex === index ? 1 : 0,
138125
}}
139-
/>
126+
transition={{ duration: 0.3, ease: "easeInOut" }}
127+
>
128+
<div
129+
className={`mt-3 p-5 text-base leading-relaxed transition-colors duration-200 rounded-lg border-l-4 ${
130+
isDark
131+
? "text-gray-100 bg-gradient-to-r from-gray-800/80 to-gray-900/60 border-l-indigo-400 shadow-lg"
132+
: "text-gray-900 bg-gradient-to-r from-white to-gray-50 border-l-indigo-500 shadow-md"
133+
}`}
134+
dangerouslySetInnerHTML={{
135+
__html: faq.answer.replace(
136+
/<strong>/g,
137+
`<strong style="color: ${isDark ? '#ffffff' : '#000000'}; font-weight: 700; background: ${isDark ? 'rgba(99, 102, 241, 0.2)' : 'rgba(199, 210, 254, 0.4)'}; padding: 2px 6px; border-radius: 4px;">`
138+
).replace(
139+
/<a /g,
140+
`<a style="color: ${isDark ? '#c4b5fd' : '#3730a3'}; text-decoration: underline; font-weight: 600; transition: all 0.2s ease;" `
141+
).replace(
142+
/ /g,
143+
`<span style="color: ${isDark ? '#818cf8' : '#4f46e5'}; font-weight: bold;">•</span> `
144+
)
145+
}}
146+
/>
147+
</motion.div>
140148
</motion.div>
141-
</motion.div>
142-
))}
149+
))}
150+
</div>
151+
152+
{/* Right Column */}
153+
<div className="space-y-4">
154+
{rightColumnFAQs.map((faq, index) => {
155+
const actualIndex = index + leftColumnFAQs.length;
156+
return (
157+
<motion.div
158+
key={actualIndex}
159+
className="accordion border-gray-200 dark:border-gray-700"
160+
initial={{ opacity: 0, y: 10 }}
161+
animate={{ opacity: 1, y: 0 }}
162+
transition={{ duration: 0.3 }}
163+
>
164+
<button
165+
className={`accordion-toggle group flex justify-between items-center text-lg font-semibold w-full transition-all duration-300
166+
${
167+
isDark
168+
? "text-gray-100 bg-gray-800 hover:bg-gray-700 hover:text-white border border-gray-700 hover:border-gray-600"
169+
: "text-gray-900 bg-white hover:bg-gray-50 hover:text-gray-900 border border-gray-200 hover:border-gray-300 shadow-sm"
170+
}
171+
p-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`}
172+
onClick={() => toggleAccordion(actualIndex)}
173+
>
174+
<span className="text-left pr-4">{faq.question}</span>
175+
<motion.span
176+
className={`transform transition-transform duration-300 flex-shrink-0 ${
177+
isDark ? "text-gray-300" : "text-gray-600"
178+
}`}
179+
animate={{ rotate: activeIndex === actualIndex ? 180 : 0 }}
180+
>
181+
<FiChevronDown size={22} />
182+
</motion.span>
183+
</button>
184+
<motion.div
185+
className="accordion-content overflow-hidden"
186+
initial={{ height: 0, opacity: 0 }}
187+
animate={{
188+
height: activeIndex === actualIndex ? "auto" : 0,
189+
opacity: activeIndex === actualIndex ? 1 : 0,
190+
}}
191+
transition={{ duration: 0.3, ease: "easeInOut" }}
192+
>
193+
<div
194+
className={`mt-3 p-5 text-base leading-relaxed transition-colors duration-200 rounded-lg border-l-4 ${
195+
isDark
196+
? "text-gray-100 bg-gradient-to-r from-gray-800/80 to-gray-900/60 border-l-indigo-400 shadow-lg"
197+
: "text-gray-900 bg-gradient-to-r from-white to-gray-50 border-l-indigo-500 shadow-md"
198+
}`}
199+
dangerouslySetInnerHTML={{
200+
__html: faq.answer.replace(
201+
/<strong>/g,
202+
`<strong style="color: ${isDark ? '#ffffff' : '#000000'}; font-weight: 700; background: ${isDark ? 'rgba(99, 102, 241, 0.2)' : 'rgba(199, 210, 254, 0.4)'}; padding: 2px 6px; border-radius: 4px;">`
203+
).replace(
204+
/<a /g,
205+
`<a style="color: ${isDark ? '#c4b5fd' : '#3730a3'}; text-decoration: underline; font-weight: 600; transition: all 0.2s ease;" `
206+
).replace(
207+
/ /g,
208+
`<span style="color: ${isDark ? '#818cf8' : '#4f46e5'}; font-weight: bold;">•</span> `
209+
)
210+
}}
211+
/>
212+
</motion.div>
213+
</motion.div>
214+
);
215+
})}
216+
</div>
143217
</div>
144218
</div>
145219
</div>

0 commit comments

Comments
 (0)