ublo-lib 1.26.3 → 1.26.5

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.
@@ -1,26 +1,30 @@
1
1
  .date {
2
+ position: relative;
2
3
  width: 100%;
3
- padding: 8px 6px;
4
4
  display: flex;
5
+ flex-direction: column;
5
6
  align-items: center;
6
7
  justify-content: center;
7
- gap: 4px;
8
+ gap: 2px;
9
+ margin: 0;
10
+ padding: 12px 6px;
11
+ box-sizing: border-box;
8
12
  font-size: 14px;
9
13
  text-align: center;
14
+ color: var(--ds-grey-700, #262626);
15
+ font-weight: 400;
16
+ background-color: transparent;
17
+ border: 0;
18
+ border-radius: var(--ds-radius-400, 20px);
10
19
  cursor: pointer;
11
20
  user-select: none;
12
- border-radius: var(--ds-radius-400, 20px);
21
+ outline: none;
13
22
  transition: color 160ms
14
- var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1)),
23
+ var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9)),
15
24
  background-color 160ms
16
- var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1)),
25
+ var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9)),
17
26
  border-radius 160ms
18
- var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
19
- }
20
-
21
- .dateSaturday:not(.dateIsPast),
22
- .dateSunday:not(.dateIsPast) {
23
- font-weight: 700;
27
+ var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9));
24
28
  }
25
29
 
26
30
  .dateSelected {
@@ -39,32 +43,30 @@
39
43
  .dateSelected.dateFirstSelected,
40
44
  .dateSelected.dateLastSelected {
41
45
  color: #fff;
46
+ }
47
+
48
+ .dateSelected.dateFirstSelected::before,
49
+ .dateSelected.dateLastSelected::before {
50
+ content: "";
51
+ position: absolute;
52
+ top: 0;
53
+ left: 0;
54
+ width: 100%;
55
+ height: 100%;
42
56
  background-color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
57
+ border-radius: var(--ds-radius-400, 20px);
43
58
  }
44
59
 
45
60
  .dateSelected.dateFirstSelected {
46
61
  border-top-left-radius: var(--ds-radius-400, 20px);
47
62
  border-bottom-left-radius: var(--ds-radius-400, 20px);
48
63
  }
64
+
49
65
  .dateSelected.dateLastSelected {
50
66
  border-top-right-radius: var(--ds-radius-400, 20px);
51
67
  border-bottom-right-radius: var(--ds-radius-400, 20px);
52
68
  }
53
69
 
54
- .dateSelected.dateFirstSelected:not(.dateNotInMonth),
55
- .dateSelected.dateLastSelected:not(.dateNotInMonth) {
56
- @media (min-width: 810px) {
57
- color: #fff;
58
- background-color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
59
- }
60
- }
61
-
62
- .dateIsPast {
63
- opacity: 0.25;
64
- transform: translateZ(0);
65
- cursor: not-allowed;
66
- }
67
-
68
70
  .dateNotInMonth {
69
71
  opacity: 0.6;
70
72
  }
@@ -77,23 +79,23 @@
77
79
  }
78
80
  }
79
81
 
