Files
sofa/components/expandable-text.tsx
T
jake 383f0b819b Polish mobile layouts, extract ExpandableText, fix image sizing
- Stack title-hero poster/metadata vertically on mobile (flex-col md:flex-row),
  switch backdrop tall breakpoint from sm to md
- Extract bio expand/collapse logic into reusable ExpandableText component;
  use it in PersonHero and TitleHero
- Fix ContinueWatchingCard image to use fill + sizes instead of fixed
  width/height to avoid layout shift
- Add fade-out gradient on genre chip scrollbar edge on mobile
- Show scaled-down ambient glow on mobile instead of hiding it entirely
- Humanize knownForDepartment labels (Acting→Actor, Directing→Director, etc.)
- Change cast member name from truncate to line-clamp-2 for wrapping
- Hide tooltip arrow via [&>:last-child]:hidden instead of color-matching it
- Apply safe-area-inset padding to HeroBanner content on notched devices
2026-03-07 12:09:51 -05:00

58 lines
1.4 KiB
TypeScript

"use client";
import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";
interface ExpandableTextProps {
text: string;
/** Tailwind line-clamp class applied when collapsed (default: "line-clamp-3") */
clampClass?: string;
className?: string;
textClassName?: string;
}
export function ExpandableText({
text,
clampClass = "line-clamp-3",
className,
textClassName,
}: ExpandableTextProps) {
const [expanded, setExpanded] = useState(false);
const [clamped, setClamped] = useState(false);
const ref = useRef<HTMLParagraphElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const check = () => setClamped(el.scrollHeight > el.clientHeight + 1);
check();
const observer = new ResizeObserver(check);
observer.observe(el);
return () => observer.disconnect();
}, []);
return (
<div className={className}>
<p
ref={ref}
className={cn(
"break-words text-muted-foreground leading-relaxed",
!expanded && clampClass,
textClassName,
)}
>
{text}
</p>
{(clamped || expanded) && (
<button
type="button"
onClick={() => setExpanded(!expanded)}
className="mt-1 font-medium text-primary text-xs transition-colors hover:text-primary/80"
>
{expanded ? "Show less" : "Read more"}
</button>
)}
</div>
);
}