Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade date-fns to v3 #4481

Merged
merged 1 commit into from Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs-site/src/components/Example/index.js
Expand Up @@ -5,10 +5,10 @@ import DatePicker, {
registerLocale,
CalendarContainer,
} from "react-datepicker";
import * as DateFNS from "date-fns/esm";
import fi from "date-fns/locale/fi";
import ptBR from "date-fns/locale/pt-BR";
import enGB from "date-fns/locale/en-GB";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the new changes, I believe you can also combine this:

import { fi, ptBR, enGB } from "date-fns/locale";

🔹 Simplify Code (Nice to have)

Image of James D James D

import * as DateFNS from "date-fns";
import { fi } from "date-fns/locale/fi";
import { ptBR } from "date-fns/locale/pt-BR";
import { enGB } from "date-fns/locale/en-GB";
import slugify from "slugify";
import range from "lodash/range";
import prismGitHubTheme from "prism-react-renderer/themes/github";
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -106,7 +106,7 @@
"dependencies": {
"@floating-ui/react": "^0.26.2",
"classnames": "^2.2.6",
"date-fns": "^2.30.0",
"date-fns": "^3.3.1",
"prop-types": "^15.7.2",
"react-onclickoutside": "^6.13.0"
},
Expand Down
14 changes: 10 additions & 4 deletions rollup.config.js
Expand Up @@ -14,9 +14,15 @@ import pkg from "./package.json";

// it's important to mark all subpackages of data-fns as externals
// see https://github.com/Hacker0x01/react-datepicker/issues/1606
const dateFnsDirs = fs
.readdirSync(path.join(".", "node_modules", "date-fns"))
.map((d) => `date-fns/${d}`);
// We're relying on date-fn's package.json `exports` field to
// determine the list of directories to include.
const dateFnsPackageJson = JSON.parse(
fs.readFileSync(path.join(__dirname, "node_modules/date-fns/package.json")),
);
const dateFnsSubpackages = Object.keys(dateFnsPackageJson.exports)
.map((key) => key.replace("./", ""))
.filter((key) => key !== "." && key !== "package.json")
.map((key) => `date-fns/${key}`);

const globals = {
react: "React",
Expand Down Expand Up @@ -67,7 +73,7 @@ const config = {
],
external: Object.keys(pkg.dependencies)
.concat(Object.keys(pkg.peerDependencies))
.concat(dateFnsDirs),
.concat(dateFnsSubpackages),
};

