MUI v5 DatePickerの使い方 その1 ~日付ライブラリの選定 から基本の使い方 まで~


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 ~日本語化~

日付ライブラリの選定

まずはDatePickerが使用する日付ライブラリを選定します。
サポートされているライブラリは以下の4つです。
Moment.jsは現在すでに開発が停止しているため、残る3つから選びます。

  1. date-fns
  2. Day.js
  3. Luxon
  4. Moment.js 現在は非推奨です。詳しくは Moment.js | Docs#Project Status

人気順で比較

人気順で見ると Day.js か date-fns のどちらかが良さそうです。
Days.js の人気は、 Moment.js からの移行で、ほぼ同じ使用感の Days.js が選ばれていることが一因のようです。

■ npm trends ダウンロード数で比較

npm trends での ダウンロード数で比較すると date-fns > Day.js > Luxon の順になります。

■ git star の数で比較

gitstar の数で比較すると Day.js(38,332件) > date-funs(28,381件) > luxon (12,274件) の順になります。

■ 日本語記事の豊富さ

日本語記事も Day.js > date-funs > luxon の順で、Day.jsの記事が多いです。

書き方で比較

実際に書いてみて、リファレンスの分かりやすさと書き方の好みで比較してみます。

1. date-fns

https://date-fns.org/

ホームページのリファレンスがわかりやすく、ホームページだけの情報で使いこなせそうです。
書き方は関数型のアプローチでシンプルで理解しやすいと感じました。
使用する関数を一つずつimportするのが面倒ではありますが、反対にどのライブラリの何を使用しているのか解りやすいとも言えます。

インストール

npm install date-fns

使用方法
使用する関数を一つずつ import して使用します。

import { format, add, addMonths, getMonth } from 'date-fns'

// 本日日付
const today = new Date()

// 書式を設定
const formatday = format(today, 'yyyy年MM月dd日 HH:mm:ss')
console.log(formatday)

// 年と月を加算
const addday = add(today, {years: 1, months: 2})
console.log(addday)

// 月を加算
const addmonth = addMonths(today, 1)
console.log(addmonth)

// 月を取得(※月は0始まり)
const getmonth = getMonth(today)
console.log(getmonth)

2. Day.js

https://day.js.org/

バンドルサイズ 2.8kB の軽量ライブラリです。
こちらは、コア機能の dayjs に必要なプラグインをextendで機能追加して使用します。
dayjs.Dayjsオブジェクトのメソッドとして必要な機能を実行します。
date-fns が関数型のアプローチに対して、Day.js はオブジェクト型のアプローチです。

インストール

npm install dayjs

使用方法
こちらは必要なプラグインを extend して使用します。

import dayjs, { extend } from 'dayjs'
import duration from 'dayjs/plugin/duration'

extend(duration)

// 本日日付
const today = dayjs() 

// 書式を設定
const formatday = today.format('YYYY年MM月DD日 HH:mm:ss')
console.log(formatday)

// 年と月を加算
const addday = today.add(dayjs.duration({years: 1, months: 2}))
console.log(addday)

// 月を加算
const addmonth = today.add(1, 'M')
console.log(addmonth)

// 月を取得(※月は0始まり)
const getmonth = today.get('month')
console.log(getmonth)

Luxon

https://moment.github.io/luxon/#/
ホームページのリファレンスだけではわかりにくいと思いました。
インストールから躓きました。

インストール
typescriptの場合は @types/luxon もインストールします。

npm install luxon
npm install @types/luxon

使用方法

import { DateTime } from 'luxon'

const today = DateTime.now()

const formatday = today.toFormat('yyyy年MM月dd日 HH:mm:ss')
console.log(formatday)

const addday = today.plus({years: 1, months: 2})
console.log(addday)


const getmonth = today.month
console.log(getmonth)

採用した日付ライブラリ

一番わかりやすいと感じた date-fns を採用することにしました。
date-fns は MUI v5 ホームページのサンプルでも使用されているというのも安心です。

MUI v5 DatePickerの基本的な使い方

日付ライブラリの選定が終了したので、DatePicker の 使い方を見ていきます。

インストール

DatePickerは Lab パッケージに含まれているので、@mui/lab をインストールします。
Labパッケージは、Coreパッケージに含められない新しいコンポーネントを提供するパッケージです。
Coreパッケージと分離しておくことで、Coreパッケージより多くのアップデートが必要なLabパッケージを、Coreパッケージに影響することなくスムーズにバージョンアップできます。

npm install @mui/lab

続いて日付ライブラリ date-fns と、date-fns のアダプターパッケージをインストールします。

npm install date-fns
npm install @date-io/date-fns

DatePickerの基本的な使い方

基本的な DatePickerコンポーネントです。
レスポンシブに対応していて、PCサイズの画面とモバイルサイズの画面で動作が変わります。
inputFormat で入力書式、mask で入力書式に合わせたマスクを設定します。

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

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

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

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} >
      <Box sx={{ m: 2, width: '25ch' }}>

        <DatePicker
          label="DatePicker"
          value={value}
          onChange={handleChange}
          inputFormat='yyyy/MM/dd'
	  mask='____/__/__'
          renderInput={(params) => <TextField {...params} />}
        />

      </Box>
    </LocalizationProvider>
  )
}

PCサイズの場合

モバイルサイズの場合

DatePickerコンポーネントは画面サイズに応じて、その動作が変わりますが、
PCサイズに特化したコンポーネントだけでよい場合 DesktopDatePicker が 、
モバイルサイズに特化したコンポーネントだけでよい場合 MobileDatePicker があります。

年のみ選択できるDatePicker

年のみ選択できるDatePickerは、
views に yearを指定することで、年を選択するダイアログだけが表示されます。
inputFormat と mask を 年部分だけを表示するように指定します。

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

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

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

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns}>
      <Box sx={{ m: 2, width: '25ch' }}>
        <DatePicker
          label="DatePicker 年のみ"
          value={value}
          onChange={handleChange}
          views={['year']}
          inputFormat='yyyy'
          mask='____'
          renderInput={(params) => <TextField {...params} />}
        />
      </Box>
    </LocalizationProvider>
  )
}

年月のみ選択できるDatePicker

年月のみ選択できるDatePickerは、
views に yearmonthを指定することで、年を選択するダイアログと月を選択するダイアログが表示されます。
inputFormat と mask を 年月部分だけを表示するように指定します。

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

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

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

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns}>
      <Box sx={{ m: 2, width: '25ch' }}>
        <DatePicker
          label="DatePicker 年月のみ"
          value={value}
          onChange={handleChange}
          views={['year', 'month']}
          inputFormat='yyyy/MM'
          mask='____/__'
          renderInput={(params) => <TextField {...params} />}
        />
      </Box>
    </LocalizationProvider>
  )
}

まとめ

次回はDatePicker の日本語化について記事にしたいと思います。