ublo-lib 1.2.4 → 1.3.0

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 (29) hide show
  1. package/es/common/hooks/use-in-view.js +40 -37
  2. package/es/esf/components/magic-box/services/api.js +1 -1
  3. package/es/esf/components/period-picker/controls.js +47 -0
  4. package/es/esf/components/period-picker/controls.module.css +36 -0
  5. package/es/esf/components/period-picker/date-display.js +67 -0
  6. package/es/esf/components/period-picker/date-display.module.css +18 -0
  7. package/es/esf/components/period-picker/days.js +112 -0
  8. package/es/esf/components/period-picker/days.module.css +113 -0
  9. package/es/esf/components/period-picker/extended-stay-picker.js +61 -0
  10. package/es/esf/components/period-picker/extended-stay-picker.module.css +50 -0
  11. package/es/esf/components/period-picker/index.js +4 -0
  12. package/es/esf/components/period-picker/messages.js +39 -0
  13. package/es/esf/components/period-picker/period-picker.js +202 -0
  14. package/es/esf/components/period-picker/period-picker.module.css +160 -0
  15. package/es/esf/components/period-picker/popup.js +42 -0
  16. package/es/esf/components/period-picker/popup.module.css +21 -0
  17. package/es/esf/components/period-picker/services/dates.js +101 -0
  18. package/es/esf/components/period-picker/services/events.js +7 -0
  19. package/es/esf/components/period-picker/services/motions.js +38 -0
  20. package/es/esf/components/period-picker/services/sections.js +24 -0
  21. package/es/esf/components/period-picker/services/stay.js +27 -0
  22. package/es/esf/components/period-picker/services/utils.js +0 -0
  23. package/es/esf/components/period-picker/title.js +33 -0
  24. package/es/esf/components/period-picker/title.module.css +6 -0
  25. package/es/esf/components/period-picker/warning.js +59 -0
  26. package/es/esf/components/period-picker/warning.module.css +53 -0
  27. package/es/esf/components/period-picker/weeks.js +120 -0
  28. package/es/esf/components/period-picker/weeks.module.css +194 -0
  29. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { useEffect, useState, useCallback } from "react";
1
+ import * as React from "react";
2
2
 
