willba-component-library 0.2.58 → 0.2.60

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 (25) hide show
  1. package/lib/components/FilterCalendar/FilterCalendar.d.ts +1 -1
  2. package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +5 -2
  3. package/lib/core/components/calendar/CalendarTypes.d.ts +1 -1
  4. package/lib/core/components/calendar/hooks/useCalendarLoadingSpinner.d.ts +1 -3
  5. package/lib/core/components/calendar/hooks/useCalendarTooltips.d.ts +1 -6
  6. package/lib/core/components/calendar/hooks/useUpdateDisabledDates.d.ts +2 -2
  7. package/lib/core/components/calendar/utils/handleCalendarModifiers.d.ts +1 -1
  8. package/lib/index.d.ts +2 -2
  9. package/lib/index.esm.js +47 -43
  10. package/lib/index.esm.js.map +1 -1
  11. package/lib/index.js +47 -43
  12. package/lib/index.js.map +1 -1
  13. package/lib/index.umd.js +47 -43
  14. package/lib/index.umd.js.map +1 -1
  15. package/package.json +1 -1
  16. package/src/components/FilterCalendar/FilterCalendar.stories.tsx +415 -379
  17. package/src/components/FilterCalendar/FilterCalendar.tsx +5 -3
  18. package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +11 -3
  19. package/src/core/components/calendar/Calendar.tsx +4 -10
  20. package/src/core/components/calendar/CalendarTypes.ts +1 -1
  21. package/src/core/components/calendar/hooks/useCalendarLoadingSpinner.tsx +2 -8
  22. package/src/core/components/calendar/hooks/useCalendarTooltips.tsx +2 -18
  23. package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +3 -3
  24. package/src/core/components/calendar/utils/calendarSelectionRules.tsx +14 -1
  25. package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +15 -13
