👕
【React】文章が長くなる時にcollapseが必要か判定する方法
概要
入力した文章が長い時に、表示の折りたたみを行うようなcollapseを使用することがあると思います。ただ、入力される文章の長さが分からない場合、短い時はcollapseが不要なケースが出てくると思います。今回は文章の長さによってcollapseの表示判定を行う方法をメモ書きします。
対応方針
Reactでの実装を前提とする場合は、こちらのstackoverflowの回答での実装が良いかなと思いました。基本的な実装としては、refのcurrent.scrollHeight
とcurrent.clientHeight
を比較して、表示の判定を行うという方針となります。
前提
- 使用したReactのバージョンは
18.2.0
です。 - 今回の実装では、UIコンポーネントにshadcn/ui、Tailwindを使用しました。Collapseのコンポーネントはshadcn/uiのCollapsibleを使用しました。
実装サンプル
文章が短い時は、以下のCollapseのボタンを非表示にして、
長い時は以下のようにCollapseのボタンを表示するようにした、実装のサンプルです。
type Props = {
inputText: string;
};
export const SampleCollapseComponent: FC<Props> = ({ inputText }) => {
const [isOpenCollapse, setIsOpenCollapse] = useState<boolean>(false);
const [isDisplayCollapsible, setIsDisplayCollapsible] =
useState<boolean>(false);
const contentRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (contentRef && contentRef.current) {
setIsDisplayCollapsible(
contentRef.current.scrollHeight > contentRef.current.clientHeight
);
}
}, []);
return (
<>
<Card className="ml-2 mt-2 w-[95%]">
<CardContent>
<Collapsible open={isOpenCollapse} onOpenChange={setIsOpenCollapse}>
{isDisplayCollapsible && (
<div className="flex flex-row justify-end">
<CollapsibleTrigger asChild>
<Button variant="ghost" size="sm" className="w-9 p-0">
<ChevronsUpDown className="h-4 w-4" />
<span className="sr-only">Toggle</span>
</Button>
</CollapsibleTrigger>
</div>
)}
<div
ref={contentRef}
className={
!isOpenCollapse
? "whitespace-pre-wrap line-clamp-3 mt-3"
: "whitespace-pre-wrap mt-3"
}
>
{inputText}
</div>
</Collapsible>
</CardContent>
</Card>
</>
);
};
Discussion