@synerise/ds-date-range-picker 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/CLAUDE.md +7 -4
  3. package/README.md +0 -1
  4. package/dist/DateRangePicker.types.d.ts +0 -4
  5. package/dist/Footer/Footer.d.ts +1 -1
  6. package/dist/Footer/Footer.js +6 -14
  7. package/dist/Footer/Footer.types.d.ts +0 -4
  8. package/dist/RangeFilter/constants.js +2 -21
  9. package/dist/RangePicker/RangePicker.js +32 -53
  10. package/dist/RangePicker/RangePicker.types.d.ts +0 -2
  11. package/dist/RangePicker/utils.js +19 -45
  12. package/dist/RangePickerInput/RangePickerInput.types.d.ts +0 -4
  13. package/dist/RawDateRangePicker.d.ts +1 -1
  14. package/dist/RawDateRangePicker.js +10 -11
  15. package/dist/RelativeRangePicker/RelativeRangePicker.js +2 -21
  16. package/dist/dateUtils/add.d.ts +1 -7
  17. package/dist/dateUtils/add.js +8 -14
  18. package/dist/dateUtils/difference.d.ts +1 -7
  19. package/dist/dateUtils/difference.js +1 -7
  20. package/dist/dateUtils/endOf.d.ts +1 -7
  21. package/dist/dateUtils/endOf.js +8 -14
  22. package/dist/dateUtils/get.d.ts +1 -3
  23. package/dist/dateUtils/get.js +4 -6
  24. package/dist/dateUtils/relativeToAbsolute.js +8 -9
  25. package/dist/dateUtils/set.d.ts +1 -3
  26. package/dist/dateUtils/set.js +4 -6
  27. package/dist/dateUtils/startOf.d.ts +1 -7
  28. package/dist/dateUtils/startOf.js +8 -14
  29. package/dist/dateUtils/sub.d.ts +1 -7
  30. package/dist/dateUtils/sub.js +8 -14
  31. package/dist/dateUtils/toDateValue.d.ts +16 -0
  32. package/dist/dateUtils/toDateValue.js +14 -0
  33. package/dist/fns.d.ts +1 -20
  34. package/dist/fns.js +21 -40
  35. package/dist/index.js +2 -21
  36. package/dist/utils.d.ts +10 -1
  37. package/dist/utils.js +4 -13
  38. package/package.json +20 -22
  39. package/dist/dateUtils/format.d.ts +0 -2
  40. package/dist/dateUtils/format.js +0 -21