export default config;
113 changes: 56 additions & 57 deletions src/date_utils.js
@@ -1,60 +1,59 @@
import isDate from "date-fns/isDate";
import isValidDate from "date-fns/isValid";
import format from "date-fns/format";
import addMinutes from "date-fns/addMinutes";
import addHours from "date-fns/addHours";
import addDays from "date-fns/addDays";
import addWeeks from "date-fns/addWeeks";
import addMonths from "date-fns/addMonths";
import addQuarters from "date-fns/addQuarters";
import addYears from "date-fns/addYears";
import subDays from "date-fns/subDays";
import subWeeks from "date-fns/subWeeks";
import subMonths from "date-fns/subMonths";
import subQuarters from "date-fns/subQuarters";
import subYears from "date-fns/subYears";
import getSeconds from "date-fns/getSeconds";
import getMinutes from "date-fns/getMinutes";
import getHours from "date-fns/getHours";
import getDay from "date-fns/getDay";
import getDate from "date-fns/getDate";
import getISOWeek from "date-fns/getISOWeek";
import getMonth from "date-fns/getMonth";
import getQuarter from "date-fns/getQuarter";
import getYear from "date-fns/getYear";
import getTime from "date-fns/getTime";
import setSeconds from "date-fns/setSeconds";
import setMinutes from "date-fns/setMinutes";
import setHours from "date-fns/setHours";
import setMonth from "date-fns/setMonth";
import setQuarter from "date-fns/setQuarter";
import setYear from "date-fns/setYear";
import min from "date-fns/min";
import max from "date-fns/max";
import differenceInCalendarDays from "date-fns/differenceInCalendarDays";
import differenceInCalendarMonths from "date-fns/differenceInCalendarMonths";
import differenceInCalendarYears from "date-fns/differenceInCalendarYears";
import startOfDay from "date-fns/startOfDay";
import startOfWeek from "date-fns/startOfWeek";
import startOfMonth from "date-fns/startOfMonth";
import startOfQuarter from "date-fns/startOfQuarter";
import startOfYear from "date-fns/startOfYear";
import endOfDay from "date-fns/endOfDay";
import endOfWeek from "date-fns/endOfWeek";
import endOfMonth from "date-fns/endOfMonth";
import endOfYear from "date-fns/endOfYear";
import dfIsEqual from "date-fns/isEqual";
import dfIsSameDay from "date-fns/isSameDay";
import dfIsSameMonth from "date-fns/isSameMonth";
import dfIsSameYear from "date-fns/isSameYear";
import dfIsSameQuarter from "date-fns/isSameQuarter";
import isAfter from "date-fns/isAfter";
import isBefore from "date-fns/isBefore";
import isWithinInterval from "date-fns/isWithinInterval";
import toDate from "date-fns/toDate";
import parse from "date-fns/parse";
import parseISO from "date-fns/parseISO";
import longFormatters from "date-fns/esm/_lib/format/longFormatters";
import { isDate } from "date-fns/isDate";
import { isValid as isValidDate } from "date-fns/isValid";
import { format, longFormatters } from "date-fns/format";
import { addMinutes } from "date-fns/addMinutes";
import { addHours } from "date-fns/addHours";
import { addDays } from "date-fns/addDays";
import { addWeeks } from "date-fns/addWeeks";
import { addMonths } from "date-fns/addMonths";
import { addQuarters } from "date-fns/addQuarters";
import { addYears } from "date-fns/addYears";
import { subDays } from "date-fns/subDays";
import { subWeeks } from "date-fns/subWeeks";
import { subMonths } from "date-fns/subMonths";
import { subQuarters } from "date-fns/subQuarters";
import { subYears } from "date-fns/subYears";
import { getSeconds } from "date-fns/getSeconds";
import { getMinutes } from "date-fns/getMinutes";
import { getHours } from "date-fns/getHours";
import { getDay } from "date-fns/getDay";
import { getDate } from "date-fns/getDate";
import { getISOWeek } from "date-fns/getISOWeek";
import { getMonth } from "date-fns/getMonth";
import { getQuarter } from "date-fns/getQuarter";
import { getYear } from "date-fns/getYear";
import { getTime } from "date-fns/getTime";
import { setSeconds } from "date-fns/setSeconds";
import { setMinutes } from "date-fns/setMinutes";
import { setHours } from "date-fns/setHours";
import { setMonth } from "date-fns/setMonth";
import { setQuarter } from "date-fns/setQuarter";
import { setYear } from "date-fns/setYear";
import { min } from "date-fns/min";
import { max } from "date-fns/max";
import { differenceInCalendarDays } from "date-fns/differenceInCalendarDays";
import { differenceInCalendarMonths } from "date-fns/differenceInCalendarMonths";
import { differenceInCalendarYears } from "date-fns/differenceInCalendarYears";
import { startOfDay } from "date-fns/startOfDay";
import { startOfWeek } from "date-fns/startOfWeek";
import { startOfMonth } from "date-fns/startOfMonth";
import { startOfQuarter } from "date-fns/startOfQuarter";
import { startOfYear } from "date-fns/startOfYear";
import { endOfDay } from "date-fns/endOfDay";
import { endOfWeek } from "date-fns/endOfWeek";
import { endOfMonth } from "date-fns/endOfMonth";
import { endOfYear } from "date-fns/endOfYear";
import { isEqual as dfIsEqual } from "date-fns/isEqual";
import { isSameDay as dfIsSameDay } from "date-fns/isSameDay";
import { isSameMonth as dfIsSameMonth } from "date-fns/isSameMonth";
import { isSameYear as dfIsSameYear } from "date-fns/isSameYear";
import { isSameQuarter as dfIsSameQuarter } from "date-fns/isSameQuarter";
import { isAfter } from "date-fns/isAfter";
import { isBefore } from "date-fns/isBefore";
import { isWithinInterval } from "date-fns/isWithinInterval";
import { toDate } from "date-fns/toDate";
import { parse } from "date-fns/parse";
import { parseISO } from "date-fns/parseISO";

