@megafon/ui-core 3.0.0-beta.8 → 3.0.2

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 (87) hide show
  1. package/CHANGELOG.md +59 -85
  2. package/README.md +2 -2
  3. package/dist/es/colors/Colors.d.ts +2 -2
  4. package/dist/es/colors/colorsData.js +1 -1
  5. package/dist/es/components/Accordion/Accordion.js +1 -1
  6. package/dist/es/components/Banner/Banner.css +28 -0
  7. package/dist/es/components/Banner/Banner.d.ts +2 -0
  8. package/dist/es/components/Banner/Banner.js +15 -10
  9. package/dist/es/components/Button/Button.css +3 -3
  10. package/dist/es/components/Button/Button.js +3 -3
  11. package/dist/es/components/Calendar/Calendar.js +3 -2
  12. package/dist/es/components/Calendar/components/Day/Day.js +1 -1
  13. package/dist/es/components/Carousel/Carousel.js +17 -14
  14. package/dist/es/components/Checkbox/Checkbox.js +1 -1
  15. package/dist/es/components/Counter/Counter.js +3 -3
  16. package/dist/es/components/Link/Link.d.ts +1 -1
  17. package/dist/es/components/Link/Link.js +19 -27
  18. package/dist/es/components/Logo/Logo.js +1 -1
  19. package/dist/es/components/NavArrow/NavArrow.css +1 -1
  20. package/dist/es/components/Notification/Notification.css +34 -25
  21. package/dist/es/components/Notification/Notification.js +4 -2
  22. package/dist/es/components/Pagination/components/PaginationButton/PaginationButton.js +1 -1
  23. package/dist/es/components/Pagination/helpers.d.ts +1 -1
  24. package/dist/es/components/Paragraph/Paragraph.css +0 -9
  25. package/dist/es/components/Paragraph/Paragraph.d.ts +0 -3
  26. package/dist/es/components/Paragraph/Paragraph.js +1 -4
  27. package/dist/es/components/RadioButton/RadioButton.js +1 -1
  28. package/dist/es/components/Search/Search.js +4 -3
  29. package/dist/es/components/Select/Select.css +5 -2
  30. package/dist/es/components/Select/Select.d.ts +5 -45
  31. package/dist/es/components/Select/Select.js +364 -467
  32. package/dist/es/components/Select/reducer/selectReducer.d.ts +34 -0
  33. package/dist/es/components/Select/reducer/selectReducer.js +123 -0
  34. package/dist/es/components/Switcher/Switcher.css +19 -15
  35. package/dist/es/components/Switcher/Switcher.js +1 -1
  36. package/dist/es/components/Tabs/Tabs.d.ts +2 -0
  37. package/dist/es/components/Tabs/Tabs.js +94 -49
  38. package/dist/es/components/TextField/TextField.d.ts +3 -1
  39. package/dist/es/components/TextField/TextField.js +14 -10
  40. package/dist/es/components/Tile/Tile.js +4 -2
  41. package/dist/es/components/Tooltip/Tooltip.js +17 -17
  42. package/dist/es/index.d.ts +1 -0
  43. package/dist/es/index.js +1 -0
  44. package/dist/lib/colors/Colors.d.ts +2 -2
  45. package/dist/lib/colors/colorsData.js +1 -1
  46. package/dist/lib/components/Accordion/Accordion.js +1 -1
  47. package/dist/lib/components/Banner/Banner.css +28 -0
  48. package/dist/lib/components/Banner/Banner.d.ts +2 -0
  49. package/dist/lib/components/Banner/Banner.js +15 -10
  50. package/dist/lib/components/Button/Button.css +3 -3
  51. package/dist/lib/components/Button/Button.js +3 -3
  52. package/dist/lib/components/Calendar/Calendar.js +3 -3
  53. package/dist/lib/components/Calendar/components/Day/Day.js +1 -1
  54. package/dist/lib/components/Carousel/Carousel.js +15 -12
  55. package/dist/lib/components/Checkbox/Checkbox.js +1 -1
  56. package/dist/lib/components/Counter/Counter.js +3 -3
  57. package/dist/lib/components/Link/Link.d.ts +1 -1
  58. package/dist/lib/components/Link/Link.js +28 -43
  59. package/dist/lib/components/Logo/Logo.js +1 -1
  60. package/dist/lib/components/NavArrow/NavArrow.css +1 -1
  61. package/dist/lib/components/Notification/Notification.css +34 -25
  62. package/dist/lib/components/Notification/Notification.js +4 -2
  63. package/dist/lib/components/Pagination/components/PaginationButton/PaginationButton.js +1 -1
  64. package/dist/lib/components/Pagination/helpers.d.ts +1 -1
  65. package/dist/lib/components/Paragraph/Paragraph.css +0 -9
  66. package/dist/lib/components/Paragraph/Paragraph.d.ts +0 -3
  67. package/dist/lib/components/Paragraph/Paragraph.js +1 -4
  68. package/dist/lib/components/RadioButton/RadioButton.js +1 -1
  69. package/dist/lib/components/Search/Search.js +4 -3
  70. package/dist/lib/components/Select/Select.css +5 -2
  71. package/dist/lib/components/Select/Select.d.ts +5 -45
  72. package/dist/lib/components/Select/Select.js +358 -490
  73. package/dist/lib/components/Select/reducer/selectReducer.d.ts +34 -0
  74. package/dist/lib/components/Select/reducer/selectReducer.js +136 -0
  75. package/dist/lib/components/Switcher/Switcher.css +19 -15
  76. package/dist/lib/components/Switcher/Switcher.js +1 -1
  77. package/dist/lib/components/Tabs/Tabs.d.ts +2 -0
  78. package/dist/lib/components/Tabs/Tabs.js +94 -49
  79. package/dist/lib/components/TextField/TextField.d.ts +3 -1
  80. package/dist/lib/components/TextField/TextField.js +14 -10
  81. package/dist/lib/components/Tile/Tile.js +4 -2
  82. package/dist/lib/components/Tooltip/Tooltip.js +17 -17
  83. package/dist/lib/index.d.ts +1 -0
  84. package/dist/lib/index.js +8 -0
  85. package/package.json +4 -4
  86. package/styles/colors.css +2 -2
  87. package/styles/colorsDark.css +1 -1