package/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.1.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-date-range-picker@2.0.4...@synerise/ds-date-range-picker@2.1.0) (2026-09-10)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **date-range-picker:** stop the contract spec depending on the calendar day ([b4f19a7](https://github.com/Synerise/synerise-design/commit/b4f19a764a8abfbfb6b452709bd7bae88297a023))
11
+
12
+ ### Features
13
+
14
+ - **global:** move the pickers to date-fns 4 ([f878075](https://github.com/Synerise/synerise-design/commit/f878075940c2cd0d2d8a4a5603eb18d01f837640))
15
+ - new month, year and decade picker views, side testids, no title tooltip ([e00f29b](https://github.com/Synerise/synerise-design/commit/e00f29bfc16795bc0ceafa97746c99da1bf3ed9c))
16
+
17
+ ## [2.0.4](https://github.com/Synerise/synerise-design/compare/@synerise/ds-date-range-picker@2.0.3...@synerise/ds-date-range-picker@2.0.4) (2026-09-08)
18
+
19
+ ### Bug Fixes
20
+
21
+ - **date-range-picker:** encode non-whole-hour timezone offsets correctly ([a51b393](https://github.com/Synerise/synerise-design/commit/a51b393cad84dcb2da67dcc3da2dabf7d22cf37a))
22
+
6
23
  ## [2.0.3](https://github.com/Synerise/synerise-design/compare/@synerise/ds-date-range-picker@2.0.2...@synerise/ds-date-range-picker@2.0.3) (2026-09-07)
7
24
 
8
25
  **Note:** Version bump only for package @synerise/ds-date-range-picker
package/CLAUDE.md CHANGED
@@ -12,7 +12,7 @@ src/
12
12
  RawDateRangePicker.tsx — core picker logic without popover
13
13
  date.types.ts — DateRange, DateFilter, RelativeUnits, RangeKey
14
14
  constants.tsx — MODES, COLUMNS, presets, POPOVER_*_CONFIG
15
- utils.ts — normalizeRange, getDefaultTexts, toIsoString, DEFAULT_RANGE
15
+ utils.ts — normalizeRange, getDefaultTexts, DEFAULT_RANGE (toIsoString is re-exported from ds-core)
16
16
  fns.ts — re-exports / wrappers around date-fns
17
17
  RangePicker/ — absolute date picker (dual-month calendar)
18
18
  RelativeRangePicker/ — relative preset + custom range picker
@@ -20,7 +20,7 @@ src/
20
20
  Footer/ — apply button + selected range summary
21
21
  RangeFilter/ — recurring schedule filters (Daily/Weekly/Monthly)
22
22
  AddonCollapse/ — collapsible section used by relative picker and filter
23
- dateUtils/ — date utility functions (add, sub, format, startOf, endOf, …)
23
+ dateUtils/ — date utility functions (add, sub, startOf, endOf, toDateValue, …)
24
24
  ```
25
25
 
26
26
  ## Public exports
@@ -114,7 +114,7 @@ Re-export of `format` from `date-fns` — use for consistent date formatting acr
114
114
 
115
115
  ### `utils`
116
116
 
117
- Namespace export: `normalizeRange`, `toIsoString`, `toIsoStringWithoutZone`, `getDefaultTexts`, `DEFAULT_RANGE`, `START_OF`, `END_OF`.
117
+ Namespace export: `normalizeRange`, `toIsoString` (re-exported from `@synerise/ds-core`), `toIsoStringWithoutZone`, `getDefaultTexts`, `DEFAULT_RANGE`, `START_OF`, `END_OF`.
118
118
 
119
119
  ### `CONST`
120
120
 
@@ -193,12 +193,15 @@ Addons (relative picker, filter) appear below the calendar and are toggled via `
193
193
  - All sub-components have co-located `*.styles.ts(x)` files
194
194
  - Uses `@synerise/ds-core` tokens — no hardcoded colour values
195
195
  - Popover overlay has `data-testid="ds-date-range-picker-overlay"` and class `ds-date-range-popover`
196
+ - Each half of the panel is wrapped in `data-testid="date-range-picker-side-left"` / `-side-right` — the scope E2E suites use to reach the days and navigation of one side. The wrapper hosts whichever picker the side is in (day grid, month/year grid, or time picker), so the testid is stable across modes
196
197
 
197
198
  ## Key dependencies
198
199
 
199
200
  - `react-day-picker ^10` — calendar grid rendering inside `RangePicker` (see the v10 notes in `ds-date-picker`'s CLAUDE.md; day cells now contain a `<button class="DayPicker-Day-Button">`)
200
201
  - `@synerise/ds-popover` — floating popover (floating-ui underneath)
201
- - `date-fns ^2` + `date-fns-tz 1.1.4` — date arithmetic and timezone support
202
+ - `date-fns ^4` — date arithmetic, imported **by name from the package root** (`import { addDays as fnsAddDays } from 'date-fns'`). v4 submodules are named-export-only, so the old `import fnsAddDays from 'date-fns/addDays'` form yields `undefined`
203
+ - Loosely-typed date values are normalised by `dateUtils/toDateValue.ts`, which replaced `@date-fns/upgrade`'s `legacyParse`. Use it rather than `new Date` or `toDate`: a naive string must be read as *local* time, and only `parseISO` does that. Note `toDateValue(null)` is the **epoch**, which `isValid` accepts — preserved deliberately, since call sites are written around it
204
+ - Timezone handling is not this package's: `toIsoString` is re-exported from `@synerise/ds-core`, which owns the wall-clock convention and the `@date-fns/tz` dependency behind it
202
205
  - `dayjs ^1.8` — used in parts of `RangeFilter`
203
206
  - `ramda ^0.27` — functional utilities in `RangeFilter`
204
207
  - `react-intl` — i18n (peer dependency via host app)
package/README.md CHANGED
@@ -48,7 +48,6 @@ const value = {
48
48
  | disabledDate | Function to specify if particular dates are disabled or not | (date:Date)=>boolean | - |
49
49
  | disabledDefaultTexts | Disables the default texts translations provided by `react-intl` | boolean | `false` |
50
50
  | forceAbsolute | Force the outcome to be converted to an absolute date | boolean | `false` |
51
- | format | Format of the value displayed in the footer | string | "MMM D, YYYY" |
52
51
  | onApply | Callback executed after applying changes | (value: Partial<DateFilter> \| undefined) => void | - |
53
52
  | ranges | An array containing custom ranges which may be used as a short-hand | DateRangePreset[] | [] |
54
53
  | popoverProps | Object representing props applied to the ds-popover component | Partial<PopoverProps> | {} |
@@ -22,10 +22,6 @@ export type DateRangePickerProps = {
22
22
  disabled?: boolean;
23
23
  disableDefaultTexts?: boolean;
24
24
  disabledDate?: (date?: Date) => boolean;
25
- /**
26
- * @deprecated use `valueFormatOptions` instead
27
- */
28
- format?: string;
29
25
  valueFormatOptions?: DateToFormatOptions;
30
26
  forceAdjacentMonths?: boolean;
31
27
  forceAbsolute?: boolean;
@@ -1,4 +1,4 @@
1
1
  import { default as React } from 'react';
2
2
  import { Props } from './Footer.types';
3
- declare const Footer: ({ canApply, onApply, canSwitchMode, onSwitchMode, mode, dateOnly, message, texts, value, format, valueFormatOptions, showTime, displayDateContainerClass, ...rest }: Props) => React.JSX.Element;
3
+ declare const Footer: ({ canApply, onApply, canSwitchMode, onSwitchMode, mode, dateOnly, message, texts, value, valueFormatOptions, showTime, displayDateContainerClass, ...rest }: Props) => React.JSX.Element;
4
4
  export default Footer;
@@ -1,15 +1,12 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { parseISO, isValid } from "date-fns";
2
3
  import { useCallback, useMemo } from "react";
3
- import { useIntl } from "react-intl";
4
4
  import Button from "@synerise/ds-button";
5
5
  import { useDataFormat, getDefaultDataTimeOptions } from "@synerise/ds-core";
6
6
  import Icon, { ArrowRightS } from "@synerise/ds-icon";
7
7
  import Tooltip from "@synerise/ds-tooltip";
8
8
  import { isLifetime } from "../RelativeRangePicker/Elements/RangeDropdown/RangeDropdown.js";
9
9
  import { ALL_TIME } from "../constants.js";
10
- import format from "../dateUtils/format.js";
11
- import getDateFromString from "../dateUtils/getDateFromString.js";
12
- import { toIsoStringWithoutZone } from "../utils.js";
13
10
  import { ChosenRange, InvisibleTextContent, Container, ActionsPlaceholder, Actions } from "./Footer.styles.js";
14
11
  const Footer = ({
15
12
  canApply,
@@ -21,7 +18,6 @@ const Footer = ({
21
18
  message,
22
19
  texts,
23
20
  value,
24
- format: format$1,
25
21
  valueFormatOptions,
26
22
  showTime,
27
23
  displayDateContainerClass = "ds-date-range-picker-value",
@@ -30,20 +26,16 @@ const Footer = ({
30
26
  const {
31
27
  formatValue
32
28
  } = useDataFormat();
33
- const {
34
- locale
35
- } = useIntl();
36
- const footerFormat = format$1 || (showTime ? "MMM D, YYYY, HH:mm" : "MMM D, YYYY");
37
29
  const footerDateToString = useCallback((date) => {
38
- if (format$1 || typeof date === "string") {
39
- return format(getDateFromString(date), footerFormat, locale);
30
+ const parsed = typeof date === "string" ? parseISO(date) : date;
31
+ if (!isValid(parsed)) {
32
+ return "";
40
33
  }
41
- const parseDate = new Date(toIsoStringWithoutZone(date));
42
- return formatValue(parseDate, {
34
+ return formatValue(parsed, {
43
35
  ...getDefaultDataTimeOptions(showTime),
44
36
  ...valueFormatOptions
45
37
  });
46
- }, [footerFormat, format$1, formatValue, locale, valueFormatOptions, showTime]);
38
+ }, [formatValue, valueFormatOptions, showTime]);
47
39
  const ChosenRange$1 = useMemo(() => {
48
40
  if (value?.key === ALL_TIME || value && isLifetime(value)) {
49
41
  return /* @__PURE__ */ jsx(ChosenRange, { className: "ds-date-range-picker-value", children: value?.translationKey ? texts[value.translationKey] ?? value.translationKey : value?.key || "LIFETIME" });
@@ -11,10 +11,6 @@ export type Props = {
11
11
  onSwitchMode?: () => void;
12
12
  message?: React.ReactNode | string;
13
13
  texts: Texts;
14
- /**
15
- * @deprecated use `valueFormatOptions` instead
16
- */
17
- format?: string;
18
14
  valueFormatOptions?: DateToFormatOptions;
19
15
  showTime?: boolean;
20
16
  displayDateContainerClass?: string;
@@ -1,25 +1,6 @@
1
1
  import range from "lodash.range";
2
2
  import { v4 } from "uuid";
3
- import fnsAddDays from "date-fns/addDays";
4
- import "date-fns/addHours";
5
- import "date-fns/addMinutes";
6
- import "date-fns/addMonths";
7
- import "date-fns/addSeconds";
8
- import "date-fns/addWeeks";
9
- import "date-fns/addYears";
10
- import "date-fns/endOfDay";
11
- import "date-fns/endOfMonth";
12
- import fnsFormat from "date-fns/format";
13
- import "date-fns/getYear";
14
- import "date-fns/isAfter";
15
- import "date-fns/isBefore";
16
- import "date-fns/isSameMonth";
17
- import "date-fns/isSameYear";
18
- import "date-fns/setDate";
19
- import "date-fns/setMonth";
20
- import "date-fns/setYear";
21
- import "date-fns/startOfDay";
22
- import "date-fns/startOfMonth";
3
+ import { format, addDays } from "date-fns";
23
4
  import DailyFilter from "./Filters/DailyFilter/DailyFilter.js";
24
5
  import MonthlyFilter from "./Filters/MonthlyFilter/MonthlyFilter.js";
25
6
  import WeeklyFilter from "./Filters/WeeklyFilter/WeeklyFilter.js";
@@ -27,7 +8,7 @@ const LONG_MONTH = new Date(0, 0, 1);
27
8
  const TIME_FORMAT = "HH:mm:ss.SSS";
28
9
  const DEFAULT_RANGE_START = "00:00:00.000";
29
10
  const DEFAULT_RANGE_END = "23:59:59.999";
30
- const MONTH_DAYS = (locale) => range(0, 31).map((i) => locale === "pl" ? `${i + 1}.` : fnsFormat(fnsAddDays(LONG_MONTH, i), "Do"));
11
+ const MONTH_DAYS = (locale) => range(0, 31).map((i) => locale === "pl" ? `${i + 1}.` : format(addDays(LONG_MONTH, i), "Do"));
31
12
  var DAYS_OF_PERIOD_ENUM = /* @__PURE__ */ ((DAYS_OF_PERIOD_ENUM2) => {
32
13
  DAYS_OF_PERIOD_ENUM2["DAY_OF_MONTH"] = "MONTH";
33
14
  DAYS_OF_PERIOD_ENUM2["DAY_OF_WEEK"] = "WEEK";
@@ -1,8 +1,6 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
- import fnsIsSameDay from "date-fns/isSameDay";
3
- import fnsIsValid from "date-fns/isValid";
2
+ import { startOfDay, endOfDay, addDays, isSameMonth, isAfter, isValid, isSameDay, addMinutes, isBefore } from "date-fns";
4
3
  import { PureComponent } from "react";
5
- import { legacyParse } from "@date-fns/upgrade/v2";
6
4
  import { withDataFormat, getDefaultDataTimeOptions } from "@synerise/ds-core";
7
5
  import { YearPicker, MonthPicker, fnsDifferenceInYears, DayPicker, localeUtils, TimePicker, datePickerFormat } from "@synerise/ds-date-picker";
8
6
  import { DayBackground, DayText, DayForeground } from "@synerise/ds-date-picker/dist/Elements/DayPicker/DayPicker.styles";
@@ -12,29 +10,10 @@ import { Range } from "../RelativeRangePicker/RelativeRangePicker.styles.js";
12
10
  import { ABSOLUTE, COLUMNS, MODES } from "../constants.js";
13
11
  import ADD from "../dateUtils/add.js";
14
12
  import getDateFromString from "../dateUtils/getDateFromString.js";
15
- import fnsAddDays from "date-fns/addDays";
16
- import "date-fns/addHours";
17
- import fnsAddMinutes from "date-fns/addMinutes";
18
- import "date-fns/addMonths";
19
- import "date-fns/addSeconds";
20
- import "date-fns/addWeeks";
21
- import "date-fns/addYears";
22
- import fnsEndOfDay from "date-fns/endOfDay";
23
- import "date-fns/endOfMonth";
24
- import "date-fns/format";
25
- import "date-fns/getYear";
26
- import fnsIsAfter from "date-fns/isAfter";
27
- import fnsIsBefore from "date-fns/isBefore";
28
- import fnsIsSameMonth from "date-fns/isSameMonth";
29
- import "date-fns/isSameYear";
30
- import "date-fns/setDate";
31
- import "date-fns/setMonth";
32
- import "date-fns/setYear";
33
- import fnsStartOfDay from "date-fns/startOfDay";
34
- import "date-fns/startOfMonth";
13
+ import toDateValue from "../dateUtils/toDateValue.js";
35
14
  import { Sides, Side, PickerFooter, FooterSeparator, DateTimeModeSwitch } from "./RangePicker.styles.js";
36
15
  import { getModifiers, getDisabledTimeOptions, getSidesState } from "./utils.js";
37
- const isDayBefore = (day, reference) => fnsIsBefore(fnsStartOfDay(day), fnsStartOfDay(reference));
16
+ const isDayBefore = (day, reference) => isBefore(startOfDay(day), startOfDay(reference));
38
17
  const NOOP = () => {
39
18
  };
40
19
  const TOOLTIP_FORMAT = "MMM d, yyyy, HH:mm";
@@ -51,10 +30,10 @@ function replaceRange(value, day) {
51
30
  }
52
31
  if (!from) {
53
32
  from = day;
54
- } else if (from && to && fnsIsSameDay(from, to) && fnsIsSameDay(day, from)) {
33
+ } else if (from && to && isSameDay(from, to) && isSameDay(day, from)) {
55
34
  from = null;
56
35
  to = null;
57
- } else if (to && fnsIsSameDay(day, to)) {
36
+ } else if (to && isSameDay(day, to)) {
58
37
  from = day;
59
38
  to = day;
60
39
  } else if (from && to) {
@@ -99,8 +78,8 @@ class RangePicker extends PureComponent {
99
78
  from,
100
79
  to
101
80
  } = replaceRange(value, day);
102
- from = from ? fnsStartOfDay(from) : from;
103
- to = to ? fnsEndOfDay(to) : to;
81
+ from = from ? startOfDay(from) : from;
82
+ to = to ? endOfDay(to) : to;
104
83
  onChange && onChange({
105
84
  type: ABSOLUTE,
106
85
  from,
@@ -138,7 +117,7 @@ class RangePicker extends PureComponent {
138
117
  onChange({
139
118
  ...value,
140
119
  type: ABSOLUTE,
141
- from: fnsAddDays(legacyParse(value.from), numberOfDays)
120
+ from: addDays(toDateValue(value.from), numberOfDays)
142
121
  });
143
122
  }
144
123
  if (side === COLUMNS.RIGHT) {
@@ -149,7 +128,7 @@ class RangePicker extends PureComponent {
149
128
  onChange({
150
129
  ...value,
151
130
  type: ABSOLUTE,
152
- to: fnsAddDays(legacyParse(value.to), numberOfDays)
131
+ to: addDays(toDateValue(value.to), numberOfDays)
153
132
  });
154
133
  }
155
134
  };
@@ -161,8 +140,8 @@ class RangePicker extends PureComponent {
161
140
  const {
162
141
  forceAdjacentMonths
163
142
  } = this.props;
164
- if (fnsIsSameMonth(month, legacyParse(state[opposite].month))) {
165
- const dir = fnsIsAfter(month, legacyParse(state[side].month)) ? 1 : -1;
143
+ if (isSameMonth(month, toDateValue(state[opposite].month))) {
144
+ const dir = isAfter(month, toDateValue(state[side].month)) ? 1 : -1;
166
145
  const adjacentMonth = ADD.MONTHS(month, dir);
167
146
  this.setState((prevState) => ({
168
147
  ...prevState,
@@ -217,7 +196,7 @@ class RangePicker extends PureComponent {
217
196
  } = this.props;
218
197
  const formatDate = (date) => {
219
198
  if (typeof date === "string") {
220
- return datePickerFormat(legacyParse(date), TOOLTIP_FORMAT, intl.locale);
199
+ return datePickerFormat(toDateValue(date), TOOLTIP_FORMAT, intl.locale);
221
200
  }
222
201
  return formatValue(date, {
223
202
  ...getDefaultDataTimeOptions(true)
@@ -227,9 +206,9 @@ class RangePicker extends PureComponent {
227
206
  from,
228
207
  to
229
208
  } = value;
230
- const rangeFrom = from ? legacyParse(from) : null;
231
- const rangeTo = to ? legacyParse(to) : null;
232
- const isSelectedRangeDay = !!rangeFrom && !!rangeTo && fnsIsValid(rangeFrom) && fnsIsValid(rangeTo) && !isDayBefore(day, rangeFrom) && !isDayBefore(rangeTo, day);
209
+ const rangeFrom = from ? toDateValue(from) : null;
210
+ const rangeTo = to ? toDateValue(to) : null;
211
+ const isSelectedRangeDay = !!rangeFrom && !!rangeTo && isValid(rangeFrom) && isValid(rangeTo) && !isDayBefore(day, rangeFrom) && !isDayBefore(rangeTo, day);
233
212
  const dayForeground = /* @__PURE__ */ jsx(DayForeground, { className: "DayPicker-Day-FG" });
234
213
  return /* @__PURE__ */ jsxs(Fragment, { children: [
235
214
  /* @__PURE__ */ jsx(DayBackground, { className: "DayPicker-Day-BG" }),
@@ -252,7 +231,7 @@ class RangePicker extends PureComponent {
252
231
  [side]: currentSide,
253
232
  [opposite]: oppositeSide
254
233
  } = this.state;
255
- const oppositeMonth = legacyParse(oppositeSide.month);
234
+ const oppositeMonth = toDateValue(oppositeSide.month);
256
235
  return /* @__PURE__ */ jsx(MonthPicker, { max: side === COLUMNS.LEFT ? ADD.MONTHS(oppositeMonth, -1) : void 0, min: side === COLUMNS.RIGHT ? ADD.MONTHS(oppositeMonth, 1) : void 0, value: currentSide.month instanceof Date ? currentSide.month : new Date(currentSide.month), onChange: (month) => this.handleSideMonthChange(side, month, "date") }, `month_picker_${opposite}`);
257
236
  };
258
237
  this.renderDatePicker = (side) => {
@@ -272,16 +251,16 @@ class RangePicker extends PureComponent {
272
251
  to,
273
252
  type
274
253
  } = value;
275
- const modifiers = getModifiers(fnsIsValid(from) ? from : null, fnsIsValid(to) ? to : null, enteredTo);
276
- const selectedDays = fnsIsValid(from) && fnsIsValid(to) ? [legacyParse(from), {
277
- from: legacyParse(from),
278
- to: legacyParse(to)
254
+ const modifiers = getModifiers(isValid(from) ? from : null, isValid(to) ? to : null, enteredTo);
255
+ const selectedDays = isValid(from) && isValid(to) ? [toDateValue(from), {
256
+ from: toDateValue(from),
257
+ to: toDateValue(to)
279
258
  }] : [];
280
- const parsedLeft = legacyParse(left.month);
281
- const parsedRight = legacyParse(right.month);
282
- const adjacentMonths = forceAdjacentMonths || fnsIsSameMonth(ADD.MONTHS(parsedLeft, 1), parsedRight);
259
+ const parsedLeft = toDateValue(left.month);
260
+ const parsedRight = toDateValue(right.month);
261
+ const adjacentMonths = forceAdjacentMonths || isSameMonth(ADD.MONTHS(parsedLeft, 1), parsedRight);
283
262
  const adjacentYears = forceAdjacentMonths || fnsDifferenceInYears(ADD.MONTHS(parsedLeft, 1), parsedRight) === 0;
284
- return /* @__PURE__ */ jsx(DayPicker, { className: type.toLowerCase(), canChangeMonth: false, disabledDays: disabledDate, localeUtils, month: getDateFromString(sideState.month), title: sideState.monthTitle, hideLongNext: side === COLUMNS.LEFT && adjacentYears, hideShortNext: side === COLUMNS.LEFT && adjacentMonths, hideLongPrev: side === COLUMNS.RIGHT && adjacentYears, hideShortPrev: side === COLUMNS.RIGHT && adjacentMonths, renderDay: this.renderDay, onDayMouseEnter: this.handleDayMouseEnter, onDayMouseLeave: this.handleDayMouseLeave, onMonthNameClick: () => this.handleSideModeChange(side, "month"), onYearNameClick: () => this.handleSideModeChange(side, "year"), onMonthChange: (month) => this.handleSideMonthChange(side, month, "date"), fixedWeeks: true, showOutsideDays: true, modifiers, onDayClick: this.handleDayClick, selectedDays }, `day_picker_${side}`);
263
+ return /* @__PURE__ */ jsx(DayPicker, { className: type.toLowerCase(), canChangeMonth: false, disabledDays: disabledDate, localeUtils, month: getDateFromString(sideState.month), hideLongNext: side === COLUMNS.LEFT && adjacentYears, hideShortNext: side === COLUMNS.LEFT && adjacentMonths, hideLongPrev: side === COLUMNS.RIGHT && adjacentYears, hideShortPrev: side === COLUMNS.RIGHT && adjacentMonths, renderDay: this.renderDay, onDayMouseEnter: this.handleDayMouseEnter, onDayMouseLeave: this.handleDayMouseLeave, onMonthNameClick: () => this.handleSideModeChange(side, "month"), onYearNameClick: () => this.handleSideModeChange(side, "year"), onMonthChange: (month) => this.handleSideMonthChange(side, month, "date"), fixedWeeks: true, showOutsideDays: true, modifiers, onDayClick: this.handleDayClick, selectedDays }, `day_picker_${side}`);
285
264
  };
286
265
  this.renderTimePicker = (side) => {
287
266
  const {
@@ -295,7 +274,7 @@ class RangePicker extends PureComponent {
295
274
  if (!from || !to) {
296
275
  return null;
297
276
  }
298
- const sidesAreAdjacent = fnsIsSameDay(legacyParse(from), legacyParse(to));
277
+ const sidesAreAdjacent = isSameDay(toDateValue(from), toDateValue(to));
299
278
  switch (side) {
300
279
  case COLUMNS.LEFT: {
301
280
  return /* @__PURE__ */ jsx(TimePicker, { value: getDateFromString(from), onChange: this.handleFromTimeChange, disabledHours: getDisabledTimeOptions(from, "HOURS", null, to, is12HoursClock), disabledMinutes: getDisabledTimeOptions(from, "MINUTES", null, to, is12HoursClock), disabledSeconds: getDisabledTimeOptions(from, "SECONDS", null, to, is12HoursClock), onShortNext: sidesAreAdjacent ? void 0 : () => {
@@ -356,21 +335,21 @@ class RangePicker extends PureComponent {
356
335
  } = this.state;
357
336
  const toDateChanged = !!value?.to && value?.to !== prevProps?.value?.to;
358
337
  const fromDateChanged = !!value?.from && value?.from !== prevProps?.value?.from;
359
- const startOnLeft = fnsIsSameMonth(legacyParse(value.from), legacyParse(left.month));
360
- const endOnLeft = fnsIsSameMonth(legacyParse(value.to), legacyParse(left.month));
338
+ const startOnLeft = isSameMonth(toDateValue(value.from), toDateValue(left.month));
339
+ const endOnLeft = isSameMonth(toDateValue(value.to), toDateValue(left.month));
361
340
  if (fromDateChanged && !endOnLeft || toDateChanged && !endOnLeft || forceAdjacentMonths !== prevProps.forceAdjacentMonths) {
362
341
  if (startAlwaysOnTheLeft) {
363
342
  this.setState(getSidesState(value, forceAdjacentMonths));
364
343
  }
365
344
  }
366
345
  if (jumpToStartAndEnd && (fromDateChanged || toDateChanged)) {
367
- const startOnRight = fnsIsSameMonth(legacyParse(value.from), legacyParse(right.month));
346
+ const startOnRight = isSameMonth(toDateValue(value.from), toDateValue(right.month));
368
347
  const isStartVisible = startOnLeft || startOnRight;
369
348
  if (!isStartVisible) {
370
349
  this.setState(getSidesState(value, forceAdjacentMonths));
371
350
  return null;
372
351
  }
373
- const endOnRight = fnsIsSameMonth(legacyParse(value.to), legacyParse(right.month));
352
+ const endOnRight = isSameMonth(toDateValue(value.to), toDateValue(right.month));
374
353
  const isEndVisible = endOnLeft || endOnRight;
375
354
  if (!isEndVisible) {
376
355
  this.setState(getSidesState(value, forceAdjacentMonths));
@@ -394,8 +373,8 @@ class RangePicker extends PureComponent {
394
373
  } = this.props;
395
374
  return /* @__PURE__ */ jsxs(Fragment, { children: [
396
375
  /* @__PURE__ */ jsxs(Sides, { children: [
397
- /* @__PURE__ */ jsx(Side, { mode, children: this.renderSide(COLUMNS.LEFT) }),
398
- /* @__PURE__ */ jsx(Side, { mode, children: this.renderSide(COLUMNS.RIGHT) })
376
+ /* @__PURE__ */ jsx(Side, { mode, "data-testid": `date-range-picker-side-${COLUMNS.LEFT}`, children: this.renderSide(COLUMNS.LEFT) }),
377
+ /* @__PURE__ */ jsx(Side, { mode, "data-testid": `date-range-picker-side-${COLUMNS.RIGHT}`, children: this.renderSide(COLUMNS.RIGHT) })
399
378
  ] }),
400
379
  /* @__PURE__ */ jsxs(PickerFooter, { children: [
401
380
  showNowButton && /* @__PURE__ */ jsx(Range, { onClick: ({
@@ -407,7 +386,7 @@ class RangePicker extends PureComponent {
407
386
  translationKey: "now",
408
387
  type: "ABSOLUTE",
409
388
  from: now,
410
- to: fnsAddMinutes(now, 1)
389
+ to: addMinutes(now, 1)
411
390
  };
412
391
  onChange(literallyNow);
413
392
  currentTarget.blur();
@@ -24,12 +24,10 @@ export interface State {
24
24
  enteredTo?: Date | null;
25
25
  left: {
26
26
  month: Date | string;
27
- monthTitle: string;
28
27
  mode: string;
29
28
  };
30
29
  right: {
31
30
  month: Date | string;
32
- monthTitle: string;
33
31
  mode: string;
34
32
  };
35
33
  }
@@ -1,35 +1,11 @@
1
- import fnsIsValid from "date-fns/isValid";
2
- import fnsIsWithinRange from "date-fns/isWithinInterval";
3
- import fnsMax from "date-fns/max";
4
- import fnsMin from "date-fns/min";
1
+ import { isWithinInterval, endOfDay, startOfDay, isBefore, min, max, startOfMonth, isValid, isSameMonth } from "date-fns";
5
2
  import dayjs from "dayjs";
6
- import { legacyParse } from "@date-fns/upgrade/v2";
7
3
  import { AM, HOUR_12, PM, MAP_24_HOUR_TO_12, DISABLE_CLOCK_MODE_HOUR, HOUR } from "@synerise/ds-time-picker";
8
4
  import { TIME_OPTIONS } from "../constants.js";
9
5
  import ADD from "../dateUtils/add.js";
10
- import format from "../dateUtils/format.js";
11
6
  import GET from "../dateUtils/get.js";
12
7
  import SET from "../dateUtils/set.js";
13
- import "date-fns/addDays";
14
- import "date-fns/addHours";
15
- import "date-fns/addMinutes";
16
- import "date-fns/addMonths";
17
- import "date-fns/addSeconds";
18
- import "date-fns/addWeeks";
19
- import "date-fns/addYears";
20
- import fnsEndOfDay from "date-fns/endOfDay";
21
- import "date-fns/endOfMonth";
22
- import "date-fns/format";
23
- import "date-fns/getYear";
24
- import "date-fns/isAfter";
25
- import fnsIsBefore from "date-fns/isBefore";
26
- import fnsIsSameMonth from "date-fns/isSameMonth";
27
- import "date-fns/isSameYear";
28
- import "date-fns/setDate";
29
- import "date-fns/setMonth";
30
- import "date-fns/setYear";
31
- import fnsStartOfDay from "date-fns/startOfDay";
32
- import fnsStartOfMonth from "date-fns/startOfMonth";
8
+ import toDateValue from "../dateUtils/toDateValue.js";
33
9
  const NOW = /* @__PURE__ */ new Date();
34
10
  const HOURS_GRANULARITY = "HOURS";
35
11
  const getAmOrPmFromDate = (date) => {
@@ -38,20 +14,20 @@ const getAmOrPmFromDate = (date) => {
38
14
  const getInterval = (initialDate, startDate, endDate) => {
39
15
  if (!startDate && !endDate) {
40
16
  return {
41
- start: fnsStartOfDay(initialDate),
42
- end: fnsEndOfDay(initialDate)
17
+ start: startOfDay(initialDate),
18
+ end: endOfDay(initialDate)
43
19
  };
44
20
  }
45
21
  if (!startDate && endDate) {
46
22
  return {
47
- start: fnsIsBefore(initialDate, endDate) ? fnsStartOfDay(initialDate) : fnsStartOfDay(endDate),
23
+ start: isBefore(initialDate, endDate) ? startOfDay(initialDate) : startOfDay(endDate),
48
24
  end: endDate
49
25
  };
50
26
  }
51
27
  if (!endDate && startDate) {
52
28
  return {
53
29
  start: startDate,
54
- end: fnsIsBefore(initialDate, startDate) ? fnsEndOfDay(startDate) : fnsEndOfDay(initialDate)
30
+ end: isBefore(initialDate, startDate) ? endOfDay(startDate) : endOfDay(initialDate)
55
31
  };
56
32
  }
57
33
  return {
@@ -67,7 +43,7 @@ const getDisabledTimeOptions = (initialDay, granularity, initialLowerLimit = nul
67
43
  return [];
68
44
  }
69
45
  const dayBuilder = dayjs(day);
70
- const dayAsDate = typeof day === "string" ? legacyParse(day) : day;
46
+ const dayAsDate = typeof day === "string" ? toDateValue(day) : day;
71
47
  const dayClockMode = getAmOrPmFromDate(dayAsDate);
72
48
  let disableMeridienToggle = false;
73
49
  if (is12HoursClock && granularity === HOURS_GRANULARITY) {
@@ -85,11 +61,11 @@ const getDisabledTimeOptions = (initialDay, granularity, initialLowerLimit = nul
85
61
  }
86
62
  }
87
63
  }
88
- const intervalStartDate = lowerLimit ? legacyParse(lowerLimit) : void 0;
89
- const intervalEndDate = upperLimit ? legacyParse(upperLimit) : void 0;
64
+ const intervalStartDate = lowerLimit ? toDateValue(lowerLimit) : void 0;
65
+ const intervalEndDate = upperLimit ? toDateValue(upperLimit) : void 0;
90
66
  const interval = getInterval(dayAsDate, intervalStartDate, intervalEndDate);
91
67
  const options = TIME_OPTIONS[granularity].map((option) => SET[granularity](dayAsDate, option));
92
- let result = options.filter((opt) => !fnsIsWithinRange(opt, interval)).map((option) => GET[granularity](option));
68
+ let result = options.filter((opt) => !isWithinInterval(opt, interval)).map((option) => GET[granularity](option));
93
69
  if (is12HoursClock && granularity === HOURS_GRANULARITY) {
94
70
  if (dayClockMode === AM) {
95
71
  result = result.filter((item) => item < HOUR_12);
@@ -104,20 +80,18 @@ const getDisabledTimeOptions = (initialDay, granularity, initialLowerLimit = nul
104
80
  return result;
105
81
  };
106
82
  const getSidesState = (value, forceAdjacentMonths) => {
107
- const from = fnsStartOfMonth(fnsIsValid(value.from) ? legacyParse(value.from) : /* @__PURE__ */ new Date());
108
- let to = fnsIsValid(value.to) ? fnsStartOfMonth(legacyParse(value.to)) : from;
109
- if (fnsIsSameMonth(from, to)) {
83
+ const from = startOfMonth(isValid(value.from) ? toDateValue(value.from) : /* @__PURE__ */ new Date());
84
+ let to = isValid(value.to) ? startOfMonth(toDateValue(value.to)) : from;
85
+ if (isSameMonth(from, to)) {
110
86
  to = ADD.MONTHS(to, 1);
111
87
  }
112
88
  return {
113
89
  left: {
114
90
  month: from,
115
- monthTitle: fnsIsValid(from) ? format(legacyParse(from), "MMM yyyy") : "",
116
91
  mode: "date"
117
92
  },
118
93
  right: {
119
94
  month: forceAdjacentMonths ? ADD.MONTHS(from, 1) : to,
120
- monthTitle: fnsIsValid(to) ? format(legacyParse(to), "MMM yyyy") : "",
121
95
  mode: "date"
122
96
  }
123
97
  };
@@ -126,15 +100,15 @@ const toDate = (value) => {
126
100
  if (value === null || value === void 0) {
127
101
  return void 0;
128
102
  }
129
- return value instanceof Date ? value : legacyParse(value);
103
+ return value instanceof Date ? value : toDateValue(value);
130
104
  };
131
105
  const getModifiers = (from, to, enteredTo) => {
132
106
  const isSelecting = from && !to && enteredTo;
133
- const enteredStart = isSelecting ? fnsMin([legacyParse(from), legacyParse(enteredTo)]) : enteredTo;
134
- const enteredEnd = isSelecting ? fnsMax([legacyParse(from), legacyParse(enteredTo)]) : enteredTo;
135
- const entered = isSelecting ? (day) => fnsIsWithinRange(legacyParse(day), {
136
- start: legacyParse(enteredStart),
137
- end: legacyParse(enteredEnd)
107
+ const enteredStart = isSelecting ? min([toDateValue(from), toDateValue(enteredTo)]) : enteredTo;
108
+ const enteredEnd = isSelecting ? max([toDateValue(from), toDateValue(enteredTo)]) : enteredTo;
109
+ const entered = isSelecting ? (day) => isWithinInterval(toDateValue(day), {
110
+ start: toDateValue(enteredStart),
111
+ end: toDateValue(enteredEnd)
138
112
  }) : enteredTo;
139
113
  const startModifier = isSelecting && !!enteredTo && !!from && enteredTo < from ? void 0 : from;
140
114
  const endModifier = isSelecting && !!enteredTo && !!from && enteredTo < from ? from : to;
@@ -5,10 +5,6 @@ import { Texts } from '../DateRangePicker.types';
5
5
  import { DateFilter, DateRange } from '../date.types';
6
6
  export type RangePickerInputProps = {
7
7
  size?: 'large' | 'default' | 'small';
8
- /**
9
- * @deprecated use `valueFormatOptions` instead
10
- */
11
- format?: string;
12
8
  valueFormatOptions?: DateToFormatOptions;
13
9
  showTime?: boolean;
14
10
  allowClear?: boolean;
@@ -2,5 +2,5 @@ import { default as React } from 'react';
2
2
  import { DateRangePickerProps } from './DateRangePicker.types';
3
3
  import { DateRange } from './date.types';
4
4
  export declare function defaultValueTransformer(value: DateRange): DateRange;
5
- export declare const RawDateRangePicker: ({ showRelativePicker, showFilter, showTime, format, valueFormatOptions, disabledDate, validate, forceAdjacentMonths, savedFilters, onFilterSave, containerClass, footerProps, allowedFilterTypes, disableAbsoluteTimepickerInRelative, filterValueSelectionModes, filterRangeDisplayMode, showNowButton, relativeFuture, relativePast, ranges, relativeModes, rangeUnits, showCustomRange, valueTransformer, onValueChange, isTruncateMs, forceAbsolute, onApply, texts, value, }: Omit<DateRangePickerProps, "placement">) => React.JSX.Element;
5
+ export declare const RawDateRangePicker: ({ showRelativePicker, showFilter, showTime, valueFormatOptions, disabledDate, validate, forceAdjacentMonths, savedFilters, onFilterSave, containerClass, footerProps, allowedFilterTypes, disableAbsoluteTimepickerInRelative, filterValueSelectionModes, filterRangeDisplayMode, showNowButton, relativeFuture, relativePast, ranges, relativeModes, rangeUnits, showCustomRange, valueTransformer, onValueChange, isTruncateMs, forceAbsolute, onApply, texts, value, }: Omit<DateRangePickerProps, "placement">) => React.JSX.Element;
6
6
  export default RawDateRangePicker;