willba-component-library 0.2.80 → 0.2.82

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 (54) hide show
  1. package/lib/components/FilterBar/FilterBar.stories.d.ts +1 -1
  2. package/lib/components/FilterBar/FilterBarTypes.d.ts +2 -2
  3. package/lib/components/FilterCalendar/FilterCalendar.d.ts +1 -1
  4. package/lib/components/FilterCalendar/FilterCalendar.stories.d.ts +3 -1
  5. package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +10 -3
  6. package/lib/core/components/buttons/submit-button/SubmitButton.d.ts +3 -1
  7. package/lib/core/components/calendar/CalendarTypes.d.ts +9 -2
  8. package/lib/index.d.ts +11 -4
  9. package/lib/index.esm.js +896 -268
  10. package/lib/index.esm.js.map +1 -1
  11. package/lib/index.js +896 -268
  12. package/lib/index.js.map +1 -1
  13. package/lib/index.umd.js +896 -268
  14. package/lib/index.umd.js.map +1 -1
  15. package/lib/themes/useTheme.d.ts +2 -0
  16. package/package.json +1 -1
  17. package/src/assets/IconsSvg.tsx +68 -0
  18. package/src/components/FilterBar/FilterBar.stories.tsx +2 -1
  19. package/src/components/FilterBar/FilterBar.tsx +2 -2
  20. package/src/components/FilterBar/FilterBarTypes.ts +1 -1
  21. package/src/components/FilterBar/components/buttons/tab-button/TabButton.css +1 -1
  22. package/src/components/FilterBar/hooks/useFilterBar.tsx +1 -1
  23. package/src/components/FilterCalendar/FilterCalendar.css +26 -10
  24. package/src/components/FilterCalendar/FilterCalendar.stories.tsx +522 -153
  25. package/src/components/FilterCalendar/FilterCalendar.tsx +25 -54
  26. package/src/components/FilterCalendar/FilterCalendarTypes.ts +0 -1
  27. package/src/components/FilterCalendar/components/Footer.tsx +96 -0
  28. package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +94 -4
  29. package/src/core/components/buttons/submit-button/SubmitButton.css +16 -2
  30. package/src/core/components/buttons/submit-button/SubmitButton.tsx +6 -5
  31. package/src/core/components/calendar/Calendar.css +71 -18
  32. package/src/core/components/calendar/Calendar.tsx +132 -342
  33. package/src/core/components/calendar/CalendarTypes.ts +10 -3
  34. package/src/core/components/calendar/hooks/index.ts +3 -0
  35. package/src/core/components/calendar/hooks/useCalendarLoadingSpinner.tsx +19 -0
  36. package/src/core/components/calendar/hooks/useCalendarTooltips.tsx +125 -0
  37. package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +107 -0
  38. package/src/core/components/calendar/utils/calendarSelectionRules.tsx +228 -0
  39. package/src/core/components/calendar/utils/checkForContinuousSelection.tsx +86 -0
  40. package/src/core/components/calendar/utils/disabledDatesByPage.tsx +36 -0
  41. package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +147 -0
  42. package/src/core/components/calendar/utils/handleRangeContextDisabledDates.tsx +75 -0
  43. package/src/core/components/calendar/utils/index.ts +8 -0
  44. package/src/locales/en/common.json +7 -1
  45. package/src/locales/en/filterBar.json +2 -1
  46. package/src/locales/fi/common.json +7 -1
  47. package/src/locales/fi/filterBar.json +2 -1
  48. package/src/themes/Default.css +12 -3
  49. package/src/themes/useTheme.tsx +3 -0
  50. package/src/assets/SpinnerSvg.tsx +0 -40
  51. package/src/core/utils/index.ts +0 -3
  52. /package/src/core/{utils → components/calendar/utils}/nightsCount.tsx +0 -0
  53. /package/src/core/{utils → components/calendar/utils}/parseDate.tsx +0 -0
  54. /package/src/core/{utils → components/calendar/utils}/parseDates.tsx +0 -0
@@ -1,12 +1,24 @@
1
- import React, { forwardRef, useEffect, useMemo, useState } from 'react'
2
- import { addDays, startOfDay, format } from 'date-fns'
1
+ import React, { forwardRef } from 'react'
2
+ import { startOfDay } from 'date-fns'
3
3
  import { fi, enUS } from 'date-fns/locale'
4
4
  import { useTranslation } from 'react-i18next'
5
- import { DateRange, DayPicker, Matcher } from 'react-day-picker'
5
+ import { DateRange, DayPicker } from 'react-day-picker'
6
6
  import { useMediaQuery } from 'react-responsive'
7
7
 
8
- import { CalendarTypes, DisableCalendarDates } from './CalendarTypes'
9
- 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'
10
22
 
11
23
  import 'react-day-picker/dist/style.css'
12
24
  import './Calendar.css'
@@ -24,11 +36,14 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
24
36
  setDisabledDates,
25
37
  updateCalendarMonthNavigation,
26
38
  setUpdateCalendarMonthNavigation,
27
- updateCalendarDefaultMoth,
39
+ updateCalendarDefaultMonth,
28
40
  loadingData,
