Skip to content

Commit 625c988

Browse files
author
Arnel Jan Sarmiento
committed
feat: add text overflow handling in testimonials
1 parent 13c0f12 commit 625c988

1 file changed

Lines changed: 47 additions & 21 deletions

File tree

app/(home)/components/Testimonials.tsx

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import Image from 'next/image';
55
import { Container } from '@/components/ui/container';
66
import Link from 'next/link';
77
import { CarouselDots, type CarouselApi } from '@/components/ui/carousel';
8-
import { useState } from 'react';
9-
import { useEffect } from 'react';
8+
import { useState, useRef, useEffect } from 'react';
109
import YellowStar from '@/public/assets/testimonials/yellow-star.svg';
1110
import WhiteStar from '@/public/assets/testimonials/white-star.svg';
1211
import ChatBubble from '@/public/assets/testimonials/chat-bubble.svg';
@@ -204,6 +203,26 @@ export function Testimonials() {
204203

205204
export function TestimonialCard({ text, rate, active }: TestimonialProps) {
206205
const starRate = [];
206+
const textRef = useRef<HTMLDivElement>(null);
207+
const [isTextOverflowing, setIsTextOverflowing] = useState(false);
208+
209+
// Check if text is overflowing
210+
useEffect(() => {
211+
const checkOverflow = () => {
212+
if (textRef.current) {
213+
const element = textRef.current;
214+
const isOverflowing =
215+
element.scrollHeight > element.clientHeight ||
216+
element.scrollWidth > element.clientWidth;
217+
setIsTextOverflowing(isOverflowing);
218+
}
219+
};
220+
221+
checkOverflow();
222+
// Re-check on window resize
223+
window.addEventListener('resize', checkOverflow);
224+
return () => window.removeEventListener('resize', checkOverflow);
225+
}, [text]);
207226

208227
// Append stars
209228
for (let i = 0; i < 5; i++) {
@@ -224,15 +243,17 @@ export function TestimonialCard({ text, rate, active }: TestimonialProps) {
224243
{/* Mobile View Display */}
225244
<div className="relative sm:hidden h-24 p-5 bg-medium-dark-green border border-[#36FF90] rounded-xl w-full text-clip overflow-hidden">
226245
<div className="text-xs sm:text-base">{text}</div>
227-
<div className="absolute bottom-0 pb-2 pt-14 bg-gradient-to-t from-medium-dark-green from-20% inset-x-5">
228-
<Link
229-
href="/404"
230-
target="_blank"
231-
className="text-xs sm:text-base text-yellow-400 underline"
232-
>
233-
Read more
234-
</Link>
235-
</div>
246+
{isTextOverflowing && (
247+
<div className="absolute bottom-0 pb-2 pt-14 bg-gradient-to-t from-medium-dark-green from-20% inset-x-5">
248+
<Link
249+
href="/404"
250+
target="_blank"
251+
className="text-xs sm:text-base text-yellow-400 underline"
252+
>
253+
Read more
254+
</Link>
255+
</div>
256+
)}
236257
</div>
237258

238259
{/* Tablet & Laptop View Display */}
@@ -247,18 +268,23 @@ export function TestimonialCard({ text, rate, active }: TestimonialProps) {
247268
<div className="flex absolute top-5 inset-x-0 justify-center space-x-2.5 lg:space-x-0.5">
248269
{starRate}
249270
</div>
250-
<div className="absolute top-16 mt-1 h-44 px-9 text-lg text-clip overflow-hidden lg:text-base lg:px-7 lg:h-1/3 xl:h-1/2">
271+
<div
272+
ref={textRef}
273+
className="absolute top-16 mt-1 h-44 px-9 text-lg text-clip overflow-hidden lg:text-base lg:px-7 lg:h-1/3 xl:h-1/2"
274+
>
251275
{text}
252276
</div>
253-
<div className="absolute bottom-14 pb-2 pt-28 bg-gradient-to-t from-medium-dark-green from-25% inset-x-9 lg:inset-x-7 lg:bottom-10">
254-
<Link
255-
href="/404"
256-
target="_blank"
257-
className="text-[#B3B3B3] underline lg:text-xs"
258-
>
259-
Read more
260-
</Link>
261-
</div>
277+
{isTextOverflowing && (
278+
<div className="absolute bottom-14 pb-2 pt-28 bg-gradient-to-t from-medium-dark-green from-25% inset-x-9 lg:inset-x-7 lg:bottom-10">
279+
<Link
280+
href="/404"
281+
target="_blank"
282+
className="text-[#B3B3B3] underline lg:text-xs"
283+
>
284+
Read more
285+
</Link>
286+
</div>
287+
)}
262288
</div>
263289
</>
264290
);

0 commit comments

Comments
 (0)