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
@@ -0,0 +1,59 @@
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 * as Icons from "dt-design-system/es/icons";
6
+ import * as Messages from "./messages";
7
+ import * as Motions from "./services/motions";
8
+ import css from "./warning.module.css";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+
12
+ const Warning = ({
13
+ warn,
14
+ setWarn,
15
+ selectWeek,
16
+ chosenWeek
17
+ }) => {
18
+ const {
19
+ lang
20
+ } = useUbloContext();
21
+
22
+ const cancel = () => {
23
+ setWarn(false);
24
+ };
25
+
26
+ const confirm = () => {
27
+ selectWeek(chosenWeek, true);
28
+ };
29
+
30
+ return _jsx(AnimatePresence, {
31
+ mode: "wait",
32
+ children: warn && _jsxs(motion.div, {
33
+ className: css.warn,
34
+ initial: "hidden",
35
+ animate: "visible",
36
+ exit: "hidden",
37
+ variants: Motions.fading,
38
+ children: [_jsxs("div", {
39
+ className: css.text,
40
+ children: [_jsx(Icons.AlertCircle, {
41
+ className: css.icon
42
+ }), Messages.get(lang, "warn")]
43
+ }), _jsxs("div", {
44
+ className: css.buttons,
45
+ children: [_jsx(Button, {
46
+ className: css.cancelButton,
47
+ onClick: cancel,
48
+ children: Messages.get(lang, "cancel")
49
+ }), _jsx(Button, {
50
+ className: css.button,
51
+ onClick: confirm,
52
+ children: Messages.get(lang, "ok")
53
+ })]
54
+ })]
55
+ })
56
+ });
57
+ };
58
+
59
+ export default Warning;
@@ -0,0 +1,53 @@
1
+ .warn {
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
+ align-items: center;
11
+ gap: 16px;
12
+ padding: 10px;
13
+ background-color: var(--ds-grey-000, #ffffff);
14
+ z-index: 1;
15
+ }
16
+
17
+ .text {
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 8px;
21
+ padding: 12px;
22
+ color: var(--ds-grey-700, #171e30);
23
+ font-size: 17px;
24
+ font-weight: 700;
25
+ background-color: var(--ds-grey-100, #f5f5f5);
26
+ border-radius: var(--ds-radius-200, 10px);
27
+ }
28
+
29
+ .icon {
30
+ width: 22px;
31
+ height: 22px;
32
+ fill: currentColor;
33
+ }
34
+
35
+ .buttons {
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ gap: 8px;
40
+ }
41
+
42
+ .cancelButton {
43
+ color: var(--ds-grey-700, #171e30);
44
+ background-color: var(--ds-grey-000, #ffffff);
45
+ }
46
+
47
+ .cancelButton:not(:disabled):hover {
48
+ background-color: var(--ds-grey-100, #f5f5f5);
49
+ }
50
+
51
+ .button:nth-child(2) {
52
+ background-color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
53
+ }
@@ -0,0 +1,120 @@
1
+ import * as React from "react";
2
+ import classnames from "classnames";
3
+ import { LayoutGroup, motion } from "framer-motion";
4
+ import { useUbloContext } from "ublo/with-ublo";
5
+ import * as Icons from "dt-design-system/es/icons";
6
+ import css from "./weeks.module.css";
7
+ import * as Dates from "./services/dates";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+
11
+ const Week = ({
12
+ week,
13
+ beginWeek,
14
+ endWeek,
15
+ selected,
16
+ select,
17
+ forceSeasonSwitch,
18
+ openExtendedPicker,
19
+ isPopup
20
+ }) => {
21
+ const {
22
+ lang
23
+ } = useUbloContext();
24
+ const [checkVisible, setCheckVisible] = React.useState(false);
25
+ const [checkTimeout, setCheckTimeout] = React.useState();
26
+ const now = new Date();
27
+ const prevDate = Dates.weekToDate(week - 1, endWeek, forceSeasonSwitch);
28
+ const currDate = Dates.weekToDate(week, endWeek, forceSeasonSwitch);
29
+ const nextDate = Dates.weekToDate(week + 1, endWeek, forceSeasonSwitch);
30
+ const isSelected = selected === week;
31
+ const isPast = now.getTime() > nextDate.getTime();
32
+ const isFirst = week === beginWeek;
33
+ const isLast = week === endWeek;
34
+ const prevYear = prevDate.getFullYear();
35
+ const currYear = currDate.getFullYear();
36
+ const hasYearChanged = prevYear !== currYear;
37
+ const showYear = isFirst || hasYearChanged;
38
+ const prevMonth = prevDate.getMonth();
39
+ const currMonth = currDate.getMonth();
40
+ const hasMonthChanged = prevMonth !== currMonth;
41
+ const showMonth = isFirst || hasMonthChanged;
42
+ const locale = Dates.locales[lang] || Dates.locales.en;
43
+ const formatedMonth = currDate.toLocaleString(locale, {
44
+ month: "short"
45
+ });
46
+ const weekClasses = classnames(css.item, {
47
+ [css.itemSelected]: isSelected,
48
+ [css.itemPast]: isPast
49
+ });
50
+
51
+ const selectWeek = () => {
52
+ select(week);
53
+ openExtendedPicker();
54
+ clearTimeout(checkTimeout);
55
+ setCheckVisible(true);
56
+ setCheckTimeout(setTimeout(() => {
57
+ setCheckVisible(false);
58
+ }, 1200));
59
+ };
60
+
61
+ const layoutId = isPopup ? "current-popup" : "current";
62
+ return _jsxs("div", {
63
+ className: weekClasses,
64
+ children: [_jsxs("button", {
65
+ className: css.button,
66
+ onClick: selectWeek,
67
+ "aria-label": `${Dates.weekToLongDate(week)} - ${Dates.weekToLongDate(week + 1)}`,
68
+ disabled: isPast,
69
+ children: [isSelected && _jsx(motion.div, {
70
+ layoutId: layoutId,
71
+ className: css.buttonFiller
72
+ }), checkVisible && _jsx(Icons.CheckCircle, {
73
+ className: css.check
74
+ })]
75
+ }), _jsxs("div", {
76
+ className: css.date,
77
+ children: [_jsx("div", {
78
+ className: css.dateFrom,
79
+ children: Dates.formatShort(currDate)
80
+ }), isLast && _jsx("div", {
81
+ className: css.dateTo,
82
+ children: Dates.formatShort(nextDate)
83
+ })]
84
+ }), showMonth && _jsxs("span", {
85
+ className: css.month,
86
+ children: [formatedMonth, " ", showYear && _jsx("b", {
87
+ className: css.year,
88
+ children: currYear
89
+ })]
90
+ })]
91
+ });
92
+ };
93
+
94
+ const Weeks = React.forwardRef(({
95
+ weeks,
96
+ ...props
97
+ }, ref) => {
98
+ React.useEffect(() => {
99
+ const bar = ref.current;
100
+ if (props.selected === undefined || !bar) return;
101
+ const selectedItem = bar.querySelector(`.${css.itemSelected}`);
102
+ if (!selectedItem) return;
103
+ const {
104
+ clientWidth,
105
+ offsetLeft
106
+ } = selectedItem;
107
+ bar.scrollLeft = offsetLeft - clientWidth * 1.5;
108
+ }, [props.selected, ref]);
109
+ return _jsx(LayoutGroup, {
110
+ children: _jsx("div", {
111
+ ref: ref,
112
+ className: css.weeks,
113
+ children: weeks.map(week => _jsx(Week, {
114
+ week: week,
115
+ ...props
116
+ }, week))
117
+ })
118
+ });
119
+ });
120
+ export default Weeks;
@@ -0,0 +1,194 @@
1
+ .weeks {
2
+ --gap: 2px;
3
+ --item-height: 36px;
4
+ --item-width: 50px;
5
+
6
+ position: relative;
7
+ width: 100%;
8
+ display: inline-flex;
9
+ align-items: flex-start;
10
+ gap: 2px;
11
+ margin: 0 auto;
12
+ padding: 0 26px 10px 26px;
13
+ overflow: auto;
14
+ scroll-behavior: smooth;
15
+ }
16
+
17
+ @media (min-width: 1100px) {
18
+ .weeks {
19
+ --item-width: 40px;
20
+ --item-height: 20px;
21
+
22
+ padding: 0 26px;
23
+ overflow: visible;
24
+ }
25
+ }
26
+
27
+ .weeks::before {
28
+ content: "";
29
+ position: absolute;
30
+ top: 0;
31
+ left: 0;
32
+ width: 100%;
33
+ height: var(--item-height);
34
+ background-color: var(--ds-grey-100, #f5f5f5);
35
+ pointer-events: none;
36
+ touch-action: none;
37
+ z-index: 0;
38
+ }
39
+
40
+ .item {
41
+ --button-bg-color: var(--ds-grey-400, #d2d2d2);
42
+
43
+ position: relative;
44
+ flex: 0 0 var(--item-width);
45
+ min-width: var(--item-width);
46
+ display: flex;
47
+ flex-direction: column;
48
+ }
49
+
50
+ .itemPast {
51
+ --button-bg-color: var(--ds-grey-200, #efefef);
52
+
53
+ cursor: not-allowed;
54
+ }
55
+
56
+ .item:first-of-type {
57
+ margin-left: auto;
58
+ }
59
+
60
+ .item:last-of-type {
61
+ margin-right: auto;
62
+ }
63
+
64
+ .item:first-of-type::before,
65
+ .item:last-of-type::after {
66
+ content: "";
67
+ position: absolute;
68
+ top: 0;
69
+ width: calc(var(--item-width) * 2);
70
+ height: var(--item-height);
71
+ background-color: var(--button-bg-color);
72
+ z-index: 0;
73
+ transition: background-color 160ms
74
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
75
+ }
76
+
77
+ .item:first-of-type::before {
78
+ right: calc(100% + var(--gap));
79
+ border-radius: var(--item-height) 0 0 var(--item-height);
80
+ }
81
+
82
+ .item:last-of-type::after {
83
+ left: calc(100% + var(--gap));
84
+ border-radius: 0 var(--item-height) var(--item-height) 0;
85
+ }
86
+
87
+ .itemSelected {
88
+ z-index: 1;
89
+ }
90
+
91
+ .button {
92
+ position: relative;
93
+ width: 100%;
94
+ height: var(--item-height);
95
+ background-color: var(--button-bg-color);
96
+ border-radius: inherit;
97
+ cursor: pointer;
98
+ user-select: none;
99
+ transition: background-color 160ms
100
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
101
+ }
102
+
103
+ .button:disabled {
104
+ cursor: not-allowed;
105
+ }
106
+
107
+ .button:not(:disabled):hover {
108
+ background-color: var(--ds-grey-500, #484848);
109
+ }
110
+
111
+ .buttonFiller {
112
+ position: relative;
113
+ width: calc(100% + var(--gap) * 2);
114
+ height: 100%;
115
+ margin-left: calc(0px - var(--gap));
116
+ background-color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
117
+ pointer-events: none;
118
+ touch-action: none;
119
+ z-index: 1;
120
+ }
121
+
122
+ .buttonFiller::before {
123
+ --border-width: 8px;
124
+
125
+ content: "";
126
+ position: absolute;
127
+ width: calc(100% + var(--border-width) * 2);
128
+ height: 100%;
129
+ left: calc(0px - var(--border-width));
130
+ background-color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
131
+ opacity: 0.5;
132
+ }
133
+
134
+ .check {
135
+ --size: 16px;
136
+ --opacity: 0.75;
137
+
138
+ position: absolute;
139
+ top: calc(50% - calc(var(--size) / 2));
140
+ left: calc(50% - calc(var(--size) / 2));
141
+ width: var(--size);
142
+ height: var(--size);
143
+ fill: var(--ds-grey-000, #ffffff);
144
+ z-index: 1;
145
+ opacity: var(--opacity);
146
+ animation: week-check-appearance 640ms
147
+ var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1));
148
+ }
149
+
150
+ @keyframes week-check-appearance {
151
+ 0%,
152
+ 50% {
153
+ opacity: 0;
154
+ transform: scale(0);
155
+ }
156
+ 90% {
157
+ opacity: var(--opacity);
158
+ transform: scale(1.1);
159
+ }
160
+ 100% {
161
+ opacity: var(--opacity);
162
+ transform: none;
163
+ }
164
+ }
165
+
166
+ .date {
167
+ width: 100%;
168
+ height: 100%;
169
+ display: flex;
170
+ justify-content: space-between;
171
+ margin-top: 6px;
172
+ font-size: 13px;
173
+ text-align: center;
174
+ color: var(--ds-grey-700, #171e30);
175
+ pointer-events: none;
176
+ touch-action: none;
177
+ user-select: none;
178
+ transform: translateX(calc(0px - (var(--item-width)) / 5));
179
+ }
180
+
181
+ .dateFrom,
182
+ .dateTo {
183
+ width: 0;
184
+ }
185
+
186
+ .month {
187
+ width: 0;
188
+ display: flex;
189
+ flex-direction: column;
190
+ margin-top: 6px;
191
+ font-size: 11px;
192
+ text-transform: uppercase;
193
+ transform: translateX(calc(0px - (var(--item-width)) / 5));
194
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ublo-lib",
3
- "version": "1.2.4",
3
+ "version": "1.3.0",
4
4
  "peerDependencies": {
5
5
  "dt-design-system": "^2.1.0",
6
6
  "next": "^12.0.0",