@@ -9,8 +9,6 @@ exports["default"] = exports.SelectTypes = exports.Verification = void 0;
9
9
 
10
10
  require("core-js/modules/es.array.concat");
11
11
 
12
- require("core-js/modules/es.array.every");
13
-
14
12
  require("core-js/modules/es.array.filter");
15
13
 
16
14
  require("core-js/modules/es.array.find");
@@ -19,14 +17,8 @@ require("core-js/modules/es.array.find-index");
19
17
 
20
18
  require("core-js/modules/es.array.map");
21
19
 
22
- require("core-js/modules/es.date.to-string");
23
-
24
- require("core-js/modules/es.object.to-string");
25
-
26
20
  require("core-js/modules/es.object.values");
27
21
 
28
- require("core-js/modules/es.reflect.construct");
29
-
30
22
  require("core-js/modules/es.regexp.constructor");
31
23
 
32
24
  require("core-js/modules/es.regexp.exec");
@@ -37,17 +29,11 @@ require("core-js/modules/es.string.replace");
37
29
 
38
30
  require("core-js/modules/es.string.split");
39
31
 
40
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
32
+ require("core-js/modules/es.string.trim");
41
33
 
42
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
43
-
44
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
45
-
46
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
47
-
48
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
34
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
49
35
 
50
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
36
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
51
37
 
52
38
  var React = _interopRequireWildcard(require("react"));
53
39
 
@@ -59,41 +45,21 @@ var PropTypes = _interopRequireWildcard(require("prop-types"));
59
45
 
60
46
  var _InputLabel = _interopRequireDefault(require("../InputLabel/InputLabel"));
61
47
 
48
+ var _selectReducer = _interopRequireWildcard(require("./reducer/selectReducer"));
49
+
62
50
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
63
51
 
64
52
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
65
53
 
66
54
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
67
55
 
68
- function _createSuper(Derived) {
69
- return function () {
70
- var Super = (0, _getPrototypeOf2["default"])(Derived),
71
- result;
72
-
73
- if (_isNativeReflectConstruct()) {
74
- var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor;
75
- result = Reflect.construct(Super, arguments, NewTarget);
76
- } else {
77
- result = Super.apply(this, arguments);
78
- }
79
-
80
- return (0, _possibleConstructorReturn2["default"])(this, result);
81
- };
82
- }
83
-
84
- function _isNativeReflectConstruct() {
85
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
86
- if (Reflect.construct.sham) return false;
87
- if (typeof Proxy === "function") return true;
88
-
89
- try {
90
- Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
91
- return true;
92
- } catch (e) {
93
- return false;
94
- }
95
- }
96
-
56
+ var UPDATE_ITEMS_LIST = _selectReducer.SelectActions.UPDATE_ITEMS_LIST,
57
+ UPDATE_VALUE_FROM_PROPS = _selectReducer.SelectActions.UPDATE_VALUE_FROM_PROPS,
58
+ COMBOBOX_VALUE_DEBOUNCE = _selectReducer.SelectActions.COMBOBOX_VALUE_DEBOUNCE,
59
+ COMBOBOX_INPUT_CHANGE = _selectReducer.SelectActions.COMBOBOX_INPUT_CHANGE,
60
+ TOGGLE_DROPDOWN = _selectReducer.SelectActions.TOGGLE_DROPDOWN,
61
+ UPDATE_SELECT_VALUE = _selectReducer.SelectActions.UPDATE_SELECT_VALUE,
62
+ SET_HOVERED_ITEM_INDEX = _selectReducer.SelectActions.SET_HOVERED_ITEM_INDEX;
97
63
  var Verification = {
98
64
  VALID: 'valid',
99
65
  ERROR: 'error'
@@ -102,498 +68,406 @@ exports.Verification = Verification;
102
68
  var SelectTypes = {
103
69
  CLASSIC: 'classic',
104
70
  COMBOBOX: 'combobox'
105
- };
71
+ }; // List of cases to check on component change:
72
+ // - Should correctly choose value and trigger callbacks with correct arguments on click or touch.
73
+ // - Should correctly choose value and trigger callbacks with correct arguments on choose via filtration in combobox.
74
+ // - Should highlight chosen item with bold only in cases without view
75
+ // - Should scroll to chosen element (to make it visible), highlight it with bold and set hovered on dropdown open.
76
+ // - Should scroll (to make hovered element visible) and highlight next/previous element on arrow up and arrow down presses when dropdown is opened.
77
+ // - Should correctly set value on enter press while some element hovered.
78
+ // - If select dropdown is closed and select focused, dropdown should toggle open on Enter press.
79
+ // - Opened dropdown could be closed only via value choose, click outside of select and on TAB press.
80
+ // - Should add event listener for outside of dropdown click on list open and remove it on list close.
81
+ // - onClose callback shouldn't fire multiple times on outside click if dropdown was opened multiple times.
82
+
106
83
  exports.SelectTypes = SelectTypes;