export const DEFAULT_YEAR_ITEM_NUMBER = 12;

Expand Down
8 changes: 4 additions & 4 deletions src/index.jsx
Expand Up @@ -6,10 +6,10 @@ import Portal from "./portal";
import PopperComponent from "./popper_component";
import { popperPlacementPositions } from "./with_floating";
import classnames from "classnames";
import set from "date-fns/set";
import startOfDay from "date-fns/startOfDay";
import endOfDay from "date-fns/endOfDay";
import isValid from "date-fns/isValid";
import { set } from "date-fns/set";
import { startOfDay } from "date-fns/startOfDay";
import { endOfDay } from "date-fns/endOfDay";
import { isValid } from "date-fns/isValid";
import {
newDate,
isDate,
Expand Down
4 changes: 2 additions & 2 deletions test/calendar_test.test.js
Expand Up @@ -14,8 +14,8 @@ import MonthYearDropdown from "../src/month_year_dropdown";
import DatePicker from "../src/index.jsx";
import { shallow, mount } from "enzyme";
import * as utils from "../src/date_utils";
import eo from "date-fns/locale/eo";
import fi from "date-fns/locale/fi";
import { eo } from "date-fns/locale/eo";
import { fi } from "date-fns/locale/fi";
import { isSunday } from "date-fns";

// TODO Possibly rename
Expand Down
28 changes: 14 additions & 14 deletions test/date_utils_test.test.js
Expand Up @@ -42,10 +42,10 @@ import {
isDateBefore,
getMidnightDate,
} from "../src/date_utils";
import setMinutes from "date-fns/setMinutes";
import setHours from "date-fns/setHours";
import addQuarters from "date-fns/addQuarters";
import ptBR from "date-fns/locale/pt-BR";
import { setMinutes } from "date-fns/setMinutes";
import { setHours } from "date-fns/setHours";
import { addQuarters } from "date-fns/addQuarters";
import { ptBR } from "date-fns/locale/pt-BR";
import { registerLocale } from "../src/date_utils";
import { addYears } from "date-fns";

Expand Down Expand Up @@ -249,15 +249,15 @@ describe("date_utils", () => {
).toBe(true);
});

