willba-component-library 0.2.55 → 0.2.57

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 (58) hide show
  1. package/lib/assets/IconsSvg.d.ts +9 -0
  2. package/lib/components/FilterBar/FilterBar.stories.d.ts +1 -1
  3. package/lib/components/FilterCalendar/FilterCalendar.d.ts +1 -1
  4. package/lib/components/FilterCalendar/FilterCalendar.stories.d.ts +2 -1
  5. package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +3 -3
  6. package/lib/core/components/calendar/CalendarTypes.d.ts +8 -6
  7. package/lib/core/components/calendar/hooks/index.d.ts +3 -0
  8. package/lib/core/components/calendar/hooks/useCalendarLoadingSpinner.d.ts +7 -0
  9. package/lib/core/components/calendar/hooks/useCalendarTooltips.d.ts +10 -0
  10. package/lib/core/components/calendar/hooks/useUpdateDisabledDates.d.ts +13 -0
  11. package/lib/core/components/calendar/utils/calendarSelectionRules.d.ts +15 -0
  12. package/lib/core/components/calendar/utils/checkForContinuousSelection.d.ts +10 -0
  13. package/lib/core/components/calendar/utils/disabledDatesByPage.d.ts +9 -0
  14. package/lib/core/components/calendar/utils/handleCalendarModifiers.d.ts +46 -0
  15. package/lib/core/components/calendar/utils/handleRangeContextDisabledDates.d.ts +27 -0
  16. package/lib/core/components/calendar/utils/index.d.ts +8 -0
  17. package/lib/core/components/calendar/utils/nightsCount.d.ts +6 -0
  18. package/lib/core/components/calendar/utils/parseDate.d.ts +7 -0
  19. package/lib/core/components/calendar/utils/parseDates.d.ts +6 -0
  20. package/lib/index.d.ts +10 -7
  21. package/lib/index.esm.js +670 -273
  22. package/lib/index.esm.js.map +1 -1
  23. package/lib/index.js +670 -273
  24. package/lib/index.js.map +1 -1
  25. package/lib/index.umd.js +670 -273
  26. package/lib/index.umd.js.map +1 -1
  27. package/lib/themes/useTheme.d.ts +2 -0
  28. package/package.json +1 -1
  29. package/src/assets/IconsSvg.tsx +66 -0
  30. package/src/components/FilterBar/FilterBar.stories.tsx +2 -1
  31. package/src/components/FilterBar/FilterBar.tsx +1 -1
  32. package/src/components/FilterCalendar/FilterCalendar.css +8 -9
  33. package/src/components/FilterCalendar/FilterCalendar.stories.tsx +345 -158
  34. package/src/components/FilterCalendar/FilterCalendar.tsx +69 -52
  35. package/src/components/FilterCalendar/FilterCalendarTypes.ts +0 -1
  36. package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +44 -4
  37. package/src/core/components/buttons/submit-button/SubmitButton.tsx +1 -4
  38. package/src/core/components/calendar/Calendar.css +24 -6
  39. package/src/core/components/calendar/Calendar.tsx +127 -382
  40. package/src/core/components/calendar/CalendarTypes.ts +9 -4
  41. package/src/core/components/calendar/hooks/index.ts +3 -0
  42. package/src/core/components/calendar/hooks/useCalendarLoadingSpinner.tsx +25 -0
  43. package/src/core/components/calendar/hooks/useCalendarTooltips.tsx +139 -0
  44. package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +94 -0
  45. package/src/core/components/calendar/utils/calendarSelectionRules.tsx +179 -0
  46. package/src/core/components/calendar/utils/checkForContinuousSelection.tsx +50 -0
  47. package/src/core/components/calendar/utils/disabledDatesByPage.tsx +36 -0
  48. package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +151 -0
  49. package/src/core/components/calendar/utils/handleRangeContextDisabledDates.tsx +70 -0
  50. package/src/core/components/calendar/utils/index.ts +8 -0
  51. package/src/themes/Default.css +6 -0
  52. package/src/themes/useTheme.tsx +3 -0
  53. package/src/assets/SpinnerSvg.tsx +0 -40
  54. package/src/core/utils/handleOverlappingDates.tsx +0 -3
  55. package/src/core/utils/index.ts +0 -3
  56. /package/src/core/{utils → components/calendar/utils}/nightsCount.tsx +0 -0
  57. /package/src/core/{utils → components/calendar/utils}/parseDate.tsx +0 -0
  58. /package/src/core/{utils → components/calendar/utils}/parseDates.tsx +0 -0
