useRef で作る Auto Resize するテキストフィールド
本記事では、React Hooks のひとつである useRef を使った Auto Resize するテキストフィールドの実装例を紹介します。
Auto Resize とは入力された文字の量(高さ)に応じてテキストフィールドの高さを伸縮させることを指します。
デフォルトの <textarea>
では、複数行入力して要素の高さを超えた場合、スクロールバーが表示され文章全体を見渡すことができなくなります。
ググっても実装例があまりなくライブラリを入れるほどでもないので参考になれば幸いです。
TL;DR
さっそく、コード例を紹介します。
CodeSandbox で実際に触ることもできます。
import { useEffect, useRef, useState } from "react";
import "./styles.css";
function useAutoResizeTextArea(value: string | undefined) {
const ref = useRef<HTMLTextAreaElement>null;
useEffect(() => {
const element = ref.current;
if (!element) {
return;
}
const { borderTopWidth, borderBottomWidth, paddingTop, paddingBottom } =
getComputedStyle(element);
element.style.height = "auto";
element.style.height = `calc(${element.scrollHeight}px + ${paddingTop} + ${paddingBottom} + ${borderTopWidth} + ${borderBottomWidth})`;
}, [value]);
return ref;
}
export default function App() {
const [value, setValue] = useState("");
const textAreaRef = useAutoResizeTextArea(value);
return (
<div className="App">
<textarea
style={{ resize: "none", boxSizing: "border-box" }}
value={value}
onChange={(e) => setValue(e.target.value)}
ref={textAreaRef}
/>
</div>
);
}
簡単な解説
useAutoResizeTextArea()
という Custom Hooks のなかで、参照した DOM (<textarea>
) の高さを計算しています。
element.style.height = "auto";
行数が減ったときに縮むように、いったん “auto” を指定しています。
element.style.height = `calc(${element.scrollHeight}px + ${paddingTop} + ${paddingBottom} + ${borderTopWidth} + ${borderBottomWidth})`;
そして、各プロパティの合算を要素の高さに代入します。
style={{ resize: "none", boxSizing: "border-box" }}
スタイルについて、細かいですが入力すると高さがリセットされるのでドラッグでの resize は無効にしています。
また、最近の Reset CSS の傾向から boxSizing: "border-box"
がデフォルトっぽいので指定しています( content-box
指定なら scrollHeight
だけを代入で済むかも)。
さいごに
同様に useRef を使ったライブラリがあるので、より細かい設定がしたい場合は参考になると思います。
以上、この記事が誰かのお役に立てれば幸いです。
今すぐの転職でなくてもOKです!まずはお話しませんか?
現在弊社では一緒にお仕事をしてくださるエンジニアさんやデザイナーさんを積極募集しています。まずはカジュアルな面談で、お互いに大事にしていることをお話できたらうれしいです。詳しい応募要項は以下からチェックしてください。
- React, Next.js を得意とするフロントエンドエンジニア募集要項
- シニアクラスのフロントエンドエンジニア募集要項
- 抽象的な物事を具体的な機能にビジュアライズできるUIデザイナー募集要項
- UIデザイナーとして手ざわりのいいUIを作りたい業務委託パートナーさん募集(Wantedly)
パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでの面談でお話しましょう。ぜひお気軽にお問い合わせください!
話をしてみたい!