willba-component-library 0.2.21 → 0.2.23
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/components/FilterCalendar/FilterCalendar.d.ts +1 -1
- package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +3 -1
- package/lib/core/components/calendar/CalendarTypes.d.ts +3 -0
- package/lib/core/utils/parseDate.d.ts +2 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.esm.js +94 -30
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +94 -30
- package/lib/index.js.map +1 -1
- package/lib/index.umd.js +94 -30
- package/lib/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/FilterCalendar/FilterCalendar.stories.tsx +9 -836
- package/src/components/FilterCalendar/FilterCalendar.tsx +9 -1
- package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +19 -10
- package/src/core/components/calendar/Calendar.css +6 -0
- package/src/core/components/calendar/Calendar.tsx +85 -8
- package/src/core/components/calendar/CalendarTypes.ts +3 -0
- package/src/core/utils/parseDate.tsx +10 -2
- package/src/locales/en/common.json +2 -2
- package/src/locales/fi/common.json +4 -4
- package/src/locales/fi/filterBar.json +1 -1
|
@@ -26,6 +26,8 @@ export default function FilterCalendar({
|
|
|
26
26
|
loadingData,
|
|
27
27
|
setToggleCalendar,
|
|
28
28
|
requestDates,
|
|
29
|
+
showFeedback,
|
|
30
|
+
noActiveSelection,
|
|
29
31
|
}: FilterCalendarTypes) {
|
|
30
32
|
const themePalette = useTheme({ palette })
|
|
31
33
|
|
|
@@ -42,7 +44,8 @@ export default function FilterCalendar({
|
|
|
42
44
|
setDisabledDates,
|
|
43
45
|
updateCalendar,
|
|
44
46
|
setUpdateCalendar,
|
|
45
|
-
|
|
47
|
+
initialCalendarRange,
|
|
48
|
+
} = useFilterCalendar({ onSubmit, setToggleCalendar, noActiveSelection })
|
|
46
49
|
|
|
47
50
|
// Display component after fully loaded
|
|
48
51
|
useAwaitRender()
|
|
@@ -76,6 +79,9 @@ export default function FilterCalendar({
|
|
|
76
79
|
updateCalendar={updateCalendar}
|
|
77
80
|
setUpdateCalendar={setUpdateCalendar}
|
|
78
81
|
loadingData={loadingData}
|
|
82
|
+
initialCalendarRange={initialCalendarRange}
|
|
83
|
+
showFeedback={showFeedback}
|
|
84
|
+
noActiveSelection={noActiveSelection}
|
|
79
85
|
/>
|
|
80
86
|
</div>
|
|
81
87
|
<div className={`will-calendar-footer`}>
|
|
@@ -85,6 +91,7 @@ export default function FilterCalendar({
|
|
|
85
91
|
{parseDate({
|
|
86
92
|
date: calendarRange?.from,
|
|
87
93
|
dateFormat: 'EEEEEE d.M.yyyy',
|
|
94
|
+
language,
|
|
88
95
|
}) || t('common:checkIn')}
|
|
89
96
|
</span>
|
|
90
97
|
<span className={`will-calendar-footer-dates-separator`}>
|
|
@@ -94,6 +101,7 @@ export default function FilterCalendar({
|
|
|
94
101
|
{parseDate({
|
|
95
102
|
date: calendarRange?.to,
|
|
96
103
|
dateFormat: 'EEEEEE d.M.yyyy',
|
|
104
|
+
language,
|
|
97
105
|
}) || t('common:checkOut')}
|
|
98
106
|
</span>
|
|
99
107
|
</div>
|
|
@@ -4,10 +4,18 @@ import { DateRange, Matcher } from 'react-day-picker'
|
|
|
4
4
|
type Props = {
|
|
5
5
|
onSubmit: (val: any) => void
|
|
6
6
|
setToggleCalendar: (val: boolean) => void
|
|
7
|
+
noActiveSelection?: boolean
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
export const useFilterCalendar = ({
|
|
10
|
+
export const useFilterCalendar = ({
|
|
11
|
+
onSubmit,
|
|
12
|
+
setToggleCalendar,
|
|
13
|
+
noActiveSelection,
|
|
14
|
+
}: Props) => {
|
|
10
15
|
const [calendarRange, setCalendarRange] = useState<DateRange | undefined>()
|
|
16
|
+
const [initialCalendarRange, setInitialCalendarRange] = useState<
|
|
17
|
+
DateRange | undefined
|
|
18
|
+
>()
|
|
11
19
|
const [disabledDates, setDisabledDates] = useState<Matcher[]>([])
|
|
12
20
|
const [updateCalendar, setUpdateCalendar] = useState<boolean>(false)
|
|
13
21
|
|
|
@@ -20,18 +28,18 @@ export const useFilterCalendar = ({ onSubmit, setToggleCalendar }: Props) => {
|
|
|
20
28
|
const endDateParam = urlSearchParams.get('endDate')
|
|
21
29
|
|
|
22
30
|
if (startDateParam && endDateParam) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
noActiveSelection
|
|
32
|
+
? setInitialCalendarRange({
|
|
33
|
+
from: new Date(startDateParam),
|
|
34
|
+
to: new Date(endDateParam),
|
|
35
|
+
})
|
|
36
|
+
: setCalendarRange({
|
|
37
|
+
from: new Date(startDateParam),
|
|
38
|
+
to: new Date(endDateParam),
|
|
39
|
+
})
|
|
27
40
|
}
|
|
28
41
|
}, [])
|
|
29
42
|
|
|
30
|
-
// TODO - handle the onSubmit on calendar open
|
|
31
|
-
// useEffect(() => {
|
|
32
|
-
// onSubmit(calendarRange)
|
|
33
|
-
// }, [])
|
|
34
|
-
|
|
35
43
|
const handleSubmit = () => {
|
|
36
44
|
setToggleCalendar(false)
|
|
37
45
|
return onSubmit(calendarRange)
|
|
@@ -51,5 +59,6 @@ export const useFilterCalendar = ({ onSubmit, setToggleCalendar }: Props) => {
|
|
|
51
59
|
calendarRange,
|
|
52
60
|
disabledDates,
|
|
53
61
|
updateCalendar,
|
|
62
|
+
initialCalendarRange,
|
|
54
63
|
}
|
|
55
64
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useEffect
|
|
1
|
+
import React, { forwardRef, useEffect } from 'react'
|
|
2
2
|
import { addDays, startOfDay, format } from 'date-fns'
|
|
3
3
|
import { fi, enUS } from 'date-fns/locale'
|
|
4
4
|
import { useTranslation } from 'react-i18next'
|
|
@@ -24,6 +24,8 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
24
24
|
updateCalendar,
|
|
25
25
|
setUpdateCalendar,
|
|
26
26
|
loadingData,
|
|
27
|
+
initialCalendarRange,
|
|
28
|
+
showFeedback,
|
|
27
29
|
}: CalendarTypes,
|
|
28
30
|
ref
|
|
29
31
|
) => {
|
|
@@ -50,7 +52,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
50
52
|
|
|
51
53
|
// Handle tooltip
|
|
52
54
|
useEffect(() => {
|
|
53
|
-
if (typeof document === 'undefined') return
|
|
55
|
+
if (typeof document === 'undefined' || !showFeedback) return
|
|
54
56
|
|
|
55
57
|
const calendarTooltip = document.querySelector('.will-calendar-tooltip')
|
|
56
58
|
const calendarTooltipCheckOut = document.querySelector(
|
|
@@ -115,6 +117,36 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
115
117
|
}
|
|
116
118
|
}, [loadingData])
|
|
117
119
|
|
|
120
|
+
// Handle overlapping availableDates.lastCheckOut and disabledDates.start
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (disableCalendarDates) {
|
|
123
|
+
const dateFormat = 'dd-MM-yyyy'
|
|
124
|
+
|
|
125
|
+
const availableDateMap = new Map()
|
|
126
|
+
disableCalendarDates.availableDates?.forEach((available) => {
|
|
127
|
+
availableDateMap.set(
|
|
128
|
+
format(available.lastCheckOut, dateFormat),
|
|
129
|
+
available
|
|
130
|
+
)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
const updatedDisabledDates = disableCalendarDates.disabledDates?.map(
|
|
134
|
+
(dateRange) => {
|
|
135
|
+
const formattedFromDate = format(dateRange.from, dateFormat)
|
|
136
|
+
if (availableDateMap.has(formattedFromDate)) {
|
|
137
|
+
return {
|
|
138
|
+
...dateRange,
|
|
139
|
+
from: addDays(dateRange.from, 1),
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return dateRange
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
disableCalendarDates.disabledDates = updatedDisabledDates
|
|
147
|
+
}
|
|
148
|
+
}, [disableCalendarDates])
|
|
149
|
+
|
|
118
150
|
// Handle disable dates by page
|
|
119
151
|
const disabledDatesByPage = handleDisabledDatesByPage({
|
|
120
152
|
today,
|
|
@@ -145,6 +177,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
145
177
|
today: 'my-today',
|
|
146
178
|
booked: 'booked',
|
|
147
179
|
disabledAfterCheckIn: 'disabled-after-check-in',
|
|
180
|
+
noActiveSelection: 'no-active-selection',
|
|
148
181
|
}}
|
|
149
182
|
captionLayout="dropdown-buttons"
|
|
150
183
|
defaultMonth={
|
|
@@ -176,6 +209,10 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
|
|
|
176
209
|
disabledAfterCheckIn: calendarRange?.from
|
|
177
210
|
? [{ after: calendarRange.from }]
|
|
178
211
|
: [],
|
|
212
|
+
|
|
213
|
+
noActiveSelection: !calendarRange
|
|
214
|
+
? initialCalendarRange || []
|
|
215
|
+
: [],
|
|
179
216
|
}}
|
|
180
217
|
/>
|
|
181
218
|
|
|
@@ -226,18 +263,26 @@ const handleSelectedCheckIn = ({
|
|
|
226
263
|
)
|
|
227
264
|
: null
|
|
228
265
|
|
|
229
|
-
if (
|
|
230
|
-
rangeFrom &&
|
|
231
|
-
// rangeFrom !== calendarTo &&
|
|
232
|
-
checkOutRange &&
|
|
233
|
-
setDisabledDates
|
|
234
|
-
) {
|
|
266
|
+
if (rangeFrom && checkOutRange && setDisabledDates) {
|
|
235
267
|
const checkIn = addDays(checkOutRange.checkIn, 1)
|
|
236
268
|
const firstCheckOut = addDays(checkOutRange.firstCheckOut, -1)
|
|
237
269
|
const noDatesRange =
|
|
238
270
|
format(checkIn, dateFormat) ===
|
|
239
271
|
format(checkOutRange.firstCheckOut, dateFormat)
|
|
240
272
|
|
|
273
|
+
// Handle overlapping availableDates.lastCheckOut and disabledDates.start
|
|
274
|
+
// const filteredDisabledCalendarDates =
|
|
275
|
+
// disableCalendarDates?.disabledDates?.map((dateRange) => {
|
|
276
|
+
// if (
|
|
277
|
+
// dateRange.from &&
|
|
278
|
+
// format(dateRange.from, dateFormat) ===
|
|
279
|
+
// format(checkOutRange.lastCheckOut, dateFormat)
|
|
280
|
+
// ) {
|
|
281
|
+
// return { ...dateRange, from: addDays(checkOutRange.lastCheckOut, 1) }
|
|
282
|
+
// }
|
|
283
|
+
// return dateRange
|
|
284
|
+
// })
|
|
285
|
+
|
|
241
286
|
setDisabledDates([
|
|
242
287
|
// { before: findCheckOutRange?.checkIn },
|
|
243
288
|
|
|
@@ -247,6 +292,7 @@ const handleSelectedCheckIn = ({
|
|
|
247
292
|
from: noDatesRange ? undefined : checkIn,
|
|
248
293
|
to: noDatesRange ? undefined : firstCheckOut,
|
|
249
294
|
},
|
|
295
|
+
|
|
250
296
|
{ after: checkOutRange?.lastCheckOut },
|
|
251
297
|
])
|
|
252
298
|
}
|
|
@@ -299,3 +345,34 @@ const handleDisabledDatesByPage = ({
|
|
|
299
345
|
]
|
|
300
346
|
: []
|
|
301
347
|
}
|
|
348
|
+
|
|
349
|
+
// const handleOverlappingDates = ({
|
|
350
|
+
// disableCalendarDates,
|
|
351
|
+
// }: {
|
|
352
|
+
// disableCalendarDates?: DisableCalendarDates
|
|
353
|
+
// }): DisableCalendarDates | undefined => {
|
|
354
|
+
// if (!disableCalendarDates) return undefined
|
|
355
|
+
|
|
356
|
+
// const dateFormat = 'dd-MM-yyyy'
|
|
357
|
+
|
|
358
|
+
// disableCalendarDates.disabledDates = disableCalendarDates.disabledDates?.map(
|
|
359
|
+
// (dateRange) => {
|
|
360
|
+
// const overlappingDate = disableCalendarDates.availableDates?.find(
|
|
361
|
+
// (available) =>
|
|
362
|
+
// format(available.lastCheckOut, dateFormat) ===
|
|
363
|
+
// format(dateRange.from, dateFormat)
|
|
364
|
+
// )
|
|
365
|
+
|
|
366
|
+
// if (overlappingDate) {
|
|
367
|
+
// return {
|
|
368
|
+
// ...dateRange,
|
|
369
|
+
// from: addDays(dateRange.from, 1),
|
|
370
|
+
// }
|
|
371
|
+
// }
|
|
372
|
+
|
|
373
|
+
// return dateRange
|
|
374
|
+
// }
|
|
375
|
+
// )
|
|
376
|
+
|
|
377
|
+
// return disableCalendarDates
|
|
378
|
+
// }
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { format } from 'date-fns'
|
|
2
|
+
import { fi, enUS } from 'date-fns/locale'
|
|
2
3
|
|
|
3
4
|
type Props = {
|
|
4
5
|
date?: Date
|
|
5
6
|
dateFormat?: string
|
|
7
|
+
language?: string
|
|
6
8
|
}
|
|
7
|
-
export const parseDate = ({
|
|
8
|
-
|
|
9
|
+
export const parseDate = ({
|
|
10
|
+
date,
|
|
11
|
+
dateFormat = 'dd.MM.yyyy',
|
|
12
|
+
language,
|
|
13
|
+
}: Props) => {
|
|
14
|
+
return date
|
|
15
|
+
? format(date, dateFormat, { locale: language === 'en' ? enUS : fi })
|
|
16
|
+
: null
|
|
9
17
|
}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
"checkIn": "check-in",
|
|
5
5
|
"checkOut": "check-out",
|
|
6
6
|
"search": "Hae",
|
|
7
|
-
"apply": "
|
|
8
|
-
"clearDates": "
|
|
9
|
-
"noCheckIn": "
|
|
10
|
-
"noCheckOut": "
|
|
7
|
+
"apply": "Aseta",
|
|
8
|
+
"clearDates": "Tyhjennä",
|
|
9
|
+
"noCheckIn": "Huone ei saatavilla",
|
|
10
|
+
"noCheckOut": "Uloskirjaus ei saatavilla"
|
|
11
11
|
}
|
|
12
12
|
|