@@ -1,19 +1,24 @@
1
- import React, { forwardRef, useEffect, useMemo, useState } from 'react'
2
- import {
3
- addDays,
4
- startOfDay,
5
- format,
6
- isAfter,
7
- isEqual,
8
- isBefore,
9
- } from 'date-fns'
1
+ import React, { forwardRef } from 'react'
2
+ import { startOfDay, isBefore, endOfDay, isEqual, isAfter } from 'date-fns'
10
3
  import { fi, enUS } from 'date-fns/locale'
11
4
  import { useTranslation } from 'react-i18next'
12
- import { DateRange, DayPicker, Matcher } from 'react-day-picker'
5
+ import { DateRange, DayPicker } from 'react-day-picker'
13
6
  import { useMediaQuery } from 'react-responsive'
14
7
 
15
- import { CalendarTypes, DisableCalendarDates } from './CalendarTypes'
16
- import { SpinnerSVG } from '../../../assets/SpinnerSvg'
8
+ import { CalendarTypes } from './CalendarTypes'
9
+ import { IconsSvg } from '../../../assets/IconsSvg'
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'
17
22
 
18
23
  import 'react-day-picker/dist/style.css'
19
24
  import './Calendar.css'
@@ -33,10 +38,12 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
33
38
  setUpdateCalendarMonthNavigation,
34
39
  updateCalendarDefaultMoth,
35
40
  loadingData,
36
- initialCalendarRange,
37
41
  showFeedback,
38
42
  palette,
39
- setOverlappingDates,
43
+ setCalendarHasError,
44
+ setUpdatedForSubmit,
45
+ rangeContext,
46
+ calendarHasError,
40
47
  }: CalendarTypes,
41
48
  ref
