【React】FullCalendarのカレンダーを整えるためのTips

1. 概要

前回の記事でヘッダーツールバーをNotion風にカスタマイズしました。
今回はその続きで、カレンダーのセルやコンテンツをカスタマイズしていきます。

目標はこんな感じ

2. 環境

CodeSandbox(React, TypeScriptテンプレート使用)

React v18.0.0
FullCalendar v5.11.3

3. 実装

3-1. 曜日のレイアウトを変更する

const StyleWrapper = styled.div`
	/* ・・・ 省略 */
	.fc .fc-col-header-cell {
	    font-size: 0.75rem;
			font-weight: normal;
	    color: #b6b5b3;
	    border: none;
	}
`

CSSを追加し、曜日の文字列と枠線を変更します。

3-2. カレンダーの枠線を変更する

const StyleWrapper = styled.div`
	/* ・・・ 省略 */
  .fc .fc-scrollgrid {
    border-width: 0;
  }

  .fc .fc-scrollgrid-section > * {
    border: none;
  }

  .fc .fc-scrollgrid-sync-table {
    border: 1px;
  }
`

こちらもCSSを追加し、カレンダーの枠線を変更します。
曜日と日付の両方に枠線が適用されているためそれを削除し、日付だけに対して枠線を引き直しています。

3-3. カレンダーのレイアウトを変更する

export const Calendar = (): JSX.Element => {
	// ・・・ 省略
return (
    <StyleWrapper>
      <FullCalendar
        // ・・・ 省略
        aspectRatio={1.6}
      />
    </StyleWrapper>
  )
}

aspectRatioというオプションでカレンダーの縦横比率を変更しています。

aspectRatio

3-4. 日付のテキストを変更する

import FullCalendar, {
  DayCellContentArg,
  EventInput
} from '@fullcalendar/react'
// ・・・ 省略
const StyleWrapper = styled.div`
	/* ・・・ 省略 */
	.fc .fc-daygrid-day-number {
    font-size: 0.75rem;
  }
`

export const Calendar = (): JSX.Element => {
// ・・・ 省略
const renderDayCell = (e: DayCellContentArg) => {
    const { date, dayNumberText } = e
    const renderDayNumberText =
      dayNumberText === '1日'
        ? format(date, 'M月d日')
        : dayNumberText.replace('日', '')
    return renderDayNumberText
  }

return (
    <StyleWrapper>
      <FullCalendar
        // ・・・ 省略
        headerToolbar={{ left: 'title', center: '', right: 'prev today next' }}
      />
    </StyleWrapper>
  )
}

dayCellContentというオプションを利用して日付表示の書き換えを行います。
Notionのカレンダーでは月初の日付だけ「○月1日」という表記となっているため、1日だった場合はdate-fnsのformatで変換しています。
また、CSSを追加して日付テキストのサイズを縮小させています。

Day-Cell Render Hooks

3-5. 土日の背景色を変更する

export const Calendar = (): JSX.Element => {
	// ・・・ 省略
return (
    <StyleWrapper>
      <FullCalendar
        // ・・・ 省略
        businessHours={{ daysOfWeek: [1, 2, 3, 4, 5] }}
      />
    </StyleWrapper>
  )
}

businessHoursというオプションを利用すると、特定の曜日や時間帯を強調表示することができます。
用途が少し違う気がしますが、daysOfWeekで月曜日から金曜日を指定し平日と土日の色を変更します。

businessHours

3-6. イベントのレイアウトを変更する

export const Calendar = (): JSX.Element => {
	// ・・・ 省略
return (
    <StyleWrapper>
      <FullCalendar
        // ・・・ 省略
        eventBackgroundColor={'#FFFFFF'}
        eventBorderColor={'#acaba9'}
        eventTextColor={'#37362f'}
      />
    </StyleWrapper>
  )
}

カレンダーに表示するイベントに関しては、背景色や枠線などの色を変更するためのオプションが用意されているため、 CSSではなくそれらのオプションを使用してレイアウトを変更していきます。

枠線と背景色を分けない場合はeventColorを指定するだけでOKです。

Docs Event Display

3-7. 今日の日付のレイアウトを変更する

const StyleWrapper = styled.div`
	/* ・・・ 省略 */
  .fc .fc-daygrid-day.fc-day-today {
    background-color: #ffffff00;
  }
`

const CircleNumber = styled.div`
  display: inline-flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  flex-flow: column;
  vertical-align: top;
  background: #eb5757;
  color: white;
  width: 30px;
  height: 30px;
`

export const Calendar = (): JSX.Element => {
	// ・・・ 省略
	const renderDayCell = (e: DayCellContentArg) => {
    const { date, dayNumberText, isToday } = e
    const replaceDayNumberText = dayNumberText.replace('日', '')

    return isToday ? (
      <CircleNumber>{replaceDayNumberText}</CircleNumber>
    ) : dayNumberText === '1日' ? (
      <>{format(date, 'M月d日')}</>
    ) : (
      <>{replaceDayNumberText}</>
    )
  }

return (
    <StyleWrapper>
      <FullCalendar
        // ・・・ 省略
      />
    </StyleWrapper>
  )
}

Notionのカレンダーでは今日の日付の数値が丸囲み文字で表現されています。
また、自分が確認した限りですが、今日の日付が月初だった場合は「○月1日」とせずに丸囲み文字の「1日」となっていました。

上記を実現するために、「3-4. 日付のテキストを変更する」で追加を行ったrenderDayCellに条件を追加し、 対象の日付が今日だった場合、丸囲み文字を返すよう変更を加えていきます。

丸囲み文字のCSSは以下を参考にしました。

【Flex使用】CSSで丸囲み文字 – Qiita

4. まとめ

最初の投稿から今回までの実装で、かなりNotionっぽいカレンダーになったのではないでしょうか! FullCalendarでカレンダーを実装する際に参考になれば幸いです。

Before
After

5. 関連リンク

【React】FullCalendarを使用してカレンダーを表示するためのTips

【React】FullCalendarのカレンダーにイベントを表示するためのTips

【React】FullCalendarのヘッダーツールバーを整えるためのTips

関連記事

  1. TypeScript

    【TypeScript】Vitestを使ってみる

  2. 【TypeScript】filterを使って配列からundefined…

  3. 【React×TypeScript】環境構築メモ

  4. TypeScript

    【TypeScript】触ってみる

  5. TypeScript

    【TypeScript】TypeScriptで変数の型を宣言する

  6. 【React】FullCalendarを使用してカレンダーを表示するた…

最近の記事

  1. AWS
  2. AWS
  3. AWS
  4. AWS
  5. AWS
  6. AWS
  7. AWS
  8. AWS

制作実績一覧

  1. Checkeys