ublo-lib 1.26.3 → 1.26.4

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.
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import classNames from "classnames";
3
3
  import { useUbloContext } from "ublo/with-ublo";
4
4
  import Month from "./month";
5
- import Popup from "../popup";
5
+ import Popup from "ublo-lib/es/common/components/popup";
6
6
  import Helper from "./helper";
7
7
  import Button from "dt-design-system/es/button";
8
8
  import * as Icons from "dt-design-system/es/icons";
@@ -13,24 +13,18 @@ import datePickerStyles from "./date-picker.module.css";
13
13
  import styles from "./calendar.module.css";
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
16
- export default React.memo(Calendar);
17
- function Calendar({
16
+ export default function Calendar({
18
17
  date,
19
- mode,
20
- setMode,
21
18
  display,
22
19
  stayDates = [],
23
20
  min,
24
21
  max,
25
22
  onSubmit,
26
- specialRule,
27
- setSpecialRule,
28
- rules,
29
- hideModes,
30
23
  singleDate,
31
24
  submitOnSelectionEnd,
32
25
  availabilities,
33
- disableConfirmModal
26
+ disableConfirmModal,
27
+ close
34
28
  }) {
35
29
  const isDateObject = Utils.isDate(date);
36
30
  const _date = isDateObject ? date : new Date();
@@ -50,7 +44,8 @@ function Calendar({
50
44
  const [lastSelectedDate, setLastSelectedDate] = React.useState();
51
45
  const [showPopup, setShowPopup] = React.useState(false);
52
46
  const [stays, setStays] = React.useState();
53
- const mustKeepSelected = firstRangeDate && !selecting && (Utils.isSaturday(firstRangeDate) && Utils.isSaturday(selectedDates[selectedDates.length - 1]) || Utils.isSunday(firstRangeDate) && Utils.isSunday(selectedDates[selectedDates.length - 1]));
47
+ const [isLoading, setIsLoading] = React.useState(false);
48
+ const [error, setError] = React.useState();
54
49
  const gotoPreviousMonth = () => {
55
50
  const {
56
51
  month: newMonth,
@@ -67,6 +62,12 @@ function Calendar({
67
62
  setMonth(newMonth);
68
63
  setYear(newYear);
69
64
  };
65
+ const reset = () => {
66
+ setSelectedDates([]);
67
+ setSelecting(false);
68
+ setFirstSelectedDate(undefined);
69
+ setLastSelectedDate(undefined);
70
+ };
70
71
  const submit = dates => {
71
72
  const hasCart = window.sessionStorage.cartId !== undefined;
72
73
  if (!disableConfirmModal && hasCart) {
@@ -79,66 +80,28 @@ function Calendar({
79
80
  if (month === 12) {
80
81
  setMonthAlt(1);
81
82
  setYearAlt(year + 1);
82
- return;
83
- }
84
- if (month === 11) {
83
+ } else if (month === 11) {
85
84
  setMonthAlt(month + 1);
86
85
  setYearAlt(year);
87
- return;
86
+ } else {
87
+ setMonthAlt(month + 1);
88
88
  }
89
- setMonthAlt(month + 1);
90
89
  }, [month, year]);
91
- React.useEffect(() => {
92
- if (!firstRangeDate) return;
93
- const from = Utils.formatDate(firstRangeDate);
94
- const matchingRule = rules.find(rule => rule.trigger === from);
95
- setSpecialRule(matchingRule);
96
- if (matchingRule) return;
97
- if (display !== Data.DISPLAYS.PHONE && mode === Data.MODES.SATURDAY && Utils.isSunday(firstRangeDate) && Utils.isSunday(selectedDates[selectedDates.length - 1])) {
98
- const newSelectedDates = selectedDates.map(date => {
99
- const d = new Date(date);
100
- const newDate = new Date(d.setDate(d.getDate() - 1));
101
- return newDate;
102
- });
103
- setSelectedDates(newSelectedDates);
104
- }
105
- if (display !== Data.DISPLAYS.PHONE && mode === Data.MODES.SUNDAY && Utils.isSaturday(firstRangeDate) && Utils.isSaturday(selectedDates[selectedDates.length - 1])) {
106
- const newSelectedDates = selectedDates.map(date => {
107
- const d = new Date(date);
108
- const newDate = new Date(d.setDate(d.getDate() + 1));
109
- return newDate;
110
- });
111
- setSelectedDates(newSelectedDates);
112
- }
113
- if ((mode === Data.MODES.SATURDAY || mode === Data.MODES.SUNDAY) && !mustKeepSelected) {
114
- setSelectedDates([]);
115
- }
116
- }, [display, firstRangeDate, mode, mustKeepSelected, rules, selectedDates, setSpecialRule]);
117
- React.useEffect(() => {
118
- if (specialRule) {
119
- const {
120
- interval,
121
- mode
122
- } = specialRule;
123
- const from = new Date(interval.from);
124
- from.setHours(0, 0, 0, 0);
125
- const to = new Date(interval.to);
126
- to.setHours(0, 0, 0, 0);
127
- const dateInterval = Utils.getDateInterval(from, to);
128
- setMode(mode);
129
- setSelecting(false);
130
- setSelectedDates(dateInterval);
131
- }
132
- }, [setMode, specialRule]);
133
90
  const now = new Date();
134
91
  const currentMonth = now.getMonth() + 1;
135
92
  const currentYear = now.getFullYear();
136
93
  const isPast = month <= currentMonth && year <= currentYear;
137
- const showSubmit = !submitOnSelectionEnd && selectedDates.length > 0 && !selecting;
94
+ const showReset = !singleDate && selectedDates.length > 0;
95
+ const submitEnabled = !submitOnSelectionEnd && selectedDates.length > 0 && !selecting;
138
96
  const hide2ndMonth = display !== Data.DISPLAYS.DESKTOP;
97
+ const enableAvailability = Boolean(stays);
98
+ const matchingStays = Utils.getMatchingStays(stays, selectedDates);
99
+ const allMatchingStaysEnd = enableAvailability ? matchingStays?.map(stay => Utils.formatDate(stay.end)) : undefined;
139
100
  React.useEffect(() => {
140
101
  if (availabilities) {
141
102
  const fetchAvailabilities = async () => {
103
+ setIsLoading(true);
104
+ setError(undefined);
142
105
  setStays(undefined);
143
106
  const bareStart = `${year}-${Utils.zeroPad(month, 2)}-01`;
144
107
  const start = Utils.formatDate(Utils.addDays(bareStart, -7));
@@ -147,89 +110,119 @@ function Calendar({
147
110
  fetcher,
148
111
  ...rest
149
112
  } = availabilities;
150
- const {
151
- stays
152
- } = await fetcher({
153
- ...rest,
154
- start,
155
- numberDays
156
- });
157
- if (stays?.length) {
158
- const formatedStays = stays.map(stay => {
159
- return {
160
- start: new Date(stay.start),
161
- end: new Date(stay.end)
162
- };
113
+ try {
114
+ const {
115
+ stays
116
+ } = await fetcher({
117
+ ...rest,
118
+ start,
119
+ numberDays
163
120
  });
164
- setStays(formatedStays);
121
+ if (stays?.length) {
122
+ const formatedStays = stays.map(stay => {
123
+ return {
124
+ start: new Date(stay.start),
125
+ end: new Date(stay.end)
126
+ };
127
+ });
128
+ setStays(formatedStays);
129
+ }
130
+ } catch (e) {
131
+ setError(Messages.get(lang, "availability-loading-error"));
165
132
  }
133
+ setIsLoading(false);
166
134
  };
167
135
  fetchAvailabilities();
168
136
  }
169
- }, [availabilities, hide2ndMonth, month, year]);
137
+ }, [availabilities, hide2ndMonth, lang, month, year]);
170
138
  const classes = classNames(styles.calendar, {
171
139
  [styles.calendarTouch]: hide2ndMonth,
172
- [styles.hiddenModes]: hideModes
140
+ [styles.calendarLoading]: isLoading
173
141
  });
174
142
  return _jsxs("div", {
175
143
  className: classes,
176
144
  children: [!singleDate && _jsx(Helper, {
177
145
  lang: lang,
178
146
  selecting: selecting,
179
- selectedDates: selectedDates
147
+ selectedDates: selectedDates,
148
+ availabilities: availabilities,
149
+ isLoading: isLoading,
150
+ error: error
180
151
  }), _jsxs("div", {
181
- className: styles.controls,
182
- children: [!isPast && _jsx(Icons.ChevronLeft, {
183
- className: styles.control,
184
- onClick: gotoPreviousMonth
185
- }), _jsx(Icons.ChevronRight, {
186
- className: styles.control,
187
- onClick: gotoNextMonth
152
+ className: styles.months,
153
+ children: [_jsxs("div", {
154
+ className: styles.controls,
155
+ children: [_jsx(Button, {
156
+ variant: "transparent",
157
+ className: styles.control,
158
+ onClick: gotoPreviousMonth,
159
+ disabled: isPast,
160
+ children: _jsx(Icons.ChevronLeft, {})
161
+ }), _jsx(Button, {
162
+ variant: "transparent",
163
+ className: styles.control,
164
+ onClick: gotoNextMonth,
165
+ children: _jsx(Icons.ChevronRight, {})
166
+ })]
167
+ }), _jsx(Month, {
168
+ display: display,
169
+ month: month,
170
+ year: year,
171
+ min: min,
172
+ max: max,
173
+ selecting: selecting,
174
+ setSelecting: setSelecting,
175
+ selectedDates: selectedDates,
176
+ setSelectedDates: setSelectedDates,
177
+ firstSelectedDate: firstSelectedDate,
178
+ setFirstSelectedDate: setFirstSelectedDate,
179
+ lastSelectedDate: lastSelectedDate,
180
+ setLastSelectedDate: setLastSelectedDate,
181
+ singleDate: singleDate,
182
+ submitOnSelectionEnd: submitOnSelectionEnd,
183
+ onSubmit: submit,
184
+ stays: stays,
185
+ matchingStays: matchingStays,
186
+ allMatchingStaysEnd: allMatchingStaysEnd
187
+ }), !hide2ndMonth && _jsx(Month, {
188
+ display: display,
189
+ month: monthAlt,
190
+ year: yearAlt,
191
+ min: min,
192
+ max: max,
193
+ selecting: selecting,
194
+ setSelecting: setSelecting,
195
+ selectedDates: selectedDates,
196
+ setSelectedDates: setSelectedDates,
197
+ firstSelectedDate: firstSelectedDate,
198
+ setFirstSelectedDate: setFirstSelectedDate,
199
+ lastSelectedDate: lastSelectedDate,
200
+ setLastSelectedDate: setLastSelectedDate,
201
+ singleDate: singleDate,
202
+ submitOnSelectionEnd: submitOnSelectionEnd,
203
+ onSubmit: submit,
204
+ stays: stays,
205
+ matchingStays: matchingStays,
206
+ allMatchingStaysEnd: allMatchingStaysEnd
207
+ })]
208
+ }), _jsxs("div", {
209
+ className: styles.buttons,
210
+ children: [_jsx(Button, {
211
+ variant: "transparent",
212
+ className: styles.close,
213
+ onClick: close,
214
+ children: Messages.get(lang, "close")
215
+ }), showReset && _jsx(Button, {
216
+ variant: "link",
217
+ className: styles.reset,
218
+ onClick: reset,
219
+ children: Messages.get(lang, "reset")
220
+ }), _jsxs(Button, {
221
+ className: styles.submit,
222
+ onClick: () => submit(selectedDates),
223
+ disabled: !submitEnabled,
224
+ children: [_jsx(Icons.Check, {}), Messages.get(lang, "submit")]
188
225
  })]
189
- }), _jsx(Month, {
190
- mode: mode,
191
- setMode: setMode,
192
- display: display,
193
- month: month,
194
- year: year,
195
- min: min,
196
- max: max,
197
- selecting: selecting,
198
- setSelecting: setSelecting,
199
- selectedDates: selectedDates,
200
- setSelectedDates: setSelectedDates,
201
- firstSelectedDate: firstSelectedDate,
202
- setFirstSelectedDate: setFirstSelectedDate,
203
- lastSelectedDate: lastSelectedDate,
204
- setLastSelectedDate: setLastSelectedDate,
205
- singleDate: singleDate,
206
- submitOnSelectionEnd: submitOnSelectionEnd,
207
- onSubmit: submit,
208
- stays: stays
209
- }), !hide2ndMonth && _jsx(Month, {
210
- mode: mode,
211
- setMode: setMode,
212
- display: display,
213
- month: monthAlt,
214
- year: yearAlt,
215
- min: min,
216
- max: max,
217
- selecting: selecting,
218
- setSelecting: setSelecting,
219
- selectedDates: selectedDates,
220
- setSelectedDates: setSelectedDates,
221
- firstSelectedDate: firstSelectedDate,
222
- setFirstSelectedDate: setFirstSelectedDate,
223
- lastSelectedDate: lastSelectedDate,
224
- setLastSelectedDate: setLastSelectedDate,
225
- singleDate: singleDate,
226
- submitOnSelectionEnd: submitOnSelectionEnd,
227
- onSubmit: submit,
228
- stays: stays
229
- }), showSubmit && _jsxs(Button, {
230
- className: styles.submit,
231
- onClick: () => submit(selectedDates),
232
- children: [Messages.get(lang, "submit"), _jsx(Icons.Check, {})]
233
226
  }), showPopup && _jsx(Popup, {
234
227
  title: Messages.get(lang, "warning-date-change-title"),
235
228
  className: datePickerStyles.popup,
@@ -2,16 +2,13 @@
2
2
  grid-column: auto;
3
3
  position: relative;
4
4
  display: flex;
5
- padding: 20px 10px;
5
+ flex-direction: column;
6
+ padding: 12px;
6
7
  }
7
8
 
8
- @media (min-width: 650px) {
9
+ @media (min-width: 746px) {
9
10
  .calendar {
10
- padding: 20px 10px 20px 0;
11
- }
12
-
13
- .hiddenModes {
14
- padding: 20px 10px;
11
+ padding: 20px;
15
12
  }
16
13
  }
17
14
 
@@ -19,21 +16,32 @@
19
16
  flex: 0 0 auto;
20
17
  }
21
18
 
19
+ .calendarLoading * {
20
+ cursor: wait !important;
21
+ }
22
+
23
+ .months {
24
+ position: relative;
25
+ display: flex;
26
+ gap: 20px;
27
+ }
28
+
22
29
  .controls {
23
30
  position: absolute;
24
- top: 20px;
31
+ top: -4px;
25
32
  left: 0;
26
33
  width: 100%;
27
- height: 20px;
34
+ height: 40px;
28
35
  display: flex;
29
- padding: 0 20px;
36
+ padding: 0 6px;
30
37
  pointer-events: none;
31
38
  touch-action: none;
32
39
  }
33
40
 
34
41
  .control {
35
- width: 20px;
36
- height: 20px;
42
+ flex: 0 0 30px;
43
+ height: 30px;
44
+ padding: 2px;
37
45
  fill: var(--ds-grey-500, #484848);
38
46
  cursor: pointer;
39
47
  user-select: none;
@@ -45,33 +53,28 @@
45
53
  margin-left: auto;
46
54
  }
47
55
 
48
- button.submit {
49
- --ds-button-padding: 12px;
50
- --ds-button-text-transform: none;
56
+ .buttons {
57
+ display: flex;
58
+ justify-content: flex-end;
59
+ gap: 20px;
60
+ }
51
61
 
52
- width: auto;
53
- position: absolute;
54
- top: 100%;
55
- right: var(--ds-radius-200, 10px);
56
- font-size: 18px;
57
- transform-origin: right top;
58
- animation: date-picker-submit-button-appearance 320ms
59
- var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
60
- border-radius: 0 0 var(--ds-radius-100, 3px) var(--ds-radius-100, 3px);
62
+ button.submit,
63
+ button.close {
64
+ --padding: 10px;
65
+
66
+ font-size: 16px;
67
+ border-radius: var(--ds-radius-200, 10px);
61
68
  }
62
69
 
63
- @media (min-width: 1001px) {
64
- button.submit {
65
- font-size: 20px;
66
- }
70
+ button.close {
71
+ display: none;
67
72
  }
68
73
 
69
- @keyframes date-picker-submit-button-appearance {
70
- 0% {
71
- opacity: 0%;
72
- }
73
- 60% {
74
- transform: scale(1.15);
74
+ @media (min-width: 746px) {
75
+ button.close {
76
+ display: block;
77
+ margin-right: auto;
75
78
  }
76
79
  }
77
80
 
@@ -1,16 +1,11 @@
1
1
  import * as Utils from "./utils";
2
- export const MODES = {
3
- SATURDAY: 0,
4
- SUNDAY: 1,
5
- CUSTOM: 2
6
- };
7
2
  export const DISPLAYS = {
8
3
  DESKTOP: 0,
9
4
  TABLET: 1,
10
5
  PHONE: 2
11
6
  };
12
7
  export const BREAKPOINTS = {
13
- TABLET: 955,
8
+ TABLET: 745,
14
9
  PHONE: 650
15
10
  };
16
11
  export const THIS_YEAR = new Date().getFullYear();
@@ -47,22 +42,22 @@ export const MONTHS = {
47
42
  };
48
43
  export const WEEK_DAYS = {
49
44
  fr: {
50
- monday: "L",
51
- tuesday: "M",
52
- wednesday: "M",
53
- thursday: "J",
54
- friday: "V",
55
- saturday: "S",
56
- sunday: "D"
45
+ monday: "Lun.",
46
+ tuesday: "Mar.",
47
+ wednesday: "Mer.",
48
+ thursday: "Jeu.",
49
+ friday: "Ven.",
50
+ saturday: "Sam.",
51
+ sunday: "Dim."
57
52
  },
58
53
  en: {
59
- monday: "M",
60
- tuesday: "T",
61
- wednesday: "W",
62
- thursday: "T",
63
- friday: "F",
64
- saturday: "S",
65
- sunday: "S"
54
+ monday: "Mon.",
55
+ tuesday: "Tue",
56
+ wednesday: "Wed.",
57
+ thursday: "Tue.",
58
+ friday: "Fri.",
59
+ saturday: "Sat.",
60
+ sunday: "Sun."
66
61
  }
67
62
  };
68
63
  export const CALENDAR_WEEKS = 6;
@@ -1,11 +1,14 @@
1
1
  import * as React from "react";
2
2
  import classNames from "classnames";
3
- import * as Data from "./data";
3
+ import { useUbloContext } from "ublo/with-ublo";
4
+ import Popover from "dt-design-system/es/popover";
5
+ import Button from "dt-design-system/es/button";
4
6
  import * as Utils from "./utils";
7
+ import * as Messages from "./messages";
5
8
  import styles from "./date-item.module.css";
6
9
  import { jsx as _jsx } from "react/jsx-runtime";
7
- const DateItem = ({
8
- display,
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ export default function DateItem({
9
12
  date,
10
13
  index,
11
14
  month,
@@ -16,34 +19,55 @@ const DateItem = ({
16
19
  setSelectedDates,
17
20
  setFirstSelectedDate,
18
21
  setLastSelectedDate,
19
- mode,
20
- setMode,
21
22
  selecting,
22
23
  setSelecting,
23
24
  singleDate,
24
25
  submitOnSelectionEnd,
25
26
  onSubmit,
26
- stays
27
- }) => {
27
+ stays,
28
+ matchingStays,
29
+ allMatchingStaysEnd
30
+ }) {
31
+ const {
32
+ lang
33
+ } = useUbloContext();
28
34
  const today = new Date();
29
- const _date = new Date(date.join("-"));
35
+ const _date = React.useMemo(() => new Date(date.join("-")), [date]);
30
36
  _date.setHours(0, 0, 0, 0);
31
37
  const isToday = Utils.isSameDay(_date, today);
32
- const inMonth = month && year && Utils.isSameMonth(_date, new Date([Utils.zeroPad(year, 2), Utils.zeroPad(month, 2), "01"].join("-")));
33
- const isDisabled = Utils.isBefore(date, min) || Utils.isAfter(date, max);
38
+ const isInMonth = month && year && Utils.isSameMonth(_date, new Date([Utils.zeroPad(year, 2), Utils.zeroPad(month, 2), "01"].join("-")));
39
+ const firstSelectedDate = selectedDates[0];
40
+ const isFirstSelected = selectedDates.map(Number).indexOf(Number(_date)) === 0;
41
+ const isLastSelected = selectedDates.map(Number).indexOf(Number(_date)) === selectedDates.length - 1;
42
+ const isPastDate = Utils.isPast(date) || selecting && firstSelectedDate && Utils.isBefore(date, firstSelectedDate);
43
+ const isSelected = selectedDates.some(d => d.getTime() === _date.getTime());
34
44
  const enableAvailability = Boolean(stays);
35
45
  const isAvailable = stays?.some(stay => {
36
- return stay.start < _date && stay.end > _date;
46
+ const {
47
+ start,
48
+ end
49
+ } = stay;
50
+ const formatedStart = Utils.formatDate(start);
51
+ const formatedEnd = Utils.formatDate(end);
52
+ const formatedDate = Utils.formatDate(date);
53
+ return formatedStart === formatedDate || selecting && formatedEnd === formatedDate;
37
54
  }) || false;
38
- const firstDate = selectedDates[0];
39
- const isFirstSelected = selectedDates.map(Number).indexOf(Number(_date)) === 0;
40
- const isLastSelected = selectedDates.map(Number).indexOf(Number(_date)) === selectedDates.length - 1;
41
- const isPastDate = Utils.isPast(date) || selecting && firstDate && Utils.isBefore(date, firstDate);
55
+ const shortestMatchingStaysLength = enableAvailability && matchingStays?.reduce((acc, stay) => {
56
+ const fromDate = new Date(stay.start);
57
+ const toDate = new Date(stay.end);
58
+ const days = Utils.getDateInterval(fromDate, toDate);
59
+ const nights = days.length - 1;
60
+ if (nights < acc) {
61
+ return nights;
62
+ }
63
+ return acc;
64
+ }, Infinity);
65
+ const isDisabled = enableAvailability && selecting && allMatchingStaysEnd?.length && !allMatchingStaysEnd.includes(date.join("-")) || enableAvailability && !isAvailable || isPastDate || !isInMonth || Utils.isBefore(date, min) || Utils.isAfter(date, max);
42
66
  React.useEffect(() => {
43
67
  if (isFirstSelected) setFirstSelectedDate(index);
44
68
  if (isLastSelected) setLastSelectedDate(index);
45
69
  }, [index, isFirstSelected, isLastSelected, setFirstSelectedDate, setLastSelectedDate]);
46
- const updateDateSelection = () => {
70
+ const updateDateSelection = React.useCallback(() => {
47
71
  if (isPastDate || isDisabled) return;
48
72
  if (singleDate) {
49
73
  setSelectedDates([_date]);
@@ -53,66 +77,51 @@ const DateItem = ({
53
77
  }
54
78
  return;
55
79
  }
56
- if (display !== Data.DISPLAYS.PHONE && (mode === Data.MODES.SATURDAY || mode === Data.MODES.SUNDAY) && (Utils.isSaturday(date) || Utils.isSunday(date))) {
57
- const nights = [...new Array(8)];
58
- const dates = nights.map((_, i) => {
59
- const d = new Date(_date);
60
- const currDay = new Date(d.setDate(_date.getDate() + i));
61
- currDay.setHours(0, 0, 0, 0);
62
- return currDay;
63
- });
64
- if (Utils.isSaturday(date)) {
65
- if (mode !== Data.MODES.SATURDAY) setMode(Data.MODES.SATURDAY);
66
- setSelecting(false);
67
- }
68
- if (Utils.isSunday(date)) {
69
- if (mode !== Data.MODES.SUNDAY) setMode(Data.MODES.SUNDAY);
70
- setSelecting(false);
71
- }
72
- setSelectedDates(dates);
80
+ if (selecting) {
81
+ const isPastDate = _date < firstSelectedDate;
82
+ const interval = isPastDate ? Utils.getDateInterval(_date, firstSelectedDate) : Utils.getDateInterval(firstSelectedDate, _date);
83
+ setSelectedDates(interval);
84
+ setSelecting(false);
85
+ } else {
86
+ setSelectedDates([_date]);
87
+ setSelecting(true);
73
88
  if (submitOnSelectionEnd) {
74
- onSubmit(dates);
75
- }
76
- }
77
- if (mode === Data.MODES.CUSTOM || !Utils.isSaturday(date) && !Utils.isSunday(date) || display === Data.DISPLAYS.PHONE) {
78
- if (mode !== Data.MODES.CUSTOM) setMode(Data.MODES.CUSTOM);
79
- if (selecting) {
80
- const isPastDate = _date < firstDate;
81
- const interval = isPastDate ? Utils.getDateInterval(_date, firstDate) : Utils.getDateInterval(firstDate, _date);
82
- setSelectedDates(interval);
83
- if (interval.length === 8) {
84
- if (Utils.isSaturday(interval[0]) && Utils.isSaturday(interval[7])) setMode(Data.MODES.SATURDAY);
85
- if (Utils.isSunday(interval[0]) && Utils.isSunday(interval[7])) setMode(Data.MODES.SUNDAY);
86
- }
87
- setSelecting(false);
88
- } else {
89
- setSelectedDates([_date]);
90
- setSelecting(true);
91
- if (submitOnSelectionEnd) {
92
- onSubmit([_date]);
93
- }
89
+ onSubmit([_date]);
94
90
  }
95
91
  }
96
- };
97
- const isSelected = !!selectedDates.find(d => d.getTime() === _date.getTime());
92
+ }, [_date, firstSelectedDate, isDisabled, isPastDate, onSubmit, selecting, setSelectedDates, setSelecting, singleDate, submitOnSelectionEnd]);
98
93
  const classes = classNames(styles.date, {
99
94
  [styles.dateToday]: isToday,
100
95
  [styles.dateSelected]: isSelected,
101
96
  [styles.dateFirstSelected]: isFirstSelected,
102
97
  [styles.dateLastSelected]: isLastSelected,
103
- [styles.dateNotInMonth]: !inMonth,
104
- [styles.dateIsPast]: isPastDate || isDisabled,
105
- [styles.dateSaturday]: mode === Data.MODES.SATURDAY && Utils.isSaturday(date),
106
- [styles.dateSunday]: mode === Data.MODES.SUNDAY && Utils.isSunday(date),
98
+ [styles.dateNotInMonth]: !isInMonth,
99
+ [styles.dateIsPast]: !isSelected && isDisabled,
107
100
  [styles.available]: enableAvailability && isAvailable,
108
- [styles.notAvailable]: enableAvailability && !isAvailable
101
+ [styles.notAvailable]: enableAvailability && !isAvailable && !isSelected
109
102
  });
110
- return _jsx("button", {
103
+ const dateComponent = _jsx(Button, {
111
104
  className: classes,
112
105
  onClick: updateDateSelection,
113
- tabIndex: isPastDate ? -1 : 0,
114
- disabled: isPastDate || isDisabled,
115
- children: _date.getDate()
106
+ disabled: !isSelected && isDisabled,
107
+ children: _jsx("span", {
108
+ children: _date.getDate()
109
+ })
116
110
  });
117
- };
118
- export default React.memo(DateItem);
111
+ const showPopover = enableAvailability && isInMonth && isFirstSelected && shortestMatchingStaysLength && selecting;
112
+ if (showPopover) {
113
+ const tooltip = Messages.get(lang, shortestMatchingStaysLength > 1 ? "min-nights-plural" : "min-nights-singular");
114
+ return _jsxs(Popover, {
115
+ trigger: dateComponent,
116
+ open: true,
117
+ className: styles.popover,
118
+ innerClassName: "nights-number-hint__inner",
119
+ contentProps: {
120
+ side: "top"
121
+ },
122
+ children: [shortestMatchingStaysLength, " ", tooltip]
123
+ });
124
+ } else {
125
+ return dateComponent;
126
+ }
127
+ }