42
49
  ) => {
@@ -46,81 +53,17 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
46
53
  const isTablet = useMediaQuery({ maxWidth: 960 })
47
54
  const today = startOfDay(new Date())
48
55
  const selectedStartDate = calendarRange?.from
56
+ const rangeContextStartDate = rangeContext?.from
49
57
 
50
58
  // Handle overlapping availableDates.lastCheckOut and disabledDates.start
51
- const [overlappingDate, setOverlappingDate] = useState<
52
- DateRange[] | undefined
53
- >(undefined)
54
-
55
- const newDisableCalendarDates = useMemo(() => {
56
- if (disableCalendarDates?.availableDates) {
57
- const dateFormat = 'dd-MM-yyyy'
58
-
59
- const { disabledDates } = disableCalendarDates
60
-
61
- const { updatedDisabledDates, newOverlappingDates } = (
62
- disabledDates || []
63
- ).reduce(
64
- (
65
- acc: {
66
- updatedDisabledDates: { to: Date; from: Date }[]
67
- newOverlappingDates: { to: Date; from: Date }[]
68
- },
69
- dateRange
70
- ) => {
71
- const formattedFromDate = format(dateRange.from, dateFormat)
72
- const formattedToDate = format(dateRange.to, dateFormat)
73
-
74
- const hasTwoOverlappingDates =
75
- disableCalendarDates.availableDates?.some(
76
- (item) =>
77
- format(item.lastCheckOut, dateFormat) === formattedFromDate &&
78
- format(item.lastCheckOut, dateFormat) === formattedToDate
79
- )
80
-
81
- const hasOneOverlappingDate =
82
- disableCalendarDates.availableDates?.some(
83
- (item) =>
84
- format(item.lastCheckOut, dateFormat) === formattedFromDate &&
85
- format(item.lastCheckOut, dateFormat) !== formattedToDate
86
- )
87
-
88
- if (hasTwoOverlappingDates) {
89
- acc.newOverlappingDates.push(dateRange)
90
- } else if (hasOneOverlappingDate) {
91
- acc.newOverlappingDates.push(dateRange)
92
- acc.updatedDisabledDates.push({
93
- ...dateRange,
94
- from: addDays(dateRange.from, 1),
95
- })
96
- } else {
97
- acc.updatedDisabledDates.push(dateRange)
98
- }
99
-
100
- return acc
101
- },
102
- { updatedDisabledDates: [], newOverlappingDates: [] }
103
- )
104
-
105
- if (newOverlappingDates.length) {
106
- setOverlappingDate((prev = []) => [...prev, ...newOverlappingDates])
107
- }
108
-
109
- const newDisableCalendarDates = {
110
- ...disableCalendarDates,
111
- disabledDates: updatedDisabledDates,
112
- }
113
-
114
- return newDisableCalendarDates
59
+ const { newDisableCalendarDates, overlappingDate } = useUpdateDisabledDates(
60
+ {
61
+ disableCalendarDates,
62
+ calendarRange,
63
+ updateCalendarMonthNavigation,
64
+ updateCalendarDefaultMoth,
115
65
  }
116
- return disableCalendarDates
117
- }, [
118
- disableCalendarDates,
119
- calendarRange,
120
- updateCalendarMonthNavigation,
121
- initialCalendarRange,
122
- updateCalendarDefaultMoth,
123
- ])
66
+ )
124
67
 
125
68
  // Handle disable dates by page
126
69
  const disabledDatesByPage = handleDisabledDatesByPage({
@@ -130,106 +73,59 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
130
73
  })
131
74
 
132
75
  // Handle tooltip
133
- useEffect(() => {
134
- if (typeof document === 'undefined' || !showFeedback) return
135
-
136
- // Children
137
- const calendarTooltip = document.querySelector('.will-calendar-tooltip')
138
- const calendarTooltipCheckOut = document.querySelector(
139
- '.will-calendar-tooltip-check-out'
140
- )
141
-
142
- const calendarTooltipOverlappingDate = document.querySelector(
143
- '.will-calendar-tooltip-overlapping-date'
144
- )
145
-
146
- const loadingSpinner = document.querySelector(
147
- '.will-filter-bar-calendar .will-calendar-spinner'
148
- )
149
-
150
- // Parents
151
- const calendarButtons = document.querySelectorAll(
152
- '.will-filter-bar-calendar .rdp-cell:has(.booked):not(:has(.disabled-after-check-in))'
153
- )
154
- const calendarButtonsCheckOut = document.querySelectorAll(
155
- '.will-filter-bar-calendar .rdp-cell:has(.booked.disabled-after-check-in)'
156
- )
157
- const calendarMonthContainer = document.querySelector(
158
- '.will-filter-bar-calendar .rdp-months'
159
- )
160
- const calendarOverlappingDate = document.querySelectorAll(
161
- '.will-filter-bar-calendar .rdp-cell:has(.overlapping-date)'
162
- )
163
-
164
- const tooltipClonesCheckIn: Element[] = []
165
- const tooltipClonesCheckOut: Element[] = []
166
- const tooltipClonesSpinner: Element[] = []
167
- const tooltipClonesOverlappingDates: Element[] = []
168
-
169
- if (calendarTooltip && calendarButtons.length > 0) {
170
- calendarButtons.forEach((element) => {
171
- const tooltipClone: Element = calendarTooltip.cloneNode(
172
- true
173
- ) as Element
174
- element.appendChild(tooltipClone)
175
- tooltipClonesCheckIn.push(tooltipClone)
176
- })
177
- }
178
-
179
- if (calendarTooltipCheckOut && calendarButtonsCheckOut.length > 0) {
180
- calendarButtonsCheckOut.forEach((element) => {
181
- const tooltipClone: Element = calendarTooltipCheckOut.cloneNode(
182
- true
183
- ) as Element
184
- element.appendChild(tooltipClone)
185
- tooltipClonesCheckOut.push(tooltipClone)
186
- })
187
- }
188
-
189
- if (loadingSpinner && calendarMonthContainer) {
190
- const tooltipClone: Element = loadingSpinner.cloneNode(true) as Element
191
- calendarMonthContainer.appendChild(tooltipClone)
192
- tooltipClonesSpinner.push(tooltipClone)
193
- }
194
-
195
- if (
196
- calendarTooltipOverlappingDate &&
197
- calendarOverlappingDate.length > 0
198
- ) {
199
- calendarOverlappingDate.forEach((element) => {
200
- const tooltipClone: Element =
201
- calendarTooltipOverlappingDate.cloneNode(true) as Element
202
- element.appendChild(tooltipClone)
203
- tooltipClonesOverlappingDates.push(tooltipClone)
204
- })
205
- }
206
-
207
- return () => {
208
- tooltipClonesCheckIn.forEach((clone) => clone.remove())
209
- tooltipClonesCheckOut.forEach((clone) => clone.remove())
210
- tooltipClonesSpinner.forEach((clone) => clone.remove())
211
- tooltipClonesOverlappingDates.forEach((clone) => clone.remove())
212
- }
213
- }, [
76
+ useCalendarTooltips({
214
77
  calendarRange,
215
78
  updateCalendarMonthNavigation,
216
79
  overlappingDate,
217
- initialCalendarRange,
218
80
  updateCalendarDefaultMoth,
219
- ])
81
+ showFeedback,
82
+ })
220
83
 
221
84
  // Handle loading spinner
222
- useEffect(() => {
223
- if (typeof document === 'undefined') return
224
- const loadingSpinner: HTMLElement | null = document.querySelector(
225
- '.will-filter-bar-calendar .rdp-months .will-calendar-spinner'
226
- )
227
- if (loadingData) {
228
- if (loadingSpinner) loadingSpinner.style.display = 'flex'
229
- } else {
230
- if (loadingSpinner) loadingSpinner.style.display = 'none'
231
- }
232
- }, [loadingData, updateCalendarMonthNavigation, updateCalendarDefaultMoth])
85
+ useCalendarLoadingSpinner({
86
+ loadingData,
87
+ updateCalendarMonthNavigation,
88
+ updateCalendarDefaultMoth,
89
+ })
90
+
91
+ // Handle the date selection and availability for selection logic.
92
+ const handleOnSelect = (range?: DateRange) => {
93
+ setCalendarHasError && calendarHasError && setCalendarHasError(false)
94
+
95
+ calendarSelectionRules({
96
+ range,
97
+ newDisableCalendarDates,
98
+ setCalendarRange,
99
+ setDisabledDates,
100
+ calendarRange,
101
+ overlappingDate,
102
+ setCalendarHasError,
103
+ rangeContext,
104
+ })
105
+
106
+ setUpdatedForSubmit && setUpdatedForSubmit(true)
107
+ }
108
+
109
+ // Handle disabled dates for range context
110
+ const {
111
+ findFirstPossibleRangeContextCheckIn,
112
+ findLastPossibleRangeContextCheckOut,
113
+ firstPossibleRangeContextCheckIn,
114
+ lastPossibleRangeContextCheckOut,
115
+ currentSelectionLastCheckoutDate,
116
+ } = handleRangeContextDisabledDates({
117
+ rangeContext,
118
+ availableDates: newDisableCalendarDates?.availableDates,
119
+ calendarRange,
120
+ })
121
+
122
+ // Handle check for continuous selection in the range context
123
+ checkForContinuousSelection({
124
+ setCalendarHasError,
125
+ rangeContext,
126
+ calendarRange,
127
+ calendarHasError,
128
+ })
233
129
 
234
130
  return (
235
131
  <div className="will-filter-bar-calendar" ref={ref}>
@@ -242,21 +138,12 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
242
138
  numberOfMonths={!isTablet ? 2 : 1}
243
139
  weekStartsOn={1}
244
140
  selected={calendarRange}
245
- onSelect={(range) =>
246
- handleSelectedCheckIn({
247
- range,
248
- newDisableCalendarDates,
249
- setCalendarRange,
250
- setDisabledDates,
251
- calendarRange,
252
- overlappingDate,
253
- setOverlappingDates,
254
- })
255
- }
141
+ onSelect={(range) => handleOnSelect(range)}
256
142
  captionLayout="dropdown-buttons"
257
143
  defaultMonth={
258
- initialCalendarRange?.from ||
144
+ calendarRange?.from ||
259
145
  selectedStartDate ||
146
+ rangeContextStartDate ||
260
147
  (newDisableCalendarDates?.disabledDates?.length
261
148
  ? newDisableCalendarDates.disabledDates[0].from
262
149
  : today)
@@ -265,8 +152,18 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
265
152
  disabledDatesByPage.length
266
153
  ? disabledDatesByPage
267
154
  : disabledDates?.length
268
- ? disabledDates
269
- : newDisableCalendarDates?.disabledDates || []
155
+ ? [
156
+ ...disabledDates,
157
+ ...firstPossibleRangeContextCheckIn,
158
+ ...lastPossibleRangeContextCheckOut,
159
+ ]
160
+ : newDisableCalendarDates?.disabledDates?.length
161
+ ? [
162
+ ...newDisableCalendarDates.disabledDates,
163
+ ...firstPossibleRangeContextCheckIn,
164
+ ...lastPossibleRangeContextCheckOut,
165
+ ]
166
+ : []
270
167
  }
271
168
  fromMonth={today}
272
169
  onMonthChange={(val) => {
@@ -275,55 +172,43 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
275
172
  setUpdateCalendarMonthNavigation((prev) => !prev))
276
173
  : null
277
174
  }}
175
+ classNames={{
176
+ day_range_start: calendarRange?.from ? 'rdp-day_range_start' : '',
177
+ day_range_end: calendarRange?.to ? 'rdp-day_range_end' : '',
178
+ }}
278
179
  modifiersClassNames={{
279
180
  today: 'my-today',
280
181
  booked: 'booked',
281
182
  disabledAfterCheckIn: 'disabled-after-check-in',
282
183
  overlappingDate: 'overlapping-date',
283
-
284
184
  noActiveSelectionStart:
285
- 'rdp-day_selected rdp-day_range_start no-active-selection ',
185
+ 'rdp-day_selected rdp-day_range_start no-active-selection',
286
186
  noActiveSelectionMid:
287
187
  'rdp-day_selected rdp-day_range_middle no-active-selection',
288
188
  noActiveSelectionEnd:
289
189
  'rdp-day_selected rdp-day_range_end no-active-selection',
290
- }}
291
- modifiers={{
292
- booked: disabledDatesByPage.length
293
- ? disabledDatesByPage
294
- : disabledDates?.length
295
- ? disabledDates
296
- : newDisableCalendarDates?.disabledDates || [],
297
-
298
- disabledAfterCheckIn: calendarRange?.from
299
- ? [{ after: calendarRange.from }]
300
- : [],
190
+ checkoutOptionsMid:
191
+ 'rdp-day_selected rdp-day_range_middle checkout-option',
301
192
 
302
- noActiveSelectionStart: !calendarRange
303
- ? initialCalendarRange?.from || []
304
- : [],
305
- noActiveSelectionMid:
306
- !calendarRange &&
307
- initialCalendarRange?.from &&
308
- initialCalendarRange?.to
309
- ? [
310
- {
311
- after: initialCalendarRange?.from,
312
- before: initialCalendarRange?.to,
313
- },
314
- ]
315
- : [],
316
- noActiveSelectionEnd: !calendarRange
317
- ? initialCalendarRange?.to || []
318
- : [],
319
-
320
- overlappingDate:
321
- (!calendarRange?.from &&
322
- overlappingDate?.map((item) => ({
323
- from: item.from,
324
- }))) ||
325
- [],
193
+ checkInOnly: 'check-in-only',
194
+ checkOutOnly: 'check-out-only',
326
195
  }}
196
+ modifiers={
197
+ // This function handles conditions for applying the modifiersClassNames
198
+ handleCalendarModifiers({
199
+ newDisableCalendarDates,
200
+ calendarRange,
201
+ disabledDatesByPage,
202
+ disabledDates,
203
+ overlappingDate,
204
+ rangeContext,
205
+ findFirstPossibleRangeContextCheckIn,
206
+ findLastPossibleRangeContextCheckOut,
207
+ firstPossibleRangeContextCheckIn,
208
+ lastPossibleRangeContextCheckOut,
209
+ currentSelectionLastCheckoutDate,
210
+ })
211
+ }
327
212
  />
328
213
 
329
214
  <div className={'will-calendar-tooltip'}>
@@ -335,161 +220,21 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
335
220
  <div className={'will-calendar-tooltip-overlapping-date'}>
336
221
  <div>{t('checkOutOnly')}</div>
337
222
  </div>
223
+ <div className={'will-calendar-tooltip-check-in-only'}>
224
+ <div>Check-in Only</div>
225
+ </div>
226
+ <div className={'will-calendar-tooltip-check-out-only'}>
227
+ <div>Checkout Only</div>
228
+ </div>
338
229
  <div className={'will-calendar-spinner'}>
339
- <SpinnerSVG fill={palette?.primary || 'inherit'} size={50} />
230
+ <IconsSvg
231
+ fill={palette?.primary || 'inherit'}
232
+ size={50}
233
+ icon="spinner"
234
+ />
340
235
  </div>
341
236
  </div>
342
237
  </div>
343
238
  )
344
239
  }
