MUIはさまざまなリッチなコンポーネントを提供してくれるライブラリです。MUIでは、日付も扱うパッケージもあり、@mui/x-date-pickers
は日付の入力用コンポーネントを提供しています。
しかしながら、日付を範囲選択するコンポーネント(Date Range Calendar)は、proプランに加入しないと利用できないため、泣く泣く別ライブラリで代用するということもあるかもしれません。
今回は、@mui/x-date-pickers
(MITライセンスの方)のみを使って、Date Range Calendar(もどき)を実現したいと思います。
ソースコード
naoki-tateyama/MUI-date-range-calendar
Contribute to naoki-tateyama/MUI-date-range-calendar development by creating an account on GitHub.
DateCalendar
DateCalendar
には、slots
propsがあり、これによってDateCalendar
内の各要素を描画することができます。slots
で指定したコンポーネントには、slotProps
によってpropsを渡すことが可能です。本記事では、各日のコンポーネントである、day
をカスタマイズします。
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DateCalendar
onChange={onClickDay}
slots={{
day: SelectedDay,
}}
slotProps={{
day: {
dates,
} as object,
}}
/>
</LocalizationProvider>;
SelectedDay
では、自身が選択状態かなどによって、背景色を変えるスタイルを当てています。
export const SelectedDay: React.FC<Props> = (props: Props) => {
const theme = useTheme();
const { dates = [], day } = props;
const isSelected =
(dates.length === 0
? false
: dates.length === 1
? day.isSame(dates[0], 'date')
: day.isSameOrAfter(dates[0], 'date') &&
day.isSameOrBefore(dates[1], 'date'));
return (
<PickersDay
{...props}
selected={isSelected}
aria-selected={isSelected}
day={day}
sx={{
backgroundColor: isSelected ? theme.palette.primary.main : 'inherit',
color: isSelected ? theme.palette.primary.contrastText : 'inherit',
'&:hover': {
backgroundColor: alpha(theme.palette.primary.light, 0.4),
color: theme.palette.primary.contrastText,
},
'&.Mui-selected': isSelected
? {
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
}
: {
backgroundColor: 'inherit',
color: 'inherit',
},
'&.Mui-selected:hover': isSelected
? {
backgroundColor: theme.palette.primary.light,
color: theme.palette.primary.contrastText,
}
: {
backgroundColor: 'inherit',
color: 'inherit',
},
}}
/>
);
};
aria-selected
を指定しているのは、PickersDay
の挙動として、最後にクリックされた日付しかaria-selected=true
が指定できないためです。
コメント