はじめに
まず、この記事を書いている私がReact、MUI歴3ヶ月ちょっとの半端者です。
そのため、フィーリングで書いている部分が多々あります。
間違っている部分があるかもしれませんがとにかく実装するため調べてわかったことを書き記します。
やりたかったこと
調整さんみたいなものを作りたかった。
その中でカレンダーを押したら、選択した日時が入力されるっていう機能を実装しようと調べ始めた。
DayPicker,TimePicker
カレンダーや時計のコンポーネントを使用して日時を決まった形式で出力してくれるコンポーネントの総称。
ライブラリとして公開されているものが「なんちゃらDayPicker」みたいな名前で公開されている。
まず、このPickerという名前にたどり着かなくてやりたいことを実現するためのコンポーネント探すのに苦労した。
MUIの他にも公開されているものはあるが、CSSを書きたくなかったのと他の部分で既にMUIを使っていたのでMUIのDateTimePickerを使うことにした。
MUIのDateTimePicker
英語だけどチュートリアルはある。
チュートリアルを見ると、表示とかはやるけど実際に現在時刻の表示や日時を出力するときのフォーマットは別のライブラリに任せてる感じかな?ってなった。
実際に使ったやつ
チュートリアルではないけどカレンダーを常に表示できないかなあ〜ってことで探してたら、staticモードを見つけた。
じゃあ、これを使おうと試行錯誤した結果以下のようなコードに落ち着いた。
import React, { useState } from 'react';
import { StaticDateTimePicker, LocalizationProvider } from '@mui/x-date-pickers/';
import { Box, TextField } from '@mui/material/';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { useRecoilState } from 'recoil';
import format from 'date-fns/format';
import { ja } from 'date-fns/locale';
import { formValueState, selectedDayState } from '../../../recoil/state';
const PickDayCalendar = () => {
const [value, setValue] = useState(); //カレンダーの中で値を保持しておくためのstate
const [selectedDates, setSelectedDates] = useRecoilState(selectedDayState);
const [values, setValues] = useRecoilState(formValueState); //今回はあんまり関係ない裏でゴニョゴニョstate
const handleChange = (v) => {
setSelectedDates(selectedDates ? selectedDates+'\n'+format(v, 'yyyy-MM-dd HH:mm') : format(v, 'yyyy-MM-dd HH:mm'));
const newValues = {
...values,
proposed_at: selectedDates.split('\n'),
};
setValues(newValues);
};
return (
<Box>
<LocalizationProvider adapterLocale={ja} dateAdapter={AdapterDateFns}
localeText={{
previousMonth: '前月を表示',
nextMonth: '次月を表示',
}}>
<StaticDateTimePicker
displayStaticWrapperAs="mobile"
openTo="day"
toolbarTitle="日付選択"
toolbarFormat="MM月dd日"
disablePast={true}
value={value}
onChange={(v)=>{
setValue(v);
}}
onAccept={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
</Box>
);
};
export default PickDayCalendar;
絶対無駄はあるけどこの形に落ち着いた。
recoil使ってますが、この辺はuseStateで置き換えれると思う。
軽く説明
コードに色々書いていますが、重要なPickerのパラメータです。
- displayStaticWrapperAs
モバイル版にするかPC版にするか。PC版にするとAMとPMの表記が飛び出しまくって治せなかったのでモバイル版を使ってます。 - disablePast
過去の日程を選択できないようにするパラメータ。 - onAccept
OKボタンを押したときに実行される関数を入れるところ。
この3つが個人的には見つけにくくて辛かった。
あとは説明が下手なので自分で調べてください。
propsの説明を日本語訳して読んだり、stackoverflowとかで調べたらわかるかも。
結論
MUIはCSSとかわからなくてもなんとなくで使えるのが強み。デザインをもっと調整したいなって思ったらsxのパラメータとかいじればできるっぽいし万能すごい(小並感)。
少しでも私のコードが誰かの参考になりますように