React で折り畳み (Collapse) をアニメーション付きで実装しました。
ちょっとハマったので記録を残しておきます。
実装コード
App.tsx
import { useState } from 'react'
import './App.css'
const App = () => {
const [open, setOpen] = useState(false)
const onClick = () => setOpen((prev) => !prev)
return (
<>
<button onClick={onClick}>{open ? 'close' : 'open'}</button>
<div className={`collapse ${open ? 'visible' : 'hidden'}`}>example</div>
</>
)
}
export default App
App.css
.collapse {
transition: height 300ms;
overflow: hidden;
color: white;
background-color: #333;
}
.visible {
height: 30px;
}
.hidden {
height: 0;
}
CSS のポイント
- 折り畳み (Collapse) を開いた時と閉じた時で height を切り替える
-
transition: height {X}ms;
を指定する -
overflow: hidden;
を指定する
ハマった箇所
overflow: hidden;
overflow: hidden;
を指定しないと、子要素(例だと「example」というテキスト)がアニメーションに関係なく表示されてしまいます。
stack overflow の記事を見て overflow: hidden;
を指定する事に気づきました。
display: none;
元は Bootstrap の Collapse を真似て作ろうと思ったのですが、元のソースコードを眺めていると非表示時は display: none;
が設定されていました。
この部分だけ読んでいた自分が早合点した可能性もありますが、 display: none;
だと DOM がマウントされていないので transition が機能しませんでした。