80
- .date:not(.dateIsPast):not(.dateSelected):hover {
82
+ .date:not(:disabled):hover {
81
83
  background-color: var(--ds-grey-200, #efefef);
82
84
  }
83
85
 
84
- .available::after,
85
- .notAvailable::after {
86
- content: "";
87
- flex: 0 0 6px;
88
- width: 6px;
89
- height: 6px;
90
- border-radius: 50%;
86
+ .available {
87
+ font-weight: 700;
88
+ }
89
+
90
+ .notAvailable {
91
+ text-decoration: line-through;
91
92
  }
92
93
 
93
- .available::after {
94
- background-color: hsl(var(--green));
94
+ .date > span {
95
+ z-index: 1;
95
96
  }
96
97
 
97
- .notAvailable::after {
98
- background-color: hsl(var(--red));
98
+ .popover {
99
+ min-width: auto;
100
+ font-size: 12px;
99
101
  }
@@ -1,82 +1,42 @@
1
1
  import * as React from "react";
2
2
  import classNames from "classnames";
3
- import { useUbloContext } from "ublo/with-ublo";
4
- import Modes from "./modes";
3
+ import useWindowSizes from "../../hooks/use-window-sizes";
5
4
  import Calendar from "./calendar";
6
- import * as Icons from "dt-design-system/es/icons";
7
- import styles from "./date-picker.module.css";
8
5
  import * as Data from "./data";
9
6
  import * as Utils from "./utils";
7
+ import styles from "./date-picker.module.css";
10
8
  import { jsx as _jsx } from "react/jsx-runtime";
11
- import { jsxs as _jsxs } from "react/jsx-runtime";
12
9
  import { Fragment as _Fragment } from "react/jsx-runtime";
13
- const DEFAULT_MODE = "CUSTOM";
14
- const DatePicker = ({
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ export { Data, Utils };
12
+ export default function DatePicker({
15
13
  stayDates = [],
16
14
  onSubmit,
17
- popup = true,
18
15
  close,
19
- hideModes,
20
16
  min,
21
17
  max,
22
- defaultMode = Data.MODES[DEFAULT_MODE],
23
- rules,
18
+ availabilities,
19
+ popup = true,
24
20
  singleDate,
25
21
  submitOnSelectionEnd,
26
- availabilities,
27
22
  disableConfirmModal
28
- }) => {
23
+ }) {
29
24
  const [display, setDisplay] = React.useState(Data.DISPLAYS.DESKTOP);
30
- const [specialRule, setSpecialRule] = React.useState();
31
25
  const {
32
- lang
33
- } = useUbloContext();
34
- const showModes = display !== Data.DISPLAYS.PHONE && !hideModes;
35
- const getDefaultMode = () => {
36
- if (!showModes) {
37
- return Data.MODES.CUSTOM;
38
- }
39
- if (stayDates.length === 0) {
40
- return defaultMode;
41
- }
42
- const firstDate = stayDates[0];
43
- const lastDate = stayDates[stayDates.length - 1];
44
- if (Utils.isSaturday(firstDate) && Utils.isSaturday(lastDate)) {
45
- return Data.MODES.SATURDAY;
46
- }
47
- if (Utils.isSunday(firstDate) && Utils.isSunday(lastDate)) {
48
- return Data.MODES.SUNDAY;
49
- }
50
- return Data.MODES.CUSTOM;
51
- };
52
- const [currentMode, setCurrentMode] = React.useState(getDefaultMode());
53
- const resized = React.useCallback(() => {
54
- if (window.innerWidth <= Data.BREAKPOINTS.PHONE) {
26
+ width: windowWidth
27
+ } = useWindowSizes();
28
+ React.useEffect(() => {
29
+ if (windowWidth <= Data.BREAKPOINTS.PHONE) {
55
30
  setDisplay(Data.DISPLAYS.PHONE);
56
31
  return;
57
32
  }
58
- if (window.innerWidth <= Data.BREAKPOINTS.TABLET) {
33
+ if (windowWidth <= Data.BREAKPOINTS.TABLET) {
59
34
  setDisplay(Data.DISPLAYS.TABLET);
60
35
  return;
61
- }
62
- setDisplay(Data.DISPLAYS.DESKTOP);
63
- }, []);
64
- React.useEffect(() => {
65
- resized();
66
- const isCompatible = typeof ResizeObserver !== "undefined";
67
- if (isCompatible) {
68
- const observer = new window.ResizeObserver(resized);
69
- observer.observe(document.body);
70
- return () => {
71
- observer.unobserve(document.body);
72
- };
73
36
  } else {
74
- window.addEventListener("resize", resized);
75
- return () => {
76
- window.removeEventListener("resize", resized);
77
- };
37
+ setDisplay(Data.DISPLAYS.DESKTOP);
78
38
  }
79
- }, [resized]);
39
+ }, [windowWidth]);
80
40
  const openInPopup = display !== Data.DISPLAYS.DESKTOP || popup;
81
41
  const classes = classNames(styles.datePicker, {
82
42
  [styles.datePickerPopup]: openInPopup
@@ -85,42 +45,20 @@ const DatePicker = ({
85
45
  children: [openInPopup && _jsx("div", {
86
46
  className: styles.backdrop,
87
47
  onClick: close
88
- }), _jsxs("div", {
48
+ }), _jsx("div", {
89
49
  className: classes,
90
- children: [showModes && _jsx(Modes, {
91
- currentMode: currentMode,
92
- setCurrentMode: setCurrentMode
93
- }), _jsx(Calendar, {
94
- mode: currentMode,
95
- setMode: setCurrentMode,
50
+ children: _jsx(Calendar, {
96
51
  display: display,
97
52
  stayDates: stayDates,
98
53
  min: min,
99
54
  max: max,
100
55
  onSubmit: onSubmit,
101
- rules: rules,
102
- specialRule: specialRule,
103
- setSpecialRule: setSpecialRule,
104
- hideModes: hideModes,
105
56
  singleDate: singleDate,
106
57
  submitOnSelectionEnd: submitOnSelectionEnd,
107
58
  availabilities: availabilities,
108
- disableConfirmModal: disableConfirmModal
109
- }), specialRule && _jsxs("div", {
110
- className: styles.specialRule,
111
- children: [_jsx(Icons.Info, {}), _jsxs("div", {
112
- className: styles.specialRuleText,
113
- children: [_jsx("div", {
114
- className: styles.specialRuleTitle,
115
- children: specialRule.title[lang]
116
- }), _jsx("div", {
117
- className: styles.specialRuleMessage,
118
- children: specialRule.message[lang]
119
- })]
120
- })]
121
- })]
59
+ disableConfirmModal: disableConfirmModal,
60
+ close: close
61
+ })
122
62
  })]
123
63
  });
124
- };
125
- export { Data, Utils };
126
- export default React.memo(DatePicker);
64
+ }
@@ -5,10 +5,11 @@ div.popup {
5
5
  .datePicker {
6
6
  position: relative;
7
7
  width: min-content;
8
+ max-width: 100%;
8
9
  display: grid;
9
10
  grid-template-columns: repeat(3, 1fr);
10
11
  background-color: var(--ds-grey-000, #fff);
11
- border-radius: var(--ds-radius-200, 10px);
12
+ border-radius: var(--ds-radius-400, 20px);
12
13
  box-shadow: var(--ds-shadow-300, 0 8px 30px rgba(0, 0, 0, 0.12));
13
14
  }
14
15
 
@@ -22,75 +23,6 @@ div.popup {
22
23
  var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
23
24
  }
24
25
 
25
- .specialRule {
26
- position: absolute;
27
- top: calc(100% + 50px);
28
- left: 0;
29
- width: 100%;
30
- display: flex;
31
- align-items: center;
32
- padding: 10px 20px;
33
- background-color: var(--ds-grey-100, #f5f5f5);
34
- border: 2px solid var(--ds-blue-400, #4177f6);
35
- border-radius: 6px;
36
- }
37
-
38
- @media (min-width: 650px) {
39
- .specialRule {
40
- top: calc(100% + 10px);
41
- max-width: calc(100% - 115px);
42
- }
43
- }
44
-
45
- .specialRule > svg {
46
- display: none;
47
- }
48
-
49
- @media (min-width: 650px) {
50
- .specialRule > svg {
51
- display: block;
52
- width: 20px;
53
- height: 20px;
54
- margin-right: 20px;
55
- fill: #000;
56
- }
57
- }
58
-
59
- .specialRuleTitle {
60
- color: var(--ds-grey-700, #232324);
61
- font-size: 13px;
62
- font-weight: 700;
63
- }
64
-
65
- @media (min-width: 480px) {
66
- .specialRuleTitle {
67
- font-size: 15px;
68
- }
69
- }
70
-
71
- @media (min-width: 1001px) {
72
- .specialRuleTitle {
73
- font-size: 17px;
74
- }
75
- }
76
-
77
- .specialRuleMessage {
78
- color: var(--ds-grey-700, #232324);
79
- font-size: 13px;
80
- }
81
-
82
- @media (min-width: 480px) {
83
- .specialRuleMessage {
84
- font-size: 15px;
85
- }
86
- }
87
-
88
- @media (min-width: 1001px) {
89
- .specialRuleMessage {
90
- font-size: 17px;
91
- }
92
- }
93
-
94
26
  .backdrop {
95
27
  position: fixed;
96
28
  top: 0;
@@ -1,39 +1,57 @@
1
1
  import * as React from "react";
2
2
  import classNames from "classnames";
3
+ import Loader from "dt-design-system/es/loader";
3
4
  import * as Messages from "./messages";
4
5
  import * as Utils from "./utils";
5
6
  import styles from "./helper.module.css";
6
7
  import { jsx as _jsx } from "react/jsx-runtime";
7
8
  import { jsxs as _jsxs } from "react/jsx-runtime";
8
- const Helper = ({
9
+ export default function Helper({
9
10
  lang,
10
11
  selecting,
11
- selectedDates
12
- }) => {
13
- const startClasses = classNames(styles.helperStep, {
14
- [styles.helperStepCurrent]: !selectedDates.length
15
- });
16
- const endClasses = classNames(styles.helperStep, {
17
- [styles.helperStepCurrent]: selecting && selectedDates.length
18
- });
12
+ selectedDates,
13
+ availabilities,
14
+ isLoading,
15
+ error
16
+ }) {
17
+ const enableAvailability = Boolean(availabilities);
19
18
  const firstDate = selectedDates[0] ? Utils.weekToLongDate(selectedDates[0]) : null;
20
19
  const lastDate = !selecting && selectedDates[selectedDates.length - 1] ? Utils.weekToLongDate(selectedDates[selectedDates.length - 1]) : null;
21
- return _jsx("div", {
20
+ const loadingClasses = classNames(styles.loading, {
21
+ [styles.loadingError]: error
22
+ });
23
+ const startClasses = classNames(styles.step, {
24
+ [styles.stepCurrent]: !selectedDates.length
25
+ });
26
+ const endClasses = classNames(styles.step, {
27
+ [styles.stepCurrent]: selecting && selectedDates.length
28
+ });
29
+ return _jsxs("div", {
22
30
  className: styles.helper,
23
- children: _jsxs("div", {
24
- className: styles.helperInner,
31
+ children: [_jsxs("div", {
32
+ className: styles.left,
33
+ children: [_jsx("div", {
34
+ className: styles.title,
35
+ children: Messages.get(lang, "helper-title")
36
+ }), enableAvailability && (isLoading || error) && _jsxs("div", {
37
+ className: loadingClasses,
38
+ children: [!error && _jsx(Loader, {
39
+ className: styles.loader
40
+ }), error || Messages.get(lang, "availability-loading")]
41
+ })]
42
+ }), _jsxs("div", {
43
+ className: styles.steps,
25
44
  children: [_jsxs("div", {
26
45
  className: startClasses,
27
46
  children: [Messages.get(lang, "helper-start-date"), " ", _jsx("span", {
28
- children: firstDate
47
+ children: firstDate || Messages.get(lang, "helper-placeholder")
29
48
  })]
30
49
  }), _jsxs("div", {
31
50
  className: endClasses,
32
51
  children: [Messages.get(lang, "helper-end-date"), " ", _jsx("span", {
33
- children: lastDate
52
+ children: lastDate || Messages.get(lang, "helper-placeholder")
34
53
  })]
35
54
  })]
36
- })
55
+ })]
37
56
  });
38
- };
39
- export default Helper;
57
+ }
@@ -1,81 +1,85 @@
1
1
  .helper {
2
- width: min-content;
3
- font-size: 16px;
4
- position: absolute;
5
- bottom: calc(100% + 6px);
6
- left: 50%;
7
2
  display: flex;
8
- align-items: center;
9
- padding: 8px 4px;
10
- background-color: #fff;
11
- box-shadow: var(--ds-shadow-200, 0 5px 10px rgba(0, 0, 0, 0.12));
12
- border-radius: var(--ds-radius-200, 10px);
13
- transform: translateX(-50%);
3
+ flex-direction: column;
4
+ gap: 8px;
5
+ margin-bottom: 16px;
14
6
  }
15
7
 
16
- @media (min-width: 480px) {
8
+ @media (min-width: 746px) {
17
9
  .helper {
18
- padding: 8px;
10
+ flex-direction: row;
19
11
  }
20
12
  }
21
13
 
22
- .helperInner {
23
- flex: 1 1 100%;
14
+ .left {
24
15
  display: flex;
16
+ flex-direction: column;
17
+ margin-right: 8px;
25
18
  }
26
19
 
27
- .helperStep {
28
- flex: 0 0 50%;
20
+ .loading {
29
21
  display: flex;
30
22
  align-items: center;
31
- justify-content: center;
32
- padding: 10px;
33
- color: var(--ds-grey-600, #383838);
34
- font-size: 14px;
35
- text-transform: uppercase;
36
- border-radius: var(--ds-radius-100, 3px);
37
- transition: background-color 160ms
38
- var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
23
+ gap: 5px;
24
+ margin-top: 4px;
25
+ font-size: 13px;
39
26
  }
40
27
 
41
- @media (min-width: 480px) {
42
- .helperStep {
43
- font-size: 15px;
44
- }
28
+ .loadingError {
29
+ color: var(--ds-red-400, #ee3535);
45
30
  }
46
31
 
47
- .helperStepCurrent {
48
- background-color: var(--ds-grey-200, #efefef);
32
+ .loader {
33
+ --ds-loader-spinner-size: 14px;
34
+ --ds-loader-thickness: 2px;
35
+
36
+ margin: 0;
49
37
  }
50
38
 
51
- .helperStep > span {
52
- width: 9ch;
53
- margin-left: 1ch;
54
- text-transform: none;
39
+ .title {
40
+ font-size: 20px;
55
41
  font-weight: 700;
56
- text-align: right;
42
+ color: var(--ds-grey-600, #383838);
57
43
  }
58
44
 
59
- .helperRemove {
60
- flex: 0 0 30px;
61
- min-width: 30px;
62
- height: 30px;
63
- margin-left: 1ch;
45
+ .steps {
46
+ width: fit-content;
64
47
  display: flex;
65
- align-items: center;
66
- justify-content: center;
67
- cursor: pointer;
68
- border-radius: 50%;
48
+ border: 1px solid var(--ds-grey-300, #d7d7d7);
49
+ border-radius: var(--ds-radius-200, 10px);
50
+ }
51
+
52
+ @media (min-width: 746px) {
53
+ .steps {
54
+ margin-left: auto;
55
+ }
56
+ }
57
+
58
+ .step {
59
+ display: flex;
60
+ flex-direction: column;
61
+ padding: 7px 16px;
62
+ color: var(--ds-grey-600, #383838);
63
+ font-size: 15px;
64
+ font-weight: 700;
65
+ border-radius: var(--ds-radius-200, 10px);
66
+ transition: background-color 160ms
67
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
68
+ }
69
+
70
+ .step:not(.stepCurrent):last-child {
71
+ border-left: 1px solid var(--ds-grey-200, #efefef);
72
+ border-top-left-radius: 0;
73
+ border-bottom-left-radius: 0;
69
74
  }
70
75
 
71
- .helperRemove:disabled {
72
- opacity: 0.5;
73
- filter: grayscale(100%);
74
- cursor: not-allowed;
76
+ .stepCurrent {
77
+ outline: 2px solid var(--ds-grey-600, #383838);
78
+ z-index: 1;
75
79
  }
76
80
 
77
- .helperRemove > svg {
78
- width: 18px;
79
- height: 18px;
80
- fill: var(--ds-grey-700, #232324);
81
+ .step > span {
82
+ width: auto;
83
+ max-width: 100%;
84
+ font-weight: 400;
81
85
  }
@@ -8,9 +8,17 @@ const locales = {
8
8
  "warning-date-change-text": "Si vous modifiez vos dates de séjour, le contenu de votre panier sera supprimé.",
9
9
  "warning-date-change-cancel": "Annuler",
10
10
  "warning-date-change-confirm": "J'ai compris",
11
+ "helper-title": "Sélectionnez les dates",
11
12
  "helper-start-date": "Arrivée",
12
13
  "helper-end-date": "Départ",
13
- submit: "Valider"
14
+ "helper-placeholder": "Ajoutez une date",
15
+ submit: "Valider",
16
+ reset: "Effacer les dates",
17
+ close: "Fermer",
18
+ "min-nights-singular": "nuit minimum",
19
+ "min-nights-plural": "nuits minimum",
20
+ "availability-loading": "Chargement des disponibilités...",
21
+ "availability-loading-error": "Erreur lors du chargement des disponibilités."
14
22
  },
15
23
  en: {
16
24
  "mode-book": "I'm staying",
@@ -21,9 +29,17 @@ const locales = {
21
29
  "warning-date-change-text": "If you proceed with this date change, the content of your cart will be removed.",
22
30
  "warning-date-change-cancel": "Cancel",
23
31
  "warning-date-change-confirm": "Understood",
32
+ "helper-title": "Select dates",
24
33
  "helper-start-date": "Begin",
25
34
  "helper-end-date": "End",
26
- submit: "Confirm"
35
+ "helper-placeholder": "Add a date",
36
+ submit: "Confirm",
37
+ reset: "Clear dates",
38
+ close: "Close",
39
+ "min-nights-singular": "minimum night",
40
+ "min-nights-plural": "minimum nights",
41
+ "availability-loading": "Loading availabilities...",
42
+ "availability-loading-error": "Error while loading availabilities."
27
43
  }
28
44
  };
29
45
  export const get = (lang, id) => {
@@ -1,14 +1,11 @@
1
1
  import * as React from "react";
2
- import classNames from "classnames";
3
2
  import { useUbloContext } from "ublo/with-ublo";
4
3
  import DateItem from "./date-item";
5
4
  import * as Data from "./data";
6
5
  import styles from "./month.module.css";
7
6
  import { jsxs as _jsxs } from "react/jsx-runtime";
8
7
  import { jsx as _jsx } from "react/jsx-runtime";
9
- const Month = ({
10
- mode,
11
- setMode,
8
+ export default function Month({
12
9
  display,
13
10
  month,
14
11
  year,
@@ -23,8 +20,10 @@ const Month = ({
23
20
  singleDate,
24
21
  submitOnSelectionEnd,
25
22
  onSubmit,
26
- stays
27
- }) => {
23
+ stays,
24
+ matchingStays,
25
+ allMatchingStaysEnd
26
+ }) {
28
27
  const {
29
28
  lang
30
29
  } = useUbloContext();
@@ -42,12 +41,9 @@ const Month = ({
42
41
  children: [monthName, " ", year]
43
42
  }), _jsx("div", {
44
43
  className: styles.days,
45
- children: days.map((day, i) => {
46
- const classes = classNames(styles.day, {
47
- [styles.dayActive]: mode === Data.MODES.SUNDAY && i === 6 || mode === Data.MODES.SATURDAY && i === 5
48
- });
44
+ children: days.map(day => {
49
45
  return _jsx("div", {
50
- className: classes,
46
+ className: styles.day,
51
47
  children: i18nWeekDays[day]
52
48
  }, day);
53
49
  })
@@ -66,17 +62,16 @@ const Month = ({
66
62
  setSelectedDates: setSelectedDates,
67
63
  setFirstSelectedDate: setFirstSelectedDate,
68
64
  setLastSelectedDate: setLastSelectedDate,
69
- mode: mode,
70
- setMode: setMode,
71
65
  selecting: selecting,
72
66
  setSelecting: setSelecting,
73
67
  singleDate: singleDate,
74
68
  submitOnSelectionEnd: submitOnSelectionEnd,
75
69
  onSubmit: onSubmit,
76
- stays: stays
70
+ stays: stays,
71
+ matchingStays: matchingStays,
72
+ allMatchingStaysEnd: allMatchingStaysEnd
77
73
  }, i);
78
74
  })
79
75
  })]
80
76
  });
81
- };
82
- export default React.memo(Month);
77
+ }