react-big-calendar は、react専用のカレンダーライブラリであるが、セットアップで必ず言語設定を行う必要がある。
公式には、言語対応のために使う日付フォーマットについて、
You can use either the Moment.js, Globalize.js, date-fns, Day.js localizers.
と記述しているが、なかなか上手く日本語化することができず、date-fns
を使ってやっとのこと日本語か対応することが出来た。
この記事ではその手法について記述する。
完成形
これを作っていく。
注意書き
日本語対応の箇所以外のコードや説明は省きます。
実行環境
React v18
Next.js v13
react-big-calendar v1.8
@mui/material v5.6.4
1. 日本語対応
もろもろインポート
まず、 react-big-calendar
関連から必要なものを引っ張ってくる。
dateFnsLocalizer
が必要になるので、import。
以下を最初の状態とする。
import 'react-big-calendar/lib/css/react-big-calendar.css';
import { Calendar, dateFnsLocalizer } from 'react-big-calendar'
export const MyCalendar = () => {
return (
<>
<Calendar />
</>
);
}
date-fns
からもろもろインポート
日本語対応のため、date-fns
をフル活用する。
import format from "date-fns/format";
import getDay from "date-fns/getDay";
import parse from "date-fns/parse";
import { ja } from "date-fns/locale";
import startOfWeek from "date-fns/startOfWeek";
localize 用の設定を追加
何気に最初の locales
の設定が沼った。
const locales = {
"ja": ja
};
const localizer = dateFnsLocalizer({
format,
parse,
startOfWeek,
getDay,
locales
});
localizer
を、Calendar
の localizer
props にセット。
<Calendar
localizer={localizer}
/>
盛り付け
import 'react-big-calendar/lib/css/react-big-calendar.css';
import { Calendar, dateFnsLocalizer } from 'react-big-calendar'
import format from "date-fns/format";
import getDay from "date-fns/getDay";
import parse from "date-fns/parse";
import { ja } from "date-fns/locale";
import startOfWeek from "date-fns/startOfWeek";
const locales = {
"ja": ja
};
const localizer = dateFnsLocalizer({
format,
parse,
startOfWeek,
getDay,
locales
});
export const MyCalendar = () => {
return (
<>
<Calendar
localizer={localizer}
// .... その他のパラメタ
/>
</>
);
}
これで以下のものが出来上がる。
ここまではおそらく公式の情報でできる。
2. ツールバーの日本語対応
ツールバーを以下のように追加する。 any
を使っているのは見逃してほしい。
toolbar.label
は、カレンダーの現在日付を表示するパラメタであるので、それを日本語表示したい。
const SchedulerToolbarWrapper = styled("div")({
display: "flex",
width: "80%",
marginBottom: "8px",
flexDirection: "row",
alignItems: "center"
});
export interface ICustomToolbarProps {
view: string;
label: any;
localizer: any;
onNavigate: (action: any) => void;
onView: (view: any) => void;
}
const SchedulerToolbar = (toolbar: ICustomToolbarProps) => {
// 設定している日付を取得する
// gotoNextとかで日付が変わったら変更する
const goToBack = () => { toolbar.onNavigate('PREV');};
const goToNext = () => { toolbar.onNavigate('NEXT');};
const goToCurrent = () => { toolbar.onNavigate('TODAY');};
return (
<SchedulerToolbarWrapper>
{ /* 日付を出力 */ }
<div>{toolbar.label}</div>
<Button variant="contained" size="small" color="primary" sx={{ mx: "8px;" }} onClick={goToBack}>前日</Button>
<Button variant="contained" size="small" color="primary" onClick={goToNext}>翌日</Button>
</SchedulerToolbarWrapper>
);
}
これをそのまま Calendar
の components
props に追加する。
export const MyCalendar = () => {
return (
<>
<Calendar
localizer={localizer}
components={{ toolbar: props => ( <SchedulerToolbar {...props} /> ) }}
/>
</>
);
}
すると結果は以下。
日本語になっていない。
なので culture
props を設定する。
export const MyCalendar = () => {
return (
<>
<Calendar
localizer={localizer}
culture={"ja"}
components={{ toolbar: props => ( <SchedulerToolbar {...props} /> ) }}
/>
</>
);
}
すると今度はこうなる。
う〜〜〜ん、なんか惜しい。「xx年〇〇月▲▲日◎曜日」みたいにならないのか。
そこで format
props を使って、日付のフォーマットをしよう。
const formats = useMemo(() => ({
dayHeaderFormat: 'yyyy年MM月dd日(EEEE)',
}), [])
export const MyCalendar = () => {
return (
<>
<Calendar
localizer={localizer}
formats={formats}
culture={"ja"}
components={{ toolbar: props => ( <SchedulerToolbar {...props} /> ) }}
/>
</>
);
}
結果はついに...!!
日本語表示することが出来ました!!👏
こうして5時間ほどかけて、日本語対応することが出来ました。
めでたしめでたし。