MUI v5 DatePickerの使い方 その2 ~日本語化~


Vite+React+TypeScript 環境で MUI v5 DatePicker の使い方について、Tips的にまとめてみました。
今回はDatePickerの日本語化についての記事です。

MUI の導入方法についてはコチラ
Vite+React+TypeScript で、UIフレームワークにMUI(v5)を導入する。

MUI v5 DatePicker の記事一覧
MUI v5 DatePickerの使い方 その1 ~日付ライブラリの選定 から基本の使い方 まで~
MUI v5 DatePickerの使い方 その2 ~日本語化~

基本的な日本語化

date-fns の日本語ロケールを LocalizationProvider の locale に設定します。
選択した日付を「年月日」表示にするには、inputFormat や mask で設定します。

/* eslint-disable react/jsx-props-no-spreading */
import * as React from 'react'
import { Box, TextField } from '@mui/material'
import { LocalizationProvider, DatePicker } from '@mui/lab'
import AdapterDateFns from '@mui/lab/AdapterDateFns'
+ import ja from 'date-fns/locale/ja'

export function DatePickerSample() {
  const [value, setValue] = React.useState<Date | null>(null)

  const handleChange = (newValue: Date | null) => {
    setValue(newValue)
  }

  return (
-   <LocalizationProvider dateAdapter={AdapterDateFns} >
+   <LocalizationProvider dateAdapter={AdapterDateFns} locale={ja}>
      <Box sx={{ m: 2, width: '25ch' }}>
        <DatePicker
          label="DatePicker"
          value={value}
          onChange={handleChange}
+          inputFormat='yyyy年MM月dd日'
+          mask='____年__月__日'
          renderInput={(params) => <TextField {...params} />}
        />

      </Box>
    </LocalizationProvider>
  )
}

年月の順番は残念ですが、日本語化はできています。

モバイルモードの表示も、惜しいです。


DataPicker を もっと細かく日本語化する

■ デスクトップ版の DatePicker の日本語化

左右矢印をホバーした際に「Previous month」と「Next month」が表示されます。

左矢印をホバーしたときのテキストはleftArrowButtonText に指定し
右矢印をホバーしたときのテキストはrightArrowButtonTextに指定します。

 <DatePicker
   label="DatePicker"
   value={value}
   onChange={handleChange}
   inputFormat="yyyy年MM月dd日"
   mask="____年__月__日"
+  leftArrowButtonText="前月を表示"
+  rightArrowButtonText="次月を表示"
   renderInput={(params) => <TextField {...params} />}
 />

■ モバイル版の DatePicker の日本語化


画面上部の「DATEPICKER」はtoolbarTitleでテキストを指定します。
画面下部の「CANCEL」はcancelTextで、「OK」はokTextでテキストを指定します。

  <DatePicker
    label="DatePicker"
    value={value}
    onChange={handleChange}
    inputFormat="yyyy年MM月dd日"
    mask="____年__月__日"
    leftArrowButtonText="前月を表示"
    rightArrowButtonText="次月を表示"
+    toolbarTitle="日付選択"
+    cancelText="キャンセル"
+    okText="選択"
    renderInput={(params) => <TextField {...params} />}
  />

選択した日付の書式をtoolbarFormatで指定します。

  <DatePicker
    label="DatePicker"
    value={value}
    onChange={handleChange}
    inputFormat="yyyy年MM月dd日"
    mask="____年__月__日"
    leftArrowButtonText="前月を表示"
    rightArrowButtonText="次月を表示"
    toolbarTitle="日付選択"
    cancelText="キャンセル"
    okText="選択"
+    toolbarFormat="yyyy年MM月dd日"
    renderInput={(params) => <TextField {...params} />}
  />

選択した日付の書式はいい感じになりましたが、フォントサイズが大きすぎるので、少し小さくしたいと思います。
DialogPropsの sx にスタイルを指定します。

import * as React from 'react'
import { Box, TextField } from '@mui/material'
import { LocalizationProvider, DatePicker } from '@mui/lab'
import AdapterDateFns from '@mui/lab/AdapterDateFns'
import ja from 'date-fns/locale/ja'

