willba-component-library 0.2.78 → 0.2.80
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.
- package/lib/assets/IconsSvg.d.ts +9 -0
- package/lib/assets/SpinnerSvg.d.ts +5 -0
- package/lib/components/Button/Button.d.ts +29 -0
- package/lib/components/Button/Button.stories.d.ts +7 -0
- package/lib/components/Button/index.d.ts +1 -0
- package/lib/components/FilterBar/FilterBar.d.ts +5 -0
- package/lib/components/FilterBar/FilterBar.stories.d.ts +6 -0
- package/lib/components/FilterBar/FilterBarTypes.d.ts +56 -0
- package/lib/components/FilterBar/components/buttons/close-button/CloseButton.d.ts +7 -0
- package/lib/components/FilterBar/components/buttons/index.d.ts +4 -0
- package/lib/components/FilterBar/components/buttons/select-button/SelectButton.d.ts +10 -0
- package/lib/components/FilterBar/components/buttons/submit-button/SubmitButton.d.ts +3 -0
- package/lib/components/FilterBar/components/buttons/tab-button/TabButton.d.ts +10 -0
- package/lib/components/FilterBar/components/calendar/Calendar.d.ts +14 -0
- package/lib/components/FilterBar/components/categories/Categories.d.ts +8 -0
- package/lib/components/FilterBar/components/divider/Divider.d.ts +3 -0
- package/lib/components/FilterBar/components/guests/GuestCount/GuestCount.d.ts +4 -0
- package/lib/components/FilterBar/components/guests/Guests.d.ts +10 -0
- package/lib/components/FilterBar/components/index.d.ts +4 -0
- package/lib/components/FilterBar/hooks/index.d.ts +2 -0
- package/lib/components/FilterBar/hooks/useCloseFilterSection.d.ts +8 -0
- package/lib/components/FilterBar/hooks/useFilterBar.d.ts +27 -0
- package/lib/components/FilterBar/hooks/useScrollInToView.d.ts +9 -0
- package/lib/components/FilterBar/hooks/useUpdateTranslations.d.ts +5 -0
- package/lib/components/FilterBar/index.d.ts +2 -0
- package/lib/components/FilterBar/utils/index.d.ts +1 -0
- package/lib/components/FilterBar/utils/parseDates.d.ts +6 -0
- package/lib/components/FilterBar/utils/parseGuests.d.ts +17 -0
- package/lib/components/FilterCalendar/FilterCalendar.d.ts +5 -0
- package/lib/components/FilterCalendar/FilterCalendar.stories.d.ts +6 -0
- package/lib/components/FilterCalendar/FilterCalendarTypes.d.ts +9 -0
- package/lib/components/FilterCalendar/components/Footer.d.ts +10 -0
- package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +21 -0
- package/lib/components/FilterCalendar/index.d.ts +2 -0
- package/lib/core/components/buttons/close-button/CloseButton.d.ts +7 -0
- package/lib/core/components/buttons/submit-button/SubmitButton.d.ts +11 -0
- package/lib/core/components/calendar/Calendar.d.ts +5 -0
- package/lib/core/components/calendar/CalendarTypes.d.ts +39 -0
- package/{src/core/components/calendar/hooks/index.ts → lib/core/components/calendar/hooks/index.d.ts} +3 -3
- package/lib/core/components/calendar/hooks/useCalendarLoadingSpinner.d.ts +5 -0
- package/lib/core/components/calendar/hooks/useCalendarTooltips.d.ts +5 -0
- package/lib/core/components/calendar/hooks/useUpdateDisabledDates.d.ts +14 -0
- package/lib/core/components/calendar/utils/calendarSelectionRules.d.ts +15 -0
- package/lib/core/components/calendar/utils/checkForContinuousSelection.d.ts +11 -0
- package/lib/core/components/calendar/utils/disabledDatesByPage.d.ts +9 -0
- package/lib/core/components/calendar/utils/handleCalendarModifiers.d.ts +47 -0
- package/lib/core/components/calendar/utils/handleRangeContextDisabledDates.d.ts +27 -0
- package/{src/core/components/calendar/utils/index.ts → lib/core/components/calendar/utils/index.d.ts} +8 -8
- package/lib/core/components/calendar/utils/nightsCount.d.ts +6 -0
- package/lib/core/components/calendar/utils/parseDate.d.ts +7 -0
- package/lib/core/components/calendar/utils/parseDates.d.ts +6 -0
- package/lib/core/components/index.d.ts +3 -0
- package/lib/core/hooks/index.d.ts +3 -0
- package/lib/core/hooks/useAwaitRender.d.ts +1 -0
- package/lib/core/hooks/useCloseFilterSection.d.ts +8 -0
- package/lib/core/hooks/useUpdateTranslations.d.ts +5 -0
- package/lib/core/utils/handleOverlappingDates.d.ts +1 -0
- package/lib/core/utils/index.d.ts +3 -0
- package/lib/core/utils/nightsCount.d.ts +6 -0
- package/lib/core/utils/parseDate.d.ts +7 -0
- package/lib/core/utils/parseDates.d.ts +6 -0
- package/lib/i18n.d.ts +2 -0
- package/lib/index.d.ts +119 -0
- package/lib/index.esm.js +11576 -0
- package/lib/index.esm.js.map +1 -0
- package/lib/index.js +11598 -0
- package/lib/index.js.map +1 -0
- package/lib/index.umd.js +11602 -0
- package/lib/index.umd.js.map +1 -0
- package/lib/themes/useTheme.d.ts +13 -0
- package/package.json +1 -1
- package/src/assets/SpinnerSvg.tsx +40 -0
- package/src/components/FilterBar/FilterBar.stories.tsx +1 -2
- package/src/components/FilterBar/FilterBar.tsx +1 -1
- package/src/components/FilterBar/components/buttons/tab-button/TabButton.css +1 -1
- package/src/components/FilterBar/hooks/useFilterBar.tsx +1 -1
- package/src/components/FilterCalendar/FilterCalendar.css +10 -26
- package/src/components/FilterCalendar/FilterCalendar.stories.tsx +153 -522
- package/src/components/FilterCalendar/FilterCalendar.tsx +54 -25
- package/src/components/FilterCalendar/FilterCalendarTypes.ts +1 -0
- package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +4 -94
- package/src/core/components/buttons/submit-button/SubmitButton.css +2 -16
- package/src/core/components/buttons/submit-button/SubmitButton.tsx +5 -6
- package/src/core/components/calendar/Calendar.css +18 -71
- package/src/core/components/calendar/Calendar.tsx +342 -132
- package/src/core/components/calendar/CalendarTypes.ts +3 -10
- package/src/core/utils/index.ts +3 -0
- package/src/locales/en/common.json +1 -7
- package/src/locales/en/filterBar.json +1 -2
- package/src/locales/fi/common.json +1 -7
- package/src/locales/fi/filterBar.json +1 -2
- package/src/themes/Default.css +3 -12
- package/src/themes/useTheme.tsx +0 -3
- package/src/assets/IconsSvg.tsx +0 -68
- package/src/components/FilterCalendar/components/Footer.tsx +0 -96
- package/src/core/components/calendar/hooks/useCalendarLoadingSpinner.tsx +0 -19
- package/src/core/components/calendar/hooks/useCalendarTooltips.tsx +0 -125
- package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +0 -107
- package/src/core/components/calendar/utils/calendarSelectionRules.tsx +0 -228
- package/src/core/components/calendar/utils/checkForContinuousSelection.tsx +0 -86
- package/src/core/components/calendar/utils/disabledDatesByPage.tsx +0 -36
- package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +0 -147
- package/src/core/components/calendar/utils/handleRangeContextDisabledDates.tsx +0 -75
- package/willba-component-library-0.2.77.tgz +0 -0
- /package/src/core/{components/calendar/utils → utils}/nightsCount.tsx +0 -0
- /package/src/core/{components/calendar/utils → utils}/parseDate.tsx +0 -0
- /package/src/core/{components/calendar/utils → utils}/parseDates.tsx +0 -0
|
@@ -1,24 +1,12 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react'
|
|
2
|
-
import { startOfDay } from 'date-fns'
|
|
1
|
+
import React, { forwardRef, useEffect, useMemo, useState } from 'react'
|
|
2
|
+
import { addDays, startOfDay, format } from 'date-fns'
|
|
3
3
|
import { fi, enUS } from 'date-fns/locale'
|
|
4
4
|
import { useTranslation } from 'react-i18next'
|
|
5
|
-
import { DateRange, DayPicker } from 'react-day-picker'
|
|
5
|
+
import { DateRange, DayPicker, Matcher } from 'react-day-picker'
|
|
6
6
|
import { useMediaQuery } from 'react-responsive'
|
|
7
7
|
|
|
8
|
-
import { CalendarTypes } from './CalendarTypes'
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
calendarSelectionRules,
|
|
12
|
-
checkForContinuousSelection,
|
|
13
|
-
handleCalendarModifiers,
|
|
14
|
-
disabledDatesByPage as handleDisabledDatesByPage,
|
|
15
|
-
handleRangeContextDisabledDates,
|
|
16
|
-
} from './utils'
|
|
17
|
-
import {
|
|
18
|
-
useCalendarLoadingSpinner,
|
|
19
|
-
useCalendarTooltips,
|
|
20
|
-
useUpdateDisabledDates,
|
|
21
|
-
} from './hooks'
|
|
8
|
+
import { CalendarTypes, DisableCalendarDates } from './CalendarTypes'
|
|
9
|
+
import { SpinnerSVG } from '../../../assets/SpinnerSvg'
|
|
22
10
|
|
|
23
11
|
import 'react-day-picker/dist/style.css'
|
|
24
12
|
import './Calendar.css'
|
|
@@ -36,14 +24,11 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
36
24
|
setDisabledDates,
|
|
37
25
|
updateCalendarMonthNavigation,
|
|
38
26
|
setUpdateCalendarMonthNavigation,
|
|
39
|
-
|
|
27
|
+
updateCalendarDefaultMoth,
|
|
40
28
|
loadingData,
|
|
29
|
+
initialCalendarRange,
|
|
41
30
|
showFeedback,
|
|
42
31
|
palette,
|
|
43
|
-
setCalendarHasError,
|
|
44
|
-
setUpdatedForSubmit,
|
|
45
|
-
rangeContext,
|
|
46
|
-
calendarHasError,
|
|
47
32
|
}: CalendarTypes,
|
|
48
33
|
ref
|
|
49
34
|
) => {
|
|
@@ -53,16 +38,81 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
53
38
|
const isTablet = useMediaQuery({ maxWidth: 960 })
|
|
54
39
|
const today = startOfDay(new Date())
|
|
55
40
|
const selectedStartDate = calendarRange?.from
|
|
56
|
-
const rangeContextStartDate = rangeContext?.from
|
|
57
41
|
|
|
58
|
-
// Handle
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
42
|
+
// Handle overlapping availableDates.lastCheckOut and disabledDates.start
|
|
43
|
+
const [overlappingDate, setOverlappingDate] = useState<
|
|
44
|
+
DateRange[] | undefined
|
|
45
|
+
>(undefined)
|
|
46
|
+
|
|
47
|
+
const newDisableCalendarDates = useMemo(() => {
|
|
48
|
+
if (disableCalendarDates?.availableDates) {
|
|
49
|
+
const dateFormat = 'dd-MM-yyyy'
|
|
50
|
+
|
|
51
|
+
const { disabledDates } = disableCalendarDates
|
|
52
|
+
|
|
53
|
+
const { updatedDisabledDates, newOverlappingDates } = (
|
|
54
|
+
disabledDates || []
|
|
55
|
+
).reduce(
|
|
56
|
+
(
|
|
57
|
+
acc: {
|
|
58
|
+
updatedDisabledDates: { to: Date; from: Date }[]
|
|
59
|
+
newOverlappingDates: { to: Date; from: Date }[]
|
|
60
|
+
},
|
|
61
|
+
dateRange
|
|
62
|
+
) => {
|
|
63
|
+
const formattedFromDate = format(dateRange.from, dateFormat)
|
|
64
|
+
const formattedToDate = format(dateRange.to, dateFormat)
|
|
65
|
+
|
|
66
|
+
const hasTwoOverlappingDates =
|
|
67
|
+
disableCalendarDates.availableDates?.some(
|
|
68
|
+
(item) =>
|
|
69
|
+
format(item.lastCheckOut, dateFormat) === formattedFromDate &&
|
|
70
|
+
format(item.lastCheckOut, dateFormat) === formattedToDate
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
const hasOneOverlappingDate =
|
|
74
|
+
disableCalendarDates.availableDates?.some(
|
|
75
|
+
(item) =>
|
|
76
|
+
format(item.lastCheckOut, dateFormat) === formattedFromDate &&
|
|
77
|
+
format(item.lastCheckOut, dateFormat) !== formattedToDate
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if (hasTwoOverlappingDates) {
|
|
81
|
+
acc.newOverlappingDates.push(dateRange)
|
|
82
|
+
} else if (hasOneOverlappingDate) {
|
|
83
|
+
acc.newOverlappingDates.push(dateRange)
|
|
84
|
+
acc.updatedDisabledDates.push({
|
|
85
|
+
...dateRange,
|
|
86
|
+
from: addDays(dateRange.from, 1),
|
|
87
|
+
})
|
|
88
|
+
} else {
|
|
89
|
+
acc.updatedDisabledDates.push(dateRange)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return acc
|
|
93
|
+
},
|
|
94
|
+
{ updatedDisabledDates: [], newOverlappingDates: [] }
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
if (newOverlappingDates.length) {
|
|
98
|
+
setOverlappingDate((prev = []) => [...prev, ...newOverlappingDates])
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const newDisableCalendarDates = {
|
|
102
|
+
...disableCalendarDates,
|
|
103
|
+
disabledDates: updatedDisabledDates,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return newDisableCalendarDates
|
|
107
|
+
}
|
|
108
|
+
return disableCalendarDates
|
|
109
|
+
}, [
|
|
110
|
+
disableCalendarDates,
|
|
111
|
+
calendarRange,
|
|
112
|
+
updateCalendarMonthNavigation,
|
|
113
|
+
initialCalendarRange,
|
|
114
|
+
updateCalendarDefaultMoth,
|
|
115
|
+
])
|
|
66
116
|
|
|
67
117
|
// Handle disable dates by page
|
|
68
118
|
const disabledDatesByPage = handleDisabledDatesByPage({
|
|
@@ -72,72 +122,132 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
72
122
|
})
|
|
73
123
|
|
|
74
124
|
// Handle tooltip
|
|
75
|
-
|
|
76
|
-
showFeedback
|
|
77
|
-
})
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (typeof document === 'undefined' || !showFeedback) return
|
|
78
127
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
128
|
+
// Children
|
|
129
|
+
const calendarTooltip = document.querySelector('.will-calendar-tooltip')
|
|
130
|
+
const calendarTooltipCheckOut = document.querySelector(
|
|
131
|
+
'.will-calendar-tooltip-check-out'
|
|
132
|
+
)
|
|
83
133
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
rangeContext,
|
|
111
|
-
availableDates: newDisableCalendarDates?.availableDates,
|
|
112
|
-
calendarRange,
|
|
113
|
-
})
|
|
134
|
+
const calendarTooltipOverlappingDate = document.querySelector(
|
|
135
|
+
'.will-calendar-tooltip-overlapping-date'
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
const loadingSpinner = document.querySelector(
|
|
139
|
+
'.will-filter-bar-calendar .will-calendar-spinner'
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
// Parents
|
|
143
|
+
const calendarButtons = document.querySelectorAll(
|
|
144
|
+
'.will-filter-bar-calendar .rdp-cell:has(.booked):not(:has(.disabled-after-check-in))'
|
|
145
|
+
)
|
|
146
|
+
const calendarButtonsCheckOut = document.querySelectorAll(
|
|
147
|
+
'.will-filter-bar-calendar .rdp-cell:has(.booked.disabled-after-check-in)'
|
|
148
|
+
)
|
|
149
|
+
const calendarMonthContainer = document.querySelector(
|
|
150
|
+
'.will-filter-bar-calendar .rdp-months'
|
|
151
|
+
)
|
|
152
|
+
const calendarOverlappingDate = document.querySelectorAll(
|
|
153
|
+
'.will-filter-bar-calendar .rdp-cell:has(.overlapping-date)'
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
const tooltipClonesCheckIn: Element[] = []
|
|
157
|
+
const tooltipClonesCheckOut: Element[] = []
|
|
158
|
+
const tooltipClonesSpinner: Element[] = []
|
|
159
|
+
const tooltipClonesOverlappingDates: Element[] = []
|
|
114
160
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
161
|
+
if (calendarTooltip && calendarButtons.length > 0) {
|
|
162
|
+
calendarButtons.forEach((element) => {
|
|
163
|
+
const tooltipClone: Element = calendarTooltip.cloneNode(
|
|
164
|
+
true
|
|
165
|
+
) as Element
|
|
166
|
+
element.appendChild(tooltipClone)
|
|
167
|
+
tooltipClonesCheckIn.push(tooltipClone)
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (calendarTooltipCheckOut && calendarButtonsCheckOut.length > 0) {
|
|
172
|
+
calendarButtonsCheckOut.forEach((element) => {
|
|
173
|
+
const tooltipClone: Element = calendarTooltipCheckOut.cloneNode(
|
|
174
|
+
true
|
|
175
|
+
) as Element
|
|
176
|
+
element.appendChild(tooltipClone)
|
|
177
|
+
tooltipClonesCheckOut.push(tooltipClone)
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (loadingSpinner && calendarMonthContainer) {
|
|
182
|
+
const tooltipClone: Element = loadingSpinner.cloneNode(true) as Element
|
|
183
|
+
calendarMonthContainer.appendChild(tooltipClone)
|
|
184
|
+
tooltipClonesSpinner.push(tooltipClone)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (
|
|
188
|
+
calendarTooltipOverlappingDate &&
|
|
189
|
+
calendarOverlappingDate.length > 0
|
|
190
|
+
) {
|
|
191
|
+
calendarOverlappingDate.forEach((element) => {
|
|
192
|
+
const tooltipClone: Element =
|
|
193
|
+
calendarTooltipOverlappingDate.cloneNode(true) as Element
|
|
194
|
+
element.appendChild(tooltipClone)
|
|
195
|
+
tooltipClonesOverlappingDates.push(tooltipClone)
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return () => {
|
|
200
|
+
tooltipClonesCheckIn.forEach((clone) => clone.remove())
|
|
201
|
+
tooltipClonesCheckOut.forEach((clone) => clone.remove())
|
|
202
|
+
tooltipClonesSpinner.forEach((clone) => clone.remove())
|
|
203
|
+
tooltipClonesOverlappingDates.forEach((clone) => clone.remove())
|
|
204
|
+
}
|
|
205
|
+
}, [
|
|
119
206
|
calendarRange,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
207
|
+
updateCalendarMonthNavigation,
|
|
208
|
+
overlappingDate,
|
|
209
|
+
initialCalendarRange,
|
|
210
|
+
updateCalendarDefaultMoth,
|
|
211
|
+
])
|
|
212
|
+
|
|
213
|
+
// Handle loading spinner
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (typeof document === 'undefined') return
|
|
216
|
+
const loadingSpinner: HTMLElement | null = document.querySelector(
|
|
217
|
+
'.will-filter-bar-calendar .rdp-months .will-calendar-spinner'
|
|
218
|
+
)
|
|
219
|
+
if (loadingData) {
|
|
220
|
+
if (loadingSpinner) loadingSpinner.style.display = 'flex'
|
|
221
|
+
} else {
|
|
222
|
+
if (loadingSpinner) loadingSpinner.style.display = 'none'
|
|
223
|
+
}
|
|
224
|
+
}, [loadingData, updateCalendarMonthNavigation, updateCalendarDefaultMoth])
|
|
123
225
|
|
|
124
226
|
return (
|
|
125
227
|
<div className="will-filter-bar-calendar" ref={ref}>
|
|
126
228
|
<div className="will-calendar-filter-container">
|
|
127
229
|
<DayPicker
|
|
128
|
-
key={
|
|
230
|
+
key={updateCalendarDefaultMoth}
|
|
129
231
|
id="will-calendar"
|
|
130
232
|
mode="range"
|
|
131
233
|
locale={language === 'en' ? enUS : fi}
|
|
132
234
|
numberOfMonths={!isTablet ? 2 : 1}
|
|
133
235
|
weekStartsOn={1}
|
|
134
236
|
selected={calendarRange}
|
|
135
|
-
onSelect={(range) =>
|
|
237
|
+
onSelect={(range) =>
|
|
238
|
+
handleSelectedCheckIn({
|
|
239
|
+
range,
|
|
240
|
+
newDisableCalendarDates,
|
|
241
|
+
setCalendarRange,
|
|
242
|
+
setDisabledDates,
|
|
243
|
+
calendarRange,
|
|
244
|
+
overlappingDate,
|
|
245
|
+
})
|
|
246
|
+
}
|
|
136
247
|
captionLayout="dropdown-buttons"
|
|
137
248
|
defaultMonth={
|
|
138
|
-
|
|
249
|
+
initialCalendarRange?.from ||
|
|
139
250
|
selectedStartDate ||
|
|
140
|
-
rangeContextStartDate ||
|
|
141
251
|
(newDisableCalendarDates?.disabledDates?.length
|
|
142
252
|
? newDisableCalendarDates.disabledDates[0].from
|
|
143
253
|
: today)
|
|
@@ -146,20 +256,8 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
146
256
|
disabledDatesByPage.length
|
|
147
257
|
? disabledDatesByPage
|
|
148
258
|
: disabledDates?.length
|
|
149
|
-
?
|
|
150
|
-
|
|
151
|
-
...disabledDates,
|
|
152
|
-
...firstPossibleRangeContextCheckIn,
|
|
153
|
-
...lastPossibleRangeContextCheckOut,
|
|
154
|
-
]
|
|
155
|
-
: newDisableCalendarDates?.disabledDates?.length
|
|
156
|
-
? [
|
|
157
|
-
lastPossibleCheckout && lastPossibleCheckout,
|
|
158
|
-
...newDisableCalendarDates.disabledDates,
|
|
159
|
-
...firstPossibleRangeContextCheckIn,
|
|
160
|
-
...lastPossibleRangeContextCheckOut,
|
|
161
|
-
]
|
|
162
|
-
: []
|
|
259
|
+
? disabledDates
|
|
260
|
+
: newDisableCalendarDates?.disabledDates || []
|
|
163
261
|
}
|
|
164
262
|
fromMonth={today}
|
|
165
263
|
onMonthChange={(val) => {
|
|
@@ -168,43 +266,55 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
168
266
|
setUpdateCalendarMonthNavigation((prev) => !prev))
|
|
169
267
|
: null
|
|
170
268
|
}}
|
|
171
|
-
classNames={{
|
|
172
|
-
day_range_start: calendarRange?.from ? 'rdp-day_range_start' : '',
|
|
173
|
-
day_range_end: calendarRange?.to ? 'rdp-day_range_end' : '',
|
|
174
|
-
}}
|
|
175
269
|
modifiersClassNames={{
|
|
176
270
|
today: 'my-today',
|
|
177
271
|
booked: 'booked',
|
|
178
272
|
disabledAfterCheckIn: 'disabled-after-check-in',
|
|
179
273
|
overlappingDate: 'overlapping-date',
|
|
180
274
|
|
|
181
|
-
noActiveSelectionStart:
|
|
182
|
-
|
|
183
|
-
|
|
275
|
+
noActiveSelectionStart:
|
|
276
|
+
'rdp-day_selected rdp-day_range_start no-active-selection ',
|
|
277
|
+
noActiveSelectionMid:
|
|
278
|
+
'rdp-day_selected rdp-day_range_middle no-active-selection',
|
|
279
|
+
noActiveSelectionEnd:
|
|
280
|
+
'rdp-day_selected rdp-day_range_end no-active-selection',
|
|
281
|
+
}}
|
|
282
|
+
modifiers={{
|
|
283
|
+
booked: disabledDatesByPage.length
|
|
284
|
+
? disabledDatesByPage
|
|
285
|
+
: disabledDates?.length
|
|
286
|
+
? disabledDates
|
|
287
|
+
: newDisableCalendarDates?.disabledDates || [],
|
|
184
288
|
|
|
185
|
-
|
|
186
|
-
|
|
289
|
+
disabledAfterCheckIn: calendarRange?.from
|
|
290
|
+
? [{ after: calendarRange.from }]
|
|
291
|
+
: [],
|
|
187
292
|
|
|
188
|
-
|
|
189
|
-
|
|
293
|
+
noActiveSelectionStart: !calendarRange
|
|
294
|
+
? initialCalendarRange?.from || []
|
|
295
|
+
: [],
|
|
296
|
+
noActiveSelectionMid:
|
|
297
|
+
!calendarRange &&
|
|
298
|
+
initialCalendarRange?.from &&
|
|
299
|
+
initialCalendarRange?.to
|
|
300
|
+
? [
|
|
301
|
+
{
|
|
302
|
+
after: initialCalendarRange?.from,
|
|
303
|
+
before: initialCalendarRange?.to,
|
|
304
|
+
},
|
|
305
|
+
]
|
|
306
|
+
: [],
|
|
307
|
+
noActiveSelectionEnd: !calendarRange
|
|
308
|
+
? initialCalendarRange?.to || []
|
|
309
|
+
: [],
|
|
310
|
+
|
|
311
|
+
overlappingDate:
|
|
312
|
+
(!calendarRange?.from &&
|
|
313
|
+
overlappingDate?.map((item) => ({
|
|
314
|
+
from: item.from,
|
|
315
|
+
}))) ||
|
|
316
|
+
[],
|
|
190
317
|
}}
|
|
191
|
-
modifiers={
|
|
192
|
-
// This function handles conditions for applying the modifiersClassNames
|
|
193
|
-
handleCalendarModifiers({
|
|
194
|
-
newDisableCalendarDates,
|
|
195
|
-
calendarRange,
|
|
196
|
-
disabledDatesByPage,
|
|
197
|
-
disabledDates,
|
|
198
|
-
overlappingDate,
|
|
199
|
-
rangeContext,
|
|
200
|
-
lastPossibleCheckout,
|
|
201
|
-
findFirstPossibleRangeContextCheckIn,
|
|
202
|
-
findLastPossibleRangeContextCheckOut,
|
|
203
|
-
firstPossibleRangeContextCheckIn,
|
|
204
|
-
lastPossibleRangeContextCheckOut,
|
|
205
|
-
currentSelectionLastCheckoutDate,
|
|
206
|
-
})
|
|
207
|
-
}
|
|
208
318
|
/>
|
|
209
319
|
|
|
210
320
|
<div className={'will-calendar-tooltip'}>
|
|
@@ -216,21 +326,121 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
216
326
|
<div className={'will-calendar-tooltip-overlapping-date'}>
|
|
217
327
|
<div>{t('checkOutOnly')}</div>
|
|
218
328
|
</div>
|
|
219
|
-
<div className={'will-calendar-tooltip-check-in-only'}>
|
|
220
|
-
<div>{t('checkInOnly')}</div>
|
|
221
|
-
</div>
|
|
222
|
-
<div className={'will-calendar-tooltip-check-out-only'}>
|
|
223
|
-
<div>{t('checkOutOnly')}</div>
|
|
224
|
-
</div>
|
|
225
329
|
<div className={'will-calendar-spinner'}>
|
|
226
|
-
<
|
|
227
|
-
fill={palette?.primary || 'inherit'}
|
|
228
|
-
size={50}
|
|
229
|
-
icon="spinner"
|
|
230
|
-
/>
|
|
330
|
+
<SpinnerSVG fill={palette?.primary || 'inherit'} size={50} />
|
|
231
331
|
</div>
|
|
232
332
|
</div>
|
|
233
333
|
</div>
|
|
234
334
|
)
|
|
235
335
|
}
|
|
236
336
|
)
|
|
337
|
+
|
|
338
|
+
/////////
|
|
339
|
+
|
|
340
|
+
const handleSelectedCheckIn = ({
|
|
341
|
+
range,
|
|
342
|
+
newDisableCalendarDates,
|
|
343
|
+
setCalendarRange,
|
|
344
|
+
setDisabledDates,
|
|
345
|
+
calendarRange,
|
|
346
|
+
overlappingDate,
|
|
347
|
+
}: {
|
|
348
|
+
range: DateRange | undefined
|
|
349
|
+
newDisableCalendarDates?: DisableCalendarDates
|
|
350
|
+
setCalendarRange: (range: DateRange | undefined) => void
|
|
351
|
+
setDisabledDates: ((arg: Matcher[]) => void) | undefined
|
|
352
|
+
calendarRange?: DateRange
|
|
353
|
+
overlappingDate?: DateRange[]
|
|
354
|
+
}) => {
|
|
355
|
+
// Calendar dates select logic
|
|
356
|
+
const dateFormat = 'dd-MM-yyyy'
|
|
357
|
+
const rangeFrom = range?.from ? format(range.from, dateFormat) : null
|
|
358
|
+
const rangeTo = range?.to ? format(range.to, dateFormat) : null
|
|
359
|
+
const calendarFrom = calendarRange?.from
|
|
360
|
+
? format(calendarRange?.from, dateFormat)
|
|
361
|
+
: null
|
|
362
|
+
|
|
363
|
+
const overlappingDateFrom = overlappingDate?.length
|
|
364
|
+
? overlappingDate.find(
|
|
365
|
+
(date) => format(date.from || 1, dateFormat) === rangeFrom
|
|
366
|
+
)
|
|
367
|
+
: null
|
|
368
|
+
|
|
369
|
+
const checkOutRange = newDisableCalendarDates?.availableDates?.length
|
|
370
|
+
? newDisableCalendarDates.availableDates.find(
|
|
371
|
+
(checkInDate) =>
|
|
372
|
+
format(checkInDate.checkIn || 1, dateFormat) ===
|
|
373
|
+
format(range?.from || 1, dateFormat)
|
|
374
|
+
)
|
|
375
|
+
: null
|
|
376
|
+
|
|
377
|
+
if (rangeFrom && checkOutRange && setDisabledDates) {
|
|
378
|
+
const checkIn = addDays(checkOutRange.checkIn, 1)
|
|
379
|
+
const firstCheckOut = addDays(checkOutRange.firstCheckOut, -1)
|
|
380
|
+
const noDatesRange =
|
|
381
|
+
format(checkIn, dateFormat) ===
|
|
382
|
+
format(checkOutRange.firstCheckOut, dateFormat)
|
|
383
|
+
|
|
384
|
+
setDisabledDates([
|
|
385
|
+
// { before: findCheckOutRange?.checkIn },
|
|
386
|
+
|
|
387
|
+
...(newDisableCalendarDates?.disabledDates || []),
|
|
388
|
+
|
|
389
|
+
{
|
|
390
|
+
from: noDatesRange ? undefined : checkIn,
|
|
391
|
+
to: noDatesRange ? undefined : firstCheckOut,
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
{ after: checkOutRange?.lastCheckOut },
|
|
395
|
+
])
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (
|
|
399
|
+
(rangeTo && rangeFrom && rangeFrom === rangeTo) ||
|
|
400
|
+
(!rangeTo && !rangeFrom) ||
|
|
401
|
+
overlappingDateFrom
|
|
402
|
+
) {
|
|
403
|
+
setCalendarRange(undefined)
|
|
404
|
+
setDisabledDates && setDisabledDates([])
|
|
405
|
+
} else if (calendarFrom && rangeFrom && rangeFrom !== calendarFrom) {
|
|
406
|
+
setCalendarRange({
|
|
407
|
+
from: range?.from,
|
|
408
|
+
to: undefined,
|
|
409
|
+
})
|
|
410
|
+
} else {
|
|
411
|
+
setCalendarRange(range)
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const handleDisabledDatesByPage = ({
|
|
416
|
+
newDisableCalendarDates,
|
|
417
|
+
selectedPath,
|
|
418
|
+
today,
|
|
419
|
+
}: {
|
|
420
|
+
newDisableCalendarDates?: DisableCalendarDates
|
|
421
|
+
selectedPath?: string
|
|
422
|
+
today: Date
|
|
423
|
+
}) => {
|
|
424
|
+
const daysToOffsetCalendar =
|
|
425
|
+
newDisableCalendarDates?.disabledDatesByPage && selectedPath
|
|
426
|
+
? [
|
|
427
|
+
newDisableCalendarDates?.disabledDatesByPage?.find(
|
|
428
|
+
(item) => selectedPath === item.page
|
|
429
|
+
),
|
|
430
|
+
]
|
|
431
|
+
: []
|
|
432
|
+
|
|
433
|
+
return daysToOffsetCalendar.length
|
|
434
|
+
? [
|
|
435
|
+
{
|
|
436
|
+
from: addDays(
|
|
437
|
+
today,
|
|
438
|
+
daysToOffsetCalendar.length && daysToOffsetCalendar[0]?.offset
|
|
439
|
+
? daysToOffsetCalendar[0]?.offset
|
|
440
|
+
: -2
|
|
441
|
+
),
|
|
442
|
+
to: addDays(today, -100),
|
|
443
|
+
},
|
|
444
|
+
]
|
|
445
|
+
: []
|
|
446
|
+
}
|
|
@@ -18,11 +18,6 @@ export type DisableCalendarDates = {
|
|
|
18
18
|
}[]
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export type RangeContext = {
|
|
22
|
-
from: Date
|
|
23
|
-
to: Date
|
|
24
|
-
}
|
|
25
|
-
|
|
26
21
|
export type CalendarTypes = {
|
|
27
22
|
calendarRange?: DateRange | undefined
|
|
28
23
|
setCalendarRange: (range: DateRange | undefined) => void
|
|
@@ -34,14 +29,12 @@ export type CalendarTypes = {
|
|
|
34
29
|
disabledDates?: Matcher[]
|
|
35
30
|
setDisabledDates?: (arg: Matcher[]) => void
|
|
36
31
|
loadingData?: boolean
|
|
32
|
+
initialCalendarRange?: DateRange | undefined
|
|
37
33
|
showFeedback?: boolean
|
|
38
34
|
noActiveSelection?: boolean
|
|
39
35
|
palette?: Palette
|
|
36
|
+
|
|
40
37
|
updateCalendarMonthNavigation?: boolean
|
|
41
38
|
setUpdateCalendarMonthNavigation?: (arg: (prev: boolean) => boolean) => void
|
|
42
|
-
|
|
43
|
-
setCalendarHasError?: (arg: boolean) => void
|
|
44
|
-
setUpdatedForSubmit?: (arg: boolean) => void
|
|
45
|
-
rangeContext?: RangeContext
|
|
46
|
-
calendarHasError?: boolean
|
|
39
|
+
updateCalendarDefaultMoth?: number
|
|
47
40
|
}
|
|
@@ -8,11 +8,5 @@
|
|
|
8
8
|
"clearDates": "Clear dates",
|
|
9
9
|
"noCheckIn": "Room not available",
|
|
10
10
|
"noCheckOut": "Check-out not available",
|
|
11
|
-
"checkOutOnly": "Check-out only"
|
|
12
|
-
"checkInOnly": "Check-in only",
|
|
13
|
-
"errors": {
|
|
14
|
-
"calendarErrors": {
|
|
15
|
-
"checkInAvailabilityError": "All room reservations in a single purchase must be for the same dates. If you need reservations for different dates, please make a separate purchase."
|
|
16
|
-
}
|
|
17
|
-
}
|
|
11
|
+
"checkOutOnly": "Check-out only"
|
|
18
12
|
}
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
"endDate": "End date",
|
|
8
8
|
"title": "Calendar",
|
|
9
9
|
"checkoutOnly": "Check-out only",
|
|
10
|
-
"hasDisableDates": "Contains unavailable dates"
|
|
11
|
-
"minNights": "2 nights min"
|
|
10
|
+
"hasDisableDates": "Contains unavailable dates"
|
|
12
11
|
},
|
|
13
12
|
"guests": {
|
|
14
13
|
"label": "Number of guests",
|
|
@@ -8,12 +8,6 @@
|
|
|
8
8
|
"clearDates": "Tyhjennä",
|
|
9
9
|
"noCheckIn": "Huone ei saatavilla",
|
|
10
10
|
"noCheckOut": "Uloskirjaus ei saatavilla",
|
|
11
|
-
"checkOutOnly": "Vain uloskirjaus"
|
|
12
|
-
"checkInOnly": "Vain sisäänkirjaus",
|
|
13
|
-
"errors": {
|
|
14
|
-
"calendarErrors": {
|
|
15
|
-
"checkInAvailabilityError": "Yhdellä ostolla tehdyt huonevaraukset tulee olla samalle ajankohdalle. Jos tarvitset huonevarauksia eri ajankohdille, ole hyvä ja tee uusi osto."
|
|
16
|
-
}
|
|
17
|
-
}
|
|
11
|
+
"checkOutOnly": "Vain uloskirjaus"
|
|
18
12
|
}
|
|
19
13
|
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
"endDate": "Loppu",
|
|
8
8
|
"title": "Kalenteri",
|
|
9
9
|
"checkoutOnly": "Check-out only",
|
|
10
|
-
"hasDisableDates": "Contains unavailable dates"
|
|
11
|
-
"minNights": "2 nights min"
|
|
10
|
+
"hasDisableDates": "Contains unavailable dates"
|
|
12
11
|
},
|
|
13
12
|
"guests": {
|
|
14
13
|
"label": "Vierasmäärä",
|
package/src/themes/Default.css
CHANGED
|
@@ -15,30 +15,21 @@
|
|
|
15
15
|
--will-primary: #374269;
|
|
16
16
|
--will-secondary: #374269;
|
|
17
17
|
--will-grey: #ABA7AF;
|
|
18
|
-
--will-light-grey: #C8C8C8;
|
|
19
18
|
--will-white: #fff;
|
|
20
19
|
--will-white-transparent: #ffffffcf;
|
|
21
20
|
--will-black: #000;
|
|
22
21
|
--will-onahau: #CDEEFF;
|
|
23
22
|
--will-text: #5A5959;
|
|
24
23
|
--will-charcoal-blue: #384265;
|
|
25
|
-
--will-error: #d32f2f;
|
|
26
|
-
|
|
27
|
-
/* Transparent */
|
|
28
|
-
--will-transparent-black: rgba(0, 0, 0, 0.5);
|
|
29
24
|
--will-transparent-white: rgba(255, 255, 255, 0.30);
|
|
30
|
-
--will-transparent-
|
|
31
|
-
|
|
32
|
-
/* Color mix */
|
|
33
|
-
--will-primary-lighter: color-mix(in srgb, var(--will-primary), white 50%);
|
|
34
|
-
--will-primary-lightest: color-mix(in srgb, var(--will-primary), white 80%);
|
|
25
|
+
--will-transparent-black: rgba(171, 167, 175, 0.30);
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
/* Shadows */
|
|
27
|
+
/* Confines */
|
|
38
28
|
--will-box-shadow-dark: 0px 2px 12px 2px #a1a1a180;
|
|
39
29
|
--will-box-shadow-light: 0px 2px 12px 2px #bcb9b980;
|
|
40
30
|
|
|
41
31
|
/* Breakpoints */
|
|
32
|
+
|
|
42
33
|
--will-lg: 1140px;
|
|
43
34
|
--will-md: 960px;
|
|
44
35
|
--will-sm: 600px;
|