details要素でディレクトリ表示をする

公開:2020/09/30
更新:2020/09/30
1 min読了の目安(約1300字TECH技術記事

どうも、 @uzimaru0000 です。
ディレクトリツリーを表示することがあったのでその時に使った tips 的なのをまとめていきます。

details要素

HTML5 には details 要素があります。

<details>
    <summary>detailsのtitle</summary>
</details>

GitHub の MarkDown でも使えます。

この details 要素ですが、勝手に畳んでくれる表示にしてくれます。
便利ですね。

実装

React あたりで実装してみましょう。

type Dir = { [key: string]: Dir | File };
type File = string;

const isDir = (entity: Dir | File): entity is Dir =>
  !(entity instanceof Array) && typeof entity === 'object';

const DirView = ({ dir }: { dir: Dir; }) => (
  <>
    {Object.entries(dir).map(([name, entity]) =>
      isDir(entity) ? (
        <details key={name}>
          <summary>{name}</summary>
          <DirView dir={entity} />
        </details>
      ) : (
        <div key={name}>{name}</div>
      )
    )}
  </>
);

ポイントは再帰的にコンポーネントを使うところです。
(データ構造としてツリーを描画しているので当然といえば当然ですが...)

この時点で階層構造になっているので「ディレクトリの下のディレクトリにあるファイル」みたいな表示もできるのですが、全てが揃ってしまうので少し見づらいです。
そこで以下のような CSS を書いてあげましょう。

details > details,
details > div {
  padding-left: 16px;
}

padding を付けてあげるだけです。
ポイントは details の子要素の details 要素(div 要素)に style を当てるということです。
これでネストした details 要素にネストした分だけ padding が入ります。

まとめ

↑ で実際に動いているのを見ることができます。
思いつきで実装したら意外とできてしまったのでまとめてみました。
ファイルツリーやツリー構造のものを描画する際は使ってみてください。