توضیحات

شما میتونید روز های تقویم رو با استفاده از پراپرتی mapDays شخصی سازی کنید. پراپرتی mapDays از شما یک فانکشن میگیره و ازش خاصیت های مورد نظر شما رو که میخواید رو اون روز پیاده کنید دریافت میکنه.

به طور کلی روش کار با mapDays به این صورت هست :

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

آبجکتی که داخل فانکشن به عنوان آرگومنت دریافت میشود محتوی پراپرتی های زیر است :

پراپرتیحالتتوضیحات
dateDateObject

روزی که در حال رندر شدنه

todayDateObject
selectedDateDateObject یا Array

با توجه به حالت تقویم (تکی ، چندتایی یا دامنه) ، نوع تاریخ انتخاب شده میتونه DateObject یا آرایه ای از DateObject ها باشه.

currentMonthObject

ماهی که کاربر انتخاب کرده و در عنوان تقویم در حال نمایش است. (می تونه با ماه تاریخی که کاربر انتخاب کرده متفاوت باشه).

isSameDateFunction

مقایسه ای بین اعداد روز، ماه و سال دو دیت آبجکت انجام میده.

همونطور که خودتون میدونید، میتونید مثل کد زیر آبجکت دریافت شده رو destructure کنید و هر پراپرتی ای رو که لازم میدونید ازش انتخاب کنید:

{ date, today, selectedDate, currentMonth, isSameDate }

*لطفا توجه داشته باشید که هیچ یک از خصوصیات داخل object نباید تغییر کنه ، چون باعث عملکرد نامناسب تقویم میشه.

به عنوان مثال ، اگر روز تمام تاریخ های در حال رندر شدن رو به امروز تغییر بدیم ، این نتیجه رو در بر داره:

<Calendar
  mapDays={({ date, today }) => {
    date.day = today.day
  }}
  calendar={persian}
  locale={persian_fa}
/>

پراپرتی هایی که می تونید برگردونید حاوی تمامی پراپرتی هایی است که یک عنصر span قبول می کنه ، به علاوه دو ویژگی دیگه که من به اونا اضافه کردم ، که عبارتند از:

  • disabled
  • hidden

در پایین چند تا مثال از کار هایی که میشه با mapDays انجام داد رو قرار دادم :

شخصی سازی روز ها

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<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
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

قرمز کردن روز های جمعه

برای راحتی کار، کلاس 'highlight highlight-red' رو در فایل css قرار دادم، بنابراین نیازی به ایمپورت کردنش ندارید.

برای قرمز کردن روز ها میتونید از پلاگین هم استفاده کنید که تو بخش پلاگین ها مثالش رو زدم.

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<DatePicker
  mapDays={({ date }) => {
    let props = {}
    let isWeekend = date.weekDay.index === 6
    
    if (isWeekend) props.className = "highlight highlight-red"
    
    return props
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

همچنین ببینید:

پلاگین ها #آخر هفته شمسی

هایلایت کردن روز ها

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<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 }
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

غیر فعال کردن روز ها

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<DatePicker
  mapDays={({ date }) => {
    let isWeekend = [0, 6].includes(date.weekDay.index)
    
    if (isWeekend) return {
      disabled: true,
      style: { color: "#ccc" },
      onClick: () => alert("آخر هفته ها غیر فعال هستند")
    }
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

پنهان کردن روز ها

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<DatePicker
  mapDays={({ date }) => {
    let props = {}
    
    if ([5, 10, 15, 20, 25].includes(date.day)) props.hidden = true
    
    return props
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

چند شماره روز با تقویم یا زبان های مختلف

با استفاده از پراپرتی children ، می توانید 'مقدار' یا 'کامپوننت' مورد نظر را با مقدار پیش فرض (شماره روز) جایگزین کنید.

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

    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>
      ),
    };
  }}
  calendar={persian}
  locale={persian_fa}
/>

فایل سی اس اس

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

اضافه کردن عنوان به روز ها

در این مثال عنوان های دیروز، امروز و فردا به تقویم اضافه شده:

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<DatePicker
  mapDays={({ date, today }) => {
    let props = {}
    let result = date.toDays() - today.toDays()
    
    if (result === -1) props.title = "دیروز"
    if (result === 0) props.title = "امروز"
    if (result === 1) props.title = "فردا"
    
    return props
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

Tooltip دستی

یک ترفند کوچک برای اضافه کردن tooltip دستی.

import React, { useState, useRef } from "react";
import DatePicker from "react-multi-date-picker";
import persian from "react-date-object/calendars/persian:
import persian_fa from "react-date-object/locales/persian_fa"

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,
              });
            },
          };
        }}
        calendar={persian}
        locale={persian_fa}
        calendarPosition="bottom-right"
      >
        <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>
    </>
  );
}