はじめに
- Material-UIでUIを作る(せっかくなので出たばかりのv5を使いたい)
- ReactHookFormで入力制御したい
といった条件下で、最初にHTML5に頼った日付入力<TextField type="date">で作ってみたところ
Chromeで表示したら↓のようにラベルの初期表示と"年/月/日"の表示が被って酷いことになっていた。
また、HTML5頼りのDatepickerだとまだうまく動かないブラウザがあるといった情報もちらほら見られたことから
Material-UI LabにあるDatePickerで日付入力を構築してみたのが本記事。
(LabはまだCoreに移せていないものという扱いらしいが、DatePickerについてはHTML5での入力が一般化してきたらCoreに移る前に無くなりそうな予感はしている)
目次
#環境
"@date-io/date-fns": "^2.11.0",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@mui/icons-material": "^5.0.0-rc.1",
"@mui/lab": "^5.0.0-alpha.48",
"@mui/material": "^5.0.0-rc.1",
"date-fns": "^2.24.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-hook-form": "^7.15.3",
#ソースコード
import { DatePicker, LocalizationProvider } from '@mui/lab'
import DateAdapter from '@mui/lab/AdapterDateFns'
import { Box, Button, TextField } from '@mui/material'
import { format } from 'date-fns'
import { ja } from 'date-fns/locale'
import React from 'react'
import { Controller, useForm } from 'react-hook-form'
// 日付入力フォーム
type InputDateProps = {
id: string
label: string
control: any
errors: any
}
const InputDate: React.FC<InputDateProps> = ({
id,
label,
control,
errors,
}) => {
return (
<Controller
name={id}
control={control}
rules={{
//必須入力チェック
required: '必須入力項目です',
//入力内容が日付として読み取れない状態を通さないためのチェック
validate: {
dateCheck: (value) =>
value.toString() !== 'Invalid Date' || '日付形式で入力してください',
},
}}
render={({ field }) => (
<LocalizationProvider dateAdapter={DateAdapter} locale={ja}>
<DatePicker
{...field}
label={label}
mask="____/__/__"
renderInput={(params) => (
<TextField
{...params}
margin="normal"
id={id}
error={Boolean(errors[id])}
helperText={errors[id] && errors[id].message}
/>
)}
/>
</LocalizationProvider>
)}
/>
)
}
//入力項目の使用
const Sample: React.FC<{}> = () => {
const initValue = {
date: '',
}
const {
control,
handleSubmit,
formState: { errors },
} = useForm<typeof initValue>({ defaultValues: initValue })
const onSubmit = (e) => {
//データ内容確認
console.log(e)
//Dateからstringに変換して取得
console.log(format(e.date, 'yyyy/MM/dd'))
}
return (
<Box p={4}>
<form onSubmit={handleSubmit(onSubmit)}>
<Box mb={4}>
<InputDate id="date" label="日付" control={control} errors={errors} />
</Box>
<Button variant="contained" type="submit">
submit
</Button>
</form>
</Box>
)
}
export default Sample
#機能概要
画面表示
初期表示
日付選択
バリデーション
入力データの取得結果
文字列で扱いたかったがDate型で取得される模様
⇒とりあえずonSubmitの処理でyyyy/MM/dd形式にフォーマットして使うことにした
#参考文献