対象読者
- React、Next.jsを1ヶ月程度触ったことがある
- MUIを使ったアプリを作成している
MUIって便利ですよね
UI/UXのコンポーネントがまとまっているMUIはとても便利です。
自分でコンポーネントを作る手間が大幅に省けます。
意外とカスタマイズも結構できるので、デザインにも幅を持たせることができます。(センス次第で...)
datePickerってかゆところに手が届かないんですよね
カレンダー入力はめっちゃありがたいんですけど、入力内容を削除する時が結構めんどくさいんですよね。
1回で全部削除することができないので、YYYY削除して、MM削除して、DD削除してみたいなことしなきゃいけなくて..。
しかも自分は後続で日付フォーマットの変換を入れてたから、一部分を削除するとエラーが出てしまったりして悩んでました。
うーん....
じゃあdatepickerをカスタマイズしちゃおう!
datePickerの基本形の導入方法
基本的な実装は色々な方が行なっているので、そちらを参考にしてください。
自分はMUIの公式のドキュメントを参考に実装しました。
結局公式ドキュメントが一番頼りになります。
(自分のコードだけを参考にするとライブラリでエラーになると思うので、公式を参考に導入するようにしてください)
早速完成形
やや!なんかXボタンがありますね。
押してみると...
入力内容が全て消えました!便利!!
コード紹介
import React, { useState } from "react";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { IconButton } from "@mui/material";
import ClearIcon from "@mui/icons-material/Clear";
import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
export default function CommonDatePicker(props: any) {
//カレンダーの表示を制御する
const [open, setOpen] = useState(false);
//datePickerの入力値を受け取る
const [value, setValue] = useState(null);
//バツボタンを押したらvalueをnullにする
const onClear = () => {
setValue(null);
};
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
format="YYYY/MM/DD"
sx={{ width: "240px" }}
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
value={value}
onChange={(newValue) => setValue(newValue)}
slotProps={{
textField: {
InputProps: {
endAdornment: (
<>
{value && (
<IconButton onClick={onClear}>
<ClearIcon />
</IconButton>
)}
<IconButton onClick={() => setOpen(true)}>
<CalendarTodayIcon />
</IconButton>
</>
),
},
},
}}
/>
</LocalizationProvider>
);
}
だいぶ複雑になってしまいましたね。
このslorPropsがキモです
slotProps={{
textField: {
InputProps: {
endAdornment: (
<>
{value && (
<IconButton onClick={onClear}>
<ClearIcon />
</IconButton>
)}
<IconButton onClick={() => setOpen(true)}>
<CalendarTodayIcon />
</IconButton>
</>
),
},
},
}}
slotPropsとはdatePickerの内部コンポーネントにプロパティを渡すプロパティです。
slotPropsの中で、textFieldのendAdornmentのプロパティを渡すことでバツボタンとカレンダーを表示しています。
(ここの書き方は自分も深く理解していないです)
ここまで辿り着いても問題がありまして、
バツボタンを導入するためにendAdornmentを指定したらカレンダーが消えてしまうんです...
カレンダー入力のためのアイコンとバツボタンを2つともendAdornmentで指定する必要があります。
カレンダーの表示/非表示を制御も自分で入れないといけません。
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
また、バツボタンは日付が入力されている場合のみ表示したいので、そのような条件も入れています。
<>
{value && (....
....
</>
valueはuseStateで管理しています。
//datePickerの入力値を受け取る
const [value, setValue] = useState(null);
いかがでしたでしょうか
初めて技術記事を挙げてみました。
色々と調べてここに辿り着いたので、誰かの助けになればと思い書いてみました!
もしこの記事で誰かの時短になればすごく嬉しいです!
間違っている点や、改善できる点などありましたらぜひ教えてください〜!