107
84
  var cn = (0, _uiHelpers.cnCreate)('mfui-select');
108
85
 
109
- var Select = /*#__PURE__*/function (_React$Component) {
110
- (0, _inherits2["default"])(Select, _React$Component);
86
+ var Select = function Select(_ref) {
87
+ var _ref$type = _ref.type,
88
+ type = _ref$type === void 0 ? 'classic' : _ref$type,
89
+ _ref$disabled = _ref.disabled,
90
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
91
+ verification = _ref.verification,
92
+ noticeText = _ref.noticeText,
93
+ label = _ref.label,
94
+ labelId = _ref.labelId,
95
+ _ref$required = _ref.required,
96
+ required = _ref$required === void 0 ? false : _ref$required,
97
+ _ref$className = _ref.className,
98
+ className = _ref$className === void 0 ? '' : _ref$className,
99
+ _ref$classes = _ref.classes,
100
+ classes = _ref$classes === void 0 ? {} : _ref$classes,
101
+ dataAttrs = _ref.dataAttrs,
102
+ _ref$notFoundText = _ref.notFoundText,
103
+ notFoundText = _ref$notFoundText === void 0 ? 'Ничего не нашлось' : _ref$notFoundText,
104
+ items = _ref.items,
105
+ placeholder = _ref.placeholder,
106
+ currentValue = _ref.currentValue,
107
+ onClosed = _ref.onClosed,
108
+ onOpened = _ref.onOpened,
109
+ onSelect = _ref.onSelect;
110
+
111
+ var _useReducer = (0, React.useReducer)(_selectReducer["default"], _selectReducer.initialState),
112
+ _useReducer2 = (0, _slicedToArray2["default"])(_useReducer, 2),
113
+ selectState = _useReducer2[0],
114
+ changeSelectState = _useReducer2[1];
115
+
116
+ var itemWrapperNode = React.useRef(null);
117
+ var itemsNodeList = React.useRef([]);
118
+ var selectNode = React.useRef(null);
119
+ var itemsList = selectState.itemsList,
120
+ filterValue = selectState.comparableInputValue,
121
+ isOpened = selectState.isOpened,
122
+ hoveredItemIndex = selectState.hoveredItemIndex,
123
+ inputValue = selectState.inputValue;
124
+ var isTouch = (0, _uiHelpers.detectTouch)();
125
+ var currentIndex = itemsList.findIndex(function (elem) {
126
+ return elem.value === currentValue;
127
+ });
128
+ var handleClickOutside = (0, React.useCallback)(function (e) {
129
+ var _a;
130
+
131
+ if (e.target instanceof Node && ((_a = selectNode.current) === null || _a === void 0 ? void 0 : _a.contains(e.target)) || !isOpened) {
132
+ return;
133
+ }
111
134
 
112
- var _super = _createSuper(Select);
135
+ onClosed === null || onClosed === void 0 ? void 0 : onClosed();
136
+ changeSelectState({
137
+ type: TOGGLE_DROPDOWN,
138
+ isOpened: false
139
+ });
140
+ }, [onClosed, isOpened]);
113
141
 
114
- function Select(props) {
115
- var _this;
142
+ var scrollList = function scrollList(itemIndex) {
143
+ if (!itemsNodeList.current.length) {
144
+ return;
145
+ }
116
146
 
117
- (0, _classCallCheck2["default"])(this, Select);
118
- _this = _super.call(this, props);
119
- _this.isTouch = (0, _uiHelpers.detectTouch)();
120
- _this.debouncedComboboxChange = (0, _lodash["default"])(function (filterValue) {
121
- var items = _this.props.items;
122
- var query = filterValue.replace(/[^A-Z-a-zА-ЯЁа-яё0-9]/g, function (w) {
123
- return "\\".concat(w);
124
- });
125
- var filteredItems = items.filter(function (_ref) {
126
- var title = _ref.title;
147
+ var wrapper = itemWrapperNode.current;
148
+ var item = itemsNodeList.current[itemIndex];
127
149
 
128
- if (filterValue.length <= title.length) {
129
- return RegExp(query, 'ig').test(title);
130
- }
150
+ if (!item || !wrapper) {
151
+ return;
152
+ }
131
153
 
132
- return false;
133
- });
154
+ var wrapperScroll = wrapper === null || wrapper === void 0 ? void 0 : wrapper.scrollTop;
155
+ var wrapperHeight = wrapper === null || wrapper === void 0 ? void 0 : wrapper.offsetHeight;
156
+ var itemOffset = item.offsetTop;
157
+ var itemHeight = item.offsetHeight;
134
158
 
135
- _this.setState({
136
- filteredItems: filteredItems,
137
- comparableInputValue: filterValue,
138
- isOpened: true,
139
- activeIndex: 0
140
- });
141
- }, 250);
159
+ if (itemOffset + itemHeight > wrapperScroll + wrapperHeight) {
160
+ wrapper.scrollTop = itemOffset + itemHeight - wrapperHeight;
161
+ }
142
162
 
143
- _this.isEqualItems = function (items, prevItems) {
144
- if (items.length !== prevItems.length) {
145
- return false;
146
- }
163
+ if (itemOffset < wrapperScroll) {
164
+ wrapper.scrollTop = itemOffset;
165
+ }
166
+ };
147
167
 
148
- return items.every(function (item, i) {
149
- var isEqualValue = item.value === prevItems[i].value;
150
- var isEqualTitle = item.title === prevItems[i].title;
151
- return isEqualValue && isEqualTitle;
168
+ (0, React.useEffect)(function () {
169
+ if (!isOpened) {
170
+ // Changes hovered item on dropdown close to currently chosen to hover it on dropdown open
171
+ changeSelectState({
172
+ type: SET_HOVERED_ITEM_INDEX,
173
+ hoveredItemIndex: currentIndex === -1 ? 0 : currentIndex
152
174
  });
153
- };
154
-
155
- _this.handleOpened = function () {
156
- var onOpened = _this.props.onOpened;
157
- onOpened && onOpened();
158
- };
175
+ return undefined;
176
+ }
159
177
 
160
- _this.handleClosed = function () {
161
- var onClosed = _this.props.onClosed;
162
- onClosed && onClosed();
178
+ onOpened === null || onOpened === void 0 ? void 0 : onOpened();
179
+ scrollList(currentIndex);
180
+ document.addEventListener('click', handleClickOutside);
181
+ return function () {
182
+ document.removeEventListener('click', handleClickOutside);
163
183
  };
184
+ }, [isOpened, currentIndex, onOpened, handleClickOutside]);
185
+ (0, React.useEffect)(function () {
186
+ changeSelectState({
187
+ type: UPDATE_ITEMS_LIST,
188
+ items: items
189
+ });
190
+ }, [items]);
191
+ (0, React.useEffect)(function () {
192
+ if (currentIndex === -1) {
193
+ return;
194
+ }
164
195
 
165
- _this.handleClickOutside = function (e) {
166
- var isOpened = _this.state.isOpened;
167
-
168
- if (e.target instanceof Node && _this.selectNode.contains(e.target) || !isOpened) {
169
- return;
196
+ changeSelectState({
197
+ type: UPDATE_VALUE_FROM_PROPS,
198
+ hoveredItemIndex: currentIndex,
199
+ inputValue: itemsList[currentIndex].title,
200
+ comparableInputValue: itemsList[currentIndex].title
201
+ });
202
+ }, [currentIndex, itemsList]);
203
+ var debouncedComboboxChange = (0, _lodash["default"])(function (debounceFilterValue) {
204
+ var query = debounceFilterValue.replace(/[^A-Z-a-zА-ЯЁа-яё0-9]/g, function (w) {
205
+ return "\\".concat(w);
206
+ });
207
+ var debounceItemsList = items.filter(function (_ref2) {
208
+ var title = _ref2.title;
209
+
210
+ if (debounceFilterValue.length <= title.length) {
211
+ return RegExp(query, 'ig').test(title);
170
212
  }
171
213
 
172
- _this.setState({
173
- isOpened: false
174
- }, function () {
175
- if (!_this.state.isOpened) {
176
- _this.handleClosed();
177
- }
178
- });
179
- };
214
+ return false;
215
+ });
216
+ changeSelectState({
217
+ type: COMBOBOX_VALUE_DEBOUNCE,
218
+ items: debounceItemsList,
219
+ comparableInputValue: debounceFilterValue
220
+ });
221
+ }, 250);
222
+
223
+ var handleSelectClick = function handleSelectClick() {
224
+ var isCurrentlyOpened = isOpened;
225
+ changeSelectState({
226
+ type: TOGGLE_DROPDOWN,
227
+ isOpened: !isCurrentlyOpened
228
+ });
229
+ isCurrentlyOpened && (onClosed === null || onClosed === void 0 ? void 0 : onClosed());
230
+ };
180
231
 
181
- _this.handleOpenDropdown = function () {
182
- _this.setState(function (state) {
183
- return {
184
- isOpened: !state.isOpened
185
- };
186
- }, function () {
187
- if (_this.state.isOpened) {
188
- _this.handleOpened();
189
- } else {
190
- _this.handleClosed();
191
- }
192
- });
193
- };
232
+ var handleSelectItem = function handleSelectItem(e) {
233
+ var currentItem = itemsList[hoveredItemIndex].value;
234
+ var item = itemsList.find(function (elem) {
235
+ return elem.value === currentItem;
236
+ });
194
237
 
195
- _this.handleSelectItem = function (e) {
196
- var _this$props = _this.props,
197
- onSelect = _this$props.onSelect,
198
- items = _this$props.items;
199
- var _this$state = _this.state,
200
- activeIndex = _this$state.activeIndex,
201
- filteredItems = _this$state.filteredItems;
202
- var currentItem = filteredItems[activeIndex].value;
203
- var item = filteredItems.find(function (elem) {
204
- return elem.value === currentItem;
205
- });
206
-
207
- if (!item) {
208
- return;
209
- }
238
+ if (!item) {
239
+ return;
240
+ }
210
241
 
211
- var title = item.title;
242
+ var title = item.title;
243
+ changeSelectState({
244
+ type: UPDATE_SELECT_VALUE,
245
+ inputValue: title,
246
+ comparableInputValue: title,
247
+ items: items
248
+ });
249
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(e, item);
250
+ onClosed === null || onClosed === void 0 ? void 0 : onClosed();
251
+ };
212
252
 
213
- _this.setState({
214
- isOpened: false,
215
- inputValue: title,
216
- comparableInputValue: title,
217
- filteredItems: items,
218
- isChoosenItem: true
253
+ var handleHoverItem = function handleHoverItem(index) {
254
+ return function (e) {
255
+ e.preventDefault();
256
+ changeSelectState({
257
+ type: SET_HOVERED_ITEM_INDEX,
258
+ hoveredItemIndex: index
219
259
  });
220
-
221
- onSelect && onSelect(e, item);
222
-
223
- _this.handleClosed();
224
- };
225
-
226
- _this.handleHoverItem = function (index) {
227
- return function (e) {
228
- e.preventDefault();
229
-
230
- _this.setState({
231
- activeIndex: index
232
- });
233
- };
234
260
  };
261
+ };
235
262
 
236
- _this.handleComboboxFocus = function (e) {
237
- var _this$state2 = _this.state,
238
- isOpened = _this$state2.isOpened,
239
- filteredItems = _this$state2.filteredItems;
240
- e.stopPropagation();
263
+ var handleComboboxFocus = function handleComboboxFocus(e) {
264
+ e.stopPropagation();
265
+ changeSelectState({
266
+ type: TOGGLE_DROPDOWN,
267
+ isOpened: !isOpened
268
+ });
241
269
 
242
- _this.setState(function (state) {
243
- return {
244
- isOpened: !state.isOpened
245
- };
246
- });
270
+ if (!isOpened && itemsList) {
271
+ e.target.select();
272
+ }
273
+ };
247
274
 
248
- _this.handleOpened();
275
+ var handleChangeCombobox = function handleChangeCombobox(e) {
276
+ var comboboxValue = e.target.value;
277
+ onSelect && onSelect(null);
278
+ changeSelectState({
279
+ type: COMBOBOX_INPUT_CHANGE,
280
+ inputValue: comboboxValue
281
+ });
282
+ debouncedComboboxChange(comboboxValue);
283
+ };
249
284
 
250
- if (!isOpened && filteredItems) {
251
- e.target.select();
252
- }
253
- };
285
+ var handleKeyDown = function handleKeyDown(e) {
286
+ if (itemsList.length === 0 || disabled) {
287
+ return true;
288
+ }
254
289
 
255
- _this.handleChangeCombobox = function (e) {
256
- var onSelect = _this.props.onSelect;
257
- var isChoosenItem = _this.state.isChoosenItem;
258
- var filterValue = e.target.value;
290
+ if (e.key === 'ArrowDown' && isOpened && hoveredItemIndex < itemsList.length - 1) {
291
+ var nextIndex = hoveredItemIndex + 1;
292
+ e.preventDefault();
293
+ changeSelectState({
294
+ type: SET_HOVERED_ITEM_INDEX,
295
+ hoveredItemIndex: nextIndex
296
+ });
297
+ scrollList(nextIndex);
298
+ return false;
299
+ }
259
300
 
260
- if (isChoosenItem) {
261
- onSelect && onSelect(null);
262
- }
301
+ if (e.key === 'ArrowUp' && isOpened && hoveredItemIndex > 0) {
302
+ var _nextIndex = hoveredItemIndex - 1;
263
303
 
264
- _this.setState({
265
- inputValue: filterValue,
266
- isChoosenItem: false
304
+ e.preventDefault();
305
+ changeSelectState({
306
+ type: SET_HOVERED_ITEM_INDEX,
307
+ hoveredItemIndex: _nextIndex
267
308
  });
309
+ scrollList(_nextIndex);
310
+ return false;
311
+ }
268
312
 
269
- _this.debouncedComboboxChange(filterValue);
270
- };
271
-
272
- _this.handleKeyDown = function (e) {
273
- var _this$state3 = _this.state,
274
- activeIndex = _this$state3.activeIndex,
275
- isOpened = _this$state3.isOpened,
276
- filteredItems = _this$state3.filteredItems;
277
- var disabled = _this.props.disabled;
313
+ if (e.key === 'Enter' && isOpened) {
314
+ handleSelectItem(e);
315
+ return false;
316
+ }
278
317
 
279
- if (filteredItems.length === 0 || disabled) {
280
- return true;
281
- }
318
+ if (e.key === 'Enter' && !isOpened) {
319
+ changeSelectState({
320
+ type: TOGGLE_DROPDOWN,
321
+ isOpened: true
322
+ });
323
+ onOpened === null || onOpened === void 0 ? void 0 : onOpened();
324
+ return false;
325
+ }
282
326
 
283
- if (e.key === 'ArrowDown' && isOpened && activeIndex < filteredItems.length - 1) {
284
- _this.setState({
285
- activeIndex: activeIndex + 1
286
- }, function () {
287
- _this.scrollList(_this.state.activeIndex);
288
- });
327
+ if (e.key === 'Tab') {
328
+ changeSelectState({
329
+ type: TOGGLE_DROPDOWN,
330
+ isOpened: false
331
+ });
332
+ return false;
333
+ }
289
334
 
290
- e.preventDefault();
291
- return false;
292
- }
335
+ return true;
336
+ };
293
337
 
294
- if (e.key === 'ArrowUp' && isOpened && activeIndex > 0) {
295
- _this.setState(function (prevState) {
296
- return {
297
- activeIndex: prevState.activeIndex - 1
298
- };
299
- }, function () {
300
- _this.scrollList(_this.state.activeIndex);
338
+ var highlightString = function highlightString(title, isItemActive, view) {
339
+ if (type === SelectTypes.CLASSIC) {
340
+ if (typeof view === 'function' && !React.isValidElement(view)) {
341
+ return view({
342
+ filterValue: inputValue,
343
+ isItemActive: isItemActive
301
344
  });
302
-
303
- e.preventDefault();
304
- return false;
305
345
  }
306
346
 
307
- if (e.key === 'Enter' && isOpened) {
308
- _this.handleSelectItem(e);
309
-
310
- return false;
311
- }
312
-
313
- if (e.key === 'Enter' && !isOpened) {
314
- _this.setState({
315
- isOpened: true
316
- });
317
-
318
- _this.handleOpened();
319
-
320
- return false;
321
- }
347
+ return view || title;
348
+ }
322
349
 
323
- if (e.key === 'Tab') {
324
- _this.setState({
325
- isOpened: false
350
+ if (type === SelectTypes.COMBOBOX && view) {
351
+ if (typeof view === 'function' && !React.isValidElement(view)) {
352
+ return view({
353
+ filterValue: inputValue,
354
+ isItemActive: isItemActive
326
355
  });
327
-
328
- return false;
329
356
  }
330
357
 
331
- return true;
332
- };
333
-
334
- _this.highlightString = function (title, view) {
335
- var type = _this.props.type;
336
- var _this$state4 = _this.state,
337
- comparableInputValue = _this$state4.comparableInputValue,
338
- inputValue = _this$state4.inputValue;
339
-
340
- if (type === SelectTypes.CLASSIC) {
341
- if (typeof view === 'function' && !React.isValidElement(view)) {
342
- return view({
343
- filterValue: inputValue
344
- });
345
- }
346
-
347
- return view || title;
348
- }
349
-
350
- if (type === SelectTypes.COMBOBOX && view) {
351
- if (typeof view === 'function' && !React.isValidElement(view)) {
352
- return view({
353
- filterValue: inputValue
354
- });
355
- }
356
-
357
- return view;
358
- }
359
-
360
- var stringFragments = title.split(RegExp("(".concat(comparableInputValue, ")"), 'ig'));
361
- return /*#__PURE__*/React.createElement(React.Fragment, null, stringFragments.map(function (fragment, i) {
362
- return /*#__PURE__*/React.createElement(React.Fragment, {
363
- key: i
364
- }, fragment.toLowerCase() === comparableInputValue.toLowerCase() && fragment !== '' ? /*#__PURE__*/React.createElement("span", {
365
- className: cn('highlighted-fragment')
366
- }, fragment) : fragment);
367
- }));
368
- };
369
-
370
- _this.getItemWrapper = function (node) {
371
- _this.itemWrapperNode = node;
372
- };
373
-
374
- _this.getSelectNode = function (node) {
375
- _this.selectNode = node;
376
- };
377
-
378
- _this.getNodeList = function (node) {
379
- return _this.itemsNodeList.push(node);
380
- };
381
-
382
- _this.state = {
383
- isOpened: false,
384
- activeIndex: 0,
385
- filteredItems: props.items,
386
- comparableInputValue: '',
387
- inputValue: '',
388
- isChoosenItem: false
389
- };
390
- _this.itemsNodeList = [];
391
- return _this;
392
- }
393
-
394
- (0, _createClass2["default"])(Select, [{
395
- key: "componentDidMount",
396
- value: function componentDidMount() {
397
- var currentValue = this.props.currentValue;
398
- var filteredItems = this.state.filteredItems;
399
- var currentIndex = filteredItems.findIndex(function (elem) {
400
- return elem.value === currentValue;
401
- });
402
-
403
- if (currentIndex !== -1) {
404
- this.setState({
405
- activeIndex: currentIndex,
406
- inputValue: filteredItems[currentIndex].title,
407
- comparableInputValue: filteredItems[currentIndex].title
408
- });
409
- }
358
+ return view;
410
359
  }
411
- }, {
412
- key: "componentDidUpdate",
413
- value: function componentDidUpdate(_ref2) {
414
- var prevItems = _ref2.items;
415
- var items = this.props.items;
416
- var isOpened = this.state.isOpened;
417
-
418
- if (!this.isEqualItems(items, prevItems)) {
419
- // eslint-disable-next-line react/no-did-update-set-state
420
- this.setState({
421
- filteredItems: items
422
- });
423
- }
424
360
 
425
- if (isOpened) {
426
- document.addEventListener('click', this.handleClickOutside);
427
- return;
428
- }
361
+ var stringFragments = title.split(RegExp("(".concat(filterValue, ")"), 'ig'));
362
+ return /*#__PURE__*/React.createElement(React.Fragment, null, stringFragments.map(function (fragment, i) {
363
+ return /*#__PURE__*/React.createElement(React.Fragment, {
364
+ key: i
365
+ }, fragment.toLowerCase() === filterValue.toLowerCase() && fragment !== '' ? /*#__PURE__*/React.createElement("span", {
366
+ className: cn('highlighted-fragment')
367
+ }, fragment) : fragment);
368
+ }));
369
+ };
429
370
 
430
- document.removeEventListener('click', this.handleClickOutside);
371
+ var getNodeList = (0, React.useCallback)(function (node) {
372
+ if (filterValue.trim()) {
373
+ itemsNodeList.current = [];
374
+ return;
431
375
  }
432
- }, {
433
- key: "componentWillUnmount",
434
- value: function componentWillUnmount() {
435
- document.removeEventListener('click', this.handleClickOutside);
436
- }
437
- }, {
438
- key: "scrollList",
439
- value: function scrollList(activeIndex) {
440
- if (!this.itemsNodeList) {
441
- return;
442
- }
443
376
 
444
- var wrapper = this.itemWrapperNode;
445
- var wrapperScroll = wrapper.scrollTop;
446
- var wrapperHeight = wrapper.offsetHeight;
447
- var item = this.itemsNodeList[activeIndex];
377
+ !filterValue && node && itemsNodeList.current.push(node);
378
+ }, [filterValue]);
448
379
 
449
- if (!item) {
450
- return;
451
- }
380
+ var renderTitle = function renderTitle() {
381
+ var item = items.find(function (elem) {
382
+ return elem.value === currentValue;
383
+ });
384
+ var inputTitle = placeholder;
452
385
 
453
- var itemOffset = item.offsetTop;
454
- var itemHeight = item.offsetHeight;
386
+ if (item && item.title) {
387
+ inputTitle = item.selectedView ? item.selectedView : item.title;
388
+ }
455
389
 
456
- if (itemOffset + itemHeight > wrapperScroll + wrapperHeight) {
457
- wrapper.scrollTop = itemOffset + itemHeight - wrapperHeight;
458
- }
390
+ return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.title), {
391
+ className: cn('title', {
392
+ placeholder: !!placeholder && !currentValue
393
+ }, [classes === null || classes === void 0 ? void 0 : classes.title]),
394
+ role: "button",
395
+ tabIndex: 0,
396
+ onClick: handleSelectClick
397
+ }), /*#__PURE__*/React.createElement("div", {
398
+ className: cn('title-inner', [classes === null || classes === void 0 ? void 0 : classes.titleInner])
399
+ }, inputTitle));
400
+ };
459
401
 
460
- if (itemOffset < wrapperScroll) {
461
- wrapper.scrollTop = itemOffset;
462
- }
463
- }
464
- }, {
465
- key: "renderTitle",
466
- value: function renderTitle() {
467
- var _this$props2 = this.props,
468
- placeholder = _this$props2.placeholder,
469
- items = _this$props2.items,
470
- currentValue = _this$props2.currentValue,
471
- classes = _this$props2.classes,
472
- dataAttrs = _this$props2.dataAttrs;
473
- var item = items.find(function (elem) {
474
- return elem.value === currentValue;
475
- });
476
- var inputTitle = placeholder;
402
+ var renderCombobox = function renderCombobox() {
403
+ return /*#__PURE__*/React.createElement("input", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.input), {
404
+ className: cn('combobox'),
405
+ onFocus: handleComboboxFocus,
406
+ onChange: handleChangeCombobox,
407
+ type: "text",
408
+ value: inputValue,
409
+ placeholder: placeholder
410
+ }));
411
+ };
477
412
 
478
- if (item && item.title) {
479
- inputTitle = item.selectedView ? item.selectedView : item.title;
480
- }
413
+ var renderChildren = function renderChildren() {
414
+ var currentItems = type === SelectTypes.COMBOBOX ? itemsList : items;
415
+ return /*#__PURE__*/React.createElement("div", {
416
+ className: cn('list', [classes.list])
417
+ }, /*#__PURE__*/React.createElement("div", {
418
+ className: cn('list-inner'),
419
+ ref: itemWrapperNode
420
+ }, currentItems.map(function (_ref3, i) {
421
+ var title = _ref3.title,
422
+ value = _ref3.value,
423
+ view = _ref3.view;
424
+ var isItemActive = currentValue === value;
425
+ return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.listItem, i + 1), {
426
+ className: cn('list-item', {
427
+ hovered: hoveredItemIndex === i
428
+ }, [classes.listItem]),
429
+ key: "".concat(i, "_").concat(value),
430
+ onClick: handleSelectItem,
431
+ onMouseEnter: handleHoverItem(i),
432
+ ref: getNodeList
433
+ }), /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.listItemTitle, i + 1), {
434
+ className: cn('item-title', {
435
+ active: isItemActive && !view
436
+ }, [classes.listItemTitle])
437
+ }), highlightString(title, isItemActive, view)));
438
+ }), type === SelectTypes.COMBOBOX && !currentItems.length && /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.notFound), {
439
+ className: cn('not-found')
440
+ }), notFoundText)));
441
+ };
481
442
 
482
- return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.title), {
483
- className: cn('title', {
484
- placeholder: !!placeholder && !currentValue
485
- }, [classes === null || classes === void 0 ? void 0 : classes.title]),
486
- role: "button",
487
- tabIndex: 0,
488
- onClick: this.handleOpenDropdown
489
- }), /*#__PURE__*/React.createElement("div", {
490
- className: cn('title-inner', [classes === null || classes === void 0 ? void 0 : classes.titleInner])
491
- }, inputTitle));
492
- }
493
- }, {
494
- key: "renderCombobox",
495
- value: function renderCombobox() {
496
- var _this$props3 = this.props,
497
- placeholder = _this$props3.placeholder,
498
- dataAttrs = _this$props3.dataAttrs;
499
- var inputValue = this.state.inputValue;
500
- return /*#__PURE__*/React.createElement("input", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.input), {
501
- className: cn('combobox'),
502
- onFocus: this.handleComboboxFocus,
503
- onChange: this.handleChangeCombobox,
504
- type: "text",
505
- value: inputValue,
506
- placeholder: placeholder
507
- }));
508
- }
509
- }, {
510
- key: "renderChildren",
511
- value: function renderChildren() {
512
- var _this2 = this;
513
-
514
- var _this$props4 = this.props,
515
- type = _this$props4.type,
516
- items = _this$props4.items,
517
- notFoundText = _this$props4.notFoundText,
518
- _this$props4$classes = _this$props4.classes,
519
- classes = _this$props4$classes === void 0 ? {} : _this$props4$classes,
520
- dataAttrs = _this$props4.dataAttrs;
521
- var _this$state5 = this.state,
522
- filteredItems = _this$state5.filteredItems,
523
- activeIndex = _this$state5.activeIndex;
524
- var currentItems = type === SelectTypes.COMBOBOX ? filteredItems : items;
525
- return /*#__PURE__*/React.createElement("div", {
526
- className: cn('list', [classes.list])
527
- }, /*#__PURE__*/React.createElement("div", {
528
- className: cn('list-inner'),
529
- ref: this.getItemWrapper
530
- }, currentItems.map(function (_ref3, i) {
531
- var title = _ref3.title,
532
- value = _ref3.value,
533
- view = _ref3.view;
534
- return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.listItem, i + 1), {
535
- className: cn('list-item', {
536
- active: activeIndex === i
537
- }, [classes.listItem]),
538
- key: "".concat(i, "_").concat(value),
539
- onClick: _this2.handleSelectItem,
540
- onMouseEnter: _this2.handleHoverItem(i),
541
- ref: _this2.getNodeList
542
- }), /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.listItemTitle, i + 1), {
543
- className: cn('item-title', [classes.listItemTitle])
544
- }), _this2.highlightString(title, view)));
545
- }), type === SelectTypes.COMBOBOX && !currentItems.length && /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.notFound), {
546
- className: cn('not-found')
547
- }), notFoundText)));
548
- }
549
- }, {
550
- key: "render",
551
- value: function render() {
552
- var _this$props5 = this.props,
553
- type = _this$props5.type,
554
- disabled = _this$props5.disabled,
555
- verification = _this$props5.verification,
556
- noticeText = _this$props5.noticeText,
557
- label = _this$props5.label,
558
- labelId = _this$props5.labelId,
559
- required = _this$props5.required,
560
- _this$props5$classNam = _this$props5.className,
561
- className = _this$props5$classNam === void 0 ? '' : _this$props5$classNam,
562
- _this$props5$classes = _this$props5.classes,
563
- classes = _this$props5$classes === void 0 ? {} : _this$props5$classes,
564
- dataAttrs = _this$props5.dataAttrs;
565
- var isOpened = this.state.isOpened;
566
- return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
567
- className: cn({
568
- open: isOpened,
569
- disabled: disabled,
570
- 'no-touch': !this.isTouch,
571
- valid: verification === Verification.VALID,
572
- error: verification === Verification.ERROR
573
- }, [className, classes.root]),
574
- ref: this.getSelectNode
575
- }), /*#__PURE__*/React.createElement("div", {
576
- className: cn('inner')
577
- }, label && /*#__PURE__*/React.createElement(_InputLabel["default"], {
578
- dataAttrs: {
579
- root: dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.label
580
- },
581
- htmlFor: labelId
582
- }, label, required && /*#__PURE__*/React.createElement("span", {
583
- className: cn('require-mark')
584
- }, "*")), /*#__PURE__*/React.createElement("div", {
585
- className: cn('control', classes.control),
586
- onKeyDown: this.handleKeyDown
587
- }, type === SelectTypes.COMBOBOX && this.renderCombobox(), type === SelectTypes.CLASSIC && this.renderTitle()), this.renderChildren()), noticeText && /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.noticeText), {
588
- className: cn('text', {
589
- error: verification === Verification.ERROR,
590
- success: verification === Verification.VALID
591
- })
592
- }), noticeText));
593
- }
594
- }]);
595
- return Select;
596
- }(React.Component);
443
+ return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
444
+ className: cn({
445
+ open: isOpened,
446
+ disabled: disabled,
447
+ 'no-touch': !isTouch,
448
+ valid: verification === Verification.VALID,
449
+ error: verification === Verification.ERROR
450
+ }, [className, classes.root]),
451
+ ref: selectNode
452
+ }), /*#__PURE__*/React.createElement("div", {
453
+ className: cn('inner')
454
+ }, label && /*#__PURE__*/React.createElement(_InputLabel["default"], {
455
+ dataAttrs: {
456
+ root: dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.label
457
+ },
458
+ htmlFor: labelId
459
+ }, label, required && /*#__PURE__*/React.createElement("span", {
460
+ className: cn('require-mark')
461
+ }, "*")), /*#__PURE__*/React.createElement("div", {
462
+ className: cn('control', classes.control),
463
+ onKeyDown: handleKeyDown
464
+ }, type === SelectTypes.COMBOBOX && renderCombobox(), type === SelectTypes.CLASSIC && renderTitle()), renderChildren()), noticeText && /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.noticeText), {
465
+ className: cn('text', {
466
+ error: verification === Verification.ERROR,
467
+ success: verification === Verification.VALID
468
+ })
469
+ }), noticeText));
470
+ };
597
471
 
598
472
  Select.propTypes = {
599
473
  type: PropTypes.oneOf(Object.values(SelectTypes)),
@@ -636,11 +510,5 @@ Select.propTypes = {
636
510
  onOpened: PropTypes.func,
637
511
  onClosed: PropTypes.func
638
512
  };
639
- Select.defaultProps = {
640
- disabled: false,
641
- required: false,
642
- type: 'classic',
643
- notFoundText: 'Ничего не нашлось'
644
- };
645
513
  var _default = Select;
646
514
  exports["default"] = _default;