投稿日:2023年3月28日

引き続きReactのライブラリを検証します。
今回はアコーディオンメニューを実装します。

ググったらreact-accessible-accordion というものが見つかりました。

検証してみましょう。

こちらも最初にインストールしましょう。
ターミナルで作業ディレクトリに移動し以下を実行します。

npm install --save react-accessible-accordion

デモサイト はこちらになります。

デモを見るとアコーディオンの仕様が数種類あるのが分かります。
今回は、クリックでメニューが開閉するもの(Collapsing the last expanded item)を検証してみます。

デモサイト からコピペし少々カスタマイズしました。

import React from 'react';

import {
    Accordion,
    AccordionItem,
    AccordionItemHeading,
    AccordionItemButton,
    AccordionItemPanel,
} from 'react-accessible-accordion';

import '../css/accordion.scss';

// Demo styles, see 'Styles' section below for some notes on use.
import 'react-accessible-accordion/dist/fancy-example.css';

export default function AccordionExam() {
    return (
        <Accordion allowZeroExpanded>
            <AccordionItem>
                <AccordionItemHeading>
                    <AccordionItemButton>
                        メニュー_01
                    </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                    <div className="menuWrap">
                      <a href="/submenu-01_01">サブメニュー_01_01</a>
                      <a href="/submenu-01_02">サブメニュー_01_02</a>
                      <a href="/submenu-01_03">サブメニュー_01_03</a>
                    </div>
                </AccordionItemPanel>
            </AccordionItem>
            <AccordionItem>
                <AccordionItemHeading>
                    <AccordionItemButton>
                        メニュー_02
                    </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                    <div className="menuWrap">
                      <a href="/submenu-02_01">サブメニュー_02_01</a>
                      <a href="/submenu-02_02">サブメニュー_02_02</a>
                      <a href="/submenu-02_03">サブメニュー_02_03</a>
                    </div>
                </AccordionItemPanel>
            </AccordionItem>
        </Accordion>
    );
}

▲16行目の allowZeroExpanded がオプションになります。
13行目にスタイルのセクションを参考にしてください。 との記述があります。
上記のリンクを辿ると、スタイルのカスタマイズを強く勧めている記載があります。
▼CSSもカスタマイズしました。体裁を整えるのに少々苦労しました。。。

#root {
  .accordion {
    border: initial;
  }

  .accordion__heading {


    .accordion__button {
      transition: .3s;
      padding-left: initial;
    }
  }

  .accordion__panel {
    transition: .3s;
  }

  .menuWrap {
    display: flex;
    flex-direction: column;

    a {
      padding: .5em;
    }
  }

  .accordion__item+.accordion__item {
    border-top: initial;
  }
}

▼結果、このようになります。

デザインや機能など、なかなか良いと思います。
が、クリックしないと展開しないようで、マウスホバーで動作しないか検証してみました。

結果、GitHubのissuses として掲載されてましたができないようです。

よくあるheaderでのメニューとして使うには、横並びにするなど、さらにCSSカスタマイズが必要になってきます。
先日検証したreact-burger-menu の中に組み込んでスマホ表示に特化したほうが良いと思いました。

さらにカスタマイズし以下のようなものを作ってみました。

JSXソースコードです。

import React from 'react';
import { slide as Menu } from 'react-burger-menu';

import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemButton, AccordionItemPanel, } from 'react-accessible-accordion';

import 'react-accessible-accordion/dist/fancy-example.css';

import '../css/index.scss';
import '../css/burger.scss';
import '../css/accordion.scss';

class Burger extends React.Component{
  showSetting(event) {
    event.preventDefault();
  }

  render () {
    return (
      <div id="outer-container">
        <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } right>
          <main id="page-wrap">
            <a id="home" className="menu-item" href="/">Home</a>
            <Accordion allowZeroExpanded>
              <AccordionItem>
                <AccordionItemHeading>
                  <AccordionItemButton>
                    メニュー_01
                  </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                  <div className="menuWrap">
                    <a href="/submenu-01_01">サブメニュー_01_01</a>
                    <a href="/submenu-01_02">サブメニュー_01_02</a>
                    <a href="/submenu-01_03">サブメニュー_01_03</a>
                  </div>
                </AccordionItemPanel>
              </AccordionItem>
              <AccordionItem>
                <AccordionItemHeading>
                  <AccordionItemButton>
                    メニュー_02
                  </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                  <div className="menuWrap">
                    <a href="/submenu-02_01">サブメニュー_02_01</a>
                    <a href="/submenu-02_02">サブメニュー_02_02</a>
                    <a href="/submenu-02_03">サブメニュー_02_03</a>
                  </div>
                </AccordionItemPanel>
              </AccordionItem>
            </Accordion>
          </main>
        </Menu>
      </div>
    );
  }
}
export default Burger;

▲前回作ったburgerメニューの中にアコーディオンメニューを入れ込んでみました。
アコーディオンのscssは以下です。

#root {
  .accordion {
    border: initial;
  }

  .accordion__heading {
    .accordion__button {
      transition: .3s;
      padding: initial;
      background-color: initial;
      color: #fff;
    }
  }

  .accordion__panel {
    transition: .3s;
    padding: initial;
  }

  .menuWrap {
    display: flex;
    flex-direction: column;

    a {
      padding: .5em;
    }
  }

  .accordion__item+.accordion__item {
    border-top: initial;
  }
}
まとめ

なかなかコピペだけで完成することはないようです。
楽して手に入るものはないので、じっくりとソースを把握しながら勉強し、自分なりのものを作らないといけませんね。
ここまで労力を使うならフルスクラッチで作ってもかかる時間は変わらないのかも知れません。

さらに検証し、精進したいと思います。
学んだことは必ず仕事に役立たせます。
最後まで読んでくださりありがとうございました。

関連サイト
Pocket