29
- initialCalendarRange,
30
41
  showFeedback,
31
42
  palette,
43
+ setCalendarHasError,
44
+ setUpdatedForSubmit,
45
+ rangeContext,
46
+ calendarHasError,
32
47
  }: CalendarTypes,
33
48
  ref
34
49
  ) => {
@@ -38,81 +53,16 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
38
53
  const isTablet = useMediaQuery({ maxWidth: 960 })
39
54
  const today = startOfDay(new Date())
40
55
  const selectedStartDate = calendarRange?.from
56
+ const rangeContextStartDate = rangeContext?.from
41
57
 
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
- ])
58
+ // Handle initial disable dates including overlapping availableDates.lastCheckOut and disabledDates.start
59
+ const { newDisableCalendarDates, overlappingDate, lastPossibleCheckout } =
60
+ useUpdateDisabledDates({
61
+ disableCalendarDates,
62
+ calendarRange,
63
+ updateCalendarMonthNavigation,
64
+ updateCalendarDefaultMonth,
65
+ })
116
66
 
117
67
  // Handle disable dates by page
118
68
  const disabledDatesByPage = handleDisabledDatesByPage({
@@ -122,132 +72,72 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
122
72
  })
123
73
 
124
74
  // Handle tooltip
125
- useEffect(() => {
126
- if (typeof document === 'undefined' || !showFeedback) return
127
-
128
- // Children
129
- const calendarTooltip = document.querySelector('.will-calendar-tooltip')
130
- const calendarTooltipCheckOut = document.querySelector(
131
- '.will-calendar-tooltip-check-out'
132
- )
133
-
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[] = []
160
-
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
- }
75
+ useCalendarTooltips({
76
+ showFeedback,
77
+ })
186
78
 
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
- }
79
+ // Handle loading spinner
80
+ useCalendarLoadingSpinner({
81
+ loadingData,
82
+ })
198
83
 
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
- }, [
84
+ // Handle the date selection and availability for selection logic.
85
+ const handleOnSelect = (range?: DateRange) => {
86
+ setCalendarHasError && calendarHasError && setCalendarHasError(false)
87
+
88
+ calendarSelectionRules({
89
+ range,
90
+ newDisableCalendarDates,
91
+ setCalendarRange,
92
+ setDisabledDates,
93
+ calendarRange,
94
+ overlappingDate,
95
+ setCalendarHasError,
96
+ rangeContext,
97
+ })
98
+
99
+ setUpdatedForSubmit && setUpdatedForSubmit(true)
100
+ }
101
+
102
+ // Handle disabled dates for range context
103
+ const {
104
+ findFirstPossibleRangeContextCheckIn,
105
+ findLastPossibleRangeContextCheckOut,
106
+ firstPossibleRangeContextCheckIn,
107
+ lastPossibleRangeContextCheckOut,
108
+ currentSelectionLastCheckoutDate,
109
+ } = handleRangeContextDisabledDates({
110
+ rangeContext,
111
+ availableDates: newDisableCalendarDates?.availableDates,
206
112
  calendarRange,
207
- updateCalendarMonthNavigation,
208
- overlappingDate,
209
- initialCalendarRange,
210
- updateCalendarDefaultMoth,
211
- ])
113
+ })
212
114
 
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])
115
+ // Handle check for continuous selection in the range context
116
+ checkForContinuousSelection({
117
+ setCalendarHasError,
118
+ rangeContext,
119
+ calendarRange,
120
+ calendarHasError,
121
+ disabledDates: newDisableCalendarDates?.disabledDates,
122
+ })
225
123
 
226
124
  return (
227
125
  <div className="will-filter-bar-calendar" ref={ref}>
228
126
  <div className="will-calendar-filter-container">
229
127
  <DayPicker
230
- key={updateCalendarDefaultMoth}
128
+ key={updateCalendarDefaultMonth}
231
129
  id="will-calendar"
232
130
  mode="range"
233
131
  locale={language === 'en' ? enUS : fi}
234
132
  numberOfMonths={!isTablet ? 2 : 1}
235
133
  weekStartsOn={1}
236
134
  selected={calendarRange}
237
- onSelect={(range) =>
238
- handleSelectedCheckIn({
239
- range,
240
- newDisableCalendarDates,
241
- setCalendarRange,
242
- setDisabledDates,
243
- calendarRange,
244
- overlappingDate,
245
- })
246
- }
135
+ onSelect={(range) => handleOnSelect(range)}
247
136
  captionLayout="dropdown-buttons"
248
137
  defaultMonth={
249
- initialCalendarRange?.from ||
138
+ calendarRange?.from ||
250
139
  selectedStartDate ||
140
+ rangeContextStartDate ||
251
141
  (newDisableCalendarDates?.disabledDates?.length
252
142
  ? newDisableCalendarDates.disabledDates[0].from
253
143
  : today)
@@ -256,8 +146,20 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
256
146
  disabledDatesByPage.length
257
147
  ? disabledDatesByPage
258
148
  : disabledDates?.length
259
- ? disabledDates
260
- : newDisableCalendarDates?.disabledDates || []
149
+ ? [
150
+ lastPossibleCheckout && lastPossibleCheckout,
151
+ ...disabledDates,
152
+ ...firstPossibleRangeContextCheckIn,
153
+ ...lastPossibleRangeContextCheckOut,
154
+ ]
155
+ : newDisableCalendarDates?.disabledDates?.length
156
+ ? [
157
+ lastPossibleCheckout && lastPossibleCheckout,
158
+ ...newDisableCalendarDates.disabledDates,
159
+ ...firstPossibleRangeContextCheckIn,
160
+ ...lastPossibleRangeContextCheckOut,
161
+ ]
162
+ : []
261
163
  }
262
164
  fromMonth={today}
263
165
  onMonthChange={(val) => {
@@ -266,55 +168,43 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
266
168
  setUpdateCalendarMonthNavigation((prev) => !prev))
267
169
  : null
268
170
  }}
