FullCalendarを利用して簡単にカレンダーを作成する

# はじめに

こんにちは！
リンクアンドモチベーションでエンジニアをしている[Ohtsuka](https://twitter.com/big_mound_26)です！
リンクアンドモチベーションには今年の８月にジョインしました！
今回、[リンクアンドモチベーションアドベントカレンダー2022](https://qiita.com/advent-calendar/2022/mcs)の18日を担当させてもらいます！

アドベントカレンダーということで今回はJavaScriptでサクッとカレンダーとイベントの表示できる[FullCalender](https://fullcalendar.io/)とReactを使ってカレンダー画面を作ってみます（？？）

# FullCalenderとは
手軽にカレンダーを実装できるライブラリになります！
月表示、週表示、日表示など手軽に見た目も変更できます！有償版ではさらに多くのことをできますが、今回は無償版を触ってみようと思います📅


![スクリーンショット 2022-12-15 2.26.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/e72316f0-5a9f-8606-9754-bca23453077a.png)

# インストール
yarnなどでインストールできます！
こちらは公式のドキュメントにも記載されているので、詳しくはそちらをご参照ください！
```zsh
yarn add @fullcalendar/react @fullcalendar/timegrid @fullcalendar/daygrid @fullcalendar/interaction 
```


# カレンダーの表示

今回はsrc/components/Calendar.jsを作成し、
カレンダー表示に必要最低限のものだけimportしています！
作成したコンポーネントをApp.jsから呼び出して、カレンダーを表示してみます！

```js:Calendar.js
import FullCalendar, { EventContentArg } from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';

export const Calendar = () => {
    return (
        <FullCalendar
            plugins={[dayGridPlugin, timeGridPlugin, listPlugin]}
            nowIndicator={true}
            selectable={true}
            selectHelper={true}
            allDaySlot={false}
        />

    );
};
```
とりあえずは表示されていそうですね！
![スクリーンショット 2022-12-15 1.48.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/7dd0c3ec-3e30-9613-6048-c25ed22f9c11.png)

# カレンダーの表示カスタマイズ

ここからカレンダーの表示形式を変更していきます！
自分はFullCalendarの引数で以下の設定をしました！

```js
//日本語化
locale="ja"
//ヘッダーの配置
headerToolbar={{　
    left: 'prev,next',
    center: 'title',
    right: 'dayGridMonth,listMonth,listDay',
}}
//フッターの配置
footerToolbar={{
    right: "prev,next"
}}
//ボタンに表示するテキスト
buttonText= {{
    prev:     '<',
    next:     '>',
    prevYear: '<<',
    nextYear: '>>',
    today:    '今日',
    month:    'カレンダー',
    week:     '週',
    day:      '日',
    listMonth: '今月のToDo',
    listDay: '今日のToDo'
}}
```

表示変更もうまくできました！
「今月のイベント」、「今日のイベント」などのボタンも追加していますが、
これはlistMonth, listDayボタンのテキストで、それぞれ月のイベントを一覧表示、１日のイベントを一覧表示できるように切り替えることができます！（イベントの登録はまだしていないので一旦割愛します！）
![スクリーンショット 2022-12-15 2.44.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/ee2966f9-982d-7c4e-d4ec-242a3a38e793.png)

# イベントの表示

続いてイベントの表示です！
今回はFullCalendarの紹介がメインですので、イベントの内容はコードにそのまま書き込んだものを利用させてもらいます！
```js
const calendarEvents = [
    {
        id: 1,
        title: 'Qiita書く',
        description: 'リンクアンドモチベーションのアドベントカレンダーを書く',
        start: '2022-12-15',
        end: '2022-12-16',
        backgroundColor: 'green',
        borderColor: 'red',
        editable: true
    },
    {
        id: 2,
        title: 'Qiita投稿',
        description: 'リンクアンドモチベーションのアドベントカレンダーを投稿する',
        start: '2022-12-18',
        end: '2022-12-18',
        backgroundColor: 'green',
        borderColor: 'red',
        editable: false
    }
]
```

上の配列をeventsの引数とすることでイベントの内容がカレンダー上に表示されます！
めちゃくちゃ簡単ですね！
```
events={calendarEvents}
```
![スクリーンショット 2022-12-15 3.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/7d52b37b-4661-db4c-d79c-3475a83b712d.png)

ちなみに「カレンダーの表示カスタマイズ」で配置した「今月のイベント」、「今日のイベント」は以下のようになります！

- 今月のイベント
![スクリーンショット 2022-12-15 3.06.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/597c15a0-849c-77ae-b909-9f2a3e160340.png)

- 今日のイベント
![スクリーンショット 2022-12-15 3.07.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/72bff39d-10d6-ca4e-4b57-8448a89c6712.png)


# カレンダーのイベントハンドラ

最後にイベントハンドラの設定をしていきます！
今回、以下の３つのイベントハンドラに変更を加えていきます！

- dateClick
  - 日付がクリックされた場合に発火
  - 今回はreact-modalを使ったモーダルに入力フォームが表示されるようにしています！
  　　イベント一覧をuseStateで管理しておけばフォームでの入力を終えたあと、カレンダーに反映できます！
　　　　　　クリックされた日付は```e.dateStr```から取得できます！
- eventClick
  - イベントがクリックされた場合に発火 
  - dateClickと同じく、react-modalを使ったモーダルに入力フォームが表示されるようにしています！
  　　イベントのIDは```e.event.id```で取得できます！
![スクリーンショット 2022-12-15 3.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/017ceb1e-817f-e547-18fa-02756b44b3d9.png)
 ※Clickのイベントハンドラについてはシングルクリックで発火するので、ダブルクリックにしたい場合は別途ハンドラ内のメソッドで実装をする必要があります。

- eventContent
  - イベント上にホバーしてる間に発火
  - 今回はreact-tooltipを使ったツールチップで概要が表示されるようにしています！
    イベントの概要は```e.event.extendedProps.description```から取得できます！
 ![スクリーンショット 2022-12-15 3.32.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/55671c23-5d6b-2fba-b184-6717039f9160.png)


細かい実装はかなり省きましたが、FullCalendarを使ってカレンダーを表示するまでの流れは掴めたのではないでしょうか！
FullCalendarは調べるともっと詳しい使い方も出てくるので、気になった方はぜひ使ってみてください！