willba-component-library 0.2.94 → 0.2.96

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 (28) hide show
  1. package/lib/assets/IconsSvg.d.ts +1 -1
  2. package/lib/components/FilterBar/FilterBarTypes.d.ts +1 -1
  3. package/lib/components/FilterBar/components/guests/Guests.d.ts +1 -1
  4. package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +0 -1
  5. package/lib/core/components/calendar/utils/calendarSelectionRules.d.ts +2 -3
  6. package/lib/core/components/calendar/utils/handleCalendarModifiers.d.ts +1 -9
  7. package/lib/core/components/calendar/utils/handleRangeContextDisabledDates.d.ts +1 -1
  8. package/lib/index.esm.js +63 -89
  9. package/lib/index.esm.js.map +1 -1
  10. package/lib/index.js +63 -89
  11. package/lib/index.js.map +1 -1
  12. package/lib/index.umd.js +63 -89
  13. package/lib/index.umd.js.map +1 -1
  14. package/package.json +1 -1
  15. package/src/assets/IconsSvg.tsx +1 -0
  16. package/src/components/FilterBar/FilterBarTypes.ts +1 -1
  17. package/src/components/FilterBar/components/guests/GuestCount/GuestCount.tsx +5 -5
  18. package/src/components/FilterBar/components/guests/Guests.tsx +3 -7
  19. package/src/components/FilterCalendar/FilterCalendar.stories.tsx +275 -275
  20. package/src/components/FilterCalendar/FilterCalendar.tsx +0 -2
  21. package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +0 -1
  22. package/src/core/components/calendar/Calendar.tsx +44 -34
  23. package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +3 -3
  24. package/src/core/components/calendar/utils/calendarSelectionRules.tsx +0 -48
  25. package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +1 -30
  26. package/src/core/components/calendar/utils/handleRangeContextDisabledDates.tsx +3 -3
  27. package/src/locales/en/filterBar.json +2 -5
  28. package/src/locales/fi/filterBar.json +6 -11