export function DatePickerSample() {
  const [value, setValue] = React.useState<Date | null>(null)

  const handleChange = (newValue: Date | null) => {
    setValue(newValue)
  }

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} locale={ja}>
      <Box sx={{ m: 2, width: '25ch' }}>
        <DatePicker
          label="DatePicker"
          value={value}
          onChange={handleChange}
          inputFormat="yyyy年MM月dd日"
          mask="____年__月__日"
          leftArrowButtonText="前月を表示"
          rightArrowButtonText="次月を表示"
          toolbarTitle="日付選択"
          cancelText="キャンセル"
          okText="選択"
          toolbarFormat="yyyy年MM月dd日"
          renderInput={(params) => <TextField {...params} />}
+          DialogProps={{ sx: styles.mobiledialogprops }}
        />
      </Box>
    </LocalizationProvider>
  )
}

+ const styles = {
+  mobiledialogprops: {
+    '.PrivatePickersToolbar-dateTitleContainer .MuiTypography-root': {
+      fontSize: '1.5rem'
+    }
+  }
+}

ちょうどいい大きさになりました。

ヘッダの年月表示を修正する

ヘッダに表示されている「M月 yyyy」を「yyyy年M月」と修正します。

デスクトップ版:

モバイル版:

本来であればLocalizationProviderdateFormatsに表示書式を指定するといいようなのですが、
現時点のバージョン @mui/lab:v5.0.0-alpha.75 では正常に機能していません。

<LocalizationProvider dateAdapter={AdapterDateFns} locale={ja} dateFormats={{ monthAndYear: 'yyyy年MM月' }}

参考

そこで、css で強引に変更します。
デスクトップ版はPaperPropsに、モバイル版はDialogPropsにスタイルを指定します。

import * as React from 'react'
import { Box, TextField } from '@mui/material'

import { LocalizationProvider, DatePicker, MobileDatePicker } from '@mui/lab'

import AdapterDateFns from '@mui/lab/AdapterDateFns'
import ja from 'date-fns/locale/ja'

export function DatePickerSample() {
  const [value, setValue] = React.useState<Date | null>(null)

  const handleChange = (newValue: Date | null) => {
    setValue(newValue)
  }

  return (
    // <LocalizationProvider dateAdapter={AdapterDateFns} locale={ja} dateFormats={{ monthAndYear: 'yyyy MM' }} >
    <LocalizationProvider dateAdapter={AdapterDateFns} locale={ja}>
      <Box sx={{ m: 2, width: '25ch' }}>
        <DatePicker
          label="レスポンシブDatePicker"
          value={value}
          onChange={handleChange}
          inputFormat="yyyy年MM月dd日"
          mask="____年__月__日"
          leftArrowButtonText="前月を表示"
          rightArrowButtonText="次月を表示"
          toolbarTitle="日付選択"
          cancelText="キャンセル"
          okText="選択"
          toolbarFormat="yyyy年MM月dd日"
          renderInput={(params) => <TextField {...params} />}
+          PaperProps={{ sx: styles.paperprops }}
+          DialogProps={{ sx: styles.mobiledialogprops }}
        />
      </Box>
    </LocalizationProvider>
  )
}


const styles = {
  paperprops: {
    'div[role=presentation]': {
      display: 'flex',
      '& .PrivatePickersFadeTransitionGroup-root:first-of-type': {
        order: 2
      },
      '& .PrivatePickersFadeTransitionGroup-root:nth-of-type(2)': {
        order: 1,
        '& div::after':{
          content: '"年"'
        }
      },
      '& .MuiButtonBase-root': {
        order: 3
      }
    }
  },
  mobiledialogprops: {
    '.PrivatePickersToolbar-dateTitleContainer .MuiTypography-root': {
      fontSize: '1.5rem' // 選択した日付のフォントサイズを変更
    },
    'div[role=presentation]:first-of-type': {
      display: 'flex',
      '& .PrivatePickersFadeTransitionGroup-root:first-of-type': {
        order: 2
      },
      '& .PrivatePickersFadeTransitionGroup-root:nth-of-type(2)': {
        order: 1,
        '& > div::after': {
          content: '"年"'
        },
      },
      
      '& .MuiButtonBase-root': {
        order: 3
      }
    },
  }
}

ヘッダの表示が「yyyy年M月」になりました。

まとめ

強引ではありましたがなんとかDatePickerの日本語化対応ができました。
DatePickerはまだまだ正常に動作しない機能があり、今回の日本語化対応には予想以上に時間をとられてしまいました。