@@ -29,7 +29,7 @@ export default function FilterCalendar({
29
29
  requestDates,
30
30
  showFeedback,
31
31
  noActiveSelection,
32
- rangeContext,
32
+ rangeContext: outerRangeContext,
33
33
  }: FilterCalendarTypes) {
34
34
  const themePalette = useTheme({ palette })
35
35
 
@@ -44,16 +44,18 @@ export default function FilterCalendar({
44
44
  disabledDates,
45
45
  setDisabledDates,
46
46
  updateCalendarMonthNavigation,
47
- updateCalendarDefaultMoth,
47
+ updateCalendarDefaultMonth,
48
48
  setUpdateCalendarMonthNavigation,
49
49
  calendarHasError,
50
50
  setCalendarHasError,
51
51
  setUpdatedForSubmit,
52
+ rangeContext,
52
53
  } = useFilterCalendar({
53
54
  onSubmit,
54
55
  setToggleCalendar,
55
56
  noActiveSelection,
56
57
  toggleCalendar,
58
+ outerRangeContext,
57
59
  })
58
60
 
59
61
  // Display component after fully loaded
@@ -91,7 +93,7 @@ export default function FilterCalendar({
91
93
  setUpdateCalendarMonthNavigation={
92
94
  setUpdateCalendarMonthNavigation
93
95
  }
94
- updateCalendarDefaultMoth={updateCalendarDefaultMoth}
96
+ updateCalendarDefaultMonth={updateCalendarDefaultMonth}
95
97
  loadingData={loadingData}
96
98
  showFeedback={showFeedback}
97
99
  noActiveSelection={noActiveSelection}
@@ -1,12 +1,14 @@
1
1
  import { useEffect, useState } from 'react'
2
2
  import { DateRange, Matcher } from 'react-day-picker'
3
3
  import { format } from 'date-fns'
4
+ import { RangeContext } from 'src/core/components/calendar/CalendarTypes'
4
5
 
5
6
  type Props = {
6
7
  onSubmit: (val: any) => void
7
8
  setToggleCalendar: (val: boolean) => void
8
9
  noActiveSelection?: boolean
9
10
  toggleCalendar?: boolean
11
+ outerRangeContext?: RangeContext
10
12
  }
11
13
 
12
14
  export const useFilterCalendar = ({
@@ -14,16 +16,20 @@ export const useFilterCalendar = ({
14
16
  setToggleCalendar,
15
17
  noActiveSelection,
16
18
  toggleCalendar,
19
+ outerRangeContext,
17
20
  }: Props) => {
18
21
  // State
19
22
  const [calendarRange, setCalendarRange] = useState<DateRange | undefined>()
23
+ const [rangeContext, setRangeContext] = useState<RangeContext | undefined>(
24
+ outerRangeContext
25
+ )
20
26
  const [initialCalendarRange, setInitialCalendarRange] = useState<
21
27
  DateRange | undefined
22
28
  >()
23
29
  const [disabledDates, setDisabledDates] = useState<Matcher[]>([])
24
30
  const [updateCalendarMonthNavigation, setUpdateCalendarMonthNavigation] =
25
31
  useState<boolean>(false)
26
- const [updateCalendarDefaultMoth, setUpdateCalendarDefaultMoth] =
32
+ const [updateCalendarDefaultMonth, setUpdateCalendarDefaultMonth] =
27
33
  useState<number>(0)
28
34
 
29
35
  const [calendarHasError, setCalendarHasError] = useState<boolean>(false)
@@ -42,8 +48,9 @@ export const useFilterCalendar = ({
42
48
  if (startDateParam && endDateParam) {
43
49
  if (noActiveSelection) {
44
50
  handleClearDates()
45
- setUpdateCalendarDefaultMoth((prev) => prev + 1)
51
+ setUpdateCalendarDefaultMonth((prev) => prev + 1)
46
52
  setUpdatedForSubmit(false)
53
+ setRangeContext(outerRangeContext)
47
54
  setInitialCalendarRange({
48
55
  from: new Date(startDateParam),
49
56
  to: new Date(endDateParam),
@@ -110,9 +117,10 @@ export const useFilterCalendar = ({
110
117
  calendarRange,
111
118
  disabledDates,
112
119
  updateCalendarMonthNavigation,
113
- updateCalendarDefaultMoth,
120
+ updateCalendarDefaultMonth,
114
121
  calendarHasError,
115
122
  setCalendarHasError,
116
123
  setUpdatedForSubmit,
124
+ rangeContext,
117
125
  }
118
126
  }
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef } from 'react'
2
- import { startOfDay, isBefore, endOfDay, isEqual, isAfter } from 'date-fns'
2
+ import { startOfDay } from 'date-fns'
3
3
  import { fi, enUS } from 'date-fns/locale'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import { DateRange, DayPicker } from 'react-day-picker'
@@ -36,7 +36,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
36
36
  setDisabledDates,
37
37
  updateCalendarMonthNavigation,
38
38
  setUpdateCalendarMonthNavigation,
39
- updateCalendarDefaultMoth,
39
+ updateCalendarDefaultMonth,
40
40
  loadingData,
41
41
  showFeedback,
42
42
  palette,
@@ -61,7 +61,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
61
61
  disableCalendarDates,
62
62
  calendarRange,
63
63
  updateCalendarMonthNavigation,
64
- updateCalendarDefaultMoth,
64
+ updateCalendarDefaultMonth,
65
65
  }
66
66
  )
67
67
 
@@ -74,18 +74,12 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
74
74
 
75
75
  // Handle tooltip
76
76
  useCalendarTooltips({
77
- calendarRange,
78
- updateCalendarMonthNavigation,
79
- overlappingDate,
80
- updateCalendarDefaultMoth,
81
77
  showFeedback,
82
78
  })
83
79
 
84
80
  // Handle loading spinner
85
81
  useCalendarLoadingSpinner({
86
82
  loadingData,
87
- updateCalendarMonthNavigation,
88
- updateCalendarDefaultMoth,
89
83
  })
90
84
 
91
85
  // Handle the date selection and availability for selection logic.
@@ -131,7 +125,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
131
125
  <div className="will-filter-bar-calendar" ref={ref}>
132
126
  <div className="will-calendar-filter-container">
133
127
  <DayPicker
134
- key={updateCalendarDefaultMoth}
128
+ key={updateCalendarDefaultMonth}
135
129
  id="will-calendar"
136
130
  mode="range"
137
131
  locale={language === 'en' ? enUS : fi}
@@ -39,7 +39,7 @@ export type CalendarTypes = {
39
39
  palette?: Palette
40
40
  updateCalendarMonthNavigation?: boolean
41
41
  setUpdateCalendarMonthNavigation?: (arg: (prev: boolean) => boolean) => void
42
- updateCalendarDefaultMoth?: number
42
+ updateCalendarDefaultMonth?: number
43
43
  setCalendarHasError?: (arg: boolean) => void
44
44
  setUpdatedForSubmit?: (arg: boolean) => void
45
45
  rangeContext?: RangeContext
@@ -2,15 +2,9 @@ import { useEffect } from 'react'
2
2
 
3
3
  type Props = {
4
4
  loadingData?: boolean
5
- updateCalendarMonthNavigation?: boolean
6
- updateCalendarDefaultMoth?: number
7
5
  }
8
6
 
9
- export const useCalendarLoadingSpinner = ({
10
- loadingData,
11
- updateCalendarMonthNavigation,
12
- updateCalendarDefaultMoth,
13
- }: Props) =>
7
+ export const useCalendarLoadingSpinner = ({ loadingData }: Props) =>
14
8
  useEffect(() => {
15
9
  if (typeof document === 'undefined') return
16
10
 
@@ -22,4 +16,4 @@ export const useCalendarLoadingSpinner = ({
22
16
  } else {
23
17
  if (loadingSpinner) loadingSpinner.style.display = 'none'
24
18
  }
25
- }, [loadingData, updateCalendarMonthNavigation, updateCalendarDefaultMoth])
19
+ })
@@ -1,21 +1,10 @@
1
1
  import { useEffect } from 'react'
2
- import { DateRange } from 'react-day-picker'
3
2
 
4
3
  type Props = {
5
- calendarRange?: DateRange
6
- updateCalendarMonthNavigation?: boolean
7
- overlappingDate?: DateRange[]
8
- updateCalendarDefaultMoth?: number
9
4
  showFeedback?: boolean
10
5
  }
11
6
 
12
- export const useCalendarTooltips = ({
13
- calendarRange,
14
- updateCalendarMonthNavigation,
15
- overlappingDate,
16
- updateCalendarDefaultMoth,
17
- showFeedback,
18
- }: Props) =>
7
+ export const useCalendarTooltips = ({ showFeedback }: Props) =>
19
8
  useEffect(() => {
20
9
  if (typeof document === 'undefined' || !showFeedback) return
21
10
 
@@ -131,9 +120,4 @@ export const useCalendarTooltips = ({
131
120
  tooltipClonesSpinner.forEach((clone) => clone.remove())
132
121
  tooltipClonesOverlappingDates.forEach((clone) => clone.remove())
133
122
  }
134
- }, [
135
- calendarRange,
136
- updateCalendarMonthNavigation,
137
- overlappingDate,
138
- updateCalendarDefaultMoth,
139
- ])
123
+ })
@@ -8,14 +8,14 @@ type Props = {
8
8
  disableCalendarDates?: DisableCalendarDates
9
9
  calendarRange?: DateRange
10
10
  updateCalendarMonthNavigation?: boolean
11
- updateCalendarDefaultMoth?: number
11
+ updateCalendarDefaultMonth?: number
12
12
  }
13
13
 
14
14
  export const useUpdateDisabledDates = ({
15
15
  disableCalendarDates,
16
16
  calendarRange,
17
17
  updateCalendarMonthNavigation,
18
- updateCalendarDefaultMoth,
18
+ updateCalendarDefaultMonth,
19
19
  }: Props) => {
20
20
  const [overlappingDate, setOverlappingDate] = useState<
21
21
  DateRange[] | undefined
@@ -87,7 +87,7 @@ export const useUpdateDisabledDates = ({
87
87
  disableCalendarDates,
88
88
  calendarRange,
89
89
  updateCalendarMonthNavigation,
90
- updateCalendarDefaultMoth,
90
+ updateCalendarDefaultMonth,
91
91
  ])
92
92
 
93
93
  return { newDisableCalendarDates, overlappingDate }
@@ -38,6 +38,8 @@ export const calendarSelectionRules = ({
38
38
  : null
39
39
  const rangeContextTo = rangeContext?.to ? endOfDay(rangeContext.to) : null
40
40
 
41
+ // When some dates are not available for selection, the earliest date will be available only for "end"
42
+ // and the latest date will only be available for "start"
41
43
  const overlappingDateFrom = overlappingDate?.length
42
44
  ? overlappingDate.find((date) =>
43
45
  !!(date.from && rangeFrom)
@@ -46,6 +48,13 @@ export const calendarSelectionRules = ({
46
48
  )
47
49
  : null
48
50
 
51
+ const overlappingDateTo = overlappingDate?.length
52
+ ? overlappingDate.find((date) =>
53
+ !!(date.from && rangeTo) ? isEqual(endOfDay(date.from), rangeTo) : false
54
+ )
55
+ : null
56
+ //----------
57
+
49
58
  const checkOutRange = newDisableCalendarDates?.availableDates?.length
50
59
  ? newDisableCalendarDates.availableDates.find((checkInDate) =>
51
60
  !!(checkInDate.checkIn && rangeFrom)
@@ -66,8 +75,12 @@ export const calendarSelectionRules = ({
66
75
  // The rules are processed in a specific order, so one case is handled before another.
67
76
  // Changing the order will cause the rules to break or not work properly.
68
77
 
69
- if (!!overlappingDateFrom) {
78
+ if (
79
+ !!overlappingDateFrom ||
80
+ (calendarRangeFrom && calendarRangeTo && overlappingDateTo)
81
+ ) {
70
82
  // 1. If dates overlap, clear the selection.
83
+
71
84
  return setCalendarRange(undefined)
72
85
  }
73
86
 
@@ -81,7 +81,7 @@ export const handleCalendarModifiers = ({
81
81
  : [],
82
82
 
83
83
  overlappingDate: [
84
- ...(!calendarRange?.from && !!overlappingDate?.length && !rangeContext
84
+ ...(!calendarRange?.from && !!overlappingDate?.length
85
85
  ? overlappingDate.map((date) => ({ from: date.from }))
86
86
  : []),
87
87
  ],
@@ -89,29 +89,31 @@ export const handleCalendarModifiers = ({
89
89
  noActiveSelectionStart:
90
90
  rangeContext?.from &&
91
91
  !(
92
- calendarRange?.from &&
93
- rangeContext?.from &&
94
- isEqual(endOfDay(rangeContext.from), endOfDay(calendarRange.from))
92
+ (calendarRange?.from &&
93
+ isEqual(endOfDay(rangeContext.from), endOfDay(calendarRange.from))) ||
94
+ (calendarRange?.to &&
95
+ isEqual(endOfDay(rangeContext.from), endOfDay(calendarRange.to)))
95
96
  )
96
97
  ? rangeContext.from
97
98
  : [],
98
99
 
99
- noActiveSelectionMid: [
100
- ...(rangeContextMiddleSelection.length
101
- ? rangeContextMiddleSelection
102
- : []),
103
- ],
104
-
105
100
  noActiveSelectionEnd:
106
101
  rangeContext?.to &&
107
102
  !(
108
- calendarRange?.from &&
109
- rangeContext?.to &&
110
- isEqual(endOfDay(rangeContext.to), endOfDay(calendarRange.from))
103
+ (calendarRange?.from &&
104
+ isEqual(endOfDay(rangeContext.to), endOfDay(calendarRange.from))) ||
105
+ (calendarRange?.to &&
106
+ isEqual(endOfDay(rangeContext.to), endOfDay(calendarRange.to)))
111
107
  )
112
108
  ? rangeContext.to
113
109
  : [],
114
110
 
111
+ noActiveSelectionMid: [
112
+ ...(rangeContextMiddleSelection.length
113
+ ? rangeContextMiddleSelection
114
+ : []),
115
+ ],
116
+
115
117
  checkoutOptionsMid: [
116
118
  ...(calendarRange?.from &&
117
119
  !calendarRange?.to &&