171
+ classNames={{
172
+ day_range_start: calendarRange?.from ? 'rdp-day_range_start' : '',
173
+ day_range_end: calendarRange?.to ? 'rdp-day_range_end' : '',
174
+ }}
269
175
  modifiersClassNames={{
270
176
  today: 'my-today',
271
177
  booked: 'booked',
272
178
  disabledAfterCheckIn: 'disabled-after-check-in',
273
179
  overlappingDate: 'overlapping-date',
274
180
 
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 || [],
181
+ noActiveSelectionStart: 'no-active-selection-start',
182
+ noActiveSelectionMid: 'no-active-selection-mid',
183
+ noActiveSelectionEnd: 'no-active-selection-end',
288
184
 
289
- disabledAfterCheckIn: calendarRange?.from
290
- ? [{ after: calendarRange.from }]
291
- : [],
185
+ checkoutOptionsMid:
186
+ 'rdp-day_selected rdp-day_range_middle checkout-option',
292
187
 
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
- [],
188
+ checkInOnly: 'check-in-only',
189
+ checkOutOnly: 'check-out-only',
317
190
  }}
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
+ }
318
208
  />
319
209
 
320
210
  <div className={'will-calendar-tooltip'}>
@@ -326,121 +216,21 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
326
216
  <div className={'will-calendar-tooltip-overlapping-date'}>
327
217
  <div>{t('checkOutOnly')}</div>
328
218
  </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>
329
225
  <div className={'will-calendar-spinner'}>
330
- <SpinnerSVG fill={palette?.primary || 'inherit'} size={50} />
226
+ <IconsSvg
227
+ fill={palette?.primary || 'inherit'}
228
+ size={50}
229
+ icon="spinner"
230
+ />
331
231
  </div>
332
232
  </div>
333
233
  </div>
334
234
  )
335
235
  }
336
236
  )
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,6 +18,11 @@ export type DisableCalendarDates = {
18
18
  }[]
19
19
  }
20
20
 
21
+ export type RangeContext = {
22
+ from: Date
23
+ to: Date
24
+ }
25
+
21
26
  export type CalendarTypes = {
22
27
  calendarRange?: DateRange | undefined
23
28
  setCalendarRange: (range: DateRange | undefined) => void
@@ -29,12 +34,14 @@ export type CalendarTypes = {
29
34
  disabledDates?: Matcher[]
30
35
  setDisabledDates?: (arg: Matcher[]) => void
31
36
  loadingData?: boolean
32
- initialCalendarRange?: DateRange | undefined
33
37
  showFeedback?: boolean
34
38
  noActiveSelection?: boolean
35
39
  palette?: Palette
36
-
37
40
  updateCalendarMonthNavigation?: boolean
38
41
  setUpdateCalendarMonthNavigation?: (arg: (prev: boolean) => boolean) => void
39
- updateCalendarDefaultMoth?: number
42
+ updateCalendarDefaultMonth?: number
43
+ setCalendarHasError?: (arg: boolean) => void
44
+ setUpdatedForSubmit?: (arg: boolean) => void
45
+ rangeContext?: RangeContext
46
+ calendarHasError?: boolean
40
47
  }
@@ -0,0 +1,3 @@
1
+ export { useCalendarTooltips } from './useCalendarTooltips'
2
+ export { useCalendarLoadingSpinner } from './useCalendarLoadingSpinner'
3
+ export { useUpdateDisabledDates } from './useUpdateDisabledDates'
@@ -0,0 +1,19 @@
1
+ import { useEffect } from 'react'
2
+
3
+ type Props = {
4
+ loadingData?: boolean
5
+ }
6
+
7
+ export const useCalendarLoadingSpinner = ({ loadingData }: Props) =>
8
+ useEffect(() => {
9
+ if (typeof document === 'undefined') return
10
+
11
+ const loadingSpinner: HTMLElement | null = document.querySelector(
12
+ '.will-filter-bar-calendar .rdp-months .will-calendar-spinner'
13
+ )
14
+ if (loadingData) {
15
+ if (loadingSpinner) loadingSpinner.style.display = 'flex'
16
+ } else {
17
+ if (loadingSpinner) loadingSpinner.style.display = 'none'
18
+ }
19
+ })