@sima-land/moleculas 14.2.0 → 15.0.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.
@@ -47,9 +47,11 @@ exports.HoverCard = (0, react_1.forwardRef)((props, ref) => {
47
47
  const ProductCard = (_a) => {
48
48
  var { children, className } = _a, props = __rest(_a, ["children", "className"]);
49
49
  const [hovered, toggle] = (0, react_1.useState)(false);
50
- return (react_1.default.createElement("div", Object.assign({}, props, { "data-testid": 'product-card', className: (0, classnames_1.default)(product_card_module_scss_1.default.root, className) }),
51
- react_1.default.createElement("div", { "data-testid": 'product-card:info', onMouseEnter: () => toggle(true) }, (0, exports.reduceBaseInfo)(children)),
52
- hovered && (react_1.default.createElement(exports.HoverCard, { onMouseLeave: () => toggle(false) }, (0, exports.reduceHoverInfo)(children)))));
50
+ return (react_1.default.createElement("div", Object.assign({}, props, { "data-testid": 'product-card', className: (0, classnames_1.default)(product_card_module_scss_1.default.root, className), onMouseEnter: () => toggle(true),
51
+ // вешаем onMouseLeave на корневой элемент так как в Chrome проблемы если вешать на "product-card:info"
52
+ onMouseLeave: () => toggle(false) }),
53
+ react_1.default.createElement("div", { "data-testid": 'product-card:info' }, (0, exports.reduceBaseInfo)(children)),
54
+ hovered && react_1.default.createElement(exports.HoverCard, null, (0, exports.reduceHoverInfo)(children))));
53
55
  };
54
56
  exports.ProductCard = ProductCard;
55
57
  /**
@@ -27,6 +27,7 @@ const react_1 = __importStar(require("react"));
27
27
  const carousel_1 = require("@sima-land/ui-nucleons/carousel");
28
28
  const hover_card_1 = require("./hover-card");
29
29
  const utils_1 = require("./utils");
30
+ const intersection_1 = require("@sima-land/ui-nucleons/hooks/intersection");
30
31
  const media_1 = require("@sima-land/ui-nucleons/hooks/media");
31
32
  const product_info_1 = require("../../../common/components/product-info");
32
33
  const bind_1 = __importDefault(require("classnames/bind"));
@@ -62,12 +63,15 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
62
63
  // вычисляем ширину элемента карусели для позиционирования стрелок
63
64
  const itemWidth = (0, utils_1.useChildWidth)(rootRef, `.${cx('item')}`, [items.length]);
64
65
  // инициируем загрузку данных, когда компонент почти попал в зону видимости
65
- (0, utils_1.useViewport)(rootRef, onNeedRequest, {
66
- rootMargin: '200px 0px 200px 0px',
67
- });
66
+ const options = (0, react_1.useMemo)(() => ({ rootMargin: '200px 0px 200px 0px' }), []);
67
+ (0, intersection_1.useIntersection)(rootRef, entry => {
68
+ entry.isIntersecting && onNeedRequest && onNeedRequest();
69
+ }, options);
68
70
  // отправляем статистку, когда компонент попадает в зону видимости
69
- (0, utils_1.useViewport)(rootRef, onInViewport);
70
- return (react_1.default.createElement("div", { ref: rootRef, className: cx('root', className) },
71
+ (0, intersection_1.useIntersection)(rootRef, entry => {
72
+ entry.isIntersecting && onInViewport && onInViewport();
73
+ });
74
+ return (react_1.default.createElement("div", { ref: rootRef, className: cx('root', className), "data-testid": 'product-carousel:root' },
71
75
  items.length > 0 && (react_1.default.createElement(carousel_1.Carousel, Object.assign({ step: 3, draggable: false,
72
76
  // докидываем индекс чтобы позже брать актуальные данные из списка по нему
73
77
  items: items.map((item, index) => [item, index]) }, (itemWidth !== null && {
@@ -1,11 +1,4 @@
1
1
  import React from 'react';
2
- /**
3
- * Вызывает callback когда заданный в ref элемент попал во viewport.
4
- * @param ref Ref отслеживаемого элемента.
5
- * @param callback Функция обратного вызова.
6
- * @param options Опции IntersectionObserver.
7
- */
8
- export declare const useViewport: (ref: React.MutableRefObject<HTMLElement | null>, callback?: (() => void) | undefined, options?: IntersectionObserverInit | undefined) => void;
9
2
  /**
10
3
  * Возвращает объект работы с флагом, который автоматически возвращается в true через заданный промежуток времени.
11
4
  * @return Объект работы с флагом.
@@ -3,34 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.useChildWidth = exports.useAllowFlag = exports.useViewport = void 0;
6
+ exports.useChildWidth = exports.useAllowFlag = void 0;
7
7
  const react_1 = require("react");
8
8
  const on_1 = __importDefault(require("@sima-land/ui-nucleons/helpers/on"));
9
- const identity_1 = require("@sima-land/ui-nucleons/hooks/identity");
10
- /**
11
- * Вызывает callback когда заданный в ref элемент попал во viewport.
12
- * @param ref Ref отслеживаемого элемента.
13
- * @param callback Функция обратного вызова.
14
- * @param options Опции IntersectionObserver.
15
- */
16
- const useViewport = (ref, callback, options) => {
17
- const callbackRef = (0, identity_1.useIdentityRef)(callback);
18
- (0, react_1.useEffect)(() => {
19
- const element = ref.current;
20
- if (element) {
21
- const observer = new IntersectionObserver(entries => {
22
- const fn = callbackRef.current;
23
- for (const entry of entries) {
24
- entry.target === element && entry.isIntersecting && fn && fn();
25
- break;
26
- }
27
- }, options);
28
- observer.observe(element);
29
- return () => observer.disconnect();
30
- }
31
- }, []);
32
- };
33
- exports.useViewport = useViewport;
34
9
  /**
35
10
  * Возвращает объект работы с флагом, который автоматически возвращается в true через заданный промежуток времени.
36
11
  * @return Объект работы с флагом.
@@ -24,7 +24,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.ProductSlider = void 0;
26
26
  const react_1 = __importStar(require("react"));
27
- const utils_1 = require("../../../desktop/components/product-carousel/utils");
27
+ const intersection_1 = require("@sima-land/ui-nucleons/hooks/intersection");
28
28
  const touch_slider_1 = require("@sima-land/ui-nucleons/touch-slider");
29
29
  const product_info_1 = require("../../../common/components/product-info");
30
30
  const product_slider_module_scss_1 = __importDefault(require("./product-slider.module.scss"));
@@ -36,12 +36,15 @@ const product_slider_module_scss_1 = __importDefault(require("./product-slider.m
36
36
  const ProductSlider = ({ children, onInViewport, onNeedRequest }) => {
37
37
  const rootRef = (0, react_1.useRef)(null);
38
38
  // инициируем загрузку данных, когда компонент почти попал в зону видимости
39
- (0, utils_1.useViewport)(rootRef, onNeedRequest, {
40
- rootMargin: '200px 0px 200px 0px',
41
- });
39
+ const options = (0, react_1.useMemo)(() => ({ rootMargin: '200px 0px 200px 0px' }), []);
40
+ (0, intersection_1.useIntersection)(rootRef, entry => {
41
+ entry.isIntersecting && (onNeedRequest === null || onNeedRequest === void 0 ? void 0 : onNeedRequest());
42
+ }, options);
42
43
  // сообщаем, когда компонент попадет в зону видимости
43
- (0, utils_1.useViewport)(rootRef, onInViewport);
44
- return (react_1.default.createElement("div", { ref: rootRef },
44
+ (0, intersection_1.useIntersection)(rootRef, entry => {
45
+ entry.isIntersecting && (onInViewport === null || onInViewport === void 0 ? void 0 : onInViewport());
46
+ });
47
+ return (react_1.default.createElement("div", { ref: rootRef, "data-testid": 'product-slider:root' },
45
48
  react_1.default.createElement(touch_slider_1.TouchSlider, null, react_1.Children.toArray(children).reduce((list, item) => {
46
49
  (0, react_1.isValidElement)(item) &&
47
50
  item.type === product_info_1.ProductInfo &&
@@ -24,10 +24,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.SearchBar = exports.cx = void 0;
26
26
  const react_1 = __importStar(require("react"));
27
- const bind_1 = __importDefault(require("classnames/bind"));
28
- const search_bar_module_scss_1 = __importDefault(require("./search-bar.module.scss"));
29
27
  const lodash_1 = require("lodash");
30
- const link_1 = require("@sima-land/ui-nucleons/link");
31
28
  const colors_1 = require("@sima-land/ui-nucleons/colors");
32
29
  const dropdown_1 = require("@sima-land/ui-nucleons/dropdown");
33
30
  const dropdown_item_1 = require("@sima-land/ui-nucleons/dropdown-item");
@@ -36,6 +33,8 @@ const on_1 = __importDefault(require("@sima-land/ui-nucleons/helpers/on"));
36
33
  const cross_1 = __importDefault(require("@sima-land/ui-quarks/icons/24x24/Filled/cross"));
37
34
  const search_1 = __importDefault(require("@sima-land/ui-quarks/icons/24x24/Stroked/search"));
38
35
  const more_vert_1 = __importDefault(require("@sima-land/ui-quarks/icons/24x24/Filled/more-vert"));
36
+ const bind_1 = __importDefault(require("classnames/bind"));
37
+ const search_bar_module_scss_1 = __importDefault(require("./search-bar.module.scss"));
39
38
  exports.cx = bind_1.default.bind(search_bar_module_scss_1.default);
40
39
  /**
41
40
  * Компонент поисковой строки.
@@ -56,20 +55,25 @@ const SearchBar = ({ value, onChange, inputMode, placeholder = 'Поиск', onC
56
55
  (0, react_1.useEffect)(() => needHideEndButtons
57
56
  ? (0, on_1.default)(window, 'resize', (0, lodash_1.throttle)(() => toggleDropdown(false), 500))
58
57
  : undefined, [needHideEndButtons]);
59
- return (react_1.default.createElement("div", { className: (0, exports.cx)('wrapper') },
58
+ const preventFieldBlur = e => {
59
+ if (inputRef.current &&
60
+ inputRef.current !== e.target && // не предотвращаем события на самом поле (например выделение текста)
61
+ document.activeElement === inputRef.current) {
62
+ e.preventDefault();
63
+ }
64
+ };
65
+ return (react_1.default.createElement("div", { className: (0, exports.cx)('root') },
60
66
  Boolean(startButtons.length) && (react_1.default.createElement("div", { className: (0, exports.cx)('before-field') },
61
67
  react_1.default.createElement("div", { className: (0, exports.cx)('buttons-container') }, startButtons.map((props, index) => (react_1.default.createElement(Button, Object.assign({}, props, { key: index }))))))),
62
- react_1.default.createElement("label", { className: (0, exports.cx)('input-wrapper') },
68
+ react_1.default.createElement("label", { className: (0, exports.cx)('input-wrapper'), onMouseDown: preventFieldBlur, "data-testid": 'search-bar:input-wrapper' },
63
69
  withSearchIcon && (react_1.default.createElement("span", { className: (0, exports.cx)('search-icon') },
64
70
  react_1.default.createElement(search_1.default, { fill: colors_1.COLORS.get('basic-gray38'), "aria-hidden": true }))),
65
71
  react_1.default.createElement("div", { className: (0, exports.cx)('input-container') },
66
72
  react_1.default.createElement("input", { ref: inputRef, value: value, onChange: onChange, className: (0, exports.cx)('search-field'), placeholder: placeholder, autoFocus: autoFocus, "data-testid": 'search-bar-input', type: 'text', inputMode: inputMode, tabIndex: 0 }),
67
73
  description && (react_1.default.createElement("div", { className: (0, exports.cx)('description-container') },
68
74
  react_1.default.createElement("span", { className: (0, exports.cx)('description') }, description)))),
69
- (0, lodash_1.isFunction)(onClear) && value && (react_1.default.createElement(link_1.Link, { onClick: event => {
70
- onClear(event);
71
- inputRef.current && inputRef.current.focus();
72
- }, pseudo: true, "aria-label": '\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C', "data-testid": 'search-bar:clear-icon', className: (0, exports.cx)('clear-icon'), children: react_1.default.createElement(cross_1.default, { fill: colors_1.COLORS.get('basic-gray38'), "aria-hidden": true }) }))),
75
+ value && onClear && (react_1.default.createElement("button", { onClick: onClear, "aria-label": '\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C', "data-testid": 'search-bar:clear-icon', className: (0, exports.cx)('clear-button') },
76
+ react_1.default.createElement(cross_1.default, { fill: colors_1.COLORS.get('basic-gray38'), "aria-hidden": true })))),
73
77
  Boolean(endButtons.length) && (react_1.default.createElement(react_1.default.Fragment, null,
74
78
  react_1.default.createElement("div", { className: (0, exports.cx)('after-field', needHideEndButtons && 'wide-screen') },
75
79
  react_1.default.createElement("div", { className: (0, exports.cx)('buttons-container') }, endButtons.map((props, index) => (react_1.default.createElement(Button, Object.assign({}, props, { key: index })))))),
@@ -1,13 +1,9 @@
1
1
  @import 'node_modules/@sima-land/ui-nucleons/colors';
2
2
 
3
- .wrapper {
3
+ .root {
4
4
  display: flex;
5
5
  }
6
6
 
7
- .search-cancel {
8
- margin-left: 16px;
9
- }
10
-
11
7
  .input-wrapper {
12
8
  display: inline-flex;
13
9
  position: relative;
@@ -18,7 +14,7 @@
18
14
  border-radius: 8px;
19
15
  padding: 0 0 0 12px;
20
16
  &:focus-within {
21
- .clear-icon {
17
+ .clear-button {
22
18
  display: flex;
23
19
  }
24
20
  .input-container {
@@ -42,12 +38,12 @@
42
38
  display: flex;
43
39
  justify-content: space-around;
44
40
  align-items: center;
45
- padding-right: 12px;
46
41
  }
47
42
 
48
43
  .search-field {
49
44
  background-color: transparent;
50
45
  margin: 0;
46
+ padding: 0;
51
47
  border: 0;
52
48
  outline: 0;
53
49
  line-height: 24px;
@@ -84,13 +80,15 @@
84
80
  text-overflow: ellipsis;
85
81
  }
86
82
 
87
- .clear-icon {
83
+ .clear-button {
88
84
  position: relative;
89
85
  align-items: center;
90
86
  justify-content: center;
91
87
  padding: 0 12px;
92
88
  display: none;
93
89
  cursor: pointer;
90
+ background: transparent;
91
+ border: 0;
94
92
  }
95
93
 
96
94
  .hidden {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sima-land/moleculas",
3
- "version": "14.2.0",
3
+ "version": "15.0.0",
4
4
  "repository": "ssh://git@github.com:sima-land/moleculas.git",
5
5
  "author": "www.sima-land.ru team",
6
6
  "license": "Apache-2.0",
@@ -25,7 +25,7 @@
25
25
  "prettier:check": "prettier --check \"./src/**/*.{js,jsx,ts,tsx,css,scss}\" --loglevel error"
26
26
  },
27
27
  "dependencies": {
28
- "@sima-land/ui-nucleons": "^43.1.0",
28
+ "@sima-land/ui-nucleons": "^44.0.1",
29
29
  "@sima-land/ui-quarks": "^2.2.0",
30
30
  "classnames": "^2.3.1",
31
31
  "date-fns": "^2.26.0",