ReactでAccordionコンポーネント作成


何を作るか

reactでAccordionのコンポーネントを作ったので、記事を書いてみます。
使い回し効くと思うので、新規で作られる方の何かの手助けになればと思います

↓こんな感じです

codeSandBoxに残したので、動くサンプルはこちらに
https://codesandbox.io/s/determined-sanne-txpov?from-embed=&file=/src/Accordion.tsx:146-285っd

作り方

呼び出す側

この後作成するAccordionコンポーネントを呼び出し、
アコーディオンの中を コンポーネントの中に入れていきます。
<Accordion>ここです</Accordion>

App.tsx
import { Accordion } from "./Accordion";

export default function App() {
  return (
    <div className="App">
      <h1 >Accordion</h1>
      <Accordion>
        <ul>
          <li>list1</li>
          <li>list2</li>
          <li>list3</li>
          <li>list4</li>
          <li>list5</li>
        </ul>
      </Accordion>
    </div>
  );
}


アコーディオンコンポーネント

ボタンと、アコーディオンの中身の2つを作成し、
ボタンを押すことでアコーディオンの中身の表示/非表示を切り替えます。

Accordion.tsx

export const Accordion = (props:any) => {

  const toggleAccordion = () => {
   //アコーディオンの関数
  };
  return (
    <div>
      <div>{props.children}</div>
      <button onClick={toggleAccordion}>
        ボタンの文字
      </button>
    </div>
  );
};

次に関数を作成します。
ボタンを押すたびにfalse/trueが切り替わるだけのシンプルな機能です。

Accordion.tsx

export const Accordion = (props:any) => {

  const [setActive, setActiveState] = useState(false);
  const toggleAccordion = () => {
    setActiveState(!setActive ? true : false);
  };
  return (
    <div>
      //↓Accordionの中身
      <div>{props.children}</div>
      <button onClick={toggleAccordion}>
        ボタンの文字
      </button>
    </div>
  );
};

このfalse/trueに合わせてCSSを調整していけばOKです。

Accordion.tsx

export const Accordion = (props: any) => {
  const [setActive, setActiveState] = useState(false);

  const toggleAccordion = () => {
    setActiveState(!setActive ? true : false);
  };

  const accordionHeight = setActive
    ? css`
        max-height: 800px;
      `
    : css`
        max-height: 0px;
      `;

  const rotate = setActive
    ? css`
        margin-top: 5px;
      `
    : css`
        margin-bottom: 10px;
        transform: rotate(135deg);
      `;

  return (
    <div css={accordionContainer}>
      <div css={[accordionContent, accordionHeight]}>{props.children}</div>
      <button css={accordion} onClick={toggleAccordion}>
        <div css={accordionTitle}>
          <label css={[accordionArrow, rotate]} />
        </div>
      </button>
    </div>
  );
};

const accordionContainer = css`
  display: flex;
  flex-direction: column;
`;

const accordion = css`
  color: #dddddd;
  background: #ffffff;
  cursor: pointer;
  height: 38px;
  outline: none;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 10px;
`;

const accordionTitle = css`
  font-family: "Open Sans", sans-serif;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const accordionArrow = css`
  width: 10px;
  height: 10px;
  border: 2px solid;
  border-color: #565656 #565656 transparent transparent;
  transform: rotate(-45deg);
  cursor: pointer;
  transition: transform 0.3s ease;
`;

const accordionContent = css`
  overflow: auto;
  transition: max-height 0.3s ease;
`;

感想

作るときはどうやってやろうかと色々考えたんんですが、
終わってみるとめっちゃ簡単でした
もっといいやり方あればご教示ください