アプリ作成時に使用したReactのライブラリ

# 目次
[1. アイコン表示](#1-アイコン表示)
[2. クラスネームの複数指定及び動的制御](#2-クラスネームの複数指定及び動的制御)
[3. モーダル表示](#3-モーダル表示)
[4. ドラッグ&ドロップの機能実装](#4-ドラッグドロップの機能実装)

# 1. アイコン表示
ライブラリをインストール
```
$ npm install react-icons
```
react-iconsの公式ページより使いたいアイコンを調べる
[react-icons](https://react-icons.github.io/react-icons/icons?name=ai)

react-icons/[最初の2文字]でインポートする

``` javascript:App.js
import { AiOutlineCloseCircle } from 'react-icons/ai';

function App = () => {

  const onClickDel = e => {
    //クリック時の処理
  }

  return (
    <span onClick={onClickDel}>
      <IconContext.Provider value={{ size: '28px', style: { cursor: 'pointer'} }}>
        <AiOutlineCloseCircle />
      </IconContext.Provider>
    </span>
  )
};
export default App;
```

# 2. クラスネームの複数指定及び動的制御
ライブラリをインストール
```
$ npm install classnames
```

クラス名を複数指定したり、useStateを使って動的に制御出来る

``` javascript:App.js
import classNames from 'classnames';

function App = () => {

  const [status, setStatus] = useState("progress");
  const testClassNames = { panel: true, base: status === "progress" };

  return (
    <div className={classNames(testClassNames)}>
      //略
    </div>
    <div className={classNames("panel", "base")}>
      //略
    </div>
  )
};
export default App;
```

# 3. モーダル表示
ライブラリをインストール
```
$ npm install react-modal
```

呼び出し側の記述
setShowUser(true);でモーダルが表示される

``` javascript:App.js
import ReactModal from 'react-modal';
import UserModal from './UserModal';

function App = () => {

  /* Userダイアログの開閉ステータス */
  const [showUser, setShowUser] = React.useState(false);
  /* Userダイアログのデータ */
  const [userData, setUserData] = React.useState(new Map());

  /* Userモーダルを開いた時の処理 */
  const userOpen = () => {

  }

  /* Userモーダルを閉めた時の処理 */
  const userClose = () => {

  }

  const [innerHeight, setInnerHeight] = React.useState(window.innerHeight);

  return (
      {/* Userモーダル */}
      <UserModal
        showModal={showUser}
        modalOpen={UserOpen}
        modalClose={UserClose}
        modalData={UserData}
        setModalData={setUserData}
        innerHeight={innerHeight}
      />
  )
};
export default App;
```

呼び出し側のsetShowUser(true);で表示されるモーダル
ReactModal.Stylesのcontent内の値を変更して表示位置等を調整出来る
※例は画面下部から380px幅100%のモーダルを表示している


``` javascript:UserModal.js
import React,{ useState,useEffect,Component } from 'react';
import ReactModal from 'react-modal';

const UserModal = ({showModal, modalOpen, modalClose, modalData, setModalData, innerHeight }) => {

  var modal_top = (Number(innerHeight)-380)+'px';
  var modal_height = '380px';
  var select_size = 'is-normal';

  /* モーダルのスタイル */
  const modalStyle : ReactModal.Styles = {
    content: {
      position: 'absolute',
      top: modal_top,
      left: '0px',
      right: 'auto',
      bottom: 'auto',
      height: modal_height,
      width: '100%',

//      marginRight: '-50%',
//      transform: 'translate(-50%, -50%)'
    },
    // 親ウィンドウのスタイル（ちょっと暗くする）
    overlay: {
      background: 'rgba(0, 0, 0, 0.2)'
    }
  };

  return (
    <ReactModal
      isOpen={showModal}
      onAfterOpen={modalOpen}
      onRequestClose={modalClose}
      style={modalStyle}
      contentLabel="Settings"
      
      overlayClassName={{
        base: "overlay-base",
        afterOpen: "overlay-after",
        beforeClose: "overlay-before"
      }}
      className={{
        base: "content-base",
        afterOpen: "content-after",
        beforeClose: "content-before"
      }}
      closeTimeoutMS={500}
    >
      <div>
        //略
      </div>
    </ReactModal>
  );
}

export default UserModal;
```

# 4. ドラッグ&ドロップの機能実装
ライブラリをインストール
```
$ npm install react-smooth-dnd
$ npm install array-move
```

Container コンポーネントで全体を囲み、その中の移動させたい要素を Draggable コンポーネントで囲む
onDropでドラッグ&ドロップした時に呼ばれる関数を定義する
※removedIndexとaddedIndexで元の位置と挿入する位置のindexを取得できる



``` javascript:App.js
import React,{ useState,useEffect,Component } from 'react';
import { Container, Draggable } from 'react-smooth-dnd';
import { arrayMoveImmutable } from 'array-move';

function App = () => {

  /* ドラッグ&ドロップさせるデータ */
  const [draggableDatas, setDraggableDatas] = React.useState([{}]);

  /* リストをドラッグ＆ドロップした時のイベント */
  const onDrop = ({ removedIndex, addedIndex }) => {
    if(removedIndex!=addedIndex) {
      /* データを入れ替え */
      const sortDraggables = arrayMoveImmutable(draggableDatas, removedIndex, addedIndex);
      setDraggableDatas(sortDraggables);
    }
  }

  useEffect(() => {
    //draggableDatasを取得する処理
  }, []);

  return (
    <div>
      <Container onDrop={onDrop}>
        {draggableDatas.map(draggableData => (
          <DraggableList
            draggableData={draggableData}
          />
        ))}
      </Container>
    </div>
  )
};

/* ドラッグ&ドロップさせるリスト */
function DraggableList({draggableData}) {

  return (
    <Draggable key={draggableData.key}>
      <div>
        <table>
          <tr>
            </td>{draggableData.listNo}</td>
            </td>{draggableData.listName}</td>
          </tr>
        </table>
      </div>
    </Draggable>
  );
}
export default App;
```