diff --git a/.changeset/date-fns-v4-upgrade.md b/.changeset/date-fns-v4-upgrade.md new file mode 100644 index 0000000000..958fadabf6 --- /dev/null +++ b/.changeset/date-fns-v4-upgrade.md @@ -0,0 +1,24 @@ +--- +'@toptal/picasso-calendar': patch +'@toptal/picasso-date-picker': patch +'@toptal/picasso': patch +--- + +### Calendar + +- upgrade `date-fns` to `^4.1.0`. `@base-ui/react` — the primitive layer the kit is migrating to — peers `date-fns: ^4.0.0`, which the previous `^2.30.0` did not satisfy +- import `isWeekend` and `isSameMonth` from the `date-fns` barrel instead of the `date-fns/isWeekend` and `date-fns/isSameMonth` submodules. date-fns v3 removed the default export from every submodule, so the old form resolves to `undefined` + +### DatePicker + +- upgrade `date-fns` to `^4.1.0` and `date-fns-tz` to `^3.2.0`. `date-fns-tz@3` is required because it is the first line whose peer range admits date-fns v3 and v4 +- rename `utcToZonedTime` to `toZonedTime`, which is what `date-fns-tz@3` calls it. This is internal to `timezoneConvert`; the `timezone` prop behaves exactly as before +- import `parse`, `isValid`, `format`, `isWithinInterval`, `isEqual`, `isBefore` and `isAfter` from the `date-fns` barrel instead of per-function submodules, for the same reason as Calendar + +No API or behavior change in any package. `react-day-picker@8.x` peers +`date-fns: ^2.28.0 || ^3.0.0` and no `8.x` release admits v4, so that peer is now +unsatisfied and recorded as an accepted exception in `pnpm-workspace.yaml`. +It is verified safe: react-day-picker reaches date-fns only through named barrel +imports, and all 31 functions it uses are unchanged in v4. The exception goes +away with the react-day-picker v9+ migration, where date-fns stops being a peer +of that package altogether. diff --git a/package.json b/package.json index 44967fe861..16b4c69ea4 100644 --- a/package.json +++ b/package.json @@ -218,7 +218,7 @@ "cypress": "^13.6.0", "cypress-plugin-tab": "^1.0.5", "cypress-real-events": "^1.12.0", - "date-fns": "^2.30.0", + "date-fns": "^4.1.0", "debounce": "^1.2.1", "ejs": "^3.1.10", "escodegen": "^2.1.0", diff --git a/packages/base/Calendar/package.json b/packages/base/Calendar/package.json index b7e9513eb3..81c67b4955 100644 --- a/packages/base/Calendar/package.json +++ b/packages/base/Calendar/package.json @@ -28,7 +28,7 @@ "@toptal/picasso-shared": "workspace:*", "@toptal/picasso-typography": "workspace:*", "@toptal/picasso-utils": "workspace:*", - "date-fns": "^2.30.0", + "date-fns": "^4.1.0", "react-day-picker": "^8.10.0" }, "sideEffects": [ diff --git a/packages/base/Calendar/src/Calendar/Calendar.tsx b/packages/base/Calendar/src/Calendar/Calendar.tsx index bddc7bb171..4258c9b7bf 100644 --- a/packages/base/Calendar/src/Calendar/Calendar.tsx +++ b/packages/base/Calendar/src/Calendar/Calendar.tsx @@ -12,8 +12,7 @@ import type { DateRange, } from 'react-day-picker' import { DayPicker } from 'react-day-picker' -import isWeekend from 'date-fns/isWeekend' -import { format, isEqual } from 'date-fns' +import { format, isEqual, isWeekend } from 'date-fns' import { useBreakpoint } from '@toptal/picasso-provider' import type { RenderDay } from '../CalendarDay' diff --git a/packages/base/Calendar/src/CalendarMonthHeader/CalendarMonthHeader.tsx b/packages/base/Calendar/src/CalendarMonthHeader/CalendarMonthHeader.tsx index f6440add5f..0d0b3b08ed 100644 --- a/packages/base/Calendar/src/CalendarMonthHeader/CalendarMonthHeader.tsx +++ b/packages/base/Calendar/src/CalendarMonthHeader/CalendarMonthHeader.tsx @@ -1,7 +1,7 @@ import type { ReactNode } from 'react' import React from 'react' import { useDayPicker, useNavigation } from 'react-day-picker' -import isSameMonth from 'date-fns/isSameMonth' +import { isSameMonth } from 'date-fns' import { ButtonCircular } from '@toptal/picasso-button' import { Typography } from '@toptal/picasso-typography' import { ChevronMinor24, BackMinor24 } from '@toptal/picasso-icons' diff --git a/packages/base/DatePicker/package.json b/packages/base/DatePicker/package.json index c2d26b9c16..c3374e1f0d 100644 --- a/packages/base/DatePicker/package.json +++ b/packages/base/DatePicker/package.json @@ -30,8 +30,8 @@ "@toptal/picasso-outlined-input": "workspace:*", "@toptal/picasso-popper": "workspace:*", "@toptal/picasso-utils": "workspace:*", - "date-fns": "^2.30.0", - "date-fns-tz": "^2.0.0" + "date-fns": "^4.1.0", + "date-fns-tz": "^3.2.0" }, "sideEffects": [ "**/styles.ts", diff --git a/packages/base/DatePicker/src/DatePicker/DatePicker.tsx b/packages/base/DatePicker/src/DatePicker/DatePicker.tsx index 94c0839a17..b6cd70022b 100644 --- a/packages/base/DatePicker/src/DatePicker/DatePicker.tsx +++ b/packages/base/DatePicker/src/DatePicker/DatePicker.tsx @@ -1,7 +1,7 @@ /* eslint-disable max-lines-per-function, max-lines */ /* eslint-disable complexity, max-statements */ // Squiggly lines makes code difficult to work with import type { BaseProps } from '@toptal/picasso-shared' -import formatDate from 'date-fns/format' +import { format as formatDate } from 'date-fns' import type { PopperHandle } from '@toptal/picasso-popper' import type { KeyboardEvent, ReactNode } from 'react' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' diff --git a/packages/base/DatePicker/src/DatePicker/test.tsx b/packages/base/DatePicker/src/DatePicker/test.tsx index 5a78b7d47f..2b2b4750e7 100644 --- a/packages/base/DatePicker/src/DatePicker/test.tsx +++ b/packages/base/DatePicker/src/DatePicker/test.tsx @@ -14,6 +14,105 @@ const testIds = { const FAR_EAST_TIMEZONE = 'Asia/Tokyo' const NEW_YORK_TIMEZONE = 'America/New_York' +const SHANGHAI_TIMEZONE = 'Asia/Shanghai' +const LOS_ANGELES_TIMEZONE = 'America/Los_Angeles' + +/** + * Both sides of the midnight boundary for the offsets the component realistically + * meets, including both DST states of the two zones that observe it. Tests run + * under `TZ=UTC`, so every case is one where the UTC date and the target zone's + * date disagree — the situation that makes a date land on the wrong day. + * + * Each literal carries the offset the zone genuinely has at that instant. Getting + * that wrong does not fail the test, it silently moves the case off the boundary + * it is meant to probe, so keep literal and zone in step when editing. + */ +const MIDNIGHT_BOUNDARY_CASES = [ + { + label: 'Tokyo +09:00, just after midnight', + date: '2020-06-25T00:00:00+09:00', + timezone: FAR_EAST_TIMEZONE, + expectedSelectedDate: '25', + expectedInputValue: 'Jun 25, 2020', + }, + { + label: 'Tokyo +09:00, one second before midnight', + date: '2020-06-24T23:59:59+09:00', + timezone: FAR_EAST_TIMEZONE, + expectedSelectedDate: '24', + expectedInputValue: 'Jun 24, 2020', + }, + { + label: 'Shanghai +08:00, just after midnight', + date: '2020-06-25T00:00:00+08:00', + timezone: SHANGHAI_TIMEZONE, + expectedSelectedDate: '25', + expectedInputValue: 'Jun 25, 2020', + }, + { + label: 'Shanghai +08:00, one second before midnight', + date: '2020-06-24T23:59:59+08:00', + timezone: SHANGHAI_TIMEZONE, + expectedSelectedDate: '24', + expectedInputValue: 'Jun 24, 2020', + }, + { + label: 'Los Angeles -08:00 (PST), just after midnight', + date: '2020-01-25T00:00:00-08:00', + timezone: LOS_ANGELES_TIMEZONE, + expectedSelectedDate: '25', + expectedInputValue: 'Jan 25, 2020', + }, + { + label: 'Los Angeles -08:00 (PST), one second before midnight', + date: '2020-01-24T23:59:59-08:00', + timezone: LOS_ANGELES_TIMEZONE, + expectedSelectedDate: '24', + expectedInputValue: 'Jan 24, 2020', + }, + { + label: 'Los Angeles -07:00 (PDT), just after midnight', + date: '2020-06-25T00:00:00-07:00', + timezone: LOS_ANGELES_TIMEZONE, + expectedSelectedDate: '25', + expectedInputValue: 'Jun 25, 2020', + }, + { + label: 'Los Angeles -07:00 (PDT), one second before midnight', + date: '2020-06-24T23:59:59-07:00', + timezone: LOS_ANGELES_TIMEZONE, + expectedSelectedDate: '24', + expectedInputValue: 'Jun 24, 2020', + }, + { + label: 'New York -04:00 (EDT), just after midnight', + date: '2020-06-25T00:00:00-04:00', + timezone: NEW_YORK_TIMEZONE, + expectedSelectedDate: '25', + expectedInputValue: 'Jun 25, 2020', + }, + { + label: 'New York -04:00 (EDT), one second before midnight', + date: '2020-06-24T23:59:59-04:00', + timezone: NEW_YORK_TIMEZONE, + expectedSelectedDate: '24', + expectedInputValue: 'Jun 24, 2020', + }, + { + label: 'New York -05:00 (EST), just after midnight', + date: '2020-01-25T00:00:00-05:00', + timezone: NEW_YORK_TIMEZONE, + expectedSelectedDate: '25', + expectedInputValue: 'Jan 25, 2020', + }, + { + label: 'New York -05:00 (EST), one second before midnight', + date: '2020-01-24T23:59:59-05:00', + timezone: NEW_YORK_TIMEZONE, + expectedSelectedDate: '24', + expectedInputValue: 'Jan 24, 2020', + }, +] // eslint-disable-next-line max-lines-per-function describe('DatePicker', () => { @@ -173,6 +272,22 @@ describe('DatePicker', () => { ) }) + it.each(MIDNIGHT_BOUNDARY_CASES)( + 'should display date in given timezone across a midnight boundary ($label)', + ({ date, timezone, expectedInputValue }) => { + const { getByPlaceholderText } = renderDatePicker({ + ...defaultProps, + timezone, + value: new Date(date), + }) + + expect(getByPlaceholderText(defaultProps.placeholder)).toHaveAttribute( + 'value', + expectedInputValue + ) + } + ) + it('should work within interval', () => { const MIN_DATE = new Date(2020, 6, 10) const MAX_DATE = new Date(2020, 6, 25) @@ -434,24 +549,8 @@ describe('DatePicker', () => { }) describe('Calendar', () => { - it.each([ - { - date: '2020-06-25T00:00:00+09:00', - timezone: FAR_EAST_TIMEZONE, - expectedSelectedDate: '25', - }, - { - date: '2020-06-24T23:59:59+09:00', - timezone: FAR_EAST_TIMEZONE, - expectedSelectedDate: '24', - }, - { - date: '2020-06-25T00:00:00-05:00', - timezone: NEW_YORK_TIMEZONE, - expectedSelectedDate: '25', - }, - ])( - 'should display date in given timezone', + it.each(MIDNIGHT_BOUNDARY_CASES)( + 'should display date in given timezone ($label)', ({ date, timezone, expectedSelectedDate }) => { const { getByPlaceholderText, getByTestId } = renderDatePicker({ ...defaultProps, @@ -467,21 +566,8 @@ describe('DatePicker', () => { } ) - it.each([ - { - date: '2020-06-25T00:00:00+09:00', - timezone: FAR_EAST_TIMEZONE, - }, - { - date: '2020-06-24T23:59:59+09:00', - timezone: FAR_EAST_TIMEZONE, - }, - { - date: '2020-06-25T00:00:00-05:00', - timezone: NEW_YORK_TIMEZONE, - }, - ])( - 'should display date in given timezone after day click', + it.each(MIDNIGHT_BOUNDARY_CASES)( + 'should display date in given timezone after day click ($label)', async ({ date, timezone }) => { const { getByPlaceholderText, getByTestId, getByText } = renderDatePicker({ diff --git a/packages/base/DatePicker/src/DatePicker/utils.ts b/packages/base/DatePicker/src/DatePicker/utils.ts index 2c419a54eb..c77f043346 100644 --- a/packages/base/DatePicker/src/DatePicker/utils.ts +++ b/packages/base/DatePicker/src/DatePicker/utils.ts @@ -1,11 +1,13 @@ -import parse from 'date-fns/parse' -import isValid from 'date-fns/isValid' -import formatDate from 'date-fns/format' -import isWithinInterval from 'date-fns/isWithinInterval' -import isEqual from 'date-fns/isEqual' -import isBefore from 'date-fns/isBefore' -import isAfter from 'date-fns/isAfter' -import { utcToZonedTime, format as tzFormat, toDate } from 'date-fns-tz' +import { + parse, + isValid, + format as formatDate, + isWithinInterval, + isEqual, + isBefore, + isAfter, +} from 'date-fns' +import { toZonedTime, format as tzFormat, toDate } from 'date-fns-tz' import type { DateOrDateRangeType, DateRangeType, @@ -25,7 +27,7 @@ export const timezoneConvert = ( * when someone is editing properties in a Storybook examples. */ try { - return utcToZonedTime(dateToConvert, timeZone) + return toZonedTime(dateToConvert, timeZone) } catch { return dateToConvert } diff --git a/packages/picasso/package.json b/packages/picasso/package.json index 1ea6b9fd92..f93a5d4ba5 100644 --- a/packages/picasso/package.json +++ b/packages/picasso/package.json @@ -112,8 +112,8 @@ "d3": "^7.8.2", "d3-hierarchy": "^3.1.2", "d3-zoom": "^3", - "date-fns": "^2.30.0", - "date-fns-tz": "^2.0.0", + "date-fns": "^4.1.0", + "date-fns-tz": "^3.2.0", "debounce": "^1.2.1", "detect-browser": "^5.3.0", "glider-js": "^1.7.8", diff --git a/packages/topkit-analytics-charts/package.json b/packages/topkit-analytics-charts/package.json index 8a8480fbbb..13027479f0 100644 --- a/packages/topkit-analytics-charts/package.json +++ b/packages/topkit-analytics-charts/package.json @@ -29,7 +29,7 @@ "@toptal/picasso-test-utils": "workspace:*", "@types/d3": "^7.4.0", "@types/d3-array": "3.0.4", - "date-fns": "^2.30.0" + "date-fns": "^4.1.0" }, "dependencies": { "@toptal/picasso-utils": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3a7256ff1..a64c6da86a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,7 +77,7 @@ importers: version: 7.23.1 '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@changesets/changelog-github': specifier: ^0.5.0 version: 0.5.0(encoding@0.1.13) @@ -460,8 +460,8 @@ importers: specifier: ^1.12.0 version: 1.12.0(cypress@13.6.0) date-fns: - specifier: ^2.30.0 - version: 2.30.0 + specifier: ^4.1.0 + version: 4.4.0 debounce: specifier: ^1.2.1 version: 1.2.1 @@ -614,7 +614,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-button': specifier: workspace:* version: link:../Button @@ -973,7 +973,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-checkbox': specifier: workspace:* version: link:../Checkbox @@ -1051,14 +1051,14 @@ importers: specifier: workspace:* version: link:../Utils date-fns: - specifier: ^2.30.0 - version: 2.30.0 + specifier: ^4.1.0 + version: 4.4.0 react: specifier: ^18.2.0 version: 18.2.0 react-day-picker: specifier: ^8.10.0 - version: 8.10.0(date-fns@2.30.0)(react@18.2.0) + version: 8.10.0(date-fns@4.4.0)(react@18.2.0) devDependencies: '@toptal/picasso-provider': specifier: workspace:* @@ -1102,7 +1102,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-form-label': specifier: workspace:* version: link:../FormLabel @@ -1218,11 +1218,11 @@ importers: specifier: workspace:* version: link:../Utils date-fns: - specifier: ^2.30.0 - version: 2.30.0 + specifier: ^4.1.0 + version: 4.4.0 date-fns-tz: - specifier: ^2.0.0 - version: 2.0.0(date-fns@2.30.0) + specifier: ^3.2.0 + version: 3.2.0(date-fns@4.4.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -1247,7 +1247,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-button': specifier: workspace:* version: link:../Button @@ -1887,7 +1887,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-button': specifier: workspace:* version: link:../Button @@ -2580,7 +2580,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-shared': specifier: workspace:* version: link:../../shared @@ -2648,7 +2648,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-form-label': specifier: workspace:* version: link:../FormLabel @@ -2719,7 +2719,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-container': specifier: workspace:* version: link:../Container @@ -2914,7 +2914,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.6.0 - version: 1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@toptal/picasso-shared': specifier: workspace:* version: link:../../shared @@ -3315,11 +3315,11 @@ importers: specifier: ^3 version: 3.0.0 date-fns: - specifier: ^2.30.0 - version: 2.30.0 + specifier: ^4.1.0 + version: 4.4.0 date-fns-tz: - specifier: ^2.0.0 - version: 2.0.0(date-fns@2.30.0) + specifier: ^3.2.0 + version: 3.2.0(date-fns@4.4.0) debounce: specifier: ^1.2.1 version: 1.2.1 @@ -3340,7 +3340,7 @@ importers: version: 6.2.1(react@18.2.0) react-day-picker: specifier: ^8.10.0 - version: 8.10.0(date-fns@2.30.0)(react@18.2.0) + version: 8.10.0(date-fns@4.4.0)(react@18.2.0) react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) @@ -3959,8 +3959,8 @@ importers: specifier: 3.0.4 version: 3.0.4 date-fns: - specifier: ^2.30.0 - version: 2.30.0 + specifier: ^4.1.0 + version: 4.4.0 packages: @@ -9633,15 +9633,18 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - date-fns-tz@2.0.0: - resolution: {integrity: sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==} + date-fns-tz@3.2.0: + resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} peerDependencies: - date-fns: '>=2.0.0' + date-fns: ^3.0.0 || ^4.0.0 date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} + date-fns@4.4.0: + resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==} + dateformat@3.0.3: resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} @@ -19155,7 +19158,7 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@base-ui/react@1.6.0(@types/react@17.0.39)(date-fns@2.30.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@base-ui/react@1.6.0(@types/react@17.0.39)(date-fns@4.4.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.29.2 '@base-ui/utils': 0.3.1(@types/react@17.0.39)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -19166,7 +19169,7 @@ snapshots: use-sync-external-store: 1.6.0(react@18.2.0) optionalDependencies: '@types/react': 17.0.39 - date-fns: 2.30.0 + date-fns: 4.4.0 '@base-ui/utils@0.3.1(@types/react@17.0.39)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: @@ -26101,14 +26104,16 @@ snapshots: dataloader@1.4.0: {} - date-fns-tz@2.0.0(date-fns@2.30.0): + date-fns-tz@3.2.0(date-fns@4.4.0): dependencies: - date-fns: 2.30.0 + date-fns: 4.4.0 date-fns@2.30.0: dependencies: '@babel/runtime': 7.28.4 + date-fns@4.4.0: {} + dateformat@3.0.3: {} dayjs@1.11.10: {} @@ -32924,9 +32929,9 @@ snapshots: dependencies: react: 18.2.0 - react-day-picker@8.10.0(date-fns@2.30.0)(react@18.2.0): + react-day-picker@8.10.0(date-fns@4.4.0)(react@18.2.0): dependencies: - date-fns: 2.30.0 + date-fns: 4.4.0 react: 18.2.0 react-deprecate@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 48a0f1a830..a3a86920a9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -61,6 +61,17 @@ overrides: webpack-dev-middleware: '5.3.4' yaml: '2' +# react-day-picker 8.x peers date-fns '^2.28.0 || ^3.0.0' and no 8.x release +# admits v4, while @base-ui/react peers date-fns '^4.0.0'. The two cannot both +# be satisfied, and Base UI wins: it is the primitive layer the kit is moving +# to. react-day-picker v8 is verified to work on v4 — it imports date-fns only +# through named barrel imports, and all 31 functions it uses are unchanged in +# v4. This entry goes away with the react-day-picker v9+ migration: from 9.0.0 +# on, date-fns is a regular dependency of the package and not a peer at all. +peerDependencyRules: + allowedVersions: + 'react-day-picker>date-fns': '4' + patchedDependencies: '@changesets/get-github-info@0.6.0': patches/@changesets__get-github-info@0.6.0.patch '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0': 'patches/@storybook__react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0.patch'