🐥
テキストエリア要素の高さ(height)を入力値に応じて動的に変更したい
概要
テキストエリア要素の height
をさっと動的に変更したい。
ライブラリの使用 ver. は以下のとおりです。
react: v18
next: v14.2.5
方法
以下の hook を作成し、使用します。
hook の内容と使い方は後述のとおりです。
import { useCallback, useRef } from 'react';
type UseAutoResizeTextareaProps = { defaultHeight: number; maxHeight: number };
export const useAutoResizeTextarea = ({ defaultHeight, maxHeight }: UseAutoResizeTextareaProps) => {
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const onChangeTextArea = useCallback(() => {
if (textAreaRef.current) {
// 元に戻した場合など、文字数が減少した場合に高さを合わせる
textAreaRef.current.style.height = 'auto';
if (textAreaRef.current.scrollHeight <= defaultHeight) {
textAreaRef.current.style.height = `${defaultHeight}px`;
return;
}
if (textAreaRef.current.scrollHeight >= maxHeight) {
textAreaRef.current.style.height = `${maxHeight}px`;
return;
}
textAreaRef.current.style.height = `${textAreaRef.current.scrollHeight}px`;
}
}, [defaultHeight, maxHeight]);
return { textAreaRef, onChangeTextArea };
};
hook について
前提、scrollHeight
の値を用いています。
→非表示の入力値も含めたテキストエリア要素の高さを表す数値です。
参考 の mdn に詳細な記述がありますのでご覧ください。
ざっくり処理内容
height
を auto
に変更し、表示領域の文字の高さを設定する共通処理の後に、
指定のテキストエリア要素の height
の最小値、最大値と、 scrollHeight
の値とを比較した結果に応じた処理を行います。
-
scrollHeight
が指定された最小値の高さより高いかつ、指定された最大値未満だった場合-
scrollHeight
> 最小値 かつscrollHeight
< 最大値
-
-
scrollHeight
が指定された最小値以下だった場合 -
scrollHeight
が指定された最大値以上だった場合
以下、比較した結果に応じた処理です。
-
scrollHeight
が指定された最小値の高さより高いかつ、指定された最大値未満だった場合- テキストエリア要素の
height
にscrollHeight
の値を入れる。
- テキストエリア要素の
-
scrollHeight
が指定された最小値以下だった場合- テキストエリア要素の
height
に指定された最小値を入れる。
- テキストエリア要素の
-
scrollHeight
が指定された最大値以上だった場合- テキストエリア要素の
height
に指定された最大値を入れる。
- テキストエリア要素の
hook の使い方
- hook を呼び出し、引数に以下の値を入れます。
-
defaultHeight
:テキストエリア要素の最小のheight
の px 数値。 -
maxHeight
:テキストエリア要素の最大のheight
の px 数値。
-
以下、呼び出しイメージです。
const { textAreaRef, onChangeTextArea } = useAutoResizeTextarea({ defaultHeight: 120, maxHeight: 720 });
-
textAreaRef
とonChangeTextArea
をテキストエリア要素に適用します。
以下、適用イメージです。
<textarea
className="box-border h-[120px] w-full resize-none appearance-none py-[12px] text-[20px] leading-[24px] outline-none"
name="post-text-area"
onChange={onChangeTextArea}
ref={textAreaRef}
/>
あとがき
個人開発などで、ライブラリを使いたくないときに役立てば幸いです。
最後までご覧いただきありがとうございました!
参考
Discussion