345
240
  )
346
-
347
- /////////
348
-
349
- const handleSelectedCheckIn = ({
350
- range,
351
- newDisableCalendarDates,
352
- setCalendarRange,
353
- setDisabledDates,
354
- calendarRange,
355
- overlappingDate,
356
- setOverlappingDates,
357
- }: {
358
- range: DateRange | undefined
359
- newDisableCalendarDates?: DisableCalendarDates
360
- setCalendarRange: (range: DateRange | undefined) => void
361
- setDisabledDates: ((arg: Matcher[]) => void) | undefined
362
- setOverlappingDates: (arg: boolean) => void
363
- calendarRange?: DateRange
364
- overlappingDate?: DateRange[]
365
- }) => {
366
- // Calendar dates select logic
367
- const dateFormat = 'dd-MM-yyyy'
368
- const rangeFrom = range?.from ? format(range.from, dateFormat) : null
369
- const rangeTo = range?.to ? format(range.to, dateFormat) : null
370
- const calendarFrom = calendarRange?.from
371
- ? format(calendarRange?.from, dateFormat)
372
- : null
373
-
374
- const overlappingDateFrom = overlappingDate?.length
375
- ? overlappingDate.find(
376
- (date) => format(date.from || 1, dateFormat) === rangeFrom
377
- )
378
- : null
379
-
380
- const checkOutRange = newDisableCalendarDates?.availableDates?.length
381
- ? newDisableCalendarDates.availableDates.find(
382
- (checkInDate) =>
383
- format(checkInDate.checkIn || 1, dateFormat) ===
384
- format(range?.from || 1, dateFormat)
385
- )
386
- : null
387
-
388
- // Case: Set the calendar range only if it overlaps with the previously selected dates.
389
- // The selection must remain continuous, meaning no gaps between days are allowed.
390
- // Whether selecting forwards or backwards from the initially chosen dates,
391
- // the new range must be directly adjacent to or overlap with the current selection.
392
- const selectedDates = newDisableCalendarDates?.selectedDates || null
393
- const rowRangeFrom = range?.from
394
- const rowRangeTo = range?.to
395
- const selectedDatesFrom = newDisableCalendarDates?.selectedDates?.from || null
396
- const selectedDatesTo = newDisableCalendarDates?.selectedDates?.to || null
397
-
398
- // Checking if rowRangeFrom is equal to or before selectedDatesTo
399
- const startIsEqualOrBeforeSelectedEnd =
400
- rowRangeFrom && selectedDatesFrom && selectedDatesTo
401
- ? isBefore(startOfDay(rowRangeFrom), startOfDay(selectedDatesTo)) ||
402
- isEqual(startOfDay(rowRangeFrom), startOfDay(selectedDatesTo))
403
- : null
404
-
405
- // Checking if rowRangeTo is equal to or after selectedDatesFrom
406
- const endIsEqualOrAfterSelectedStart =
407
- rowRangeTo && selectedDatesFrom && selectedDatesTo
408
- ? isAfter(startOfDay(rowRangeTo), startOfDay(selectedDatesFrom)) ||
409
- isEqual(startOfDay(rowRangeTo), startOfDay(selectedDatesFrom))
410
- : null
411
-
412
- if (rangeFrom && checkOutRange && setDisabledDates) {
413
- const checkIn = addDays(checkOutRange.checkIn, 1)
414
- const firstCheckOut = addDays(checkOutRange.firstCheckOut, -1)
415
- const noDatesRange =
416
- format(checkIn, dateFormat) ===
417
- format(checkOutRange.firstCheckOut, dateFormat)
418
-
419
- setDisabledDates([
420
- // { before: findCheckOutRange?.checkIn },
421
-
422
- ...(newDisableCalendarDates?.disabledDates || []),
423
-
424
- {
425
- from: noDatesRange ? undefined : checkIn,
426
- to: noDatesRange ? undefined : firstCheckOut,
427
- },
428
-
429
- { after: checkOutRange?.lastCheckOut },
430
- ])
431
- }
432
-
433
- console.log(
434
- selectedDates,
435
- startIsEqualOrBeforeSelectedEnd,
436
- endIsEqualOrAfterSelectedStart
437
- )
438
-
439
- setOverlappingDates && setOverlappingDates(false)
440
-
441
- if (
442
- (selectedDates && !startIsEqualOrBeforeSelectedEnd) ||
443
- (selectedDates && range?.to && !endIsEqualOrAfterSelectedStart)
444
- ) {
445
- setCalendarRange(undefined)
446
- setOverlappingDates && setOverlappingDates(true)
447
- } else if (
448
- (rangeTo && rangeFrom && rangeFrom === rangeTo) ||
449
- (!rangeTo && !rangeFrom) ||
450
- overlappingDateFrom
451
- ) {
452
- setCalendarRange(undefined)
453
- setDisabledDates && setDisabledDates([])
454
- } else if (calendarFrom && rangeFrom && rangeFrom !== calendarFrom) {
455
- setCalendarRange({
456
- from: range?.from,
457
- to: undefined,
458
- })
459
- } else {
460
- setCalendarRange(range)
461
- }
462
- }
463
-
464
- const handleDisabledDatesByPage = ({
465
- newDisableCalendarDates,
466
- selectedPath,
467
- today,
468
- }: {
469
- newDisableCalendarDates?: DisableCalendarDates
470
- selectedPath?: string
471
- today: Date
472
- }) => {
473
- const daysToOffsetCalendar =
474
- newDisableCalendarDates?.disabledDatesByPage && selectedPath
475
- ? [
476
- newDisableCalendarDates?.disabledDatesByPage?.find(
477
- (item) => selectedPath === item.page
478
- ),
479
- ]
480
- : []
481
-
482
- return daysToOffsetCalendar.length
483
- ? [
484
- {
485
- from: addDays(
486
- today,
487
- daysToOffsetCalendar.length && daysToOffsetCalendar[0]?.offset
488
- ? daysToOffsetCalendar[0]?.offset
489
- : -2
490
- ),
491
- to: addDays(today, -100),
492
- },
493
- ]
494
- : []
495
- }
@@ -16,7 +16,11 @@ export type DisableCalendarDates = {
16
16
  page: string
17
17
  offset: number
18
18
  }[]
