TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

React+TailwindCSSで高さ可変のテキストエリアを作る

ほぼ個人メモ。

HTMLのtextareaは、入力に応じて高さを自動で調整する機能がない。
ChatGPTの入力欄のように、高さが自動で変わるテキストエリアを作るには、CSSJavaScriptで実装する必要がある。

JavaScriptで高さを計算するのはややこしいので、非表示のdivタグに内容をコピーして、そのタグの高さにflexのrelativeとabsoluteを使って合わせる方法がある。
The Cleanest Trick for Autogrowing Textareas | CSS-Tricks - CSS-Tricks

このサンプルでは、Alpine.jsを使っていたので、Reactで実装する方法を調べた。

React+TailwindCSSで実装

Reactとlessを使って実装する以下のページを参考に、React+TailwindCSSで実装した。
入力文字の行数で縦幅が可変するtextareaのReactコンポーネント - Qiita

import React, { useRef } from 'react'

const App: React.FC = () => {
  const hiddenInput = useRef<HTMLDivElement>(null)

  return (
    <>
      <div className='relative w-96 border flex'>
        <div className='invisible min-h-[3em] overflow-x-hidden whitespace-pre-wrap break-words p-3' aria-hidden={true} ref={hiddenInput}></div>
        <textarea className='absolute top-0 w-full h-full resize-none p-3' onChange={ e => { if (hiddenInput.current) hiddenInput.current.textContent = e.target.value + '\u200b' }}></textarea>
      </div>
    </>
  )
}

export default App

divタグにコピーする際に、末尾に幅ゼロの文字('\u200b')がないと、末尾が空行の場合、高さがずれるため追加している。