3
3
  const ratio = steps => Array.from({
4
4
  length: steps + 1
@@ -6,13 +6,14 @@ const ratio = steps => Array.from({
6
6
 
7
7
  const buildClass = className => `${className}--in-view`;
8
8
 
9
+ const options = {
10
+ rootMargin: "0px",
11
+ threshold: ratio(100)
12
+ };
13
+
9
14
  const useInView = (ref, cmsMode, targetedClass, repeat = true, intersectionValue = 0.2) => {
10
- const [compatible, setCompatible] = useState(false);
11
- const options = {
12
- rootMargin: "0px",
13
- threshold: ratio(100)
14
- };
15
- const callback = useCallback(entries => {
15
+ const [compatible, setCompatible] = React.useState(false);
16
+ const callback = React.useCallback(entries => {
16
17
  entries.forEach(entry => {
17
18
  const {
18
19
  intersectionRatio,
@@ -32,42 +33,44 @@ const useInView = (ref, cmsMode, targetedClass, repeat = true, intersectionValue
32
33
  }
33
34
  });
34
35
  }, [intersectionValue, repeat]);
35
- useEffect(() => {
36
+ React.useEffect(() => {
36
37
  setCompatible(typeof IntersectionObserver !== "undefined");
37
- }, []);
38
- useEffect(() => {
39
- if (ref.current === undefined) return;
40
- const targets = targetedClass !== undefined ? Array.from(ref.current.querySelectorAll(targetedClass)) : [ref.current];
41
- targets.forEach(target => {
42
- const inViewClass = buildClass(target.classList[0]);
43
- target.classList.remove(inViewClass);
44
- });
45
-
46
- if (cmsMode !== "editing" && cmsMode !== "info" && cmsMode !== "connected") {
47
- if (!compatible) {
48
- return targets.forEach(target => {
49
- const inViewClass = buildClass(target.classList[0]);
50
- target.classList.add(inViewClass);
51
- });
52
- }
38
+ const container = ref.current;
39
+ const targets = targetedClass !== undefined ? Array.from(container.querySelectorAll(targetedClass)) : [container];
53
40
 
54
- const observer = new IntersectionObserver(callback, options);
41
+ if (container) {
42
+ if (!cmsMode) {
43
+ if (!compatible) {
44
+ targets.forEach(target => {
45
+ const inViewClass = buildClass(target.classList[0]);
46
+ target.classList.add(inViewClass);
47
+ });
48
+ } else {
49
+ targets.forEach(target => {
50
+ const inViewClass = buildClass(target.classList[0]);
51
+ target.classList.remove(inViewClass);
52
+ });
53
+ const observer = new IntersectionObserver(callback, options);
55
54
 
56
- const observe = () => targets.forEach(target => observer?.observe(target));
55
+ const observe = () => {
56
+ targets.forEach(target => observer?.observe(target));
57
+ };
57
58
 
58
- const unobserve = () => {
59
- targets.forEach(target => {
60
- if (!target || !target.classList[0]) return;
61
- const inViewClass = buildClass(target.classList[0]);
62
- target.classList.remove(inViewClass);
63
- observer.disconnect();
64
- });
65
- };
59
+ const unobserve = () => targets.forEach(target => {
60
+ if (!target || !target.classList[0]) return;
61
+ const inViewClass = buildClass(target.classList[0]);
62
+ target.classList.remove(inViewClass);
63
+ observer.disconnect();
64
+ });
66
65
 
67
- observe();
68
- return () => unobserve();
66
+ observe();
67
+ return () => {
68
+ unobserve();
69
+ };
70
+ }
71
+ }
69
72
  }
70
- }, [cmsMode, compatible, options, ref, repeat, targetedClass, callback]);
73
+ }, [callback, cmsMode, compatible, ref, targetedClass]);
71
74
  };
72
75
 
73
76
  export default useInView;
@@ -23,7 +23,7 @@ export const fetchFilters = async ({
23
23
  activities
24
24
  }) => {
25
25
  const selectedActivities = activities ? new Array(activities) : undefined;
26
- return Fetcher.post(`${velApi}/new/vel3/filters`, {
26
+ return Fetcher.post(`${velApi}/filters`, {
27
27
  lang,
28
28
  resort,
29
29
  season,
@@ -0,0 +1,47 @@
1
+ import * as React from "react";
2
+ import * as Icons from "dt-design-system/es/icons";
3
+ import css from "./controls.module.css";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ import { jsxs as _jsxs } from "react/jsx-runtime";
6
+ const LEFT = 0;
7
+ const RIGHT = 1;
8
+
9
+ const Controls = ({
10
+ barRef,
11
+ distance
12
+ }) => {
13
+ const scrollTo = direction => () => {
14
+ const bar = barRef.current;
15
+ if (!bar) return;
16
+ const currentScroll = bar.scrollLeft;
17
+
18
+ if (direction === LEFT) {
19
+ bar.scrollLeft = currentScroll - distance;
20
+ }
21
+
22
+ if (direction === RIGHT) {
23
+ bar.scrollLeft = currentScroll + distance;
24
+ }
25
+ };
26
+
27
+ return _jsxs("div", {
28
+ className: css.controls,
29
+ children: [_jsx("button", {
30
+ className: css.control,
31
+ onClick: scrollTo(LEFT),
32
+ "aria-label": "Previous",
33
+ children: _jsx(Icons.ChevronsLeft, {
34
+ className: css.icon
35
+ })
36
+ }), _jsx("button", {
37
+ className: css.control,
38
+ onClick: scrollTo(RIGHT),
39
+ "aria-label": "Next",
40
+ children: _jsx(Icons.ChevronsRight, {
41
+ className: css.icon
42
+ })
43
+ })]
44
+ });
45
+ };
46
+
47
+ export default Controls;
@@ -0,0 +1,36 @@
1
+ .controls {
2
+ --control-size: 48px;
3
+
4
+ position: absolute;
5
+ top: calc(100% - var(--control-size) / 3);
6
+ left: 0;
7
+ width: 100%;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ pointer-events: none;
12
+ touch-action: none;
13
+ }
14
+ @media (min-width: 900px) {
15
+ .controls {
16
+ display: none;
17
+ }
18
+ }
19
+
20
+ .control {
21
+ flex: 0 0 var(--control-size);
22
+ height: var(--control-size);
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ border-radius: var(--ds-radius-100, 3px);
27
+ cursor: pointer;
28
+ pointer-events: auto;
29
+ touch-action: auto;
30
+ }
31
+
32
+ .icon {
33
+ width: 24px;
34
+ height: 24px;
35
+ fill: currentColor;
36
+ }
@@ -0,0 +1,67 @@
1
+ import * as React from "react";
2
+ import classnames from "classnames";
3
+ import { motion } from "framer-motion";
4
+ import { useUbloContext } from "ublo/with-ublo";
5
+ import * as Messages from "./messages";
6
+ import * as Stay from "./services/stay";
7
+ import * as Motions from "./services/motions";
8
+ import css from "./date-display.module.css";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+
12
+ const DateDisplay = ({
13
+ className
14
+ }) => {
15
+ const [stay, setStay] = React.useState();
16
+ const {
17
+ lang,
18
+ metadata
19
+ } = useUbloContext();
20
+ const classes = classnames(css.display, {
21
+ [className]: className
22
+ });
23
+ const getStoredStay = React.useCallback(e => {
24
+ const storedStay = window.sessionStorage.getItem("stay");
25
+
26
+ if (storedStay) {
27
+ const newStay = JSON.parse(storedStay);
28
+ setStay(newStay);
29
+ }
30
+ }, []);
31
+ const updateStay = React.useCallback(e => {
32
+ setStay(e.detail);
33
+ }, []);
34
+ React.useEffect(() => {
35
+ if (!metadata?.disableWeekpicker) {
36
+ getStoredStay();
37
+ window.addEventListener("msem-stay-changed", updateStay);
38
+ return () => {
39
+ window.removeEventListener("msem-stay-changed", updateStay);
40
+ };
41
+ }
42
+ }, [getStoredStay, metadata?.disableWeekpicker, updateStay]);
43
+ if (!stay || metadata?.disableWeekpicker) return null;
44
+ const formatedStay = Stay.formatStay(lang, stay);
45
+ return _jsxs("div", {
46
+ className: classes,
47
+ children: [Messages.get(lang, "offers"), " ", _jsx("span", {
48
+ className: css.dates,
49
+ children: formatedStay.split(" ").map((word, index) => _jsx(motion.span, {
50
+ className: css.word,
51
+ transition: {
52
+ delayChildren: index * 0.05,
53
+ staggerChildren: 0.05
54
+ },
55
+ initial: "hidden",
56
+ animate: "visible",
57
+ children: word.split("").map((letter, index) => _jsx(motion.span, {
58
+ className: css.letter,
59
+ variants: Motions.character,
60
+ children: letter
61
+ }, `${letter}-${index}`))
62
+ }, `${word}-${index}`))
63
+ })]
64
+ });
65
+ };
66
+
67
+ export default DateDisplay;
@@ -0,0 +1,18 @@
1
+ .display {
2
+ max-width: 620px;
3
+ font-size: 40px;
4
+ font-weight: 700;
5
+ }
6
+
7
+ .dates {
8
+ color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
9
+ }
10
+
11
+ .word {
12
+ display: inline-block;
13
+ margin-right: 1rem;
14
+ }
15
+
16
+ .letter {
17
+ display: inline-block;
18
+ }
@@ -0,0 +1,112 @@
1
+ import * as React from "react";
2
+ import classnames from "classnames";
3
+ import { useUbloContext } from "ublo/with-ublo";
4
+ import * as Stay from "./services/stay";
5
+ import * as Dates from "./services/dates";
6
+ import css from "./days.module.css";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { jsxs as _jsxs } from "react/jsx-runtime";
9
+
10
+ const Day = ({
11
+ index,
12
+ day,
13
+ fullStay,
14
+ firstSelected,
15
+ updateSelection
16
+ }) => {
17
+ const {
18
+ lang
19
+ } = useUbloContext();
20
+ const locale = Dates.locales[lang] || Dates.locales.en;
21
+ const isFirstDayOfStay = day.getTime() === fullStay[0]?.getTime();
22
+ const isLastDayOfStay = day.getTime() === fullStay[fullStay.length - 1].getTime();
23
+ const isInStay = fullStay.some(date => date.getTime() === day.getTime());
24
+ const isFirstSelected = day.getTime() === new Date(firstSelected).getTime();
25
+ const dayLabel = new Date(day).toLocaleDateString(locale, {
26
+ weekday: "short"
27
+ });
28
+ const dayNumber = new Date(day).toLocaleDateString(locale, {
29
+ day: "2-digit"
30
+ });
31
+ const prevDay = new Date(day);
32
+ prevDay.setDate(day.getDate() - 1);
33
+ const prevMonth = prevDay.getMonth();
34
+ const currMonth = day.getMonth();
35
+ const hasMonthChanged = prevMonth !== currMonth;
36
+ const showMonth = index === 0 || hasMonthChanged;
37
+ const formatedMonth = day.toLocaleString(locale, {
38
+ month: "short"
39
+ });
40
+ const classes = classnames(css.day, {
41
+ [css.firstSelected]: isFirstSelected,
42
+ [css.dayFirstInStay]: !firstSelected && isFirstDayOfStay,
43
+ [css.dayLastInStay]: !firstSelected && isLastDayOfStay,
44
+ [css.dayBoundary]: !firstSelected && (isFirstDayOfStay || isLastDayOfStay),
45
+ [css.dayInStay]: !firstSelected && isInStay
46
+ });
47
+ return _jsxs("div", {
48
+ className: classes,
49
+ children: [_jsx("div", {
50
+ className: css.weekday,
51
+ children: dayLabel
52
+ }), _jsx("div", {
53
+ className: css.dayBottom,
54
+ children: _jsx("button", {
55
+ className: css.dayNumber,
56
+ onClick: updateSelection(day),
57
+ children: _jsx("span", {
58
+ className: css.dayNumberText,
59
+ children: dayNumber
60
+ })
61
+ })
62
+ }), showMonth && _jsx("span", {
63
+ className: css.month,
64
+ children: formatedMonth
65
+ })]
66
+ });
67
+ };
68
+
69
+ const Days = React.forwardRef(({
70
+ fullStay,
71
+ interval
72
+ }, ref) => {
73
+ const [firstSelected, setFirstSelected] = React.useState();
74
+
75
+ const updateSelection = day => e => {
76
+ e.stopPropagation();
77
+
78
+ if (firstSelected) {
79
+ const isBefore = firstSelected.getTime() > day.getTime();
80
+ Stay.update({
81
+ from: Dates.format(isBefore ? day : firstSelected),
82
+ to: Dates.format(isBefore ? firstSelected : day)
83
+ });
84
+ cancelSelection();
85
+ } else {
86
+ setFirstSelected(day);
87
+ }
88
+ };
89
+
90
+ const cancelSelection = () => {
91
+ setFirstSelected(undefined);
92
+ };
93
+
94
+ React.useEffect(() => {
95
+ window.addEventListener("click", cancelSelection);
96
+ return () => {
97
+ window.removeEventListener("click", cancelSelection);
98
+ };
99
+ }, []);
100
+ return _jsx("div", {
101
+ ref: ref,
102
+ className: css.days,
103
+ children: interval.map((day, i) => _jsx(Day, {
104
+ index: i,
105
+ day: day,
106
+ fullStay: fullStay,
107
+ firstSelected: firstSelected,
108
+ updateSelection: updateSelection
109
+ }, day))
110
+ });
111
+ });
112
+ export default Days;
@@ -0,0 +1,113 @@
1
+ .days {
2
+ width: 100%;
3
+ display: inline-flex;
4
+ align-items: flex-start;
5
+ margin: 0 auto;
6
+ padding: 0 18px 10px 18px;
7
+ overflow: auto;
8
+ scroll-behavior: smooth;
9
+ }
10
+
11
+ @media (min-width: 1100px) {
12
+ .days {
13
+ padding: 0 26px;
14
+ overflow: visible;
15
+ }
16
+ }
17
+
18
+ .day {
19
+ --item-size: 48px;
20
+ --padding: 6px;
21
+
22
+ flex: 0 0 var(--item-size);
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: stretch;
26
+ gap: 4px;
27
+ font-size: 14px;
28
+ font-weight: 700;
29
+ }
30
+
31
+ .day:first-of-type {
32
+ margin-left: auto;
33
+ }
34
+
35
+ .day:last-of-type {
36
+ margin-right: auto;
37
+ }
38
+
39
+ .weekday {
40
+ padding: 0 var(--padding) 10px var(--padding);
41
+ text-align: center;
42
+ border-bottom: 1px solid var(--ds-grey-700, #171e30);
43
+ }
44
+
45
+ .weekday::first-letter {
46
+ text-transform: uppercase;
47
+ }
48
+
49
+ .dayBottom {
50
+ width: var(--item-size);
51
+ height: var(--item-size);
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ margin-top: 10px;
56
+ }
57
+
58
+ .dayFirstInStay .dayBottom {
59
+ border-radius: 50% 0 0 50%;
60
+ }
61
+
62
+ .dayLastInStay .dayBottom {
63
+ border-radius: 0 50% 50% 0;
64
+ }
65
+
66
+ .dayFirstInStay.dayLastInStay .dayBottom {
67
+ border-radius: 50%;
68
+ }
69
+
70
+ .dayInStay .dayBottom {
71
+ background-color: var(--ds-grey-200, #efefef);
72
+ }
73
+
74
+ .dayNumber {
75
+ width: 100%;
76
+ height: 100%;
77
+ color: var(--ds-grey-700, #171e30);
78
+ font-weight: 700;
79
+ cursor: pointer;
80
+ transition: color 160ms
81
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
82
+ }
83
+
84
+ .day:not(.dayBoundary):not(.dayInStay):not(.firstSelected) .dayNumber:hover {
85
+ background-color: var(--ds-grey-100, #f5f5f5);
86
+ border-radius: 50%;
87
+ transition: color 160ms
88
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1)),
89
+ background-color 160ms
90
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
91
+ }
92
+
93
+ .firstSelected .dayNumber,
94
+ .dayBoundary .dayNumber {
95
+ position: relative;
96
+ border-radius: 50%;
97
+ color: var(--ds-grey-000, #ffffff);
98
+ background-color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
99
+ border-radius: 50%;
100
+ }
101
+
102
+ .firstSelected .dayNumberText,
103
+ .dayBoundary .dayNumberText {
104
+ position: relative;
105
+ }
106
+
107
+ .month {
108
+ width: 0;
109
+ margin-top: 8px;
110
+ color: var(--ds-grey-700, #171e30);
111
+ font-size: 11px;
112
+ text-transform: uppercase;
113
+ }
@@ -0,0 +1,61 @@
1
+ import * as React from "react";
2
+ import { AnimatePresence, motion } from "framer-motion";
3
+ import { useUbloContext } from "ublo/with-ublo";
4
+ import Button from "dt-design-system/es/button";
5
+ import Days from "./days";
6
+ import * as Dates from "./services/dates";
7
+ import * as Motions from "./services/motions";
8
+ import * as Messages from "./messages";
9
+ import css from "./extended-stay-picker.module.css";
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { jsxs as _jsxs } from "react/jsx-runtime";
12
+
13
+ const ExtendedStayPicker = ({
14
+ stay,
15
+ extend,
16
+ week,
17
+ endWeek,
18
+ forceSeasonSwitch,
19
+ opened,
20
+ setExtendedOpened
21
+ }) => {
22
+ const barRef = React.useRef();
23
+ const {
24
+ lang
25
+ } = useUbloContext();
26
+ const startDate = Dates.weekToDate(week, endWeek, forceSeasonSwitch);
27
+ const endDate = Dates.weekToDate(week + 1, endWeek, forceSeasonSwitch);
28
+ const fullStay = stay ? Dates.getInterval(new Date(stay.from), new Date(stay.to)) : [];
29
+ const interval = Dates.getInterval(startDate, endDate, extend);
30
+
31
+ const close = () => {
32
+ setExtendedOpened(false);
33
+ };
34
+
35
+ return _jsx(AnimatePresence, {
36
+ mode: "wait",
37
+ children: opened && _jsxs(motion.div, {
38
+ className: css.picker,
39
+ initial: "hidden",
40
+ animate: "visible",
41
+ exit: "hidden",
42
+ variants: Motions.fading,
43
+ children: [_jsxs("div", {
44
+ className: css.title,
45
+ children: [Messages.get(lang, "extended-title"), _jsx(Button, {
46
+ className: css.button,
47
+ variant: "link",
48
+ onClick: close,
49
+ compact: true,
50
+ children: Messages.get(lang, "update-period")
51
+ })]
52
+ }), _jsx(Days, {
53
+ ref: barRef,
54
+ fullStay: fullStay,
55
+ interval: interval
56
+ })]
57
+ })
58
+ });
59
+ };
60
+
61
+ export default ExtendedStayPicker;
@@ -0,0 +1,50 @@
1
+ .picker {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ display: flex;
8
+ flex-direction: column;
9
+ justify-content: center;
10
+ gap: 16px;
11
+ padding: 24px 0;
12
+ background-color: var(--ds-grey-000, #ffffff);
13
+ z-index: 1;
14
+ }
15
+
16
+ .title {
17
+ align-self: center;
18
+ position: relative;
19
+ display: flex;
20
+ flex-direction: column;
21
+ align-items: center;
22
+ justify-content: center;
23
+ gap: 6px;
24
+ padding: 0 20px;
25
+ font-size: 20px;
26
+ text-transform: uppercase;
27
+ font-weight: 700;
28
+ text-align: center;
29
+ }
30
+
31
+ @media (min-width: 1100px) {
32
+ .picker {
33
+ padding: 46px 0;
34
+ }
35
+ }
36
+
37
+ .button {
38
+ font-size: 12px;
39
+ color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
40
+ }
41
+
42
+ .buttonLabel {
43
+ display: none;
44
+ }
45
+
46
+ @media (min-width: 780px) {
47
+ .buttonLabel {
48
+ display: block;
49
+ }
50
+ }
@@ -0,0 +1,4 @@
1
+ import PeriodPicker from "./period-picker";
2
+ import DateDisplay from "./date-display";
3
+ PeriodPicker.DateDisplay = DateDisplay;
4
+ export default PeriodPicker;
@@ -0,0 +1,39 @@
1
+ const messages = {
2
+ fr: {
3
+ title: "<b>A quelle période</b> souhaitez-vous venir ?",
4
+ "selected-title": "<b>Vous venez</b> du",
5
+ warn: "Attention, modifier vos dates de séjour entraine la suppression du contenu du panier",
6
+ ok: "Confirmer",
7
+ cancel: "Annuler",
8
+ "update-period": "Choisir une autre plage de dates",
9
+ offers: "Les offres pour la période du",
10
+ to: "au",
11
+ "extended-title": "Vous pouvez ajuster vos dates de séjour"
12
+ },
13
+ en: {
14
+ title: "<span>When</span> are you coming?",
15
+ "selected-title": "<b>You are comming</b> from",
16
+ warn: "Warning, if you change your dates of stay, products in your cart will be removed",
17
+ ok: "Confirm",
18
+ cancel: "Cancel",
19
+ "update-period": "Update your stay",
20
+ offers: "Offers for the period from",
21
+ to: "to",
22
+ "extended-title": "You are coming more precisely"
23
+ },
24
+ nl: {
25
+ title: "<span>Wanneer</span> kom je?",
26
+ "selected-title": "<b>You are comming</b> from",
27
+ warn: "Waarschuwing, als u uw verblijfsdata wijzigt, wordt uw winkelwagentje gewist",
28
+ ok: "Aanpassen",
29
+ cancel: "Annuleren",
30
+ "update-period": "Update je verblijf",
31
+ offers: "Aanbiedingen voor de periode van",
32
+ to: "tot",
33
+ "extended-title": "Je komt precies"
34
+ }
35
+ };
36
+ export const get = (lang, message) => {
37
+ const locale = !messages[lang] ? "en" : lang;
38
+ return messages[locale][message];
39
+ };