it("should throw error if excluded date interval is invalid", () => {
it("should be enabled and normalize negative intervals correctly", () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See date-fns' release:

Functions that accept Interval arguments now do not throw an error if the start is before the end and handle it as a negative interval. If one of the properties in an Invalid Date, these functions also do not throw and handle them as invalid intervals.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Image of Frank T Frank T

const day = newDate();
expect(() =>
expect(
isDayDisabled(day, {
excludeDateIntervals: [
{ start: addDays(day, 1), end: subDays(day, 1) },
],
}),
).toThrow("Invalid interval");
).toBe(true);
});

it("should be enabled if excluded date interval is empty", () => {
Expand Down Expand Up @@ -366,15 +366,15 @@ describe("date_utils", () => {
).toBe(false);
});

it("should throw error if excluded date interval is invalid", () => {
it("should be enabled and normalize negative intervals correctly", () => {
const day = newDate();
expect(() =>
expect(
isDayExcluded(day, {
excludeDateIntervals: [
{ start: addDays(day, 1), end: subDays(day, 1) },
],
}),
).toThrow("Invalid interval");
).toBe(true);
});

it("should not be excluded if in excluded dates and not within excluded date intervals", () => {
Expand Down Expand Up @@ -852,12 +852,12 @@ describe("date_utils", () => {
expect(isTimeInDisabledRange(time, { minTime, maxTime })).toBe(true);
});

it("should not throw an exception if max time is before min time", () => {
it("should correctly handle max time is before min time", () => {
const date = newDate("2016-03-15");
const time = setHours(setMinutes(date, 30), 10);
const minTime = setHours(setMinutes(date, 30), 5);
const maxTime = setHours(setMinutes(date, 30), 0);
expect(isTimeInDisabledRange(time, { minTime, maxTime })).toBe(false);
expect(isTimeInDisabledRange(time, { minTime, maxTime })).toBe(true);
});
});

Expand Down Expand Up @@ -890,11 +890,11 @@ describe("date_utils", () => {
expect(isDayInRange(day, startDate, endDate)).toBe(false);
});

it("should not throw exception if end date is before start date", () => {
it("should correctly handle max time is before min time", () => {
const day = newDate("2016-02-01 09:40");
const startDate = newDate("2016-02-15 09:40");
const endDate = newDate("2016-01-15 08:40");
expect(isDayInRange(day, startDate, endDate)).toBe(false);
expect(isDayInRange(day, startDate, endDate)).toBe(true);
});
});

Expand Down
8 changes: 4 additions & 4 deletions test/month_dropdown_test.test.js
Expand Up @@ -4,9 +4,9 @@ import MonthDropdown from "../src/month_dropdown.jsx";
import MonthDropdownOptions from "../src/month_dropdown_options.jsx";
import { mount } from "enzyme";
import { getMonthInLocale, registerLocale } from "../src/date_utils";
import zh_cn from "date-fns/locale/zh-CN";
import el from "date-fns/locale/el";
import ru from "date-fns/locale/ru";
import { zhCN } from "date-fns/locale/zh-CN";
import { el } from "date-fns/locale/el";
import { ru } from "date-fns/locale/ru";

describe("MonthDropdown", () => {
let monthDropdown;
Expand Down Expand Up @@ -206,7 +206,7 @@ describe("MonthDropdown", () => {
});

it("renders month options with specified locale", () => {
registerLocale("zh-cn", zh_cn);
registerLocale("zh-cn", zhCN);
monthDropdown = getMonthDropdown({
dropdownMode: "select",
locale: "zh-cn",
Expand Down
2 changes: 1 addition & 1 deletion test/month_year_dropdown_test.test.js
Expand Up @@ -10,7 +10,7 @@ import {
isAfter,
registerLocale,
} from "../src/date_utils.js";
import fi from "date-fns/locale/fi";
import { fi } from "date-fns/locale/fi";

describe("MonthYearDropdown", () => {
let monthYearDropdown;
Expand Down
2 changes: 1 addition & 1 deletion test/time_format_test.test.js
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { mount } from "enzyme";
import TimeComponent from "../src/time";
import * as utils from "../src/date_utils";
import ptBR from "date-fns/locale/pt-BR";
import { ptBR } from "date-fns/locale/pt-BR";
import { waitFor } from "@testing-library/react";

describe("TimeComponent", () => {
Expand Down
12 changes: 5 additions & 7 deletions yarn.lock
Expand Up @@ -1131,7 +1131,7 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==

"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.21.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4":
"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4":
version "7.22.11"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4"
integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==
Expand Down Expand Up @@ -3493,12 +3493,10 @@ data-urls@^3.0.2:
whatwg-mimetype "^3.0.0"
whatwg-url "^11.0.0"

date-fns@^2.30.0:
version "2.30.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
dependencies:
"@babel/runtime" "^7.21.0"
date-fns@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.3.1.tgz#7581daca0892d139736697717a168afbb908cfed"
integrity sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==

debug@2.6.9, debug@^2.6.8:
version "2.6.9"
Expand Down