19
- selectedDates?: { to: Date; from: Date }
19
+ }
20
+
21
+ export type RangeContext = {
22
+ from: Date
23
+ to: Date
20
24
  }
21
25
 
22
26
  export type CalendarTypes = {
@@ -30,13 +34,14 @@ export type CalendarTypes = {
30
34
  disabledDates?: Matcher[]
31
35
  setDisabledDates?: (arg: Matcher[]) => void
32
36
  loadingData?: boolean
33
- initialCalendarRange?: DateRange | undefined
34
37
  showFeedback?: boolean
35
38
  noActiveSelection?: boolean
36
39
  palette?: Palette
37
-
38
40
  updateCalendarMonthNavigation?: boolean
39
41
  setUpdateCalendarMonthNavigation?: (arg: (prev: boolean) => boolean) => void
40
42
  updateCalendarDefaultMoth?: number
41
- setOverlappingDates: (arg: boolean) => void
43
+ setCalendarHasError?: (arg: boolean) => void
44
+ setUpdatedForSubmit?: (arg: boolean) => void
45
+ rangeContext?: RangeContext
46
+ calendarHasError?: boolean
42
47
  }
@@ -0,0 +1,3 @@
1
+ export { useCalendarTooltips } from './useCalendarTooltips'
2
+ export { useCalendarLoadingSpinner } from './useCalendarLoadingSpinner'
3
+ export { useUpdateDisabledDates } from './useUpdateDisabledDates'
@@ -0,0 +1,25 @@
1
+ import { useEffect } from 'react'
2
+
3
+ type Props = {
4
+ loadingData?: boolean
5
+ updateCalendarMonthNavigation?: boolean
6
+ updateCalendarDefaultMoth?: number
7
+ }
8
+
9
+ export const useCalendarLoadingSpinner = ({
10
+ loadingData,
11
+ updateCalendarMonthNavigation,
12
+ updateCalendarDefaultMoth,
13
+ }: Props) =>
14
+ useEffect(() => {
15
+ if (typeof document === 'undefined') return
16
+
17
+ const loadingSpinner: HTMLElement | null = document.querySelector(
18
+ '.will-filter-bar-calendar .rdp-months .will-calendar-spinner'
19
+ )
20
+ if (loadingData) {
21
+ if (loadingSpinner) loadingSpinner.style.display = 'flex'
22
+ } else {
23
+ if (loadingSpinner) loadingSpinner.style.display = 'none'
24
+ }
25
+ }, [loadingData, updateCalendarMonthNavigation, updateCalendarDefaultMoth])