@@ -41,7 +41,6 @@ export default function FilterCalendar({
41
41
  handleClearDates,
42
42
  calendarRange,
43
43
  disabledDates,
44
- setDisabledDates,
45
44
  updateCalendarMonthNavigation,
46
45
  updateCalendarDefaultMonth,
47
46
  setUpdateCalendarMonthNavigation,
@@ -85,7 +84,6 @@ export default function FilterCalendar({
85
84
  disableCalendarDates={disableCalendarDates}
86
85
  requestDates={requestDates}
87
86
  disabledDates={disabledDates}
88
- setDisabledDates={setDisabledDates}
89
87
  updateCalendarMonthNavigation={updateCalendarMonthNavigation}
90
88
  setUpdateCalendarMonthNavigation={
91
89
  setUpdateCalendarMonthNavigation
@@ -149,7 +149,6 @@ export const useFilterCalendar = ({
149
149
  handleSubmit,
150
150
  handleClearDates,
151
151
  setCalendarRange,
152
- setDisabledDates,
153
152
  setUpdateCalendarMonthNavigation,
154
153
  calendarRange,
155
154
  disabledDates,
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef } from 'react'
2
- import { startOfDay } from 'date-fns'
2
+ import { addDays, 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'
@@ -33,7 +33,6 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
33
33
  disableCalendarDates,
34
34
  requestDates,
35
35
  disabledDates,
36
- setDisabledDates,
37
36
  updateCalendarMonthNavigation,
38
37
  setUpdateCalendarMonthNavigation,
39
38
  updateCalendarDefaultMonth,
@@ -89,7 +88,6 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
89
88
  range,
90
89
  newDisableCalendarDates,
91
90
  setCalendarRange,
92
- setDisabledDates,
93
91
  calendarRange,
94
92
  overlappingDate,
95
93
  setCalendarHasError,
@@ -105,7 +103,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
105
103
  findLastPossibleRangeContextCheckOut,
106
104
  firstPossibleRangeContextCheckIn,
107
105
  lastPossibleRangeContextCheckOut,
108
- currentSelectionLastCheckoutDate,
106
+ currentSelectionAvailability,
109
107
  } = handleRangeContextDisabledDates({
110
108
  rangeContext,
111
109
  availableDates: newDisableCalendarDates?.availableDates,
@@ -121,6 +119,43 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
121
119
  disabledDates: newDisableCalendarDates?.disabledDates,
122
120
  })
123
121
 
122
+ const disabledInsideSelectableRange = () => {
123
+ if (
124
+ // Range end already selected
125
+ calendarRange?.to ||
126
+ // No current check-in availability
127
+ !currentSelectionAvailability ||
128
+ // No gap between check-in and first possible check-out, nothing to disable
129
+ addDays(currentSelectionAvailability.checkIn, 1) >=
130
+ currentSelectionAvailability.firstCheckOut
131
+ ) {
132
+ return []
133
+ }
134
+ // Disable dates between current check-in and first possible check-out
135
+ return [
136
+ {
137
+ from: addDays(currentSelectionAvailability.checkIn, 1),
138
+ to: addDays(currentSelectionAvailability.firstCheckOut, -1),
139
+ },
140
+ ]
141
+ }
142
+
143
+ const base = disabledDatesByPage.length
144
+ ? disabledDatesByPage
145
+ : disabledDates?.length
146
+ ? disabledDates
147
+ : newDisableCalendarDates?.disabledDates || []
148
+
149
+ const disabled = disabledDatesByPage.length
150
+ ? base
151
+ : [
152
+ lastPossibleCheckout,
153
+ ...base,
154
+ ...firstPossibleRangeContextCheckIn,
155
+ ...lastPossibleRangeContextCheckOut,
156
+ ...disabledInsideSelectableRange(),
157
+ ]
158
+
124
159
  return (
125
160
  <div className="will-filter-bar-calendar" ref={ref}>
126
161
  <div className="will-calendar-filter-container">
@@ -142,31 +177,11 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
142
177
  ? newDisableCalendarDates.disabledDates[0].from
143
178
  : today)
144
179
  }
145
- disabled={
146
- disabledDatesByPage.length
147
- ? disabledDatesByPage
148
- : disabledDates?.length
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
- : []
163
- }
180
+ disabled={disabled}
164
181
  fromMonth={today}
165
182
  onMonthChange={(val) => {
166
- requestDates && setUpdateCalendarMonthNavigation
167
- ? (requestDates(val),
168
- setUpdateCalendarMonthNavigation((prev) => !prev))
169
- : null
183
+ requestDates?.(val)
184
+ setUpdateCalendarMonthNavigation?.((prev) => !prev)
170
185
  }}
171
186
  classNames={{
172
187
  day_range_start: calendarRange?.from ? 'rdp-day_range_start' : '',
@@ -191,18 +206,13 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
191
206
  modifiers={
192
207
  // This function handles conditions for applying the modifiersClassNames
193
208
  handleCalendarModifiers({
194
- newDisableCalendarDates,
195
209
  calendarRange,
196
- disabledDatesByPage,
197
- disabledDates,
210
+ disabledDates: disabled,
198
211
  overlappingDate,
199
212
  rangeContext,
200
- lastPossibleCheckout,
201
213
  findFirstPossibleRangeContextCheckIn,
202
214
  findLastPossibleRangeContextCheckOut,
203
- firstPossibleRangeContextCheckIn,
204
- lastPossibleRangeContextCheckOut,
205
- currentSelectionLastCheckoutDate,
215
+ currentSelectionLastCheckoutDate: currentSelectionAvailability,
206
216
  })
207
217
  }
208
218
  />
@@ -74,11 +74,11 @@ export const useUpdateDisabledDates = ({
74
74
  )
75
75
 
76
76
  // Find last possible checkout ( disable all dates after the last possible checkout )
77
- const lastPossibleCheckout =
77
+ const lastPossibleCheckoutDate: Date | undefined =
78
78
  disableCalendarDates.availableDates.at(-1)?.lastCheckOut
79
79
 
80
- if (lastPossibleCheckout) {
81
- setLatsPossibleCheckout({ after: lastPossibleCheckout })
80
+ if (lastPossibleCheckoutDate) {
81
+ setLatsPossibleCheckout({ after: lastPossibleCheckoutDate })
82
82
  }
83
83
 
84
84
  // Extract overlapping dates ( dates that are only available for checkout )
@@ -7,7 +7,6 @@ type Props = {
7
7
  range: DateRange | undefined
8
8
  newDisableCalendarDates?: DisableCalendarDates
9
9
  setCalendarRange: (range: DateRange | undefined) => void
10
- setDisabledDates?: (arg: Matcher[]) => void
11
10
  setCalendarHasError?: (arg: boolean) => void
12
11
  calendarRange?: DateRange
13
12
  overlappingDate?: DateRange[]
@@ -19,7 +18,6 @@ export const calendarSelectionRules = ({
19
18
  range,
20
19
  newDisableCalendarDates,
21
20
  setCalendarRange,
22
- setDisabledDates,
23
21
  calendarRange,
24
22
  overlappingDate,
25
23
  setCalendarHasError,
@@ -67,14 +65,6 @@ export const calendarSelectionRules = ({
67
65
  )
68
66
  : null
69
67
 
70
- // On check-in, disable future dates that are unavailable for checkout
71
- disableFutureDates({
72
- rangeFrom,
73
- checkOutRange,
74
- setDisabledDates,
75
- newDisableCalendarDates,
76
- })
77
-
78
68
  // Calendar selection rules: The cases are handled sequentially, starting from simple selections to more complex contextual selections.
79
69
  // The rules are processed in a specific order, so one case is handled before another.
80
70
  // Changing the order will cause the rules to break or not work properly.
@@ -188,41 +178,3 @@ export const calendarSelectionRules = ({
188
178
 
189
179
  setCalendarRange(range)
190
180
  }
191
-
192
- /////////
193
-
194
- const disableFutureDates = ({
195
- rangeFrom,
196
- checkOutRange,
197
- setDisabledDates,
198
- newDisableCalendarDates,
199
- }: {
200
- rangeFrom: Date | null
201
- checkOutRange?:
202
- | NonNullable<DisableCalendarDates['availableDates']>['0']
203
- | null
204
- setDisabledDates?: (arg: Matcher[]) => void
205
- newDisableCalendarDates?: DisableCalendarDates
206
- }) => {
207
- if (rangeFrom && checkOutRange && setDisabledDates) {
208
- // Get parse data
209
- const checkIn = addDays(checkOutRange.checkIn, 1)
210
- const firstCheckOut = addDays(checkOutRange.firstCheckOut, -1)
211
- const noDatesRange = isEqual(checkIn, checkOutRange.firstCheckOut)
212
-
213
- setDisabledDates([
214
- // Will disable all dates before the check-in date
215
- // { before: findCheckOutRange?.checkIn },
216
-
217
- ...(newDisableCalendarDates?.disabledDates || []),
218
-
219
- {
220
- from: noDatesRange ? undefined : checkIn,
221
- to: noDatesRange ? undefined : firstCheckOut,
222
- },
223
-
224
- // Will disable all dates after the last possible check-out after a check-in has been selected
225
- //{ after: checkOutRange?.lastCheckOut },
226
- ])
227
- }
228
- }
@@ -4,14 +4,8 @@ import { DateRange, Matcher } from 'react-day-picker'
4
4
  import { DisableCalendarDates, RangeContext } from '../CalendarTypes'
5
5
 
6
6
  type Props = {
7
- newDisableCalendarDates?: DisableCalendarDates
8
7
  calendarRange?: DateRange
9
- disabledDatesByPage: {
10
- from: Date
11
- to: Date
12
- }[]
13
8
  disabledDates?: Matcher[]
14
- lastPossibleCheckout?: Matcher
15
9
  overlappingDate?: DateRange[]
16
10
  rangeContext?: RangeContext
17
11
  findFirstPossibleRangeContextCheckIn?: NonNullable<
@@ -20,26 +14,19 @@ type Props = {
20
14
  findLastPossibleRangeContextCheckOut?: NonNullable<
21
15
  DisableCalendarDates['availableDates']
22
16
  >['0']
23
- firstPossibleRangeContextCheckIn: Matcher[]
24
- lastPossibleRangeContextCheckOut: Matcher[]
25
17
  currentSelectionLastCheckoutDate?: NonNullable<
26
18
  DisableCalendarDates['availableDates']
27
19
  >['0']
28
20
  }
29
21
 
30
22
  export const handleCalendarModifiers = ({
31
- newDisableCalendarDates,
32
23
  calendarRange,
33
- disabledDatesByPage,
34
24
  disabledDates,
35
25
  overlappingDate,
36
26
  rangeContext,
37
- firstPossibleRangeContextCheckIn,
38
- lastPossibleRangeContextCheckOut,
39
27
  findFirstPossibleRangeContextCheckIn,
40
28
  findLastPossibleRangeContextCheckOut,
41
29
  currentSelectionLastCheckoutDate,
42
- lastPossibleCheckout,
43
30
  }: Props) => {
44
31
  // Parse data
45
32
  const calendarRangeFrom = calendarRange?.from && endOfDay(calendarRange.from)
@@ -69,23 +56,7 @@ export const handleCalendarModifiers = ({
69
56
  : []
70
57
 
71
58
  return {
72
- booked: disabledDatesByPage.length
73
- ? disabledDatesByPage
74
- : disabledDates?.length
75
- ? [
76
- lastPossibleCheckout || [],
77
- ...disabledDates,
78
- ...firstPossibleRangeContextCheckIn,
79
- ...lastPossibleRangeContextCheckOut,
80
- ]
81
- : newDisableCalendarDates?.disabledDates?.length
82
- ? [
83
- lastPossibleCheckout || [],
84
- ...newDisableCalendarDates?.disabledDates,
85
- ...firstPossibleRangeContextCheckIn,
86
- ...lastPossibleRangeContextCheckOut,
87
- ]
88
- : [],
59
+ booked: disabledDates || [],
89
60
 
90
61
  disabledAfterCheckIn: calendarRangeFrom
91
62
  ? [{ after: calendarRangeFrom }]
@@ -58,8 +58,8 @@ export const handleRangeContextDisabledDates = ({
58
58
  }
59
59
  }
60
60
 
61
- // Get last possible check-out dates for current check-in
62
- const currentSelectionLastCheckoutDate = availableDates?.find((date) => {
61
+ // Get possible check-out dates for current check-in
62
+ const currentSelectionAvailability = availableDates?.find((date) => {
63
63
  return calendarRangeFrom
64
64
  ? isEqual(endOfDay(date.checkIn), calendarRangeFrom)
65
65
  : false
@@ -70,6 +70,6 @@ export const handleRangeContextDisabledDates = ({
70
70
  findLastPossibleRangeContextCheckOut,
71
71
  firstPossibleRangeContextCheckIn,
72
72
  lastPossibleRangeContextCheckOut,
73
- currentSelectionLastCheckoutDate,
73
+ currentSelectionAvailability,
74
74
  }
75
75
  }
@@ -5,10 +5,7 @@
5
5
  "eventsLabelPlaceholder": "Add search dates",
6
6
  "startDate": "Start date",
7
7
  "endDate": "End date",
8
- "title": "Calendar",
9
- "checkoutOnly": "Check-out only",
10
- "hasDisableDates": "Contains unavailable dates",
11
- "minNights": "2 nights min"
8
+ "title": "Calendar"
12
9
  },
13
10
  "guests": {
14
11
  "label": "Number of guests",
@@ -27,4 +24,4 @@
27
24
  "events": "Events",
28
25
  "rooms": "Rooms"
29
26
  }
30
- }
27
+ }
@@ -5,21 +5,16 @@
5
5
  "eventsLabelPlaceholder": "Lisää aikaväli",
6
6
  "startDate": "Alku",
7
7
  "endDate": "Loppu",
8
- "title": "Kalenteri",
9
- "checkoutOnly": "Check-out only",
10
- "hasDisableDates": "Contains unavailable dates",
11
- "minNights": "2 nights min"
8
+ "title": "Kalenteri"
12
9
  },
13
10
  "guests": {
14
- "label": "Vierasmäärä",
15
- "labelPlaceholder": "Lisää vieraat",
11
+ "label": "Osallistujamäärä",
12
+ "labelPlaceholder": "Lisää osallistujat",
16
13
  "title": "Ketkä ovat tulossa?",
17
14
  "adultsLabel": "Aikuiset",
18
15
  "kidsLabel": "lapset",
19
- "guestsLabel": "vierasta",
20
- "guestLabel": "vieras",
21
- "checkoutOnly": "Check-out only",
22
- "hasDisableDates": "Contains unavailable dates"
16
+ "guestsLabel": "osallistujaa",
17
+ "guestLabel": "osallistuja"
23
18
  },
24
19
  "categories": {
25
20
  "label": "Kategoriat",
@@ -29,4 +24,4 @@
29
24
  "events": "Tapahtumat",
30
25
  "rooms": "Huoneet"
31
26
  }
32
- }
27
+ }