@megafon/ui-core 3.5.2 → 3.6.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,33 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.6.0](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@3.5.3...@megafon/ui-core@3.6.0) (2022-04-25)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **calendar:** fix go to start day after user choice ([8bbce10](https://github.com/MegafonWebLab/megafon-ui/commit/8bbce102d204f7ea7706158f3e6540c86ed3aada))
12
+
13
+
14
+ ### Features
15
+
16
+ * **tooltip:** added prop isPortal for tooltip ([e6f6d17](https://github.com/MegafonWebLab/megafon-ui/commit/e6f6d1749cd99f065c50bac4eb6a9b3592653f8d))
17
+
18
+
19
+
20
+
21
+
22
+ ## [3.5.3](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@3.5.2...@megafon/ui-core@3.5.3) (2022-04-18)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * **switcher:** fix safari bugs ([65274bc](https://github.com/MegafonWebLab/megafon-ui/commit/65274bc3c5e7385109afff94a8ff3f712c9af097))
28
+
29
+
30
+
31
+
32
+
6
33
  ## [3.5.2](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@3.5.1...@megafon/ui-core@3.5.2) (2022-04-13)
7
34
 
8
35
  **Note:** Version bump only for package @megafon/ui-core
@@ -20,7 +20,7 @@ var __rest = this && this.__rest || function (s, e) {
20
20
  return t;
21
21
  };
22
22
 
23
- import React, { useState, useEffect, useMemo } from 'react';
23
+ import React, { useState, useEffect, useMemo, useRef } from 'react';
24
24
  import { START_DATE, END_DATE, useDatepicker, useMonth } from '@datepicker-react/hooks';
25
25
  import { cnCreate, filterDataAttrs } from '@megafon/ui-helpers';
26
26
  import differenceInDays from 'date-fns/differenceInDays';
@@ -53,6 +53,17 @@ var dayLabelFormat = function dayLabelFormat(date) {
53
53
  var monthLabelFormat = function monthLabelFormat(date) {
54
54
  return formatDate(date, 'LLLL');
55
55
  };
56
+ /* List of cases to check on component change:
57
+
58
+ - Should correctly choose value and trigger callbacks with correct arguments on dates choose.
59
+ - Should set 1 day period if start and end date is equal
60
+ - Should correctly increase period if choose earlier start date
61
+ - Should correctly change start date of selected period if chosen date in period closer to current start date
62
+ - Should correctly change end date of selected period if chosen date in period closer to current end date
63
+ - Should correctly highlights period if start date chosen and hover on possible end date
64
+
65
+ */
66
+
56
67
 
57
68
  var cn = cnCreate('mfui-calendar');
58
69
 
@@ -91,6 +102,7 @@ var Calendar = function Calendar(_ref) {
91
102
  hoveredDate = _useState4[0],
92
103
  setHoveredDate = _useState4[1];
93
104
 
105
+ var isUserChoice = useRef(false);
94
106
  var stateStartDate = calendarState.startDate,
95
107
  stateEndDate = calendarState.endDate,
96
108
  stateFocusedInput = calendarState.focusedInput;
@@ -111,10 +123,13 @@ var Calendar = function Calendar(_ref) {
111
123
  goToDate = _a.goToDate,
112
124
  pickerProps = __rest(_a, ["firstDayOfWeek", "activeMonths", "goToPreviousMonths", "goToNextMonths", "goToDate"]);
113
125
 
126
+ useEffect(function () {
127
+ isUserChoice.current = false;
128
+ }, [startDate]);
114
129
  useEffect(function () {
115
130
  var propsStartDate = calendarStateFromProps.startDate;
116
131
  setCalendarState(calendarStateFromProps);
117
- propsStartDate && goToDate(propsStartDate); // eslint-disable-next-line react-hooks/exhaustive-deps
132
+ !isUserChoice.current && propsStartDate && goToDate(propsStartDate); // eslint-disable-next-line react-hooks/exhaustive-deps
118
133
  }, [calendarStateFromProps]);
119
134
 
120
135
  var getCalendarState = function getCalendarState(date) {
@@ -179,6 +194,7 @@ var Calendar = function Calendar(_ref) {
179
194
  var nextStartDate = nextState.startDate,
180
195
  nextEndDate = nextState.endDate;
181
196
  setCalendarState(nextState);
197
+ isUserChoice.current = true;
182
198
  onChange === null || onChange === void 0 ? void 0 : onChange(nextStartDate, nextEndDate);
183
199
  };
184
200
 
@@ -84,6 +84,9 @@
84
84
  border-radius: 15.5px;
85
85
  overflow: hidden;
86
86
  background-color: var(--spbSky1);
87
+ outline: none;
88
+ -webkit-transform: translateZ(0);
89
+ transform: translateZ(0);
87
90
  cursor: pointer;
88
91
  -webkit-transition: background-color 0.3s;
89
92
  transition: background-color 0.3s;
@@ -37,6 +37,8 @@ export interface ITooltipProps {
37
37
  targetElement?: React.RefObject<HTMLElement>;
38
38
  /** Управление состоянием. Компонент поддерживает контроллируемое и неконтроллируемое состояние. */
39
39
  isOpened?: boolean;
40
+ /** Отрендерить компонент в корневой элементе страницы body */
41
+ isPortal?: boolean;
40
42
  /** Дополнительный класс корневого элемента */
41
43
  className?: string;
42
44
  /** Дополнительные классы для внутренних элементов */
@@ -6,6 +6,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
6
6
  import React, { useState, useCallback, useEffect, useMemo } from 'react';
7
7
  import { cnCreate, detectTouch, checkNativeEventIsClickOrEnterPress, filterDataAttrs } from '@megafon/ui-helpers';
8
8
  import PropTypes from 'prop-types';
9
+ import ReactDOM from 'react-dom';
9
10
  import { usePopper } from 'react-popper';
10
11
  import Tile from "../Tile/Tile";
11
12
  import "./Tooltip.css";
@@ -45,6 +46,8 @@ var Tooltip = function Tooltip(_ref) {
45
46
  targetElement = _ref.targetElement,
46
47
  _ref$isOpened = _ref.isOpened,
47
48
  isOpened = _ref$isOpened === void 0 ? false : _ref$isOpened,
49
+ _ref$isPortal = _ref.isPortal,
50
+ isPortal = _ref$isPortal === void 0 ? false : _ref$isPortal,
48
51
  children = _ref.children,
49
52
  _ref$classes = _ref.classes;
50
53
  _ref$classes = _ref$classes === void 0 ? {} : _ref$classes;
@@ -58,6 +61,7 @@ var Tooltip = function Tooltip(_ref) {
58
61
  var currentTrigger = triggerElement.current;
59
62
  var currentTarget = (targetElement === null || targetElement === void 0 ? void 0 : targetElement.current) || currentTrigger;
60
63
  var currentBoundary = boundaryElement === null || boundaryElement === void 0 ? void 0 : boundaryElement.current;
64
+ var portalElem = React.useRef(null);
61
65
 
62
66
  var _useState = useState(null),
63
67
  _useState2 = _slicedToArray(_useState, 2),
@@ -215,7 +219,16 @@ var Tooltip = function Tooltip(_ref) {
215
219
 
216
220
  return undefined;
217
221
  }, [triggerEventName, isOpen, currentTrigger, handleOutsideEvent, handleClick, clickEvent]);
218
- return /*#__PURE__*/React.createElement("div", _extends({}, filterDataAttrs(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
222
+ useEffect(function () {
223
+ return function () {
224
+ if (portalElem.current) {
225
+ document.body.removeChild(portalElem.current);
226
+ }
227
+
228
+ portalElem.current = null;
229
+ };
230
+ }, []);
231
+ var template = /*#__PURE__*/React.createElement("div", _extends({}, filterDataAttrs(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
219
232
  className: cn({
220
233
  paddings: paddings,
221
234
  open: isOpen
@@ -238,6 +251,18 @@ var Tooltip = function Tooltip(_ref) {
238
251
  shadowLevel: "high",
239
252
  className: cn('content-shadow', [contentShadowClassName])
240
253
  }));
254
+ /* Не в эффекте, чтобы не создавать лишний перерендер компонента. Из-за синхронности кода в return уже будет элемент */
255
+
256
+ if (isPortal && !portalElem.current && typeof window !== 'undefined') {
257
+ portalElem.current = document.createElement('div');
258
+ document.body.appendChild(portalElem.current);
259
+ }
260
+
261
+ if (isPortal && portalElem.current) {
262
+ return portalElem.current ? ReactDOM.createPortal(template, portalElem.current) : null;
263
+ }
264
+
265
+ return template;
241
266
  };
242
267
 
243
268
  Tooltip.propTypes = {
@@ -268,6 +293,7 @@ Tooltip.propTypes = {
268
293
  current: PropTypes.elementType
269
294
  }), PropTypes.any])]),
270
295
  isOpened: PropTypes.bool,
296
+ isPortal: PropTypes.bool,
271
297
  className: PropTypes.string,
272
298
  classes: PropTypes.shape({
273
299
  root: PropTypes.string,
@@ -86,6 +86,17 @@ var dayLabelFormat = function dayLabelFormat(date) {
86
86
  var monthLabelFormat = function monthLabelFormat(date) {
87
87
  return formatDate(date, 'LLLL');
88
88
  };
89
+ /* List of cases to check on component change:
90
+
91
+ - Should correctly choose value and trigger callbacks with correct arguments on dates choose.
92
+ - Should set 1 day period if start and end date is equal
93
+ - Should correctly increase period if choose earlier start date
94
+ - Should correctly change start date of selected period if chosen date in period closer to current start date
95
+ - Should correctly change end date of selected period if chosen date in period closer to current end date
96
+ - Should correctly highlights period if start date chosen and hover on possible end date
97
+
98
+ */
99
+
89
100
 
90
101
  var cn = (0, _uiHelpers.cnCreate)('mfui-calendar');
91
102
 
@@ -124,6 +135,7 @@ var Calendar = function Calendar(_ref) {
124
135
  hoveredDate = _useState4[0],
125
136
  setHoveredDate = _useState4[1];
126
137
 
138
+ var isUserChoice = (0, _react.useRef)(false);
127
139
  var stateStartDate = calendarState.startDate,
128
140
  stateEndDate = calendarState.endDate,
129
141
  stateFocusedInput = calendarState.focusedInput;
@@ -144,10 +156,13 @@ var Calendar = function Calendar(_ref) {
144
156
  goToDate = _a.goToDate,
145
157
  pickerProps = __rest(_a, ["firstDayOfWeek", "activeMonths", "goToPreviousMonths", "goToNextMonths", "goToDate"]);
146
158
 
159
+ (0, _react.useEffect)(function () {
160
+ isUserChoice.current = false;
161
+ }, [startDate]);
147
162
  (0, _react.useEffect)(function () {
148
163
  var propsStartDate = calendarStateFromProps.startDate;
149
164
  setCalendarState(calendarStateFromProps);
150
- propsStartDate && goToDate(propsStartDate); // eslint-disable-next-line react-hooks/exhaustive-deps
165
+ !isUserChoice.current && propsStartDate && goToDate(propsStartDate); // eslint-disable-next-line react-hooks/exhaustive-deps
151
166
  }, [calendarStateFromProps]);
152
167
 
153
168
  var getCalendarState = function getCalendarState(date) {
@@ -212,6 +227,7 @@ var Calendar = function Calendar(_ref) {
212
227
  var nextStartDate = nextState.startDate,
213
228
  nextEndDate = nextState.endDate;
214
229
  setCalendarState(nextState);
230
+ isUserChoice.current = true;
215
231
  onChange === null || onChange === void 0 ? void 0 : onChange(nextStartDate, nextEndDate);
216
232
  };
217
233
 
@@ -84,6 +84,9 @@
84
84
  border-radius: 15.5px;
85
85
  overflow: hidden;
86
86
  background-color: var(--spbSky1);
87
+ outline: none;
88
+ -webkit-transform: translateZ(0);
89
+ transform: translateZ(0);
87
90
  cursor: pointer;
88
91
  -webkit-transition: background-color 0.3s;
89
92
  transition: background-color 0.3s;
@@ -37,6 +37,8 @@ export interface ITooltipProps {
37
37
  targetElement?: React.RefObject<HTMLElement>;
38
38
  /** Управление состоянием. Компонент поддерживает контроллируемое и неконтроллируемое состояние. */
39
39
  isOpened?: boolean;
40
+ /** Отрендерить компонент в корневой элементе страницы body */
41
+ isPortal?: boolean;
40
42
  /** Дополнительный класс корневого элемента */
41
43
  className?: string;
42
44
  /** Дополнительные классы для внутренних элементов */
@@ -23,6 +23,8 @@ var _uiHelpers = require("@megafon/ui-helpers");
23
23
 
24
24
  var _propTypes = _interopRequireDefault(require("prop-types"));
25
25
 
26
+ var _reactDom = _interopRequireDefault(require("react-dom"));
27
+
26
28
  var _reactPopper = require("react-popper");
27
29
 
28
30
  var _Tile = _interopRequireDefault(require("../Tile/Tile"));
@@ -72,6 +74,8 @@ var Tooltip = function Tooltip(_ref) {
72
74
  targetElement = _ref.targetElement,
73
75
  _ref$isOpened = _ref.isOpened,
74
76
  isOpened = _ref$isOpened === void 0 ? false : _ref$isOpened,
77
+ _ref$isPortal = _ref.isPortal,
78
+ isPortal = _ref$isPortal === void 0 ? false : _ref$isPortal,
75
79
  children = _ref.children,
76
80
  _ref$classes = _ref.classes;
77
81
  _ref$classes = _ref$classes === void 0 ? {} : _ref$classes;
@@ -86,6 +90,8 @@ var Tooltip = function Tooltip(_ref) {
86
90
  var currentTarget = (targetElement === null || targetElement === void 0 ? void 0 : targetElement.current) || currentTrigger;
87
91
  var currentBoundary = boundaryElement === null || boundaryElement === void 0 ? void 0 : boundaryElement.current;
88
92
 
93
+ var portalElem = _react["default"].useRef(null);
94
+
89
95
  var _useState = (0, _react.useState)(null),
90
96
  _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
91
97
  popperElement = _useState2[0],
@@ -242,7 +248,17 @@ var Tooltip = function Tooltip(_ref) {
242
248
 
243
249
  return undefined;
244
250
  }, [triggerEventName, isOpen, currentTrigger, handleOutsideEvent, handleClick, clickEvent]);
245
- return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
251
+ (0, _react.useEffect)(function () {
252
+ return function () {
253
+ if (portalElem.current) {
254
+ document.body.removeChild(portalElem.current);
255
+ }
256
+
257
+ portalElem.current = null;
258
+ };
259
+ }, []);
260
+
261
+ var template = /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
246
262
  className: cn({
247
263
  paddings: paddings,
248
264
  open: isOpen
@@ -265,6 +281,19 @@ var Tooltip = function Tooltip(_ref) {
265
281
  shadowLevel: "high",
266
282
  className: cn('content-shadow', [contentShadowClassName])
267
283
  }));
284
+ /* Не в эффекте, чтобы не создавать лишний перерендер компонента. Из-за синхронности кода в return уже будет элемент */
285
+
286
+
287
+ if (isPortal && !portalElem.current && typeof window !== 'undefined') {
288
+ portalElem.current = document.createElement('div');
289
+ document.body.appendChild(portalElem.current);
290
+ }
291
+
292
+ if (isPortal && portalElem.current) {
293
+ return portalElem.current ? _reactDom["default"].createPortal(template, portalElem.current) : null;
294
+ }
295
+
296
+ return template;
268
297
  };
269
298
 
270
299
  Tooltip.propTypes = {
@@ -295,6 +324,7 @@ Tooltip.propTypes = {
295
324
  current: _propTypes["default"].elementType
296
325
  }), _propTypes["default"].any])]),
297
326
  isOpened: _propTypes["default"].bool,
327
+ isPortal: _propTypes["default"].bool,
298
328
  className: _propTypes["default"].string,
299
329
  classes: _propTypes["default"].shape({
300
330
  root: _propTypes["default"].string,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@megafon/ui-core",
3
- "version": "3.5.2",
3
+ "version": "3.6.0",
4
4
  "files": [
5
5
  "dist",
6
6
  "styles"
@@ -97,5 +97,5 @@
97
97
  "react-popper": "^2.2.3",
98
98
  "swiper": "^6.5.6"
99
99
  },
100
- "gitHead": "96b6862cd6294fa5fb9d630b2194a1dd74d969fe"
100
+ "gitHead": "87e4483070e37f017a90358648860a5f4139bae1"
101
101
  }