@sima-land/moleculas 16.0.0-alpha.0 → 16.0.0-alpha.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.
- package/common/components/modifier/index.d.ts +46 -0
- package/common/components/modifier/index.js +102 -0
- package/common/components/modifier/modifiers.module.scss +121 -0
- package/desktop/components/modifiers/group/modifiers-group.module.scss +2 -0
- package/desktop/components/product-carousel/index.d.ts +1 -1
- package/desktop/components/product-carousel/index.js +36 -27
- package/desktop/components/product-carousel/utils.d.ts +2 -3
- package/desktop/components/product-carousel/utils.js +17 -20
- package/package.json +4 -2
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AnchorHTMLAttributes } from 'react';
|
|
2
|
+
interface TextContent {
|
|
3
|
+
type: 'text';
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
interface ColorContent {
|
|
7
|
+
type: 'color';
|
|
8
|
+
color: string;
|
|
9
|
+
}
|
|
10
|
+
interface ImageContent {
|
|
11
|
+
type: 'image';
|
|
12
|
+
src: string;
|
|
13
|
+
}
|
|
14
|
+
export type ModifierContent = TextContent | ColorContent | ImageContent;
|
|
15
|
+
export interface ModifierProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
16
|
+
/** Вывести выбранным. */
|
|
17
|
+
active?: boolean;
|
|
18
|
+
/** Вывести отключенным. */
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** Вывести зачеркнутым. */
|
|
21
|
+
crossedOut?: boolean;
|
|
22
|
+
/** Содержимое. */
|
|
23
|
+
content: ModifierContent;
|
|
24
|
+
/** Высота по дизайн-гайдам. */
|
|
25
|
+
size?: 's' | 'm';
|
|
26
|
+
/** Кол-во. */
|
|
27
|
+
count?: number;
|
|
28
|
+
/** Идентификатор для систем автоматизированного тестирования. */
|
|
29
|
+
'data-testid'?: string;
|
|
30
|
+
}
|
|
31
|
+
export type MoreButtonProps = Omit<ModifierProps, 'content' | 'crossedOut' | 'active' | 'count'> & {
|
|
32
|
+
count: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Кнопка модификатора (аналога товара).
|
|
36
|
+
* @param props Свойства.
|
|
37
|
+
* @return Элемент.
|
|
38
|
+
*/
|
|
39
|
+
export declare function Modifier({ size, active, crossedOut, disabled, content, count, className, 'data-testid': testId, ...props }: ModifierProps): JSX.Element;
|
|
40
|
+
/**
|
|
41
|
+
* Кнопка "+N" для показа полного списка модификаторов.
|
|
42
|
+
* @param props Свойства.
|
|
43
|
+
* @return Элемент.
|
|
44
|
+
*/
|
|
45
|
+
export declare function MoreButton({ count, className, 'data-testid': testId, ...rest }: MoreButtonProps): JSX.Element;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
+
var t = {};
|
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
+
t[p] = s[p];
|
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
+
t[p[i]] = s[p[i]];
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
};
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.MoreButton = exports.Modifier = void 0;
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
42
|
+
const hint_1 = require("@sima-land/ui-nucleons/hint");
|
|
43
|
+
const bind_1 = __importDefault(require("classnames/bind"));
|
|
44
|
+
const modifiers_module_scss_1 = __importDefault(require("./modifiers.module.scss"));
|
|
45
|
+
const cx = bind_1.default.bind(modifiers_module_scss_1.default);
|
|
46
|
+
/**
|
|
47
|
+
* Кнопка модификатора (аналога товара).
|
|
48
|
+
* @param props Свойства.
|
|
49
|
+
* @return Элемент.
|
|
50
|
+
*/
|
|
51
|
+
function Modifier(_a) {
|
|
52
|
+
var { size = 'm', active, crossedOut, disabled, content, count, className, 'data-testid': testId = 'modifier' } = _a, props = __rest(_a, ["size", "active", "crossedOut", "disabled", "content", "count", "className", 'data-testid']);
|
|
53
|
+
// текст хинта
|
|
54
|
+
const [hint, setHint] = (0, react_1.useState)('');
|
|
55
|
+
// состояние хинта
|
|
56
|
+
const [open, setOpen] = (0, react_1.useState)(false);
|
|
57
|
+
// позиционирование хинта
|
|
58
|
+
const _b = (0, hint_1.useHintFloating)({ open, onOpenChange: setOpen }), { refs } = _b, floating = __rest(_b, ["refs"]);
|
|
59
|
+
// пользовательское взаимодействие для хинта
|
|
60
|
+
const { getReferenceProps, getFloatingProps } = (0, hint_1.useHintOnHover)(floating);
|
|
61
|
+
// определение необходимости активации хинта
|
|
62
|
+
(0, react_1.useEffect)(() => {
|
|
63
|
+
const textElement = refs.reference.current;
|
|
64
|
+
if (!(textElement instanceof HTMLElement) || content.type !== 'text') {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// eslint-disable-next-line require-jsdoc
|
|
68
|
+
const defineHint = () => setHint(isTruncated(textElement) ? content.text : '');
|
|
69
|
+
defineHint();
|
|
70
|
+
const observer = new ResizeObserver(defineHint);
|
|
71
|
+
observer.observe(textElement);
|
|
72
|
+
return () => observer.disconnect();
|
|
73
|
+
}, [content.text]);
|
|
74
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
75
|
+
react_1.default.createElement("a", Object.assign({}, props, { className: cx('root', `size-${size}`, { active, disabled }, className), "data-testid": testId }),
|
|
76
|
+
content.type === 'color' && (react_1.default.createElement("span", { className: cx('color'), role: 'banner', style: { background: content.color } })),
|
|
77
|
+
content.type === 'image' && (react_1.default.createElement("span", { className: cx('image'), role: 'banner', style: { backgroundImage: `url(${content.src})` } })),
|
|
78
|
+
content.type === 'text' && (react_1.default.createElement("span", Object.assign({ ref: refs.setReference, className: cx('text') }, getReferenceProps()), content.text)),
|
|
79
|
+
typeof count === 'number' && (react_1.default.createElement("span", { className: cx('counter') }, count > 99 ? '99+' : count)),
|
|
80
|
+
crossedOut && (react_1.default.createElement("svg", { width: '100%', height: '100%', className: cx('diagonal') },
|
|
81
|
+
react_1.default.createElement("line", { x1: '0', y1: '100%', x2: '100%', y2: '0', stroke: 'var(--modifier-border-color)' })))),
|
|
82
|
+
hint && (react_1.default.createElement(hint_1.Hint, Object.assign({ open: open, hintRef: refs.setFloating, arrowRef: refs.setArrow }, getFloatingProps()), hint))));
|
|
83
|
+
}
|
|
84
|
+
exports.Modifier = Modifier;
|
|
85
|
+
/**
|
|
86
|
+
* Кнопка "+N" для показа полного списка модификаторов.
|
|
87
|
+
* @param props Свойства.
|
|
88
|
+
* @return Элемент.
|
|
89
|
+
*/
|
|
90
|
+
function MoreButton(_a) {
|
|
91
|
+
var { count, className, 'data-testid': testId = 'more-modifiers' } = _a, rest = __rest(_a, ["count", "className", 'data-testid']);
|
|
92
|
+
return (react_1.default.createElement(Modifier, Object.assign({ role: 'button', "aria-label": '\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u0441\u0435 \u0430\u043D\u0430\u043B\u043E\u0433\u0438' }, rest, { className: cx('more', className), content: { type: 'text', text: `+${count}` }, "data-testid": testId })));
|
|
93
|
+
}
|
|
94
|
+
exports.MoreButton = MoreButton;
|
|
95
|
+
/**
|
|
96
|
+
* Определяет, обрезан ли текст в элементе.
|
|
97
|
+
* @param el Элемент.
|
|
98
|
+
* @return Обрезан ли текст в элементе.
|
|
99
|
+
*/
|
|
100
|
+
function isTruncated(el) {
|
|
101
|
+
return el.scrollWidth > el.clientWidth;
|
|
102
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
@use 'node_modules/@sima-land/ui-nucleons/colors';
|
|
2
|
+
|
|
3
|
+
.root {
|
|
4
|
+
display: inline-block;
|
|
5
|
+
text-decoration: none;
|
|
6
|
+
position: relative;
|
|
7
|
+
color: var(--modifier-text-color);
|
|
8
|
+
border-radius: 4px;
|
|
9
|
+
min-width: var(--modifier-size);
|
|
10
|
+
min-height: var(--modifier-size);
|
|
11
|
+
font-size: 14px;
|
|
12
|
+
line-height: 20px;
|
|
13
|
+
text-align: center;
|
|
14
|
+
--modifier-text-color: #{colors.$basic-gray87};
|
|
15
|
+
--modifier-border-width: 1px;
|
|
16
|
+
--modifier-border-color: #{colors.$basic-gray12};
|
|
17
|
+
&.active {
|
|
18
|
+
--modifier-border-color: #{colors.$basic-blue};
|
|
19
|
+
}
|
|
20
|
+
&:hover:not(.disabled) {
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
}
|
|
23
|
+
&:hover:not(.disabled):not(.active) {
|
|
24
|
+
--modifier-border-width: 2px;
|
|
25
|
+
}
|
|
26
|
+
&.disabled {
|
|
27
|
+
--modifier-media-opacity: 0.24;
|
|
28
|
+
--modifier-overlay-color: rgba(0, 0, 0, 0.04);
|
|
29
|
+
--modifier-border-width: 0;
|
|
30
|
+
--modifier-text-color: #{colors.$basic-gray38};
|
|
31
|
+
}
|
|
32
|
+
&::after {
|
|
33
|
+
content: '';
|
|
34
|
+
display: block;
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
position: absolute;
|
|
37
|
+
top: 0;
|
|
38
|
+
left: 0;
|
|
39
|
+
width: 100%;
|
|
40
|
+
height: 100%;
|
|
41
|
+
border-radius: inherit;
|
|
42
|
+
box-shadow: inset 0 0 0 var(--modifier-border-width) var(--modifier-border-color);
|
|
43
|
+
background: var(--modifier-overlay-color);
|
|
44
|
+
}
|
|
45
|
+
&.more {
|
|
46
|
+
width: var(--modifier-size);
|
|
47
|
+
--modifier-text-color: #{colors.$basic-blue};
|
|
48
|
+
&.size-s {
|
|
49
|
+
--modifier-padding: 10px 0;
|
|
50
|
+
}
|
|
51
|
+
&.size-m {
|
|
52
|
+
--modifier-padding: 14px 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.size-s {
|
|
58
|
+
--modifier-size: 40px;
|
|
59
|
+
--modifier-padding: 10px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.size-m {
|
|
63
|
+
--modifier-size: 48px;
|
|
64
|
+
--modifier-padding: 14px 15px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.diagonal {
|
|
68
|
+
position: absolute;
|
|
69
|
+
top: 0;
|
|
70
|
+
left: 0;
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
overflow: hidden;
|
|
74
|
+
border-radius: inherit;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.color,
|
|
78
|
+
.image {
|
|
79
|
+
border-radius: inherit;
|
|
80
|
+
display: block;
|
|
81
|
+
position: absolute;
|
|
82
|
+
top: 0;
|
|
83
|
+
left: 0;
|
|
84
|
+
width: 100%;
|
|
85
|
+
height: 100%;
|
|
86
|
+
opacity: var(--modifier-media-opacity);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.image {
|
|
90
|
+
background-position: center;
|
|
91
|
+
background-size: cover;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.text {
|
|
95
|
+
padding: var(--modifier-padding);
|
|
96
|
+
display: block;
|
|
97
|
+
max-width: 100%;
|
|
98
|
+
white-space: nowrap;
|
|
99
|
+
text-overflow: ellipsis;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
|
|
102
|
+
// ВАЖНО: чтобы диагональная черта была под текстом
|
|
103
|
+
position: relative;
|
|
104
|
+
z-index: 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.counter {
|
|
108
|
+
font-weight: 600;
|
|
109
|
+
font-size: 12px;
|
|
110
|
+
line-height: 14px;
|
|
111
|
+
height: 14px;
|
|
112
|
+
overflow: hidden;
|
|
113
|
+
padding: 0 4px;
|
|
114
|
+
background: colors.$additional-teal;
|
|
115
|
+
color: #fff;
|
|
116
|
+
position: absolute;
|
|
117
|
+
right: -2px;
|
|
118
|
+
top: -2px;
|
|
119
|
+
border-radius: 32px;
|
|
120
|
+
z-index: 1;
|
|
121
|
+
}
|
|
@@ -27,5 +27,5 @@ export interface ProductCarouselProps {
|
|
|
27
27
|
* @param props Свойства.
|
|
28
28
|
* @return Элемент.
|
|
29
29
|
*/
|
|
30
|
-
export declare
|
|
30
|
+
export declare function ProductCarousel({ className, itemSize, onInViewport, onNeedRequest, withHoverCard, children, }: ProductCarouselProps): JSX.Element;
|
|
31
31
|
export {};
|
|
@@ -51,7 +51,7 @@ const getSizeClasses = (size = {}) => [
|
|
|
51
51
|
* @param props Свойства.
|
|
52
52
|
* @return Элемент.
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
function ProductCarousel({ className, itemSize, onInViewport, onNeedRequest, withHoverCard, children, }) {
|
|
55
55
|
const layer = (0, layer_1.useLayer)();
|
|
56
56
|
const [activeItemIndex, setActiveItemIndex] = (0, react_1.useState)(null);
|
|
57
57
|
const cardShow = (0, utils_1.useAllowFlag)();
|
|
@@ -66,7 +66,8 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
|
|
|
66
66
|
items = children ? [children] : [];
|
|
67
67
|
}
|
|
68
68
|
// вычисляем ширину элемента карусели для позиционирования стрелок
|
|
69
|
-
const
|
|
69
|
+
const firstItemRef = (0, react_1.useRef)(null);
|
|
70
|
+
const itemWidth = (0, utils_1.useClientWidth)(firstItemRef, [items.length]);
|
|
70
71
|
// инициируем загрузку данных, когда компонент почти попал в зону видимости
|
|
71
72
|
const options = (0, react_1.useMemo)(() => ({ rootMargin: '200px 0px 200px 0px' }), []);
|
|
72
73
|
(0, intersection_1.useIntersection)(rootRef, entry => {
|
|
@@ -88,34 +89,12 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
|
|
|
88
89
|
top: `${itemWidth / 2}px`,
|
|
89
90
|
},
|
|
90
91
|
},
|
|
91
|
-
}), { renderItem: ([item, index]) => (react_1.default.createElement(
|
|
92
|
+
}), { renderItem: ([item, index], realIndex) => (react_1.default.createElement(ProductCarouselItem, { rootRef: realIndex === 0 ? firstItemRef : undefined, withHoverCard: withHoverCard, className: cx(getSizeClasses(itemSize)), onMouseEnter: e => {
|
|
92
93
|
if (cardShow.allowed()) {
|
|
93
94
|
targetItemRef.current = e.currentTarget;
|
|
94
95
|
setActiveItemIndex(index);
|
|
95
96
|
}
|
|
96
|
-
} },
|
|
97
|
-
children: react_1.Children.toArray(item.props.children).reduce((list, child) => {
|
|
98
|
-
if ((0, react_1.isValidElement)(child)) {
|
|
99
|
-
switch (child.type) {
|
|
100
|
-
case product_info_1.Parts.Image: {
|
|
101
|
-
// иконки у картинки скрываем если есть HoverCard
|
|
102
|
-
list.push(withHoverCard ? (0, react_1.cloneElement)(child, { children: undefined }) : child);
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
case product_info_1.Parts.Footer:
|
|
106
|
-
// футер не выводим если есть HoverCard
|
|
107
|
-
!withHoverCard && list.push(child);
|
|
108
|
-
break;
|
|
109
|
-
default: {
|
|
110
|
-
// остальное выводим как есть
|
|
111
|
-
list.push(child);
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return list;
|
|
117
|
-
}, []),
|
|
118
|
-
}))),
|
|
97
|
+
} }, item)),
|
|
119
98
|
// длительность прокрутки в Carousel - 320, делаем слегка с запасом
|
|
120
99
|
// @todo после восстановления проверить позицию курсора чтобы показать карточку (если будет критично)
|
|
121
100
|
onChangeTargetIndex: () => cardShow.disallowFor(360) }))),
|
|
@@ -123,5 +102,35 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
|
|
|
123
102
|
activeItemIndex !== null &&
|
|
124
103
|
items[activeItemIndex] &&
|
|
125
104
|
[items[activeItemIndex]].map(item => (react_1.default.createElement(hover_card_1.HoverCard, Object.assign({ key: activeItemIndex, targetRef: targetItemRef, onMouseLeave: () => setActiveItemIndex(null) }, item.props))))));
|
|
126
|
-
}
|
|
105
|
+
}
|
|
127
106
|
exports.ProductCarousel = ProductCarousel;
|
|
107
|
+
/**
|
|
108
|
+
* Элемент карусели. Выведет базовый контент.
|
|
109
|
+
* Полное содержимое будет выведено во всплывающей карточке.
|
|
110
|
+
* @inheritdoc
|
|
111
|
+
*/
|
|
112
|
+
function ProductCarouselItem({ rootRef, className, onMouseEnter, withHoverCard, children, }) {
|
|
113
|
+
return (react_1.default.createElement("div", { ref: rootRef, "data-testid": 'product-carousel:item', className: cx('item', className), onMouseEnter: onMouseEnter }, (0, react_1.cloneElement)(children, {
|
|
114
|
+
children: react_1.Children.toArray(children.props.children).reduce((list, child) => {
|
|
115
|
+
if ((0, react_1.isValidElement)(child)) {
|
|
116
|
+
switch (child.type) {
|
|
117
|
+
case product_info_1.Parts.Image: {
|
|
118
|
+
// иконки у картинки скрываем если есть HoverCard
|
|
119
|
+
list.push(withHoverCard ? (0, react_1.cloneElement)(child, { children: undefined }) : child);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
case product_info_1.Parts.Footer:
|
|
123
|
+
// футер не выводим если есть HoverCard
|
|
124
|
+
!withHoverCard && list.push(child);
|
|
125
|
+
break;
|
|
126
|
+
default: {
|
|
127
|
+
// остальное выводим как есть
|
|
128
|
+
list.push(child);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return list;
|
|
134
|
+
}, []),
|
|
135
|
+
})));
|
|
136
|
+
}
|
|
@@ -9,9 +9,8 @@ export declare const useAllowFlag: () => {
|
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
11
|
* Возвращает ширину дочернего элемента.
|
|
12
|
-
* @param ref Ref элемента.
|
|
13
|
-
* @param selector CSS-селектор дочернего элемента.
|
|
12
|
+
* @param ref Ref дочернего элемента.
|
|
14
13
|
* @param deps Массив зависимостей от которых зависит пересчет.
|
|
15
14
|
* @return Ширина.
|
|
16
15
|
*/
|
|
17
|
-
export declare const
|
|
16
|
+
export declare const useClientWidth: (ref: React.RefObject<HTMLElement | null>, deps?: React.DependencyList) => number | null;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
3
|
+
exports.useClientWidth = exports.useAllowFlag = void 0;
|
|
7
4
|
const react_1 = require("react");
|
|
8
|
-
const on_1 = __importDefault(require("@sima-land/ui-nucleons/helpers/on"));
|
|
9
5
|
/**
|
|
10
6
|
* Возвращает объект работы с флагом, который автоматически возвращается в true через заданный промежуток времени.
|
|
11
7
|
* @return Объект работы с флагом.
|
|
@@ -25,23 +21,24 @@ const useAllowFlag = () => {
|
|
|
25
21
|
exports.useAllowFlag = useAllowFlag;
|
|
26
22
|
/**
|
|
27
23
|
* Возвращает ширину дочернего элемента.
|
|
28
|
-
* @param ref Ref элемента.
|
|
29
|
-
* @param selector CSS-селектор дочернего элемента.
|
|
24
|
+
* @param ref Ref дочернего элемента.
|
|
30
25
|
* @param deps Массив зависимостей от которых зависит пересчет.
|
|
31
26
|
* @return Ширина.
|
|
32
27
|
*/
|
|
33
|
-
const
|
|
34
|
-
const [
|
|
35
|
-
const update = (0, react_1.useCallback)(() => {
|
|
36
|
-
if (ref.current) {
|
|
37
|
-
const child = ref.current.querySelector(selector);
|
|
38
|
-
child && setItemWidth(child.clientWidth);
|
|
39
|
-
}
|
|
40
|
-
}, [ref]);
|
|
28
|
+
const useClientWidth = (ref, deps = []) => {
|
|
29
|
+
const [width, setWidth] = (0, react_1.useState)(null);
|
|
41
30
|
(0, react_1.useEffect)(() => {
|
|
42
|
-
ref.current
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
if (!ref.current) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const element = ref.current;
|
|
35
|
+
const observer = new ResizeObserver(() => {
|
|
36
|
+
setWidth(element.clientWidth);
|
|
37
|
+
});
|
|
38
|
+
observer.observe(ref.current);
|
|
39
|
+
setWidth(element.clientWidth);
|
|
40
|
+
return observer.disconnect();
|
|
41
|
+
}, [ref, ...deps]);
|
|
42
|
+
return width;
|
|
46
43
|
};
|
|
47
|
-
exports.
|
|
44
|
+
exports.useClientWidth = useClientWidth;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sima-land/moleculas",
|
|
3
|
-
"version": "16.0.0-alpha.
|
|
3
|
+
"version": "16.0.0-alpha.2",
|
|
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",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"react-transition-group": "^4.4.5"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@sima-land/ui-nucleons": "^45.0.0-alpha.
|
|
34
|
+
"@sima-land/ui-nucleons": "^45.0.0-alpha.3",
|
|
35
35
|
"@sima-land/ui-quarks": "^3.6.0",
|
|
36
36
|
"react": ">=17",
|
|
37
37
|
"react-dom": ">=17"
|
|
@@ -56,7 +56,9 @@
|
|
|
56
56
|
"@svgr/plugin-jsx": "^6.5.1",
|
|
57
57
|
"@svgr/plugin-svgo": "^6.5.1",
|
|
58
58
|
"@svgr/webpack": "^6.5.1",
|
|
59
|
+
"@testing-library/dom": "^9.2.0",
|
|
59
60
|
"@testing-library/react": "^12.1.0",
|
|
61
|
+
"@testing-library/user-event": "^14.4.3",
|
|
60
62
|
"@types/enzyme": "^3.10.12",
|
|
61
63
|
"@types/jest": "^29.4.0",
|
|
62
64
|
"@types/lodash": "^4.14.191",
|