An advanced and highly customizable Date Range Picker component for Material-UI (MUI).
View Demo here ✨
- Date Range Selection: Select a date range with ease.
- Rich UI/UX: Enjoy an enhanced user experience with a feature-rich Date Range Picker.
- Responsive Design: Works seamlessly on all devices and screen sizes (Mobile Optimized).
- Customization: A large set of customization options to meet your specific needs.
- Min and Max Date: Set minimum and maximum selectable dates.
- Defined Ranges: Use predefined date ranges for quick selection. You can add your custom ranges as well.
- Event Handling: Easily handle changes and submissions with customizable callbacks.
- Locale Support: Localized date formatting for a global audience.
Install the MUI Date Range Picker package via npm:
npm install mui-daterange-picker-plus
import { useState } from "react";
import Button from "@mui/material/Button";
import { PickerModal } from "mui-daterange-picker-plus";
import type { DateRange } from "mui-daterange-picker-plus";
export default function YourComponent() {
// state + handlers for the Modal
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
// state + handlers for the DateRange Value
const [dateRangeOnChange, setDateRangeOnChange] = useState<DateRange>({});
const [dateRangeOnSubmit, setDateRangeOnSubmit] = useState<DateRange>({});
const handleSetDateRangeOnChange = (dateRange: DateRange) => {
setDateRangeOnChange(dateRange);
handleSetDateRangeOnSubmit({});
};
const handleSetDateRangeOnSubmit = (dateRange: DateRange) => {
setDateRangeOnSubmit(dateRange);
// handleClose(); // close the modal
};
console.log("dateRangeOnChange", dateRangeOnChange);
console.log("dateRangeOnSubmit", dateRangeOnSubmit);
return (
<>
<Button variant="contained" onClick={handleClick}>
View Picker Model
</Button>
<PickerModal
onChange={(range: DateRange) => handleSetDateRangeOnChange(range)}
customProps={{
onSubmit: (range: DateRange) => handleSetDateRangeOnSubmit(range),
onCloseCallback: handleClose,
}}
modalProps={{
open,
anchorEl,
onClose: handleClose,
slotProps: {
paper: {
sx: {
borderRadius: "16px",
boxShadow: "rgba(0, 0, 0, 0.21) 0px 0px 4px",
},
},
},
anchorOrigin: {
vertical: "bottom",
horizontal: "left",
},
}}
/>
</>
);
}
import { useState } from "react";
import { PickerBase } from "mui-daterange-picker-plus";
import type { DateRange } from "mui-daterange-picker-plus";
export default function YourComponent() {
// state + handlers for the DateRange Value
const [dateRangeOnChange, setDateRangeOnChange] = useState<DateRange>({});
const handleSetDateRangeOnChange = (dateRange: DateRange) => {
setDateRangeOnChange(dateRange);
};
console.log("dateRangeOnChange", dateRangeOnChange);
return (
<PickerBase
onChange={(range: DateRange) => handleSetDateRangeOnChange(range)}
/>
);
}
import { useState } from "react";
import Button from "@mui/material/Button";
import { PickerModal } from "mui-daterange-picker-plus";
import type { DateRange } from "mui-daterange-picker-plus";
import ArrowCircleRightIcon from "@mui/icons-material/ArrowCircleRight";
import ArrowCircleDownIcon from "@mui/icons-material/ArrowCircleDown";
export default function YourComponent() {
// state + handlers for the Modal
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
// state + handlers for the DateRange Value
const [dateRangeOnChange, setDateRangeOnChange] = useState<DateRange>({});
const [dateRangeOnSubmit, setDateRangeOnSubmit] = useState<DateRange>({});
const handleSetDateRangeOnChange = (dateRange: DateRange) => {
setDateRangeOnChange(dateRange);
handleSetDateRangeOnSubmit({});
};
const handleSetDateRangeOnSubmit = (dateRange: DateRange) => {
setDateRangeOnSubmit(dateRange);
// handleClose(); // close the modal
};
console.log("dateRangeOnChange", dateRangeOnChange);
console.log("dateRangeOnSubmit", dateRangeOnSubmit);
return (
<>
<Button variant="contained" onClick={handleClick}>
View Picker Model
</Button>
<PickerModal
hideOutsideMonthDays={false}
initialDateRange={{
startDate: new Date(),
endDate: new Date("2024-12-31"),
}}
minDate={new Date("2023-08-02")}
maxDate={new Date("2025-02-04")}
onChange={(range: DateRange) => handleSetDateRangeOnChange(range)}
customProps={{
onSubmit: (range: DateRange) => handleSetDateRangeOnSubmit(range),
onCloseCallback: handleClose,
RangeSeparatorIcons: {
xs: ArrowCircleDownIcon,
md: ArrowCircleRightIcon,
},
}}
modalProps={{
open,
anchorEl,
onClose: handleClose,
slotProps: {
paper: {
sx: {
borderRadius: "16px",
boxShadow: "rgba(0, 0, 0, 0.21) 0px 0px 4px",
},
},
},
anchorOrigin: {
vertical: "bottom",
horizontal: "left",
},
}}
/>
</>
);
}
import { useState } from "react";
import { PickerBase } from "mui-daterange-picker-plus";
import type { DateRange } from "mui-daterange-picker-plus";
export default function YourComponent() {
// state + handlers for the DateRange Value
const [dateRangeOnChange, setDateRangeOnChange] = useState<DateRange>({});
const handleSetDateRangeOnChange = (dateRange: DateRange) => {
setDateRangeOnChange(dateRange);
};
console.log("dateRangeOnChange", dateRangeOnChange);
return (
<PickerBase
hideOutsideMonthDays={false}
initialDateRange={{
startDate: new Date("2023-09-15"),
endDate: new Date("2024-12-31"),
}}
minDate={new Date("2023-08-02")}
maxDate={new Date("2025-02-04")}
onChange={(range: DateRange) => handleSetDateRangeOnChange(range)}
/>
);
}
Prop | Type | Default | Description |
---|---|---|---|
initialDateRange |
DateRange |
- | Initial date range for the picker. |
definedRanges |
DefinedRange[] |
- | Predefined date ranges for quick selection. |
minDate |
Date | string |
startOfYear(addYears( new Date(), -10)) | Minimum selectable date. |
maxDate |
Date | string |
endOfYear(addYears( new Date(), 10)) | Maximum selectable date. |
onChange |
(dateRange: DateRange) => void |
- | Callback function triggered on date range change. |
locale |
Locale |
- | Locale for date formatting. |
hideDefaultRanges |
boolean |
false | Option to hide default predefined ranges. |
hideOutsideMonthDays |
boolean |
true | Option to hide days outside the current month. |
Make sure to provide
initialDateRange
within the min and max date.
Prop | Type | Default | Description |
---|---|---|---|
onSubmit |
(dateRange: DateRange) => void |
- | Callback function triggered on date range submission. |
onCloseCallback |
() => void |
- | Callback function triggered on popover close. |
RangeSeparatorIcons |
RangeSeparatorIconsProps |
- | Icons for the range separator in different sizes. |
hideActionsButtons |
boolean |
false | Option to hide action buttons. |
import { PopoverProps } from "@mui/material/Popover";
import { PickerProps, ModalCustomProps } from "./utils";
type PickerModalProps = PickerProps & {
modalProps: PopoverProps;
customProps: ModalCustomProps;
};
type PickerBaseProps = PickerProps;
In the above examples, the
PickerBase
has includedPickerBaseProps
props. Same as that,PickerModal
has includedPickerModalProps
props.
-
The
PickerProps
,ModalCustomProps
types are utility types and you can refer them as per your requirement. ( With or Without Modal) -
In the below section, you can find the details of the utility types.
-
The
PopoverProps
is a Material-UI Popover component props. You can refer to the Material-UI Popover API for more details.
import { ElementType } from "react";
import { SvgIconProps } from "@mui/material";
import { Locale } from "date-fns";
type DateRange = {
startDate?: Date;
endDate?: Date;
};
type DefinedRange = {
startDate: Date;
endDate: Date;
label: string;
};
type RangeSeparatorIconsProps = {
xs?: ElementType<SvgIconProps>;
md?: ElementType<SvgIconProps>;
};
type PickerProps = {
initialDateRange?: DateRange;
definedRanges?: DefinedRange[];
minDate?: Date | string;
maxDate?: Date | string;
locale?: Locale;
onChange?: (dateRange: DateRange) => void;
hideDefaultRanges?: boolean;
hideOutsideMonthDays?: boolean;
};
type ModalCustomProps = {
onSubmit?: (dateRange: DateRange) => void;
onCloseCallback?: () => void;
RangeSeparatorIcons?: RangeSeparatorIconsProps;
hideActionButtons?: boolean;
};
You can use these types as per your requirement.
This project is licensed under the MIT License.