Descriptions

You can customize your calendar days with the mapDays Prop and create different properties for each of them by returning the Props you want.

In general, this is how it works :

<DatePicker
  mapDays={object => {
    return { props }
  }}
/>

The object which is received as an argument, contains following properties :

PropertyTypeDescriptions
dateDateObject

The Date is being rendered

todayDateObject
selectedDateDateObject or Array

according to the calendar mode (single, multiple, or range), the type of selected date can be a DateObject or Array of DateObjects

currentMonthObject

the month that the user has selected and is displayed in the calendars header. (it can be different from the month of selected date)

isSameDateFunction

it returns the comparison between the day, month, and year of two DateObjects.

As you know you can destructure the received object and pick each property that you want as follows :

{ date, today, selectedDate, currentMonth, isSameDate }

*Please note that none of the properties inside the object should be changed, as this will cause the calendar to malfunction.

For example, if we change the day of all the rendering dates to today, it will result in an unpleasant outcome.

<Calendar
  mapDays={({ date, today }) => {
    date.day = today.day
  }}
/>

The Props you return can contain all the Props that a span element accepts, plus two other properties that I have added to them, which are:

  • disabled
  • hidden

Here are some examples of things that can be performed using mapDays:

Styling Days

<DatePicker
  mapDays={({ date, today, selectedDate, currentMonth, isSameDate }) => {
    let props = {}
    
    props.style = {
      borderRadius: "3px",
      backgroundColor: date.month.index === currentMonth.index ? "#ccc" : ""
    }

    if (isSameDate(date, today)) props.style.color = "green"
    if (isSameDate(date, selectedDate)) props.style = {
      ...props.style,
      color: "#0074d9",
      backgroundColor: "#a5a5a5",
      fontWeight: "bold",
      border: "1px solid #777"
    }

    return props
  }}
/>

Styling Weekends

For convenience, the 'highlight highlight-red' class is included in CSS files, so you do not need to import it.

<DatePicker
  mapDays={({ date }) => {
    let props = {}
    let isWeekend = [0, 6].includes(date.weekDay.index)
    
    if (isWeekend) props.className = "highlight highlight-red"
    
    return props
  }}
/>

See Also:

plugins #weekends:-gregorian

Custom Highlight

<DatePicker
  mapDays={({ date }) => {
    let color
    
    if ([4, 5, 6, 7].includes(date.day)) color = "green"
    if ([11, 12, 13, 14].includes(date.day)) color = "red"
    
    if (color) return { className: "highlight highlight-" + color }
  }}
/>

Disabling Days

<DatePicker
  mapDays={({ date }) => {
    let isWeekend = [0, 6].includes(date.weekDay.index)
    
    if (isWeekend) return {
      disabled: true,
      style: { color: "#ccc" },
      onClick: () => alert("weekends are disabled")
    }
  }}
/>

Hiding Days

<DatePicker
  mapDays={({ date }) => {
    let props = {}
    
    if ([5, 10, 15, 20, 25].includes(date.day)) props.hidden = true
    
    return props
  }}
/>

Multiple Day-Numbers With Different Calendars & Locales

By using the children property, you can replace the desired 'value' or 'component' with the default value (day number).

import persian from "react-date-object/calendars/persian";
import persian_fa from "react-date-object/locales/persian_fa";
.
.
.          
<Calendar
  className="multi-locale-days"
  mapDays={({ date }) => {
    const newDate = new DateObject(date).convert(persian, persian_fa)

    return {
      children: (
        <div
          style={{
            display: "flex",
            flexDirection: "column",
            padding: "0 10px",
            fontSize: "11px",
          }}
        >
          <div style={{ textAlign: "start" }}>{date.format("D")}</div>
          <div style={{ textAlign: "end" }}>{newDate.format("D")}</div>
        </div>
      ),
    };
  }}
/>

style.css

.multi-locale-days .rmdp-day {
  width: 40px;
  height: 40px;
}

Adding Tiltle to Days

In the example below the title has been added to today, yesterday and tomorrow.

<DatePicker
  mapDays={({ date, today }) => {
    let props = {}
    let result = date.toDays() - today.toDays()
    
    if (result === -1) props.title = "Yesterday"
    if (result === 0) props.title = "Today"
    if (result === 1) props.title = "Tomorrow"
    
    return props
  }}
/>

Custom Tooltip

A little trick to add a custom tooltip.

import React, { useState, useRef } from "react";
import DatePicker from "react-multi-date-picker";

export default function Example(){
  return <DatePickerWithTooltip />
}

function DatePickerWithTooltip() {
  const [data, setData] = useState({});
  const ref = useRef();

  return (
    <>
      <DatePicker
        ref={ref}
        containerStyle={{ position: "relative" }}
        mapDays={({ date, today }) => {
          let result = date.toDays() - today.toDays();
          let title;

          if (result === -1) title = "Yesterday";
          if (result === 0) title = "Today";
          if (result === 1) title = "Tomorrow";

          return {
            onMouseOver: (e) => {
              let spanRect = e.target.getBoundingClientRect();
              let calendarRect = ref.current
                .querySelector(".rmdp-wrapper")
                .getBoundingClientRect();

              setData({
                ...data,
                left: spanRect.left - calendarRect.left,
                top: spanRect.top - calendarRect.top,
                visible: title ? true : false,
                title,
              });
            },
            onMouseLeave: () => {
              setData({
                ...data,
                visible: false,
                title,
              });
            },
          };
        }}
      >
        <span
          style={{
            position: "absolute",
            left: 0,
            top: 0,
            backgroundColor: "white",
            border: "1px solid #ccc",
            boxShadow: "0 0 5px #ccc",
            borderRadius: "5px",
            padding: "3px 5px",
            fontSize: "14px",
            transform: `translate(${data.left}px, ${data.top + 30}px)`,
            visibility: data.visible ? "visible" : "hidden",
          }}
        >
          {data.title}
        </span>
      </DatePicker>
    </>
  );
}